media: platform: rename davinci/ to ti/davinci/
authorMauro Carvalho Chehab <mchehab@kernel.org>
Sun, 13 Mar 2022 10:18:19 +0000 (11:18 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Fri, 18 Mar 2022 04:58:34 +0000 (05:58 +0100)
As the end goal is to have platform drivers split by vendor,
rename davinci/ to ti/davinci/.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
50 files changed:
Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst
MAINTAINERS
drivers/media/platform/Kconfig
drivers/media/platform/Makefile
drivers/media/platform/davinci/Kconfig [deleted file]
drivers/media/platform/davinci/Makefile [deleted file]
drivers/media/platform/davinci/ccdc_hw_device.h [deleted file]
drivers/media/platform/davinci/dm355_ccdc.c [deleted file]
drivers/media/platform/davinci/dm355_ccdc_regs.h [deleted file]
drivers/media/platform/davinci/dm644x_ccdc.c [deleted file]
drivers/media/platform/davinci/dm644x_ccdc_regs.h [deleted file]
drivers/media/platform/davinci/isif.c [deleted file]
drivers/media/platform/davinci/isif_regs.h [deleted file]
drivers/media/platform/davinci/vpbe.c [deleted file]
drivers/media/platform/davinci/vpbe_display.c [deleted file]
drivers/media/platform/davinci/vpbe_osd.c [deleted file]
drivers/media/platform/davinci/vpbe_osd_regs.h [deleted file]
drivers/media/platform/davinci/vpbe_venc.c [deleted file]
drivers/media/platform/davinci/vpbe_venc_regs.h [deleted file]
drivers/media/platform/davinci/vpfe_capture.c [deleted file]
drivers/media/platform/davinci/vpif.c [deleted file]
drivers/media/platform/davinci/vpif.h [deleted file]
drivers/media/platform/davinci/vpif_capture.c [deleted file]
drivers/media/platform/davinci/vpif_capture.h [deleted file]
drivers/media/platform/davinci/vpif_display.c [deleted file]
drivers/media/platform/davinci/vpif_display.h [deleted file]
drivers/media/platform/davinci/vpss.c [deleted file]
drivers/media/platform/ti/davinci/Kconfig [new file with mode: 0644]
drivers/media/platform/ti/davinci/Makefile [new file with mode: 0644]
drivers/media/platform/ti/davinci/ccdc_hw_device.h [new file with mode: 0644]
drivers/media/platform/ti/davinci/dm355_ccdc.c [new file with mode: 0644]
drivers/media/platform/ti/davinci/dm355_ccdc_regs.h [new file with mode: 0644]
drivers/media/platform/ti/davinci/dm644x_ccdc.c [new file with mode: 0644]
drivers/media/platform/ti/davinci/dm644x_ccdc_regs.h [new file with mode: 0644]
drivers/media/platform/ti/davinci/isif.c [new file with mode: 0644]
drivers/media/platform/ti/davinci/isif_regs.h [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpbe.c [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpbe_display.c [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpbe_osd.c [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpbe_osd_regs.h [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpbe_venc.c [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpbe_venc_regs.h [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpfe_capture.c [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpif.c [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpif.h [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpif_capture.c [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpif_capture.h [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpif_display.c [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpif_display.h [new file with mode: 0644]
drivers/media/platform/ti/davinci/vpss.c [new file with mode: 0644]

index f0961672e6a35631702f662fba82dc4773481ffc..4e87bdbc7ae41e3c64dffc77c9fa6b58e3e4dfe1 100644 (file)
@@ -7,22 +7,22 @@ File partitioning
 -----------------
 
  V4L2 display device driver
-         drivers/media/platform/davinci/vpbe_display.c
-         drivers/media/platform/davinci/vpbe_display.h
+         drivers/media/platform/ti/davinci/vpbe_display.c
+         drivers/media/platform/ti/davinci/vpbe_display.h
 
  VPBE display controller
-         drivers/media/platform/davinci/vpbe.c
-         drivers/media/platform/davinci/vpbe.h
+         drivers/media/platform/ti/davinci/vpbe.c
+         drivers/media/platform/ti/davinci/vpbe.h
 
  VPBE venc sub device driver
-         drivers/media/platform/davinci/vpbe_venc.c
-         drivers/media/platform/davinci/vpbe_venc.h
-         drivers/media/platform/davinci/vpbe_venc_regs.h
+         drivers/media/platform/ti/davinci/vpbe_venc.c
+         drivers/media/platform/ti/davinci/vpbe_venc.h
+         drivers/media/platform/ti/davinci/vpbe_venc_regs.h
 
  VPBE osd driver
-         drivers/media/platform/davinci/vpbe_osd.c
-         drivers/media/platform/davinci/vpbe_osd.h
-         drivers/media/platform/davinci/vpbe_osd_regs.h
+         drivers/media/platform/ti/davinci/vpbe_osd.c
+         drivers/media/platform/ti/davinci/vpbe_osd.h
+         drivers/media/platform/ti/davinci/vpbe_osd_regs.h
 
 To be done
 ----------
index e56c61afe18b4bd4ac54769b0b40169eba363403..dafcff4ea014ed7fea878fdda165cd1fcdf0a5e8 100644 (file)
@@ -19321,7 +19321,7 @@ S:      Maintained
 W:     https://linuxtv.org
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
 T:     git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
-F:     drivers/media/platform/davinci/
+F:     drivers/media/platform/ti/davinci/
 F:     include/media/davinci/
 
 TI ENHANCED QUADRATURE ENCODER PULSE (eQEP) DRIVER
index f1a1a08a205b71884bef0b7e50f1a9371727de9e..9873448de215b21f0623bce71eef1c6b28789242 100644 (file)
@@ -73,7 +73,6 @@ source "drivers/media/platform/aspeed/Kconfig"
 source "drivers/media/platform/atmel/Kconfig"
 source "drivers/media/platform/cadence/Kconfig"
 source "drivers/media/platform/chips-media/Kconfig"
-source "drivers/media/platform/davinci/Kconfig"
 source "drivers/media/platform/intel/Kconfig"
 source "drivers/media/platform/marvell/Kconfig"
 source "drivers/media/platform/mediatek/mtk-jpeg/Kconfig"
@@ -98,6 +97,7 @@ source "drivers/media/platform/st/sti/Kconfig"
 source "drivers/media/platform/st/stm32/Kconfig"
 source "drivers/media/platform/ti-vpe/Kconfig"
 source "drivers/media/platform/ti/am437x/Kconfig"
+source "drivers/media/platform/ti/davinci/Kconfig"
 source "drivers/media/platform/via/Kconfig"
 source "drivers/media/platform/xilinx/Kconfig"
 
index 2a23f30f63778938371f250f8fb5478882dbdadf..d7557b25baf51da799873b3402b91a6df77ac333 100644 (file)
@@ -13,7 +13,6 @@ obj-y += aspeed/
 obj-y += atmel/
 obj-y += cadence/
 obj-y += chips-media/
-obj-y += davinci/
 obj-y += intel/
 obj-y += marvell/
 obj-y += mediatek/mtk-jpeg/
@@ -43,6 +42,7 @@ obj-y += st/sti/hva/
 obj-y += st/stm32/
 obj-y += ti-vpe/
 obj-y += ti/am437x/
+obj-y += ti/davinci/
 obj-y += via/
 obj-y += xilinx/
 
diff --git a/drivers/media/platform/davinci/Kconfig b/drivers/media/platform/davinci/Kconfig
deleted file mode 100644 (file)
index 7e5f92b..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config VIDEO_DAVINCI_VPIF_DISPLAY
-       tristate "TI DaVinci VPIF V4L2-Display driver"
-       depends on V4L_PLATFORM_DRIVERS
-       depends on VIDEO_V4L2
-       depends on ARCH_DAVINCI || COMPILE_TEST
-       depends on I2C
-       select VIDEOBUF2_DMA_CONTIG
-       select VIDEO_ADV7343 if MEDIA_SUBDRV_AUTOSELECT
-       select VIDEO_THS7303 if MEDIA_SUBDRV_AUTOSELECT
-       help
-         Enables Davinci VPIF module used for display devices.
-         This module is used for display on TI DM6467/DA850/OMAPL138
-         SoCs.
-
-         To compile this driver as a module, choose M here. There will
-         be two modules called vpif.ko and vpif_display.ko
-
-config VIDEO_DAVINCI_VPIF_CAPTURE
-       tristate "TI DaVinci VPIF video capture driver"
-       depends on V4L_PLATFORM_DRIVERS
-       depends on VIDEO_V4L2
-       depends on ARCH_DAVINCI || COMPILE_TEST
-       depends on I2C
-       select VIDEOBUF2_DMA_CONTIG
-       select V4L2_FWNODE
-       help
-         Enables Davinci VPIF module used for capture devices.
-         This module is used for capture on TI DM6467/DA850/OMAPL138
-         SoCs.
-
-         To compile this driver as a module, choose M here. There will
-         be two modules called vpif.ko and vpif_capture.ko
-
-config VIDEO_DM6446_CCDC
-       tristate "TI DM6446 CCDC video capture driver"
-       depends on V4L_PLATFORM_DRIVERS
-       depends on VIDEO_V4L2
-       depends on ARCH_DAVINCI || COMPILE_TEST
-       depends on I2C
-       select VIDEOBUF_DMA_CONTIG
-       help
-          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. There will
-          be three modules called vpfe_capture.ko, vpss.ko and dm644x_ccdc.ko
-
-config VIDEO_DM355_CCDC
-       tristate "TI DM355 CCDC video capture driver"
-       depends on V4L_PLATFORM_DRIVERS
-       depends on VIDEO_V4L2
-       depends on ARCH_DAVINCI || COMPILE_TEST
-       depends on I2C
-       select VIDEOBUF_DMA_CONTIG
-       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. There will
-          be three modules called vpfe_capture.ko, vpss.ko and dm355_ccdc.ko
-
-config VIDEO_DM365_ISIF
-       tristate "TI DM365 ISIF video capture driver"
-       depends on V4L_PLATFORM_DRIVERS
-       depends on VIDEO_V4L2
-       depends on ARCH_DAVINCI || COMPILE_TEST
-       depends on I2C
-       select VIDEOBUF_DMA_CONTIG
-       help
-          Enables ISIF hw module. This is the hardware module for
-          configuring ISIF in VPFE to capture Raw Bayer RGB data from
-          a image sensor or YUV data from a YUV source.
-
-          To compile this driver as a module, choose M here. There will
-          be three modules called vpfe_capture.ko, vpss.ko and isif.ko
-
-config VIDEO_DAVINCI_VPBE_DISPLAY
-       tristate "TI DaVinci VPBE V4L2-Display driver"
-       depends on V4L_PLATFORM_DRIVERS
-       depends on VIDEO_V4L2
-       depends on ARCH_DAVINCI || COMPILE_TEST
-       depends on I2C
-       select VIDEOBUF2_DMA_CONTIG
-       help
-           Enables Davinci VPBE module used for display devices.
-           This module is used for display on TI DM644x/DM365/DM355
-           based display devices.
-
-           To compile this driver as a module, choose M here. There will
-           be five modules created called vpss.ko, vpbe.ko, vpbe_osd.ko,
-           vpbe_venc.ko and vpbe_display.ko
diff --git a/drivers/media/platform/davinci/Makefile b/drivers/media/platform/davinci/Makefile
deleted file mode 100644 (file)
index 05c45bf..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the davinci video device drivers.
-#
-
-#VPIF Display driver
-obj-$(CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY) += vpif.o vpif_display.o
-#VPIF Capture driver
-obj-$(CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE) += vpif.o vpif_capture.o
-
-# Capture: DM6446 and DM355
-obj-$(CONFIG_VIDEO_DM6446_CCDC) += vpfe_capture.o vpss.o dm644x_ccdc.o
-obj-$(CONFIG_VIDEO_DM355_CCDC) += vpfe_capture.o vpss.o dm355_ccdc.o
-obj-$(CONFIG_VIDEO_DM365_ISIF) += vpfe_capture.o vpss.o isif.o
-obj-$(CONFIG_VIDEO_DAVINCI_VPBE_DISPLAY) += vpss.o vpbe.o vpbe_osd.o \
-       vpbe_venc.o vpbe_display.o
diff --git a/drivers/media/platform/davinci/ccdc_hw_device.h b/drivers/media/platform/davinci/ccdc_hw_device.h
deleted file mode 100644 (file)
index a545052..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2008-2009 Texas Instruments Inc
- *
- * 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_types.h>
-
-/*
- * ccdc hw operations
- */
-struct ccdc_hw_ops {
-       /* Pointer to initialize function to initialize ccdc device */
-       int (*open) (struct device *dev);
-       /* Pointer to deinitialize function */
-       int (*close) (struct device *dev);
-       /* set ccdc base address */
-       void (*set_ccdc_base)(void *base, int size);
-       /* Pointer to function to enable or disable ccdc */
-       void (*enable) (int en);
-       /* reset sbl. only for 6446 */
-       void (*reset) (void);
-       /* enable output to sdram */
-       void (*enable_out_to_sdram) (int en);
-       /* Pointer to function to set hw parameters */
-       int (*set_hw_if_params) (struct vpfe_hw_if_param *param);
-       /* get interface parameters */
-       int (*get_hw_if_params) (struct vpfe_hw_if_param *param);
-       /* Pointer to function to configure ccdc */
-       int (*configure) (void);
-
-       /* Pointer to function to set buffer type */
-       int (*set_buftype) (enum ccdc_buftype buf_type);
-       /* Pointer to function to get buffer type */
-       enum ccdc_buftype (*get_buftype) (void);
-       /* Pointer to function to set frame format */
-       int (*set_frame_format) (enum ccdc_frmfmt frm_fmt);
-       /* Pointer to function to get frame format */
-       enum ccdc_frmfmt (*get_frame_format) (void);
-       /* enumerate hw pix formats */
-       int (*enum_pix)(u32 *hw_pix, int i);
-       /* Pointer to function to set buffer type */
-       u32 (*get_pixel_format) (void);
-       /* Pointer to function to get pixel format. */
-       int (*set_pixel_format) (u32 pixfmt);
-       /* Pointer to function to set image window */
-       int (*set_image_window) (struct v4l2_rect *win);
-       /* Pointer to function to set image window */
-       void (*get_image_window) (struct v4l2_rect *win);
-       /* Pointer to function to get line length */
-       unsigned int (*get_line_length) (void);
-
-       /* Pointer to function to set frame buffer address */
-       void (*setfbaddr) (unsigned long addr);
-       /* Pointer to function to get field id */
-       int (*getfid) (void);
-};
-
-struct ccdc_hw_device {
-       /* ccdc device name */
-       char name[32];
-       /* module owner */
-       struct module *owner;
-       /* hw ops */
-       struct ccdc_hw_ops hw_ops;
-};
-
-/* Used by CCDC module to register & unregister with vpfe capture driver */
-int vpfe_register_ccdc_device(const struct ccdc_hw_device *dev);
-void vpfe_unregister_ccdc_device(const struct ccdc_hw_device *dev);
-
-#endif
-#endif
diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c
deleted file mode 100644 (file)
index e06d113..0000000
+++ /dev/null
@@ -1,935 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2005-2009 Texas Instruments Inc
- *
- * CCDC hardware module for DM355
- * ------------------------------
- *
- * This module is for configuring DM355 CCD controller of VPFE to capture
- * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
- * such as Defect Pixel Correction, Color Space Conversion etc to
- * pre-process the Bayer RGB data, before writing it to SDRAM.
- *
- * TODO: 1) Raw bayer parameter settings and bayer capture
- *      2) Split module parameter structure to module specific ioctl structs
- *      3) add support for lense shading correction
- *      4) investigate if enum used for user space type definition
- *         to be replaced by #defines or integer
- */
-#include <linux/platform_device.h>
-#include <linux/uaccess.h>
-#include <linux/videodev2.h>
-#include <linux/err.h>
-#include <linux/module.h>
-
-#include <media/davinci/dm355_ccdc.h>
-#include <media/davinci/vpss.h>
-
-#include "dm355_ccdc_regs.h"
-#include "ccdc_hw_device.h"
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("CCDC Driver for DM355");
-MODULE_AUTHOR("Texas Instruments");
-
-static struct ccdc_oper_config {
-       struct device *dev;
-       /* CCDC interface type */
-       enum vpfe_hw_if_type if_type;
-       /* Raw Bayer configuration */
-       struct ccdc_params_raw bayer;
-       /* YCbCr configuration */
-       struct ccdc_params_ycbcr ycbcr;
-       /* ccdc base address */
-       void __iomem *base_addr;
-} ccdc_cfg = {
-       /* Raw configurations */
-       .bayer = {
-               .pix_fmt = CCDC_PIXFMT_RAW,
-               .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
-               .win = CCDC_WIN_VGA,
-               .fid_pol = VPFE_PINPOL_POSITIVE,
-               .vd_pol = VPFE_PINPOL_POSITIVE,
-               .hd_pol = VPFE_PINPOL_POSITIVE,
-               .gain = {
-                       .r_ye = 256,
-                       .gb_g = 256,
-                       .gr_cy = 256,
-                       .b_mg = 256
-               },
-               .config_params = {
-                       .datasft = 2,
-                       .mfilt1 = CCDC_NO_MEDIAN_FILTER1,
-                       .mfilt2 = CCDC_NO_MEDIAN_FILTER2,
-                       .alaw = {
-                               .gamma_wd = 2,
-                       },
-                       .blk_clamp = {
-                               .sample_pixel = 1,
-                               .dc_sub = 25
-                       },
-                       .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
-                       },
-               },
-       },
-       /* YCbCr configuration */
-       .ycbcr = {
-               .win = CCDC_WIN_PAL,
-               .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
-               .frm_fmt = CCDC_FRMFMT_INTERLACED,
-               .fid_pol = VPFE_PINPOL_POSITIVE,
-               .vd_pol = VPFE_PINPOL_POSITIVE,
-               .hd_pol = VPFE_PINPOL_POSITIVE,
-               .bt656_enable = 1,
-               .pix_order = CCDC_PIXORDER_CBYCRY,
-               .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
-       },
-};
-
-
-/* Raw Bayer formats */
-static u32 ccdc_raw_bayer_pix_formats[] =
-               {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
-
-/* Raw YUV formats */
-static u32 ccdc_raw_yuv_pix_formats[] =
-               {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
-
-/* register access routines */
-static inline u32 regr(u32 offset)
-{
-       return __raw_readl(ccdc_cfg.base_addr + offset);
-}
-
-static inline void regw(u32 val, u32 offset)
-{
-       __raw_writel(val, ccdc_cfg.base_addr + offset);
-}
-
-static void ccdc_enable(int en)
-{
-       unsigned int temp;
-       temp = regr(SYNCEN);
-       temp &= (~CCDC_SYNCEN_VDHDEN_MASK);
-       temp |= (en & CCDC_SYNCEN_VDHDEN_MASK);
-       regw(temp, SYNCEN);
-}
-
-static void ccdc_enable_output_to_sdram(int en)
-{
-       unsigned int temp;
-       temp = regr(SYNCEN);
-       temp &= (~(CCDC_SYNCEN_WEN_MASK));
-       temp |= ((en << CCDC_SYNCEN_WEN_SHIFT) & CCDC_SYNCEN_WEN_MASK);
-       regw(temp, SYNCEN);
-}
-
-static void ccdc_config_gain_offset(void)
-{
-       /* configure gain */
-       regw(ccdc_cfg.bayer.gain.r_ye, RYEGAIN);
-       regw(ccdc_cfg.bayer.gain.gr_cy, GRCYGAIN);
-       regw(ccdc_cfg.bayer.gain.gb_g, GBGGAIN);
-       regw(ccdc_cfg.bayer.gain.b_mg, BMGGAIN);
-       /* configure offset */
-       regw(ccdc_cfg.bayer.ccdc_offset, OFFSET);
-}
-
-/*
- * ccdc_restore_defaults()
- * This function restore power on defaults in the ccdc registers
- */
-static int ccdc_restore_defaults(void)
-{
-       int i;
-
-       dev_dbg(ccdc_cfg.dev, "\nstarting ccdc_restore_defaults...");
-       /* set all registers to zero */
-       for (i = 0; i <= CCDC_REG_LAST; i += 4)
-               regw(0, i);
-
-       /* now override the values with power on defaults in registers */
-       regw(MODESET_DEFAULT, MODESET);
-       /* no culling support */
-       regw(CULH_DEFAULT, CULH);
-       regw(CULV_DEFAULT, CULV);
-       /* Set default Gain and Offset */
-       ccdc_cfg.bayer.gain.r_ye = GAIN_DEFAULT;
-       ccdc_cfg.bayer.gain.gb_g = GAIN_DEFAULT;
-       ccdc_cfg.bayer.gain.gr_cy = GAIN_DEFAULT;
-       ccdc_cfg.bayer.gain.b_mg = GAIN_DEFAULT;
-       ccdc_config_gain_offset();
-       regw(OUTCLIP_DEFAULT, OUTCLIP);
-       regw(LSCCFG2_DEFAULT, LSCCFG2);
-       /* select ccdc input */
-       if (vpss_select_ccdc_source(VPSS_CCDCIN)) {
-               dev_dbg(ccdc_cfg.dev, "\ncouldn't select ccdc input source");
-               return -EFAULT;
-       }
-       /* select ccdc clock */
-       if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) {
-               dev_dbg(ccdc_cfg.dev, "\ncouldn't enable ccdc clock");
-               return -EFAULT;
-       }
-       dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_restore_defaults...");
-       return 0;
-}
-
-static int ccdc_open(struct device *device)
-{
-       return ccdc_restore_defaults();
-}
-
-static int ccdc_close(struct device *device)
-{
-       /* disable clock */
-       vpss_enable_clock(VPSS_CCDC_CLOCK, 0);
-       /* do nothing for now */
-       return 0;
-}
-/*
- * ccdc_setwin()
- * This function will configure the window size to
- * be capture in CCDC reg.
- */
-static void ccdc_setwin(struct v4l2_rect *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(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
-
-       /*
-        * ppc - per pixel count. indicates how many pixels per cell
-        * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
-        * raw capture this is 1
-        */
-       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, SPH);
-       regw(horz_nr_pixels, NPH);
-       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 and VDINT1 */
-               regw(vert_start, VDINT0);
-       } else {
-               /* Since first line doesn't have any data */
-               vert_start += 1;
-               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 & CCDC_START_VER_ONE_MASK, SLV0);
-       regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1);
-       regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV);
-       dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
-}
-
-/* This function will configure CCDC for YCbCr video capture */
-static void ccdc_config_ycbcr(void)
-{
-       struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
-       u32 temp;
-
-       /* first set the CCDC power on defaults values in all registers */
-       dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
-       ccdc_restore_defaults();
-
-       /* configure pixel format & video frame format */
-       temp = (((params->pix_fmt & CCDC_INPUT_MODE_MASK) <<
-               CCDC_INPUT_MODE_SHIFT) |
-               ((params->frm_fmt & CCDC_FRM_FMT_MASK) <<
-               CCDC_FRM_FMT_SHIFT));
-
-       /* setup BT.656 sync mode */
-       if (params->bt656_enable) {
-               regw(CCDC_REC656IF_BT656_EN, REC656IF);
-               /*
-                * configure the FID, VD, HD pin polarity fld,hd pol positive,
-                * vd negative, 8-bit pack mode
-                */
-               temp |= CCDC_VD_POL_NEGATIVE;
-       } else {                /* y/c external sync mode */
-               temp |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
-                       CCDC_FID_POL_SHIFT) |
-                       ((params->hd_pol & CCDC_HD_POL_MASK) <<
-                       CCDC_HD_POL_SHIFT) |
-                       ((params->vd_pol & CCDC_VD_POL_MASK) <<
-                       CCDC_VD_POL_SHIFT));
-       }
-
-       /* pack the data to 8-bit */
-       temp |= CCDC_DATA_PACK_ENABLE;
-
-       regw(temp, MODESET);
-
-       /* configure video window */
-       ccdc_setwin(&params->win, params->frm_fmt, 2);
-
-       /* configure the order of y cb cr in SD-RAM */
-       temp = (params->pix_order << CCDC_Y8POS_SHIFT);
-       temp |= CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC;
-       regw(temp, 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) >> 5), HSIZE);
-
-       /* configure the memory line offset */
-       if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) {
-               /* two fields are interleaved in memory */
-               regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST);
-       }
-
-       dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
-}
-
-/*
- * ccdc_config_black_clamp()
- * configure parameters for Optical Black Clamp
- */
-static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
-{
-       u32 val;
-
-       if (!bclamp->b_clamp_enable) {
-               /* configure DCSub */
-               regw(bclamp->dc_sub & CCDC_BLK_DC_SUB_MASK, DCSUB);
-               regw(0x0000, CLAMP);
-               return;
-       }
-       /* Enable the Black clamping, set sample lines and pixels */
-       val = (bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) |
-             ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
-               CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE;
-       regw(val, CLAMP);
-
-       /* If Black clamping is enable then make dcsub 0 */
-       val = (bclamp->sample_ln & CCDC_NUM_LINE_CALC_MASK)
-                       << CCDC_NUM_LINE_CALC_SHIFT;
-       regw(val, DCSUB);
-}
-
-/*
- * ccdc_config_black_compense()
- * configure parameters for Black Compensation
- */
-static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
-{
-       u32 val;
-
-       val = (bcomp->b & CCDC_BLK_COMP_MASK) |
-               ((bcomp->gb & CCDC_BLK_COMP_MASK) <<
-               CCDC_BLK_COMP_GB_COMP_SHIFT);
-       regw(val, BLKCMP1);
-
-       val = ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
-               CCDC_BLK_COMP_GR_COMP_SHIFT) |
-               ((bcomp->r & CCDC_BLK_COMP_MASK) <<
-               CCDC_BLK_COMP_R_COMP_SHIFT);
-       regw(val, BLKCMP0);
-}
-
-/*
- * ccdc_write_dfc_entry()
- * write an entry in the dfc table.
- */
-static int ccdc_write_dfc_entry(int index, struct ccdc_vertical_dft *dfc)
-{
-/* TODO This is to be re-visited and adjusted */
-#define DFC_WRITE_WAIT_COUNT   1000
-       u32 val, count = DFC_WRITE_WAIT_COUNT;
-
-       regw(dfc->dft_corr_vert[index], DFCMEM0);
-       regw(dfc->dft_corr_horz[index], DFCMEM1);
-       regw(dfc->dft_corr_sub1[index], DFCMEM2);
-       regw(dfc->dft_corr_sub2[index], DFCMEM3);
-       regw(dfc->dft_corr_sub3[index], DFCMEM4);
-       /* set WR bit to write */
-       val = regr(DFCMEMCTL) | CCDC_DFCMEMCTL_DFCMWR_MASK;
-       regw(val, DFCMEMCTL);
-
-       /*
-        * Assume, it is very short. If we get an error, we need to
-        * adjust this value
-        */
-       while (regr(DFCMEMCTL) & CCDC_DFCMEMCTL_DFCMWR_MASK)
-               count--;
-       /*
-        * TODO We expect the count to be non-zero to be successful. Adjust
-        * the count if write requires more time
-        */
-
-       if (count) {
-               dev_err(ccdc_cfg.dev, "defect table write timeout !!!\n");
-               return -1;
-       }
-       return 0;
-}
-
-/*
- * ccdc_config_vdfc()
- * configure parameters for Vertical Defect Correction
- */
-static int ccdc_config_vdfc(struct ccdc_vertical_dft *dfc)
-{
-       u32 val;
-       int i;
-
-       /* Configure General Defect Correction. The table used is from IPIPE */
-       val = dfc->gen_dft_en & CCDC_DFCCTL_GDFCEN_MASK;
-
-       /* Configure Vertical Defect Correction if needed */
-       if (!dfc->ver_dft_en) {
-               /* Enable only General Defect Correction */
-               regw(val, DFCCTL);
-               return 0;
-       }
-
-       if (dfc->table_size > CCDC_DFT_TABLE_SIZE)
-               return -EINVAL;
-
-       val |= CCDC_DFCCTL_VDFC_DISABLE;
-       val |= (dfc->dft_corr_ctl.vdfcsl & CCDC_DFCCTL_VDFCSL_MASK) <<
-               CCDC_DFCCTL_VDFCSL_SHIFT;
-       val |= (dfc->dft_corr_ctl.vdfcuda & CCDC_DFCCTL_VDFCUDA_MASK) <<
-               CCDC_DFCCTL_VDFCUDA_SHIFT;
-       val |= (dfc->dft_corr_ctl.vdflsft & CCDC_DFCCTL_VDFLSFT_MASK) <<
-               CCDC_DFCCTL_VDFLSFT_SHIFT;
-       regw(val , DFCCTL);
-
-       /* clear address ptr to offset 0 */
-       val = CCDC_DFCMEMCTL_DFCMARST_MASK << CCDC_DFCMEMCTL_DFCMARST_SHIFT;
-
-       /* write defect table entries */
-       for (i = 0; i < dfc->table_size; i++) {
-               /* increment address for non zero index */
-               if (i != 0)
-                       val = CCDC_DFCMEMCTL_INC_ADDR;
-               regw(val, DFCMEMCTL);
-               if (ccdc_write_dfc_entry(i, dfc) < 0)
-                       return -EFAULT;
-       }
-
-       /* update saturation level and enable dfc */
-       regw(dfc->saturation_ctl & CCDC_VDC_DFCVSAT_MASK, DFCVSAT);
-       val = regr(DFCCTL) | (CCDC_DFCCTL_VDFCEN_MASK <<
-                       CCDC_DFCCTL_VDFCEN_SHIFT);
-       regw(val, DFCCTL);
-       return 0;
-}
-
-/*
- * ccdc_config_csc()
- * configure parameters for color space conversion
- * Each register CSCM0-7 has two values in S8Q5 format.
- */
-static void ccdc_config_csc(struct ccdc_csc *csc)
-{
-       u32 val1 = 0, val2;
-       int i;
-
-       if (!csc->enable)
-               return;
-
-       /* 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 < CCDC_CSC_COEFF_TABLE_SIZE; i++) {
-               if ((i % 2) == 0) {
-                       /* CSCM - LSB */
-                       val1 = (csc->coeff[i].integer &
-                               CCDC_CSC_COEF_INTEG_MASK)
-                               << CCDC_CSC_COEF_INTEG_SHIFT;
-                       /*
-                        * convert decimal part to binary. Use 2 decimal
-                        * precision, user values range from .00 - 0.99
-                        */
-                       val1 |= (((csc->coeff[i].decimal &
-                               CCDC_CSC_COEF_DECIMAL_MASK) *
-                               CCDC_CSC_DEC_MAX) / 100);
-               } else {
-
-                       /* CSCM - MSB */
-                       val2 = (csc->coeff[i].integer &
-                               CCDC_CSC_COEF_INTEG_MASK)
-                               << CCDC_CSC_COEF_INTEG_SHIFT;
-                       val2 |= (((csc->coeff[i].decimal &
-                                CCDC_CSC_COEF_DECIMAL_MASK) *
-                                CCDC_CSC_DEC_MAX) / 100);
-                       val2 <<= CCDC_CSCM_MSB_SHIFT;
-                       val2 |= val1;
-                       regw(val2, (CSCM0 + ((i - 1) << 1)));
-               }
-       }
-}
-
-/*
- * ccdc_config_color_patterns()
- * configure parameters for color patterns
- */
-static void ccdc_config_color_patterns(struct ccdc_col_pat *pat0,
-                                      struct ccdc_col_pat *pat1)
-{
-       u32 val;
-
-       val = (pat0->olop | (pat0->olep << 2) | (pat0->elop << 4) |
-               (pat0->elep << 6) | (pat1->olop << 8) | (pat1->olep << 10) |
-               (pat1->elop << 12) | (pat1->elep << 14));
-       regw(val, COLPTN);
-}
-
-/* This function will configure CCDC for Raw mode image capture */
-static int ccdc_config_raw(void)
-{
-       struct ccdc_params_raw *params = &ccdc_cfg.bayer;
-       struct ccdc_config_params_raw *config_params =
-                                       &ccdc_cfg.bayer.config_params;
-       unsigned int val;
-
-       dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
-
-       /* restore power on defaults to register */
-       ccdc_restore_defaults();
-
-       /* CCDCFG register:
-        * set CCD Not to swap input since input is RAW data
-        * set FID detection function to Latch at V-Sync
-        * set WENLOG - ccdc valid area to AND
-        * set TRGSEL to WENBIT
-        * set EXTRG to DISABLE
-        * disable latching function on VSYNC - shadowed registers
-        */
-       regw(CCDC_YCINSWP_RAW | CCDC_CCDCFG_FIDMD_LATCH_VSYNC |
-            CCDC_CCDCFG_WENLOG_AND | CCDC_CCDCFG_TRGSEL_WEN |
-            CCDC_CCDCFG_EXTRG_DISABLE | CCDC_LATCH_ON_VSYNC_DISABLE, CCDCFG);
-
-       /*
-        * Set VDHD direction to input,  input type to raw input
-        * normal data polarity, do not use external WEN
-        */
-       val = (CCDC_VDHDOUT_INPUT | CCDC_RAW_IP_MODE | CCDC_DATAPOL_NORMAL |
-               CCDC_EXWEN_DISABLE);
-
-       /*
-        * Configure the vertical sync polarity (MODESET.VDPOL), horizontal
-        * sync polarity (MODESET.HDPOL), field id polarity (MODESET.FLDPOL),
-        * frame format(progressive or interlace), & pixel format (Input mode)
-        */
-       val |= (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
-               ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
-               ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
-               ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
-               ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT));
-
-       /* set pack for alaw compression */
-       if ((config_params->data_sz == CCDC_DATA_8BITS) ||
-            config_params->alaw.enable)
-               val |= CCDC_DATA_PACK_ENABLE;
-
-       /* Configure for LPF */
-       if (config_params->lpf_enable)
-               val |= (config_params->lpf_enable & CCDC_LPF_MASK) <<
-                       CCDC_LPF_SHIFT;
-
-       /* Configure the data shift */
-       val |= (config_params->datasft & CCDC_DATASFT_MASK) <<
-               CCDC_DATASFT_SHIFT;
-       regw(val , MODESET);
-       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to MODESET...\n", val);
-
-       /* Configure the Median Filter threshold */
-       regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT);
-
-       /* Configure GAMMAWD register. defaur 11-2, and Mosaic cfa pattern */
-       val = CCDC_GAMMA_BITS_11_2 << CCDC_GAMMAWD_INPUT_SHIFT |
-               CCDC_CFA_MOSAIC;
-
-       /* Enable and configure aLaw register if needed */
-       if (config_params->alaw.enable) {
-               val |= (CCDC_ALAW_ENABLE |
-                       ((config_params->alaw.gamma_wd &
-                       CCDC_ALAW_GAMMA_WD_MASK) <<
-                       CCDC_GAMMAWD_INPUT_SHIFT));
-       }
-
-       /* Configure Median filter1 & filter2 */
-       val |= ((config_params->mfilt1 << CCDC_MFILT1_SHIFT) |
-               (config_params->mfilt2 << CCDC_MFILT2_SHIFT));
-
-       regw(val, GAMMAWD);
-       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to GAMMAWD...\n", val);
-
-       /* configure video window */
-       ccdc_setwin(&params->win, params->frm_fmt, 1);
-
-       /* Optical Clamp Averaging */
-       ccdc_config_black_clamp(&config_params->blk_clamp);
-
-       /* Black level compensation */
-       ccdc_config_black_compense(&config_params->blk_comp);
-
-       /* Vertical Defect Correction if needed */
-       if (ccdc_config_vdfc(&config_params->vertical_dft) < 0)
-               return -EFAULT;
-
-       /* color space conversion */
-       ccdc_config_csc(&config_params->csc);
-
-       /* color pattern */
-       ccdc_config_color_patterns(&config_params->col_pat_field0,
-                                  &config_params->col_pat_field1);
-
-       /* Configure the Gain  & offset control */
-       ccdc_config_gain_offset();
-
-       dev_dbg(ccdc_cfg.dev, "\nWriting %x to COLPTN...\n", val);
-
-       /* Configure DATAOFST  register */
-       val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) <<
-               CCDC_DATAOFST_H_SHIFT;
-       val |= (config_params->data_offset.vert_offset & CCDC_DATAOFST_MASK) <<
-               CCDC_DATAOFST_V_SHIFT;
-       regw(val, DATAOFST);
-
-       /* configuring HSIZE register */
-       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 ((config_params->data_sz == CCDC_DATA_8BITS) ||
-            config_params->alaw.enable) {
-               val |= (((params->win.width) + 31) >> 5) &
-                       CCDC_HSIZE_VAL_MASK;
-
-               /* adjust to multiple of 32 */
-               dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
-                      (((params->win.width) + 31) >> 5) &
-                       CCDC_HSIZE_VAL_MASK);
-       } else {
-               /* else one pixel will take 2 byte */
-               val |= (((params->win.width * 2) + 31) >> 5) &
-                       CCDC_HSIZE_VAL_MASK;
-
-               dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
-                      (((params->win.width * 2) + 31) >> 5) &
-                       CCDC_HSIZE_VAL_MASK);
-       }
-       regw(val, HSIZE);
-
-       /* Configure SDOFST register */
-       if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
-               if (params->image_invert_enable) {
-                       /* For interlace inverse mode */
-                       regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST);
-                       dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
-                               CCDC_SDOFST_INTERLACE_INVERSE);
-               } else {
-                       /* For interlace non inverse mode */
-                       regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST);
-                       dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
-                               CCDC_SDOFST_INTERLACE_NORMAL);
-               }
-       } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
-               if (params->image_invert_enable) {
-                       /* For progessive inverse mode */
-                       regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST);
-                       dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
-                               CCDC_SDOFST_PROGRESSIVE_INVERSE);
-               } else {
-                       /* For progessive non inverse mode */
-                       regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST);
-                       dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
-                               CCDC_SDOFST_PROGRESSIVE_NORMAL);
-               }
-       }
-       dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
-       return 0;
-}
-
-static int ccdc_configure(void)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               return ccdc_config_raw();
-       else
-               ccdc_config_ycbcr();
-       return 0;
-}
-
-static int ccdc_set_buftype(enum ccdc_buftype buf_type)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               ccdc_cfg.bayer.buf_type = buf_type;
-       else
-               ccdc_cfg.ycbcr.buf_type = buf_type;
-       return 0;
-}
-static enum ccdc_buftype ccdc_get_buftype(void)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               return ccdc_cfg.bayer.buf_type;
-       return ccdc_cfg.ycbcr.buf_type;
-}
-
-static int ccdc_enum_pix(u32 *pix, int i)
-{
-       int ret = -EINVAL;
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
-               if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
-                       *pix = ccdc_raw_bayer_pix_formats[i];
-                       ret = 0;
-               }
-       } else {
-               if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
-                       *pix = ccdc_raw_yuv_pix_formats[i];
-                       ret = 0;
-               }
-       }
-       return ret;
-}
-
-static int ccdc_set_pixel_format(u32 pixfmt)
-{
-       struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
-
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
-               ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
-               if (pixfmt == V4L2_PIX_FMT_SBGGR8)
-                       alaw->enable = 1;
-               else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
-                       return -EINVAL;
-       } else {
-               if (pixfmt == V4L2_PIX_FMT_YUYV)
-                       ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
-               else if (pixfmt == V4L2_PIX_FMT_UYVY)
-                       ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
-               else
-                       return -EINVAL;
-       }
-       return 0;
-}
-static u32 ccdc_get_pixel_format(void)
-{
-       struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
-       u32 pixfmt;
-
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               if (alaw->enable)
-                       pixfmt = V4L2_PIX_FMT_SBGGR8;
-               else
-                       pixfmt = V4L2_PIX_FMT_SBGGR16;
-       else {
-               if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
-                       pixfmt = V4L2_PIX_FMT_YUYV;
-               else
-                       pixfmt = V4L2_PIX_FMT_UYVY;
-       }
-       return pixfmt;
-}
-static int ccdc_set_image_window(struct v4l2_rect *win)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               ccdc_cfg.bayer.win = *win;
-       else
-               ccdc_cfg.ycbcr.win = *win;
-       return 0;
-}
-
-static void ccdc_get_image_window(struct v4l2_rect *win)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               *win = ccdc_cfg.bayer.win;
-       else
-               *win = ccdc_cfg.ycbcr.win;
-}
-
-static unsigned int ccdc_get_line_length(void)
-{
-       struct ccdc_config_params_raw *config_params =
-                               &ccdc_cfg.bayer.config_params;
-       unsigned int len;
-
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
-               if ((config_params->alaw.enable) ||
-                   (config_params->data_sz == CCDC_DATA_8BITS))
-                       len = ccdc_cfg.bayer.win.width;
-               else
-                       len = ccdc_cfg.bayer.win.width * 2;
-       } else
-               len = ccdc_cfg.ycbcr.win.width * 2;
-       return ALIGN(len, 32);
-}
-
-static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               ccdc_cfg.bayer.frm_fmt = frm_fmt;
-       else
-               ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
-       return 0;
-}
-
-static enum ccdc_frmfmt ccdc_get_frame_format(void)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               return ccdc_cfg.bayer.frm_fmt;
-       else
-               return ccdc_cfg.ycbcr.frm_fmt;
-}
-
-static int ccdc_getfid(void)
-{
-       return  (regr(MODESET) >> 15) & 1;
-}
-
-/* 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_params(struct vpfe_hw_if_param *params)
-{
-       ccdc_cfg.if_type = params->if_type;
-
-       switch (params->if_type) {
-       case VPFE_BT656:
-       case VPFE_YCBCR_SYNC_16:
-       case VPFE_YCBCR_SYNC_8:
-               ccdc_cfg.ycbcr.vd_pol = params->vdpol;
-               ccdc_cfg.ycbcr.hd_pol = params->hdpol;
-               break;
-       default:
-               /* TODO add support for raw bayer here */
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static const struct ccdc_hw_device ccdc_hw_dev = {
-       .name = "DM355 CCDC",
-       .owner = THIS_MODULE,
-       .hw_ops = {
-               .open = ccdc_open,
-               .close = ccdc_close,
-               .enable = ccdc_enable,
-               .enable_out_to_sdram = ccdc_enable_output_to_sdram,
-               .set_hw_if_params = ccdc_set_hw_if_params,
-               .configure = ccdc_configure,
-               .set_buftype = ccdc_set_buftype,
-               .get_buftype = ccdc_get_buftype,
-               .enum_pix = ccdc_enum_pix,
-               .set_pixel_format = ccdc_set_pixel_format,
-               .get_pixel_format = 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,
-       },
-};
-
-static int dm355_ccdc_probe(struct platform_device *pdev)
-{
-       void (*setup_pinmux)(void);
-       struct resource *res;
-       int status = 0;
-
-       /*
-        * first try to register with vpfe. If not correct platform, then we
-        * don't have to iomap
-        */
-       status = vpfe_register_ccdc_device(&ccdc_hw_dev);
-       if (status < 0)
-               return status;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               status = -ENODEV;
-               goto fail_nores;
-       }
-
-       res = request_mem_region(res->start, resource_size(res), res->name);
-       if (!res) {
-               status = -EBUSY;
-               goto fail_nores;
-       }
-
-       ccdc_cfg.base_addr = ioremap(res->start, resource_size(res));
-       if (!ccdc_cfg.base_addr) {
-               status = -ENOMEM;
-               goto fail_nomem;
-       }
-
-       /* Platform data holds setup_pinmux function ptr */
-       if (NULL == pdev->dev.platform_data) {
-               status = -ENODEV;
-               goto fail_nomap;
-       }
-       setup_pinmux = pdev->dev.platform_data;
-       /*
-        * setup Mux configuration for ccdc which may be different for
-        * different SoCs using this CCDC
-        */
-       setup_pinmux();
-       ccdc_cfg.dev = &pdev->dev;
-       printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
-       return 0;
-fail_nomap:
-       iounmap(ccdc_cfg.base_addr);
-fail_nomem:
-       release_mem_region(res->start, resource_size(res));
-fail_nores:
-       vpfe_unregister_ccdc_device(&ccdc_hw_dev);
-       return status;
-}
-
-static int dm355_ccdc_remove(struct platform_device *pdev)
-{
-       struct resource *res;
-
-       iounmap(ccdc_cfg.base_addr);
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res)
-               release_mem_region(res->start, resource_size(res));
-       vpfe_unregister_ccdc_device(&ccdc_hw_dev);
-       return 0;
-}
-
-static struct platform_driver dm355_ccdc_driver = {
-       .driver = {
-               .name   = "dm355_ccdc",
-       },
-       .remove = dm355_ccdc_remove,
-       .probe = dm355_ccdc_probe,
-};
-
-module_platform_driver(dm355_ccdc_driver);
diff --git a/drivers/media/platform/davinci/dm355_ccdc_regs.h b/drivers/media/platform/davinci/dm355_ccdc_regs.h
deleted file mode 100644 (file)
index eb381f0..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2005-2009 Texas Instruments Inc
- */
-#ifndef _DM355_CCDC_REGS_H
-#define _DM355_CCDC_REGS_H
-
-/**************************************************************************\
-* 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 CCDC_REG_LAST                  DATAOFST
-/**************************************************************
-*      Define for various register bit mask and shifts for CCDC
-*
-**************************************************************/
-#define CCDC_RAW_IP_MODE                       0
-#define CCDC_VDHDOUT_INPUT                     0
-#define CCDC_YCINSWP_RAW                       (0 << 4)
-#define CCDC_EXWEN_DISABLE                     0
-#define CCDC_DATAPOL_NORMAL                    0
-#define CCDC_CCDCFG_FIDMD_LATCH_VSYNC          0
-#define CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC       (1 << 6)
-#define CCDC_CCDCFG_WENLOG_AND                 0
-#define CCDC_CCDCFG_TRGSEL_WEN                 0
-#define CCDC_CCDCFG_EXTRG_DISABLE              0
-#define CCDC_CFA_MOSAIC                                0
-#define CCDC_Y8POS_SHIFT                       11
-
-#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                  1
-#define CCDC_GAMMAWD_CFA_SHIFT                 5
-#define CCDC_GAMMAWD_INPUT_SHIFT               2
-#define CCDC_FID_POL_MASK                      1
-#define CCDC_FID_POL_SHIFT                     4
-#define CCDC_HD_POL_MASK                       1
-#define CCDC_HD_POL_SHIFT                      3
-#define CCDC_VD_POL_MASK                       1
-#define CCDC_VD_POL_SHIFT                      2
-#define CCDC_VD_POL_NEGATIVE                   (1 << 2)
-#define CCDC_FRM_FMT_MASK                      1
-#define CCDC_FRM_FMT_SHIFT                     7
-#define CCDC_DATA_SZ_MASK                      7
-#define CCDC_DATA_SZ_SHIFT                     8
-#define CCDC_VDHDOUT_MASK                      1
-#define CCDC_VDHDOUT_SHIFT                     0
-#define CCDC_EXWEN_MASK                                1
-#define CCDC_EXWEN_SHIFT                       5
-#define CCDC_INPUT_MODE_MASK                   3
-#define CCDC_INPUT_MODE_SHIFT                  12
-#define CCDC_PIX_FMT_MASK                      3
-#define CCDC_PIX_FMT_SHIFT                     12
-#define CCDC_DATAPOL_MASK                      1
-#define CCDC_DATAPOL_SHIFT                     6
-#define CCDC_WEN_ENABLE                                (1 << 1)
-#define CCDC_VDHDEN_ENABLE                     (1 << 16)
-#define CCDC_LPF_ENABLE                                (1 << 14)
-#define CCDC_ALAW_ENABLE                       1
-#define CCDC_ALAW_GAMMA_WD_MASK                        7
-#define CCDC_REC656IF_BT656_EN                 3
-
-#define CCDC_FMTCFG_FMTMODE_MASK               3
-#define CCDC_FMTCFG_FMTMODE_SHIFT              1
-#define CCDC_FMTCFG_LNUM_MASK                  3
-#define CCDC_FMTCFG_LNUM_SHIFT                 4
-#define CCDC_FMTCFG_ADDRINC_MASK               7
-#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                   1
-#define CCDC_HSIZE_VAL_MASK                    0xFFF
-#define CCDC_SDOFST_FIELD_INTERLEAVED          0x249
-#define CCDC_SDOFST_INTERLACE_INVERSE          0x4B6D
-#define CCDC_SDOFST_INTERLACE_NORMAL           0x0B6D
-#define CCDC_SDOFST_PROGRESSIVE_INVERSE                0x4000
-#define CCDC_SDOFST_PROGRESSIVE_NORMAL         0
-#define CCDC_START_PX_HOR_MASK                 0x7FFF
-#define CCDC_NUM_PX_HOR_MASK                   0x7FFF
-#define CCDC_START_VER_ONE_MASK                        0x7FFF
-#define CCDC_START_VER_TWO_MASK                        0x7FFF
-#define CCDC_NUM_LINES_VER                     0x7FFF
-
-#define CCDC_BLK_CLAMP_ENABLE                  (1 << 15)
-#define CCDC_BLK_SGAIN_MASK                    0x1F
-#define CCDC_BLK_ST_PXL_MASK                   0x1FFF
-#define CCDC_BLK_SAMPLE_LN_MASK                        3
-#define CCDC_BLK_SAMPLE_LN_SHIFT               13
-
-#define CCDC_NUM_LINE_CALC_MASK                        3
-#define CCDC_NUM_LINE_CALC_SHIFT               14
-
-#define CCDC_BLK_DC_SUB_MASK                   0x3FFF
-#define CCDC_BLK_COMP_MASK                     0xFF
-#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            (1 << 15)
-#define CCDC_LATCH_ON_VSYNC_ENABLE             (0 << 15)
-#define CCDC_FPC_ENABLE                                (1 << 15)
-#define CCDC_FPC_FPC_NUM_MASK                  0x7FFF
-#define CCDC_DATA_PACK_ENABLE                  (1 << 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               0xF
-
-#define CCDC_CSC_COEF_INTEG_MASK               7
-#define CCDC_CSC_COEF_DECIMAL_MASK             0x1f
-#define CCDC_CSC_COEF_INTEG_SHIFT              5
-#define CCDC_CSCM_MSB_SHIFT                    8
-#define CCDC_CSC_ENABLE                                1
-#define CCDC_CSC_DEC_MAX                       32
-
-#define CCDC_MFILT1_SHIFT                      10
-#define CCDC_MFILT2_SHIFT                      8
-#define CCDC_MED_FILT_THRESH                   0x3FFF
-#define CCDC_LPF_MASK                          1
-#define CCDC_LPF_SHIFT                         14
-#define CCDC_OFFSET_MASK                       0x3FF
-#define CCDC_DATASFT_MASK                      7
-#define CCDC_DATASFT_SHIFT                     8
-
-#define CCDC_DF_ENABLE                         1
-
-#define CCDC_FMTPLEN_P0_MASK                   0xF
-#define CCDC_FMTPLEN_P1_MASK                   0xF
-#define CCDC_FMTPLEN_P2_MASK                   7
-#define CCDC_FMTPLEN_P3_MASK                   7
-#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                       0x1FFF
-#define CCDC_FMTLNH_MASK                       0x1FFF
-#define CCDC_FMTSLV_MASK                       0x1FFF
-#define CCDC_FMTLNV_MASK                       0x7FFF
-#define CCDC_FMTRLEN_MASK                      0x1FFF
-#define CCDC_FMTHCNT_MASK                      0x1FFF
-
-#define CCDC_ADP_INIT_MASK                     0x1FFF
-#define CCDC_ADP_LINE_SHIFT                    13
-#define CCDC_ADP_LINE_MASK                     3
-#define CCDC_FMTPGN_APTR_MASK                  7
-
-#define CCDC_DFCCTL_GDFCEN_MASK                        1
-#define CCDC_DFCCTL_VDFCEN_MASK                        1
-#define CCDC_DFCCTL_VDFC_DISABLE               (0 << 4)
-#define CCDC_DFCCTL_VDFCEN_SHIFT               4
-#define CCDC_DFCCTL_VDFCSL_MASK                        3
-#define CCDC_DFCCTL_VDFCSL_SHIFT               5
-#define CCDC_DFCCTL_VDFCUDA_MASK               1
-#define CCDC_DFCCTL_VDFCUDA_SHIFT              7
-#define CCDC_DFCCTL_VDFLSFT_MASK               3
-#define CCDC_DFCCTL_VDFLSFT_SHIFT              8
-#define CCDC_DFCMEMCTL_DFCMARST_MASK           1
-#define CCDC_DFCMEMCTL_DFCMARST_SHIFT          2
-#define CCDC_DFCMEMCTL_DFCMWR_MASK             1
-#define CCDC_DFCMEMCTL_DFCMWR_SHIFT            0
-#define CCDC_DFCMEMCTL_INC_ADDR                        (0 << 2)
-
-#define CCDC_LSCCFG_GFTSF_MASK                 7
-#define CCDC_LSCCFG_GFTSF_SHIFT                        1
-#define CCDC_LSCCFG_GFTINV_MASK                        0xf
-#define CCDC_LSCCFG_GFTINV_SHIFT               4
-#define CCDC_LSC_GFTABLE_SEL_MASK              3
-#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                   3
-#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                      3
-#define CCDC_LSC_FRAC_MASK                     0x3FFF
-#define CCDC_LSC_CENTRE_MASK                   0x3FFF
-#define CCDC_LSC_COEF_MASK                     0xff
-#define CCDC_LSC_COEFL_SHIFT                   0
-#define CCDC_LSC_COEFU_SHIFT                   8
-#define CCDC_GAIN_MASK                         0x7FF
-#define CCDC_SYNCEN_VDHDEN_MASK                        (1 << 0)
-#define CCDC_SYNCEN_WEN_MASK                   (1 << 1)
-#define CCDC_SYNCEN_WEN_SHIFT                  1
-
-/* Power on Defaults in hardware */
-#define MODESET_DEFAULT                                0x200
-#define CULH_DEFAULT                           0xFFFF
-#define CULV_DEFAULT                           0xFF
-#define GAIN_DEFAULT                           256
-#define OUTCLIP_DEFAULT                                0x3FFF
-#define LSCCFG2_DEFAULT                                0xE
-
-#endif
diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c
deleted file mode 100644 (file)
index c6378c4..0000000
+++ /dev/null
@@ -1,880 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2006-2009 Texas Instruments Inc
- *
- * CCDC hardware module for DM6446
- * ------------------------------
- *
- * This module is for configuring CCD controller of DM6446 VPFE to capture
- * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
- * such as Defect Pixel Correction, Color Space Conversion etc to
- * pre-process the Raw Bayer RGB data, before writing it to SDRAM.
- * This file is named DM644x so that other variants such DM6443
- * may be supported using the same module.
- *
- * TODO: Test Raw bayer parameter settings and bayer capture
- *      Split module parameter structure to module specific ioctl structs
- *      investigate if enum used for user space type definition
- *      to be replaced by #defines or integer
- */
-#include <linux/platform_device.h>
-#include <linux/uaccess.h>
-#include <linux/videodev2.h>
-#include <linux/gfp.h>
-#include <linux/err.h>
-#include <linux/module.h>
-
-#include <media/davinci/dm644x_ccdc.h>
-#include <media/davinci/vpss.h>
-
-#include "dm644x_ccdc_regs.h"
-#include "ccdc_hw_device.h"
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("CCDC Driver for DM6446");
-MODULE_AUTHOR("Texas Instruments");
-
-static struct ccdc_oper_config {
-       struct device *dev;
-       /* CCDC interface type */
-       enum vpfe_hw_if_type if_type;
-       /* Raw Bayer configuration */
-       struct ccdc_params_raw bayer;
-       /* YCbCr configuration */
-       struct ccdc_params_ycbcr ycbcr;
-       /* ccdc base address */
-       void __iomem *base_addr;
-} ccdc_cfg = {
-       /* Raw configurations */
-       .bayer = {
-               .pix_fmt = CCDC_PIXFMT_RAW,
-               .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
-               .win = CCDC_WIN_VGA,
-               .fid_pol = VPFE_PINPOL_POSITIVE,
-               .vd_pol = VPFE_PINPOL_POSITIVE,
-               .hd_pol = VPFE_PINPOL_POSITIVE,
-               .config_params = {
-                       .data_sz = CCDC_DATA_10BITS,
-               },
-       },
-       .ycbcr = {
-               .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
-               .frm_fmt = CCDC_FRMFMT_INTERLACED,
-               .win = CCDC_WIN_PAL,
-               .fid_pol = VPFE_PINPOL_POSITIVE,
-               .vd_pol = VPFE_PINPOL_POSITIVE,
-               .hd_pol = VPFE_PINPOL_POSITIVE,
-               .bt656_enable = 1,
-               .pix_order = CCDC_PIXORDER_CBYCRY,
-               .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
-       },
-};
-
-#define CCDC_MAX_RAW_YUV_FORMATS       2
-
-/* Raw Bayer formats */
-static u32 ccdc_raw_bayer_pix_formats[] =
-       {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
-
-/* Raw YUV formats */
-static u32 ccdc_raw_yuv_pix_formats[] =
-       {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
-
-/* CCDC Save/Restore context */
-static u32 ccdc_ctx[CCDC_REG_END / sizeof(u32)];
-
-/* register access routines */
-static inline u32 regr(u32 offset)
-{
-       return __raw_readl(ccdc_cfg.base_addr + offset);
-}
-
-static inline void regw(u32 val, u32 offset)
-{
-       __raw_writel(val, ccdc_cfg.base_addr + offset);
-}
-
-static void ccdc_enable(int flag)
-{
-       regw(flag, CCDC_PCR);
-}
-
-static void ccdc_enable_vport(int flag)
-{
-       if (flag)
-               /* enable video port */
-               regw(CCDC_ENABLE_VIDEO_PORT, CCDC_FMTCFG);
-       else
-               regw(CCDC_DISABLE_VIDEO_PORT, CCDC_FMTCFG);
-}
-
-/*
- * ccdc_setwin()
- * This function will configure the window size
- * to be capture in CCDC reg
- */
-static void ccdc_setwin(struct v4l2_rect *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(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
-       /*
-        * ppc - per pixel count. indicates how many pixels per cell
-        * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
-        * raw capture this is 1
-        */
-       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,
-            CCDC_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, CCDC_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, CCDC_VDINT);
-
-       }
-       regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start,
-            CCDC_VERT_START);
-       regw(vert_nr_lines, CCDC_VERT_LINES);
-       dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
-}
-
-static void ccdc_readregs(void)
-{
-       unsigned int val = 0;
-
-       val = regr(CCDC_ALAW);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to ALAW...\n", val);
-       val = regr(CCDC_CLAMP);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to CLAMP...\n", val);
-       val = regr(CCDC_DCSUB);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to DCSUB...\n", val);
-       val = regr(CCDC_BLKCMP);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to BLKCMP...\n", val);
-       val = regr(CCDC_FPC_ADDR);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC_ADDR...\n", val);
-       val = regr(CCDC_FPC);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC...\n", val);
-       val = regr(CCDC_FMTCFG);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMTCFG...\n", val);
-       val = regr(CCDC_COLPTN);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to COLPTN...\n", val);
-       val = regr(CCDC_FMT_HORZ);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_HORZ...\n", val);
-       val = regr(CCDC_FMT_VERT);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_VERT...\n", val);
-       val = regr(CCDC_HSIZE_OFF);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HSIZE_OFF...\n", val);
-       val = regr(CCDC_SDOFST);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SDOFST...\n", val);
-       val = regr(CCDC_VP_OUT);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VP_OUT...\n", val);
-       val = regr(CCDC_SYN_MODE);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SYN_MODE...\n", val);
-       val = regr(CCDC_HORZ_INFO);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HORZ_INFO...\n", val);
-       val = regr(CCDC_VERT_START);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_START...\n", val);
-       val = regr(CCDC_VERT_LINES);
-       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_LINES...\n", val);
-}
-
-static int ccdc_close(struct device *dev)
-{
-       return 0;
-}
-
-/*
- * ccdc_restore_defaults()
- * This function will write defaults to all CCDC registers
- */
-static void ccdc_restore_defaults(void)
-{
-       int i;
-
-       /* disable CCDC */
-       ccdc_enable(0);
-       /* set all registers to default value */
-       for (i = 4; i <= 0x94; i += 4)
-               regw(0,  i);
-       regw(CCDC_NO_CULLING, CCDC_CULLING);
-       regw(CCDC_GAMMA_BITS_11_2, CCDC_ALAW);
-}
-
-static int ccdc_open(struct device *device)
-{
-       ccdc_restore_defaults();
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               ccdc_enable_vport(1);
-       return 0;
-}
-
-static void ccdc_sbl_reset(void)
-{
-       vpss_clear_wbl_overflow(VPSS_PCR_CCDC_WBL_O);
-}
-
-/*
- * ccdc_config_ycbcr()
- * This function will configure CCDC for YCbCr video capture
- */
-static void ccdc_config_ycbcr(void)
-{
-       struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
-       u32 syn_mode;
-
-       dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
-       /*
-        * first restore the CCDC registers to default values
-        * This is important since we assume default values to be set in
-        * a lot of registers that we didn't touch
-        */
-       ccdc_restore_defaults();
-
-       /*
-        * configure pixel format, frame format, configure video frame
-        * format, enable output to SDRAM, enable internal timing generator
-        * and 8bit pack mode
-        */
-       syn_mode = (((params->pix_fmt & CCDC_SYN_MODE_INPMOD_MASK) <<
-                   CCDC_SYN_MODE_INPMOD_SHIFT) |
-                   ((params->frm_fmt & CCDC_SYN_FLDMODE_MASK) <<
-                   CCDC_SYN_FLDMODE_SHIFT) | CCDC_VDHDEN_ENABLE |
-                   CCDC_WEN_ENABLE | CCDC_DATA_PACK_ENABLE);
-
-       /* setup BT.656 sync mode */
-       if (params->bt656_enable) {
-               regw(CCDC_REC656IF_BT656_EN, CCDC_REC656IF);
-
-               /*
-                * configure the FID, VD, HD pin polarity,
-                * fld,hd pol positive, vd negative, 8-bit data
-                */
-               syn_mode |= CCDC_SYN_MODE_VD_POL_NEGATIVE;
-               if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
-                       syn_mode |= CCDC_SYN_MODE_10BITS;
-               else
-                       syn_mode |= CCDC_SYN_MODE_8BITS;
-       } else {
-               /* y/c external sync mode */
-               syn_mode |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
-                            CCDC_FID_POL_SHIFT) |
-                            ((params->hd_pol & CCDC_HD_POL_MASK) <<
-                            CCDC_HD_POL_SHIFT) |
-                            ((params->vd_pol & CCDC_VD_POL_MASK) <<
-                            CCDC_VD_POL_SHIFT));
-       }
-       regw(syn_mode, CCDC_SYN_MODE);
-
-       /* configure video window */
-       ccdc_setwin(&params->win, params->frm_fmt, 2);
-
-       /*
-        * configure the order of y cb cr in SDRAM, and disable latch
-        * internal register on vsync
-        */
-       if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
-               regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
-                       CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_BW656_10BIT,
-                       CCDC_CCDCFG);
-       else
-               regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
-                       CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
-
-       /*
-        * configure the horizontal line offset. This should be a
-        * on 32 byte boundary. So clear LSB 5 bits
-        */
-       regw(((params->win.width * 2  + 31) & ~0x1f), CCDC_HSIZE_OFF);
-
-       /* configure the memory line offset */
-       if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
-               /* two fields are interleaved in memory */
-               regw(CCDC_SDOFST_FIELD_INTERLEAVED, CCDC_SDOFST);
-
-       ccdc_sbl_reset();
-       dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
-}
-
-static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
-{
-       u32 val;
-
-       if (!bclamp->enable) {
-               /* configure DCSub */
-               val = (bclamp->dc_sub) & CCDC_BLK_DC_SUB_MASK;
-               regw(val, CCDC_DCSUB);
-               dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to DCSUB...\n", val);
-               regw(CCDC_CLAMP_DEFAULT_VAL, CCDC_CLAMP);
-               dev_dbg(ccdc_cfg.dev, "\nWriting 0x0000 to CLAMP...\n");
-               return;
-       }
-       /*
-        * Configure gain,  Start pixel, No of line to be avg,
-        * No of pixel/line to be avg, & Enable the Black clamping
-        */
-       val = ((bclamp->sgain & CCDC_BLK_SGAIN_MASK) |
-              ((bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) <<
-               CCDC_BLK_ST_PXL_SHIFT) |
-              ((bclamp->sample_ln & CCDC_BLK_SAMPLE_LINE_MASK) <<
-               CCDC_BLK_SAMPLE_LINE_SHIFT) |
-              ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
-               CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE);
-       regw(val, CCDC_CLAMP);
-       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to CLAMP...\n", val);
-       /* If Black clamping is enable then make dcsub 0 */
-       regw(CCDC_DCSUB_DEFAULT_VAL, CCDC_DCSUB);
-       dev_dbg(ccdc_cfg.dev, "\nWriting 0x00000000 to DCSUB...\n");
-}
-
-static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
-{
-       u32 val;
-
-       val = ((bcomp->b & CCDC_BLK_COMP_MASK) |
-             ((bcomp->gb & CCDC_BLK_COMP_MASK) <<
-              CCDC_BLK_COMP_GB_COMP_SHIFT) |
-             ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
-              CCDC_BLK_COMP_GR_COMP_SHIFT) |
-             ((bcomp->r & CCDC_BLK_COMP_MASK) <<
-              CCDC_BLK_COMP_R_COMP_SHIFT));
-       regw(val, CCDC_BLKCMP);
-}
-
-/*
- * ccdc_config_raw()
- * This function will configure CCDC for Raw capture mode
- */
-static void ccdc_config_raw(void)
-{
-       struct ccdc_params_raw *params = &ccdc_cfg.bayer;
-       struct ccdc_config_params_raw *config_params =
-                               &ccdc_cfg.bayer.config_params;
-       unsigned int syn_mode = 0;
-       unsigned int val;
-
-       dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
-
-       /*      Reset CCDC */
-       ccdc_restore_defaults();
-
-       /* Disable latching function registers on VSYNC  */
-       regw(CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
-
-       /*
-        * Configure the vertical sync polarity(SYN_MODE.VDPOL),
-        * horizontal sync polarity (SYN_MODE.HDPOL), frame id polarity
-        * (SYN_MODE.FLDPOL), frame format(progressive or interlace),
-        * data size(SYNMODE.DATSIZ), &pixel format (Input mode), output
-        * SDRAM, enable internal timing generator
-        */
-       syn_mode =
-               (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
-               ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
-               ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
-               ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
-               ((config_params->data_sz & CCDC_DATA_SZ_MASK) <<
-               CCDC_DATA_SZ_SHIFT) |
-               ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT) |
-               CCDC_WEN_ENABLE | CCDC_VDHDEN_ENABLE);
-
-       /* Enable and configure aLaw register if needed */
-       if (config_params->alaw.enable) {
-               val = ((config_params->alaw.gamma_wd &
-                     CCDC_ALAW_GAMMA_WD_MASK) | CCDC_ALAW_ENABLE);
-               regw(val, CCDC_ALAW);
-               dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to ALAW...\n", val);
-       }
-
-       /* Configure video window */
-       ccdc_setwin(&params->win, params->frm_fmt, CCDC_PPC_RAW);
-
-       /* Configure Black Clamp */
-       ccdc_config_black_clamp(&config_params->blk_clamp);
-
-       /* Configure Black level compensation */
-       ccdc_config_black_compense(&config_params->blk_comp);
-
-       /* If data size is 8 bit then pack the data */
-       if ((config_params->data_sz == CCDC_DATA_8BITS) ||
-            config_params->alaw.enable)
-               syn_mode |= CCDC_DATA_PACK_ENABLE;
-
-       /* disable video port */
-       val = CCDC_DISABLE_VIDEO_PORT;
-
-       if (config_params->data_sz == CCDC_DATA_8BITS)
-               val |= (CCDC_DATA_10BITS & CCDC_FMTCFG_VPIN_MASK)
-                   << CCDC_FMTCFG_VPIN_SHIFT;
-       else
-               val |= (config_params->data_sz & CCDC_FMTCFG_VPIN_MASK)
-                   << CCDC_FMTCFG_VPIN_SHIFT;
-       /* Write value in FMTCFG */
-       regw(val, CCDC_FMTCFG);
-
-       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMTCFG...\n", val);
-       /* Configure the color pattern according to mt9t001 sensor */
-       regw(CCDC_COLPTN_VAL, CCDC_COLPTN);
-
-       dev_dbg(ccdc_cfg.dev, "\nWriting 0xBB11BB11 to COLPTN...\n");
-       /*
-        * Configure Data formatter(Video port) pixel selection
-        * (FMT_HORZ, FMT_VERT)
-        */
-       val = ((params->win.left & CCDC_FMT_HORZ_FMTSPH_MASK) <<
-             CCDC_FMT_HORZ_FMTSPH_SHIFT) |
-             (params->win.width & CCDC_FMT_HORZ_FMTLNH_MASK);
-       regw(val, CCDC_FMT_HORZ);
-
-       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_HORZ...\n", val);
-       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(ccdc_cfg.dev, "\nparams->win.height  0x%x ...\n",
-              params->win.height);
-       regw(val, CCDC_FMT_VERT);
-
-       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_VERT...\n", val);
-
-       dev_dbg(ccdc_cfg.dev, "\nbelow regw(val, FMT_VERT)...");
-
-       /*
-        * Configure Horizontal offset register. If pack 8 is enabled then
-        * 1 pixel will take 1 byte
-        */
-       if ((config_params->data_sz == CCDC_DATA_8BITS) ||
-           config_params->alaw.enable)
-               regw((params->win.width + CCDC_32BYTE_ALIGN_VAL) &
-                   CCDC_HSIZE_OFF_MASK, CCDC_HSIZE_OFF);
-       else
-               /* else one pixel will take 2 byte */
-               regw(((params->win.width * CCDC_TWO_BYTES_PER_PIXEL) +
-                   CCDC_32BYTE_ALIGN_VAL) & CCDC_HSIZE_OFF_MASK,
-                   CCDC_HSIZE_OFF);
-
-       /* Set value for SDOFST */
-       if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
-               if (params->image_invert_enable) {
-                       /* For intelace inverse mode */
-                       regw(CCDC_INTERLACED_IMAGE_INVERT, CCDC_SDOFST);
-                       dev_dbg(ccdc_cfg.dev, "\nWriting 0x4B6D to SDOFST..\n");
-               }
-
-               else {
-                       /* For intelace non inverse mode */
-                       regw(CCDC_INTERLACED_NO_IMAGE_INVERT, CCDC_SDOFST);
-                       dev_dbg(ccdc_cfg.dev, "\nWriting 0x0249 to SDOFST..\n");
-               }
-       } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
-               regw(CCDC_PROGRESSIVE_NO_IMAGE_INVERT, CCDC_SDOFST);
-               dev_dbg(ccdc_cfg.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, CCDC_VP_OUT);
-
-       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to VP_OUT...\n", val);
-       regw(syn_mode, CCDC_SYN_MODE);
-       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode);
-
-       ccdc_sbl_reset();
-       dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
-       ccdc_readregs();
-}
-
-static int ccdc_configure(void)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               ccdc_config_raw();
-       else
-               ccdc_config_ycbcr();
-       return 0;
-}
-
-static int ccdc_set_buftype(enum ccdc_buftype buf_type)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               ccdc_cfg.bayer.buf_type = buf_type;
-       else
-               ccdc_cfg.ycbcr.buf_type = buf_type;
-       return 0;
-}
-
-static enum ccdc_buftype ccdc_get_buftype(void)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               return ccdc_cfg.bayer.buf_type;
-       return ccdc_cfg.ycbcr.buf_type;
-}
-
-static int ccdc_enum_pix(u32 *pix, int i)
-{
-       int ret = -EINVAL;
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
-               if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
-                       *pix = ccdc_raw_bayer_pix_formats[i];
-                       ret = 0;
-               }
-       } else {
-               if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
-                       *pix = ccdc_raw_yuv_pix_formats[i];
-                       ret = 0;
-               }
-       }
-       return ret;
-}
-
-static int ccdc_set_pixel_format(u32 pixfmt)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
-               ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
-               if (pixfmt == V4L2_PIX_FMT_SBGGR8)
-                       ccdc_cfg.bayer.config_params.alaw.enable = 1;
-               else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
-                       return -EINVAL;
-       } else {
-               if (pixfmt == V4L2_PIX_FMT_YUYV)
-                       ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
-               else if (pixfmt == V4L2_PIX_FMT_UYVY)
-                       ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
-               else
-                       return -EINVAL;
-       }
-       return 0;
-}
-
-static u32 ccdc_get_pixel_format(void)
-{
-       struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
-       u32 pixfmt;
-
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               if (alaw->enable)
-                       pixfmt = V4L2_PIX_FMT_SBGGR8;
-               else
-                       pixfmt = V4L2_PIX_FMT_SBGGR16;
-       else {
-               if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
-                       pixfmt = V4L2_PIX_FMT_YUYV;
-               else
-                       pixfmt = V4L2_PIX_FMT_UYVY;
-       }
-       return pixfmt;
-}
-
-static int ccdc_set_image_window(struct v4l2_rect *win)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               ccdc_cfg.bayer.win = *win;
-       else
-               ccdc_cfg.ycbcr.win = *win;
-       return 0;
-}
-
-static void ccdc_get_image_window(struct v4l2_rect *win)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               *win = ccdc_cfg.bayer.win;
-       else
-               *win = ccdc_cfg.ycbcr.win;
-}
-
-static unsigned int ccdc_get_line_length(void)
-{
-       struct ccdc_config_params_raw *config_params =
-                               &ccdc_cfg.bayer.config_params;
-       unsigned int len;
-
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
-               if ((config_params->alaw.enable) ||
-                   (config_params->data_sz == CCDC_DATA_8BITS))
-                       len = ccdc_cfg.bayer.win.width;
-               else
-                       len = ccdc_cfg.bayer.win.width * 2;
-       } else
-               len = ccdc_cfg.ycbcr.win.width * 2;
-       return ALIGN(len, 32);
-}
-
-static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               ccdc_cfg.bayer.frm_fmt = frm_fmt;
-       else
-               ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
-       return 0;
-}
-
-static enum ccdc_frmfmt ccdc_get_frame_format(void)
-{
-       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
-               return ccdc_cfg.bayer.frm_fmt;
-       else
-               return ccdc_cfg.ycbcr.frm_fmt;
-}
-
-static int ccdc_getfid(void)
-{
-       return (regr(CCDC_SYN_MODE) >> 15) & 1;
-}
-
-/* misc operations */
-static inline void ccdc_setfbaddr(unsigned long addr)
-{
-       regw(addr & 0xffffffe0, CCDC_SDR_ADDR);
-}
-
-static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
-{
-       ccdc_cfg.if_type = params->if_type;
-
-       switch (params->if_type) {
-       case VPFE_BT656:
-       case VPFE_YCBCR_SYNC_16:
-       case VPFE_YCBCR_SYNC_8:
-       case VPFE_BT656_10BIT:
-               ccdc_cfg.ycbcr.vd_pol = params->vdpol;
-               ccdc_cfg.ycbcr.hd_pol = params->hdpol;
-               break;
-       default:
-               /* TODO add support for raw bayer here */
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static void ccdc_save_context(void)
-{
-       ccdc_ctx[CCDC_PCR >> 2] = regr(CCDC_PCR);
-       ccdc_ctx[CCDC_SYN_MODE >> 2] = regr(CCDC_SYN_MODE);
-       ccdc_ctx[CCDC_HD_VD_WID >> 2] = regr(CCDC_HD_VD_WID);
-       ccdc_ctx[CCDC_PIX_LINES >> 2] = regr(CCDC_PIX_LINES);
-       ccdc_ctx[CCDC_HORZ_INFO >> 2] = regr(CCDC_HORZ_INFO);
-       ccdc_ctx[CCDC_VERT_START >> 2] = regr(CCDC_VERT_START);
-       ccdc_ctx[CCDC_VERT_LINES >> 2] = regr(CCDC_VERT_LINES);
-       ccdc_ctx[CCDC_CULLING >> 2] = regr(CCDC_CULLING);
-       ccdc_ctx[CCDC_HSIZE_OFF >> 2] = regr(CCDC_HSIZE_OFF);
-       ccdc_ctx[CCDC_SDOFST >> 2] = regr(CCDC_SDOFST);
-       ccdc_ctx[CCDC_SDR_ADDR >> 2] = regr(CCDC_SDR_ADDR);
-       ccdc_ctx[CCDC_CLAMP >> 2] = regr(CCDC_CLAMP);
-       ccdc_ctx[CCDC_DCSUB >> 2] = regr(CCDC_DCSUB);
-       ccdc_ctx[CCDC_COLPTN >> 2] = regr(CCDC_COLPTN);
-       ccdc_ctx[CCDC_BLKCMP >> 2] = regr(CCDC_BLKCMP);
-       ccdc_ctx[CCDC_FPC >> 2] = regr(CCDC_FPC);
-       ccdc_ctx[CCDC_FPC_ADDR >> 2] = regr(CCDC_FPC_ADDR);
-       ccdc_ctx[CCDC_VDINT >> 2] = regr(CCDC_VDINT);
-       ccdc_ctx[CCDC_ALAW >> 2] = regr(CCDC_ALAW);
-       ccdc_ctx[CCDC_REC656IF >> 2] = regr(CCDC_REC656IF);
-       ccdc_ctx[CCDC_CCDCFG >> 2] = regr(CCDC_CCDCFG);
-       ccdc_ctx[CCDC_FMTCFG >> 2] = regr(CCDC_FMTCFG);
-       ccdc_ctx[CCDC_FMT_HORZ >> 2] = regr(CCDC_FMT_HORZ);
-       ccdc_ctx[CCDC_FMT_VERT >> 2] = regr(CCDC_FMT_VERT);
-       ccdc_ctx[CCDC_FMT_ADDR0 >> 2] = regr(CCDC_FMT_ADDR0);
-       ccdc_ctx[CCDC_FMT_ADDR1 >> 2] = regr(CCDC_FMT_ADDR1);
-       ccdc_ctx[CCDC_FMT_ADDR2 >> 2] = regr(CCDC_FMT_ADDR2);
-       ccdc_ctx[CCDC_FMT_ADDR3 >> 2] = regr(CCDC_FMT_ADDR3);
-       ccdc_ctx[CCDC_FMT_ADDR4 >> 2] = regr(CCDC_FMT_ADDR4);
-       ccdc_ctx[CCDC_FMT_ADDR5 >> 2] = regr(CCDC_FMT_ADDR5);
-       ccdc_ctx[CCDC_FMT_ADDR6 >> 2] = regr(CCDC_FMT_ADDR6);
-       ccdc_ctx[CCDC_FMT_ADDR7 >> 2] = regr(CCDC_FMT_ADDR7);
-       ccdc_ctx[CCDC_PRGEVEN_0 >> 2] = regr(CCDC_PRGEVEN_0);
-       ccdc_ctx[CCDC_PRGEVEN_1 >> 2] = regr(CCDC_PRGEVEN_1);
-       ccdc_ctx[CCDC_PRGODD_0 >> 2] = regr(CCDC_PRGODD_0);
-       ccdc_ctx[CCDC_PRGODD_1 >> 2] = regr(CCDC_PRGODD_1);
-       ccdc_ctx[CCDC_VP_OUT >> 2] = regr(CCDC_VP_OUT);
-}
-
-static void ccdc_restore_context(void)
-{
-       regw(ccdc_ctx[CCDC_SYN_MODE >> 2], CCDC_SYN_MODE);
-       regw(ccdc_ctx[CCDC_HD_VD_WID >> 2], CCDC_HD_VD_WID);
-       regw(ccdc_ctx[CCDC_PIX_LINES >> 2], CCDC_PIX_LINES);
-       regw(ccdc_ctx[CCDC_HORZ_INFO >> 2], CCDC_HORZ_INFO);
-       regw(ccdc_ctx[CCDC_VERT_START >> 2], CCDC_VERT_START);
-       regw(ccdc_ctx[CCDC_VERT_LINES >> 2], CCDC_VERT_LINES);
-       regw(ccdc_ctx[CCDC_CULLING >> 2], CCDC_CULLING);
-       regw(ccdc_ctx[CCDC_HSIZE_OFF >> 2], CCDC_HSIZE_OFF);
-       regw(ccdc_ctx[CCDC_SDOFST >> 2], CCDC_SDOFST);
-       regw(ccdc_ctx[CCDC_SDR_ADDR >> 2], CCDC_SDR_ADDR);
-       regw(ccdc_ctx[CCDC_CLAMP >> 2], CCDC_CLAMP);
-       regw(ccdc_ctx[CCDC_DCSUB >> 2], CCDC_DCSUB);
-       regw(ccdc_ctx[CCDC_COLPTN >> 2], CCDC_COLPTN);
-       regw(ccdc_ctx[CCDC_BLKCMP >> 2], CCDC_BLKCMP);
-       regw(ccdc_ctx[CCDC_FPC >> 2], CCDC_FPC);
-       regw(ccdc_ctx[CCDC_FPC_ADDR >> 2], CCDC_FPC_ADDR);
-       regw(ccdc_ctx[CCDC_VDINT >> 2], CCDC_VDINT);
-       regw(ccdc_ctx[CCDC_ALAW >> 2], CCDC_ALAW);
-       regw(ccdc_ctx[CCDC_REC656IF >> 2], CCDC_REC656IF);
-       regw(ccdc_ctx[CCDC_CCDCFG >> 2], CCDC_CCDCFG);
-       regw(ccdc_ctx[CCDC_FMTCFG >> 2], CCDC_FMTCFG);
-       regw(ccdc_ctx[CCDC_FMT_HORZ >> 2], CCDC_FMT_HORZ);
-       regw(ccdc_ctx[CCDC_FMT_VERT >> 2], CCDC_FMT_VERT);
-       regw(ccdc_ctx[CCDC_FMT_ADDR0 >> 2], CCDC_FMT_ADDR0);
-       regw(ccdc_ctx[CCDC_FMT_ADDR1 >> 2], CCDC_FMT_ADDR1);
-       regw(ccdc_ctx[CCDC_FMT_ADDR2 >> 2], CCDC_FMT_ADDR2);
-       regw(ccdc_ctx[CCDC_FMT_ADDR3 >> 2], CCDC_FMT_ADDR3);
-       regw(ccdc_ctx[CCDC_FMT_ADDR4 >> 2], CCDC_FMT_ADDR4);
-       regw(ccdc_ctx[CCDC_FMT_ADDR5 >> 2], CCDC_FMT_ADDR5);
-       regw(ccdc_ctx[CCDC_FMT_ADDR6 >> 2], CCDC_FMT_ADDR6);
-       regw(ccdc_ctx[CCDC_FMT_ADDR7 >> 2], CCDC_FMT_ADDR7);
-       regw(ccdc_ctx[CCDC_PRGEVEN_0 >> 2], CCDC_PRGEVEN_0);
-       regw(ccdc_ctx[CCDC_PRGEVEN_1 >> 2], CCDC_PRGEVEN_1);
-       regw(ccdc_ctx[CCDC_PRGODD_0 >> 2], CCDC_PRGODD_0);
-       regw(ccdc_ctx[CCDC_PRGODD_1 >> 2], CCDC_PRGODD_1);
-       regw(ccdc_ctx[CCDC_VP_OUT >> 2], CCDC_VP_OUT);
-       regw(ccdc_ctx[CCDC_PCR >> 2], CCDC_PCR);
-}
-static const struct ccdc_hw_device ccdc_hw_dev = {
-       .name = "DM6446 CCDC",
-       .owner = THIS_MODULE,
-       .hw_ops = {
-               .open = ccdc_open,
-               .close = ccdc_close,
-               .reset = ccdc_sbl_reset,
-               .enable = ccdc_enable,
-               .set_hw_if_params = ccdc_set_hw_if_params,
-               .configure = ccdc_configure,
-               .set_buftype = ccdc_set_buftype,
-               .get_buftype = ccdc_get_buftype,
-               .enum_pix = ccdc_enum_pix,
-               .set_pixel_format = ccdc_set_pixel_format,
-               .get_pixel_format = 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,
-       },
-};
-
-static int dm644x_ccdc_probe(struct platform_device *pdev)
-{
-       struct resource *res;
-       int status = 0;
-
-       /*
-        * first try to register with vpfe. If not correct platform, then we
-        * don't have to iomap
-        */
-       status = vpfe_register_ccdc_device(&ccdc_hw_dev);
-       if (status < 0)
-               return status;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               status = -ENODEV;
-               goto fail_nores;
-       }
-
-       res = request_mem_region(res->start, resource_size(res), res->name);
-       if (!res) {
-               status = -EBUSY;
-               goto fail_nores;
-       }
-
-       ccdc_cfg.base_addr = ioremap(res->start, resource_size(res));
-       if (!ccdc_cfg.base_addr) {
-               status = -ENOMEM;
-               goto fail_nomem;
-       }
-
-       ccdc_cfg.dev = &pdev->dev;
-       printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
-       return 0;
-fail_nomem:
-       release_mem_region(res->start, resource_size(res));
-fail_nores:
-       vpfe_unregister_ccdc_device(&ccdc_hw_dev);
-       return status;
-}
-
-static int dm644x_ccdc_remove(struct platform_device *pdev)
-{
-       struct resource *res;
-
-       iounmap(ccdc_cfg.base_addr);
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res)
-               release_mem_region(res->start, resource_size(res));
-       vpfe_unregister_ccdc_device(&ccdc_hw_dev);
-       return 0;
-}
-
-static int dm644x_ccdc_suspend(struct device *dev)
-{
-       /* Save CCDC context */
-       ccdc_save_context();
-       /* Disable CCDC */
-       ccdc_enable(0);
-
-       return 0;
-}
-
-static int dm644x_ccdc_resume(struct device *dev)
-{
-       /* Restore CCDC context */
-       ccdc_restore_context();
-
-       return 0;
-}
-
-static const struct dev_pm_ops dm644x_ccdc_pm_ops = {
-       .suspend = dm644x_ccdc_suspend,
-       .resume = dm644x_ccdc_resume,
-};
-
-static struct platform_driver dm644x_ccdc_driver = {
-       .driver = {
-               .name   = "dm644x_ccdc",
-               .pm = &dm644x_ccdc_pm_ops,
-       },
-       .remove = dm644x_ccdc_remove,
-       .probe = dm644x_ccdc_probe,
-};
-
-module_platform_driver(dm644x_ccdc_driver);
diff --git a/drivers/media/platform/davinci/dm644x_ccdc_regs.h b/drivers/media/platform/davinci/dm644x_ccdc_regs.h
deleted file mode 100644 (file)
index c4894f6..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2006-2009 Texas Instruments Inc
- */
-#ifndef _DM644X_CCDC_REGS_H
-#define _DM644X_CCDC_REGS_H
-
-/**************************************************************************\
-* Register OFFSET Definitions
-\**************************************************************************/
-#define CCDC_PID                               0x0
-#define CCDC_PCR                               0x4
-#define CCDC_SYN_MODE                          0x8
-#define CCDC_HD_VD_WID                         0xc
-#define CCDC_PIX_LINES                         0x10
-#define CCDC_HORZ_INFO                         0x14
-#define CCDC_VERT_START                                0x18
-#define CCDC_VERT_LINES                                0x1c
-#define CCDC_CULLING                           0x20
-#define CCDC_HSIZE_OFF                         0x24
-#define CCDC_SDOFST                            0x28
-#define CCDC_SDR_ADDR                          0x2c
-#define CCDC_CLAMP                             0x30
-#define CCDC_DCSUB                             0x34
-#define CCDC_COLPTN                            0x38
-#define CCDC_BLKCMP                            0x3c
-#define CCDC_FPC                               0x40
-#define CCDC_FPC_ADDR                          0x44
-#define CCDC_VDINT                             0x48
-#define CCDC_ALAW                              0x4c
-#define CCDC_REC656IF                          0x50
-#define CCDC_CCDCFG                            0x54
-#define CCDC_FMTCFG                            0x58
-#define CCDC_FMT_HORZ                          0x5c
-#define CCDC_FMT_VERT                          0x60
-#define CCDC_FMT_ADDR0                         0x64
-#define CCDC_FMT_ADDR1                         0x68
-#define CCDC_FMT_ADDR2                         0x6c
-#define CCDC_FMT_ADDR3                         0x70
-#define CCDC_FMT_ADDR4                         0x74
-#define CCDC_FMT_ADDR5                         0x78
-#define CCDC_FMT_ADDR6                         0x7c
-#define CCDC_FMT_ADDR7                         0x80
-#define CCDC_PRGEVEN_0                         0x84
-#define CCDC_PRGEVEN_1                         0x88
-#define CCDC_PRGODD_0                          0x8c
-#define CCDC_PRGODD_1                          0x90
-#define CCDC_VP_OUT                            0x94
-#define CCDC_REG_END                           0x98
-
-/***************************************************************
-*      Define for various register bit mask and shifts for CCDC
-****************************************************************/
-#define CCDC_FID_POL_MASK                      1
-#define CCDC_FID_POL_SHIFT                     4
-#define CCDC_HD_POL_MASK                       1
-#define CCDC_HD_POL_SHIFT                      3
-#define CCDC_VD_POL_MASK                       1
-#define CCDC_VD_POL_SHIFT                      2
-#define CCDC_HSIZE_OFF_MASK                    0xffffffe0
-#define CCDC_32BYTE_ALIGN_VAL                  31
-#define CCDC_FRM_FMT_MASK                      0x1
-#define CCDC_FRM_FMT_SHIFT                     7
-#define CCDC_DATA_SZ_MASK                      7
-#define CCDC_DATA_SZ_SHIFT                     8
-#define CCDC_PIX_FMT_MASK                      3
-#define CCDC_PIX_FMT_SHIFT                     12
-#define CCDC_VP2SDR_DISABLE                    0xFFFBFFFF
-#define CCDC_WEN_ENABLE                                BIT(17)
-#define CCDC_SDR2RSZ_DISABLE                   0xFFF7FFFF
-#define CCDC_VDHDEN_ENABLE                     BIT(16)
-#define CCDC_LPF_ENABLE                                BIT(14)
-#define CCDC_ALAW_ENABLE                       BIT(3)
-#define CCDC_ALAW_GAMMA_WD_MASK                        7
-#define CCDC_BLK_CLAMP_ENABLE                  BIT(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                        7
-#define CCDC_BLK_SAMPLE_LN_SHIFT               28
-#define CCDC_BLK_SAMPLE_LINE_MASK              7
-#define CCDC_BLK_SAMPLE_LINE_SHIFT             25
-#define CCDC_BLK_DC_SUB_MASK                   0x03FFF
-#define CCDC_BLK_COMP_MASK                     0xFF
-#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            BIT(15)
-#define CCDC_FPC_ENABLE                                BIT(15)
-#define CCDC_FPC_DISABLE                       0
-#define CCDC_FPC_FPC_NUM_MASK                  0x7FFF
-#define CCDC_DATA_PACK_ENABLE                  BIT(11)
-#define CCDC_FMTCFG_VPIN_MASK                  7
-#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               0xF
-#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
-#define CCDC_PPC_RAW                           1
-#define CCDC_DCSUB_DEFAULT_VAL                 0
-#define CCDC_CLAMP_DEFAULT_VAL                 0
-#define CCDC_ENABLE_VIDEO_PORT                 0x8000
-#define CCDC_DISABLE_VIDEO_PORT                        0
-#define CCDC_COLPTN_VAL                                0xBB11BB11
-#define CCDC_TWO_BYTES_PER_PIXEL               2
-#define CCDC_INTERLACED_IMAGE_INVERT           0x4B6D
-#define CCDC_INTERLACED_NO_IMAGE_INVERT                0x0249
-#define CCDC_PROGRESSIVE_IMAGE_INVERT          0x4000
-#define CCDC_PROGRESSIVE_NO_IMAGE_INVERT       0
-#define CCDC_INTERLACED_HEIGHT_SHIFT           1
-#define CCDC_SYN_MODE_INPMOD_SHIFT             12
-#define CCDC_SYN_MODE_INPMOD_MASK              3
-#define CCDC_SYN_MODE_8BITS                    (7 << 8)
-#define CCDC_SYN_MODE_10BITS                   (6 << 8)
-#define CCDC_SYN_MODE_11BITS                   (5 << 8)
-#define CCDC_SYN_MODE_12BITS                   (4 << 8)
-#define CCDC_SYN_MODE_13BITS                   (3 << 8)
-#define CCDC_SYN_MODE_14BITS                   (2 << 8)
-#define CCDC_SYN_MODE_15BITS                   (1 << 8)
-#define CCDC_SYN_MODE_16BITS                   (0 << 8)
-#define CCDC_SYN_FLDMODE_MASK                  1
-#define CCDC_SYN_FLDMODE_SHIFT                 7
-#define CCDC_REC656IF_BT656_EN                 3
-#define CCDC_SYN_MODE_VD_POL_NEGATIVE          BIT(2)
-#define CCDC_CCDCFG_Y8POS_SHIFT                        11
-#define CCDC_CCDCFG_BW656_10BIT                        BIT(5)
-#define CCDC_SDOFST_FIELD_INTERLEAVED          0x249
-#define CCDC_NO_CULLING                                0xffff00ff
-#endif
diff --git a/drivers/media/platform/davinci/isif.c b/drivers/media/platform/davinci/isif.c
deleted file mode 100644 (file)
index c53cecd..0000000
+++ /dev/null
@@ -1,1128 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2008-2009 Texas Instruments Inc
- *
- * Image Sensor Interface (ISIF) driver
- *
- * This driver is for configuring the ISIF IP available on DM365 or any other
- * TI SoCs. This is used for capturing yuv or bayer video or image data
- * from a decoder or sensor. This IP is similar to the CCDC IP on DM355
- * and DM6446, but with enhanced or additional ip blocks. The driver
- * configures the ISIF upon commands from the vpfe bridge driver through
- * ccdc_hw_device interface.
- *
- * TODO: 1) Raw bayer parameter settings and bayer capture
- *      2) Add support for control ioctl
- */
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
-#include <linux/videodev2.h>
-#include <linux/err.h>
-#include <linux/module.h>
-
-#include <media/davinci/isif.h>
-#include <media/davinci/vpss.h>
-
-#include "isif_regs.h"
-#include "ccdc_hw_device.h"
-
-/* Defaults for module configuration parameters */
-static const struct isif_config_params_raw isif_config_defaults = {
-       .linearize = {
-               .en = 0,
-               .corr_shft = ISIF_NO_SHIFT,
-               .scale_fact = {1, 0},
-       },
-       .df_csc = {
-               .df_or_csc = 0,
-               .csc = {
-                       .en = 0,
-               },
-       },
-       .dfc = {
-               .en = 0,
-       },
-       .bclamp = {
-               .en = 0,
-       },
-       .gain_offset = {
-               .gain = {
-                       .r_ye = {1, 0},
-                       .gr_cy = {1, 0},
-                       .gb_g = {1, 0},
-                       .b_mg = {1, 0},
-               },
-       },
-       .culling = {
-               .hcpat_odd = 0xff,
-               .hcpat_even = 0xff,
-               .vcpat = 0xff,
-       },
-       .compress = {
-               .alg = ISIF_ALAW,
-       },
-};
-
-/* ISIF operation configuration */
-static struct isif_oper_config {
-       struct device *dev;
-       enum vpfe_hw_if_type if_type;
-       struct isif_ycbcr_config ycbcr;
-       struct isif_params_raw bayer;
-       enum isif_data_pack data_pack;
-       /* ISIF base address */
-       void __iomem *base_addr;
-       /* ISIF Linear Table 0 */
-       void __iomem *linear_tbl0_addr;
-       /* ISIF Linear Table 1 */
-       void __iomem *linear_tbl1_addr;
-} isif_cfg = {
-       .ycbcr = {
-               .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
-               .frm_fmt = CCDC_FRMFMT_INTERLACED,
-               .win = ISIF_WIN_NTSC,
-               .fid_pol = VPFE_PINPOL_POSITIVE,
-               .vd_pol = VPFE_PINPOL_POSITIVE,
-               .hd_pol = VPFE_PINPOL_POSITIVE,
-               .pix_order = CCDC_PIXORDER_CBYCRY,
-               .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED,
-       },
-       .bayer = {
-               .pix_fmt = CCDC_PIXFMT_RAW,
-               .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
-               .win = ISIF_WIN_VGA,
-               .fid_pol = VPFE_PINPOL_POSITIVE,
-               .vd_pol = VPFE_PINPOL_POSITIVE,
-               .hd_pol = VPFE_PINPOL_POSITIVE,
-               .gain = {
-                       .r_ye = {1, 0},
-                       .gr_cy = {1, 0},
-                       .gb_g = {1, 0},
-                       .b_mg = {1, 0},
-               },
-               .cfa_pat = ISIF_CFA_PAT_MOSAIC,
-               .data_msb = ISIF_BIT_MSB_11,
-               .config_params = {
-                       .data_shift = ISIF_NO_SHIFT,
-                       .col_pat_field0 = {
-                               .olop = ISIF_GREEN_BLUE,
-                               .olep = ISIF_BLUE,
-                               .elop = ISIF_RED,
-                               .elep = ISIF_GREEN_RED,
-                       },
-                       .col_pat_field1 = {
-                               .olop = ISIF_GREEN_BLUE,
-                               .olep = ISIF_BLUE,
-                               .elop = ISIF_RED,
-                               .elep = ISIF_GREEN_RED,
-                       },
-                       .test_pat_gen = 0,
-               },
-       },
-       .data_pack = ISIF_DATA_PACK8,
-};
-
-/* Raw Bayer formats */
-static const u32 isif_raw_bayer_pix_formats[] = {
-       V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
-
-/* Raw YUV formats */
-static const u32 isif_raw_yuv_pix_formats[] = {
-       V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
-
-/* register access routines */
-static inline u32 regr(u32 offset)
-{
-       return __raw_readl(isif_cfg.base_addr + offset);
-}
-
-static inline void regw(u32 val, u32 offset)
-{
-       __raw_writel(val, isif_cfg.base_addr + offset);
-}
-
-/* reg_modify() - read, modify and write register */
-static inline u32 reg_modify(u32 mask, u32 val, u32 offset)
-{
-       u32 new_val = (regr(offset) & ~mask) | (val & mask);
-
-       regw(new_val, offset);
-       return new_val;
-}
-
-static inline void regw_lin_tbl(u32 val, u32 offset, int i)
-{
-       if (!i)
-               __raw_writel(val, isif_cfg.linear_tbl0_addr + offset);
-       else
-               __raw_writel(val, isif_cfg.linear_tbl1_addr + offset);
-}
-
-static void isif_disable_all_modules(void)
-{
-       /* disable BC */
-       regw(0, CLAMPCFG);
-       /* disable vdfc */
-       regw(0, DFCCTL);
-       /* disable CSC */
-       regw(0, CSCCTL);
-       /* disable linearization */
-       regw(0, LINCFG0);
-       /* disable other modules here as they are supported */
-}
-
-static void isif_enable(int en)
-{
-       if (!en) {
-               /* Before disable isif, disable all ISIF modules */
-               isif_disable_all_modules();
-               /*
-                * wait for next VD. Assume lowest scan rate is 12 Hz. So
-                * 100 msec delay is good enough
-                */
-               msleep(100);
-       }
-       reg_modify(ISIF_SYNCEN_VDHDEN_MASK, en, SYNCEN);
-}
-
-static void isif_enable_output_to_sdram(int en)
-{
-       reg_modify(ISIF_SYNCEN_WEN_MASK, en << ISIF_SYNCEN_WEN_SHIFT, SYNCEN);
-}
-
-static void isif_config_culling(struct isif_cul *cul)
-{
-       u32 val;
-
-       /* Horizontal pattern */
-       val = (cul->hcpat_even << CULL_PAT_EVEN_LINE_SHIFT) | cul->hcpat_odd;
-       regw(val, CULH);
-
-       /* vertical pattern */
-       regw(cul->vcpat, CULV);
-
-       /* LPF */
-       reg_modify(ISIF_LPF_MASK << ISIF_LPF_SHIFT,
-                 cul->en_lpf << ISIF_LPF_SHIFT, MODESET);
-}
-
-static void isif_config_gain_offset(void)
-{
-       struct isif_gain_offsets_adj *gain_off_p =
-               &isif_cfg.bayer.config_params.gain_offset;
-       u32 val;
-
-       val = (!!gain_off_p->gain_sdram_en << GAIN_SDRAM_EN_SHIFT) |
-             (!!gain_off_p->gain_ipipe_en << GAIN_IPIPE_EN_SHIFT) |
-             (!!gain_off_p->gain_h3a_en << GAIN_H3A_EN_SHIFT) |
-             (!!gain_off_p->offset_sdram_en << OFST_SDRAM_EN_SHIFT) |
-             (!!gain_off_p->offset_ipipe_en << OFST_IPIPE_EN_SHIFT) |
-             (!!gain_off_p->offset_h3a_en << OFST_H3A_EN_SHIFT);
-
-       reg_modify(GAIN_OFFSET_EN_MASK, val, CGAMMAWD);
-
-       val = (gain_off_p->gain.r_ye.integer << GAIN_INTEGER_SHIFT) |
-              gain_off_p->gain.r_ye.decimal;
-       regw(val, CRGAIN);
-
-       val = (gain_off_p->gain.gr_cy.integer << GAIN_INTEGER_SHIFT) |
-              gain_off_p->gain.gr_cy.decimal;
-       regw(val, CGRGAIN);
-
-       val = (gain_off_p->gain.gb_g.integer << GAIN_INTEGER_SHIFT) |
-              gain_off_p->gain.gb_g.decimal;
-       regw(val, CGBGAIN);
-
-       val = (gain_off_p->gain.b_mg.integer << GAIN_INTEGER_SHIFT) |
-              gain_off_p->gain.b_mg.decimal;
-       regw(val, CBGAIN);
-
-       regw(gain_off_p->offset, COFSTA);
-}
-
-static void isif_restore_defaults(void)
-{
-       enum vpss_ccdc_source_sel source = VPSS_CCDCIN;
-
-       dev_dbg(isif_cfg.dev, "\nstarting isif_restore_defaults...");
-       isif_cfg.bayer.config_params = isif_config_defaults;
-       /* Enable clock to ISIF, IPIPEIF and BL */
-       vpss_enable_clock(VPSS_CCDC_CLOCK, 1);
-       vpss_enable_clock(VPSS_IPIPEIF_CLOCK, 1);
-       vpss_enable_clock(VPSS_BL_CLOCK, 1);
-       /* Set default offset and gain */
-       isif_config_gain_offset();
-       vpss_select_ccdc_source(source);
-       dev_dbg(isif_cfg.dev, "\nEnd of isif_restore_defaults...");
-}
-
-static int isif_open(struct device *device)
-{
-       isif_restore_defaults();
-       return 0;
-}
-
-/* This function will configure the window size to be capture in ISIF reg */
-static void isif_setwin(struct v4l2_rect *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(isif_cfg.dev, "\nStarting isif_setwin...");
-       /*
-        * ppc - per pixel count. indicates how many pixels per cell
-        * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
-        * raw capture this is 1
-        */
-       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, LNH);
-       vert_start = image_win->top;
-
-       if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
-               vert_nr_lines = (image_win->height >> 1) - 1;
-               vert_start >>= 1;
-               /* To account for VD since line 0 doesn't have any data */
-               vert_start += 1;
-       } else {
-               /* To account for VD since line 0 doesn't have any data */
-               vert_start += 1;
-               vert_nr_lines = image_win->height - 1;
-               /* configure VDINT0 and VDINT1 */
-               mid_img = vert_start + (image_win->height / 2);
-               regw(mid_img, VDINT1);
-       }
-
-       regw(0, VDINT0);
-       regw(vert_start & START_VER_ONE_MASK, SLV0);
-       regw(vert_start & START_VER_TWO_MASK, SLV1);
-       regw(vert_nr_lines & NUM_LINES_VER, LNV);
-}
-
-static void isif_config_bclamp(struct isif_black_clamp *bc)
-{
-       u32 val;
-
-       /*
-        * DC Offset is always added to image data irrespective of bc enable
-        * status
-        */
-       regw(bc->dc_offset, CLDCOFST);
-
-       if (bc->en) {
-               val = bc->bc_mode_color << ISIF_BC_MODE_COLOR_SHIFT;
-
-               /* Enable BC and horizontal clamp calculation parameters */
-               val = val | 1 | (bc->horz.mode << ISIF_HORZ_BC_MODE_SHIFT);
-
-               regw(val, CLAMPCFG);
-
-               if (bc->horz.mode != ISIF_HORZ_BC_DISABLE) {
-                       /*
-                        * Window count for calculation
-                        * Base window selection
-                        * pixel limit
-                        * Horizontal size of window
-                        * vertical size of the window
-                        * Horizontal start position of the window
-                        * Vertical start position of the window
-                        */
-                       val = bc->horz.win_count_calc |
-                             ((!!bc->horz.base_win_sel_calc) <<
-                               ISIF_HORZ_BC_WIN_SEL_SHIFT) |
-                             ((!!bc->horz.clamp_pix_limit) <<
-                               ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
-                             (bc->horz.win_h_sz_calc <<
-                               ISIF_HORZ_BC_WIN_H_SIZE_SHIFT) |
-                             (bc->horz.win_v_sz_calc <<
-                               ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);
-                       regw(val, CLHWIN0);
-
-                       regw(bc->horz.win_start_h_calc, CLHWIN1);
-                       regw(bc->horz.win_start_v_calc, CLHWIN2);
-               }
-
-               /* vertical clamp calculation parameters */
-
-               /* Reset clamp value sel for previous line */
-               val |=
-               (bc->vert.reset_val_sel << ISIF_VERT_BC_RST_VAL_SEL_SHIFT) |
-               (bc->vert.line_ave_coef << ISIF_VERT_BC_LINE_AVE_COEF_SHIFT);
-               regw(val, CLVWIN0);
-
-               /* Optical Black horizontal start position */
-               regw(bc->vert.ob_start_h, CLVWIN1);
-               /* Optical Black vertical start position */
-               regw(bc->vert.ob_start_v, CLVWIN2);
-               /* Optical Black vertical size for calculation */
-               regw(bc->vert.ob_v_sz_calc, CLVWIN3);
-               /* Vertical start position for BC subtraction */
-               regw(bc->vert_start_sub, CLSV);
-       }
-}
-
-static void isif_config_linearization(struct isif_linearize *linearize)
-{
-       u32 val, i;
-
-       if (!linearize->en) {
-               regw(0, LINCFG0);
-               return;
-       }
-
-       /* shift value for correction & enable linearization (set lsb) */
-       val = (linearize->corr_shft << ISIF_LIN_CORRSFT_SHIFT) | 1;
-       regw(val, LINCFG0);
-
-       /* Scale factor */
-       val = ((!!linearize->scale_fact.integer) <<
-              ISIF_LIN_SCALE_FACT_INTEG_SHIFT) |
-              linearize->scale_fact.decimal;
-       regw(val, LINCFG1);
-
-       for (i = 0; i < ISIF_LINEAR_TAB_SIZE; i++) {
-               if (i % 2)
-                       regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 1);
-               else
-                       regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 0);
-       }
-}
-
-static int isif_config_dfc(struct isif_dfc *vdfc)
-{
-       /* initialize retries to loop for max ~ 250 usec */
-       u32 val, count, retries = loops_per_jiffy / (4000/HZ);
-       int i;
-
-       if (!vdfc->en)
-               return 0;
-
-       /* Correction mode */
-       val = (vdfc->corr_mode << ISIF_VDFC_CORR_MOD_SHIFT);
-
-       /* Correct whole line or partial */
-       if (vdfc->corr_whole_line)
-               val |= 1 << ISIF_VDFC_CORR_WHOLE_LN_SHIFT;
-
-       /* level shift value */
-       val |= vdfc->def_level_shift << ISIF_VDFC_LEVEL_SHFT_SHIFT;
-
-       regw(val, DFCCTL);
-
-       /* Defect saturation level */
-       regw(vdfc->def_sat_level, VDFSATLV);
-
-       regw(vdfc->table[0].pos_vert, DFCMEM0);
-       regw(vdfc->table[0].pos_horz, DFCMEM1);
-       if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
-           vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
-               regw(vdfc->table[0].level_at_pos, DFCMEM2);
-               regw(vdfc->table[0].level_up_pixels, DFCMEM3);
-               regw(vdfc->table[0].level_low_pixels, DFCMEM4);
-       }
-
-       /* set DFCMARST and set DFCMWR */
-       val = regr(DFCMEMCTL) | (1 << ISIF_DFCMEMCTL_DFCMARST_SHIFT) | 1;
-       regw(val, DFCMEMCTL);
-
-       count = retries;
-       while (count && (regr(DFCMEMCTL) & 0x1))
-               count--;
-
-       if (!count) {
-               dev_dbg(isif_cfg.dev, "defect table write timeout !!!\n");
-               return -1;
-       }
-
-       for (i = 1; i < vdfc->num_vdefects; i++) {
-               regw(vdfc->table[i].pos_vert, DFCMEM0);
-               regw(vdfc->table[i].pos_horz, DFCMEM1);
-               if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
-                   vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
-                       regw(vdfc->table[i].level_at_pos, DFCMEM2);
-                       regw(vdfc->table[i].level_up_pixels, DFCMEM3);
-                       regw(vdfc->table[i].level_low_pixels, DFCMEM4);
-               }
-               val = regr(DFCMEMCTL);
-               /* clear DFCMARST and set DFCMWR */
-               val &= ~BIT(ISIF_DFCMEMCTL_DFCMARST_SHIFT);
-               val |= 1;
-               regw(val, DFCMEMCTL);
-
-               count = retries;
-               while (count && (regr(DFCMEMCTL) & 0x1))
-                       count--;
-
-               if (!count) {
-                       dev_err(isif_cfg.dev,
-                               "defect table write timeout !!!\n");
-                       return -1;
-               }
-       }
-       if (vdfc->num_vdefects < ISIF_VDFC_TABLE_SIZE) {
-               /* Extra cycle needed */
-               regw(0, DFCMEM0);
-               regw(0x1FFF, DFCMEM1);
-               regw(1, DFCMEMCTL);
-       }
-
-       /* enable VDFC */
-       reg_modify((1 << ISIF_VDFC_EN_SHIFT), (1 << ISIF_VDFC_EN_SHIFT),
-                  DFCCTL);
-       return 0;
-}
-
-static void isif_config_csc(struct isif_df_csc *df_csc)
-{
-       u32 val1 = 0, val2 = 0, i;
-
-       if (!df_csc->csc.en) {
-               regw(0, CSCCTL);
-               return;
-       }
-       for (i = 0; i < ISIF_CSC_NUM_COEFF; i++) {
-               if ((i % 2) == 0) {
-                       /* CSCM - LSB */
-                       val1 = (df_csc->csc.coeff[i].integer <<
-                               ISIF_CSC_COEF_INTEG_SHIFT) |
-                               df_csc->csc.coeff[i].decimal;
-               } else {
-
-                       /* CSCM - MSB */
-                       val2 = (df_csc->csc.coeff[i].integer <<
-                               ISIF_CSC_COEF_INTEG_SHIFT) |
-                               df_csc->csc.coeff[i].decimal;
-                       val2 <<= ISIF_CSCM_MSB_SHIFT;
-                       val2 |= val1;
-                       regw(val2, (CSCM0 + ((i - 1) << 1)));
-               }
-       }
-
-       /* program the active area */
-       regw(df_csc->start_pix, FMTSPH);
-       /*
-        * one extra pixel as required for CSC. Actually number of
-        * pixel - 1 should be configured in this register. So we
-        * need to subtract 1 before writing to FMTSPH, but we will
-        * not do this since csc requires one extra pixel
-        */
-       regw(df_csc->num_pixels, FMTLNH);
-       regw(df_csc->start_line, FMTSLV);
-       /*
-        * one extra line as required for CSC. See reason documented for
-        * num_pixels
-        */
-       regw(df_csc->num_lines, FMTLNV);
-
-       /* Enable CSC */
-       regw(1, CSCCTL);
-}
-
-static int isif_config_raw(void)
-{
-       struct isif_params_raw *params = &isif_cfg.bayer;
-       struct isif_config_params_raw *module_params =
-               &isif_cfg.bayer.config_params;
-       struct vpss_pg_frame_size frame_size;
-       struct vpss_sync_pol sync;
-       u32 val;
-
-       dev_dbg(isif_cfg.dev, "\nStarting isif_config_raw..\n");
-
-       /*
-        * Configure CCDCFG register:-
-        * Set CCD Not to swap input since input is RAW data
-        * Set FID detection function to Latch at V-Sync
-        * Set WENLOG - isif valid area
-        * Set TRGSEL
-        * Set EXTRG
-        * Packed to 8 or 16 bits
-        */
-
-       val = ISIF_YCINSWP_RAW | ISIF_CCDCFG_FIDMD_LATCH_VSYNC |
-               ISIF_CCDCFG_WENLOG_AND | ISIF_CCDCFG_TRGSEL_WEN |
-               ISIF_CCDCFG_EXTRG_DISABLE | isif_cfg.data_pack;
-
-       dev_dbg(isif_cfg.dev, "Writing 0x%x to ...CCDCFG \n", val);
-       regw(val, CCDCFG);
-
-       /*
-        * Configure the vertical sync polarity(MODESET.VDPOL)
-        * Configure the horizontal sync polarity (MODESET.HDPOL)
-        * Configure frame id polarity (MODESET.FLDPOL)
-        * Configure data polarity
-        * Configure External WEN Selection
-        * Configure frame format(progressive or interlace)
-        * Configure pixel format (Input mode)
-        * Configure the data shift
-        */
-
-       val = ISIF_VDHDOUT_INPUT | (params->vd_pol << ISIF_VD_POL_SHIFT) |
-               (params->hd_pol << ISIF_HD_POL_SHIFT) |
-               (params->fid_pol << ISIF_FID_POL_SHIFT) |
-               (ISIF_DATAPOL_NORMAL << ISIF_DATAPOL_SHIFT) |
-               (ISIF_EXWEN_DISABLE << ISIF_EXWEN_SHIFT) |
-               (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
-               (params->pix_fmt << ISIF_INPUT_SHIFT) |
-               (params->config_params.data_shift << ISIF_DATASFT_SHIFT);
-
-       regw(val, MODESET);
-       dev_dbg(isif_cfg.dev, "Writing 0x%x to MODESET...\n", val);
-
-       /*
-        * Configure GAMMAWD register
-        * CFA pattern setting
-        */
-       val = params->cfa_pat << ISIF_GAMMAWD_CFA_SHIFT;
-
-       /* Gamma msb */
-       if (module_params->compress.alg == ISIF_ALAW)
-               val |= ISIF_ALAW_ENABLE;
-
-       val |= (params->data_msb << ISIF_ALAW_GAMMA_WD_SHIFT);
-       regw(val, CGAMMAWD);
-
-       /* Configure DPCM compression settings */
-       if (module_params->compress.alg == ISIF_DPCM) {
-               val =  BIT(ISIF_DPCM_EN_SHIFT) |
-                      (module_params->compress.pred <<
-                      ISIF_DPCM_PREDICTOR_SHIFT);
-       }
-
-       regw(val, MISC);
-
-       /* Configure Gain & Offset */
-       isif_config_gain_offset();
-
-       /* Configure Color pattern */
-       val = (params->config_params.col_pat_field0.olop) |
-             (params->config_params.col_pat_field0.olep << 2) |
-             (params->config_params.col_pat_field0.elop << 4) |
-             (params->config_params.col_pat_field0.elep << 6) |
-             (params->config_params.col_pat_field1.olop << 8) |
-             (params->config_params.col_pat_field1.olep << 10) |
-             (params->config_params.col_pat_field1.elop << 12) |
-             (params->config_params.col_pat_field1.elep << 14);
-       regw(val, CCOLP);
-       dev_dbg(isif_cfg.dev, "Writing %x to CCOLP ...\n", val);
-
-       /* Configure HSIZE register  */
-       val = (!!params->horz_flip_en) << ISIF_HSIZE_FLIP_SHIFT;
-
-       /* calculate line offset in 32 bytes based on pack value */
-       if (isif_cfg.data_pack == ISIF_PACK_8BIT)
-               val |= ((params->win.width + 31) >> 5);
-       else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
-               val |= (((params->win.width +
-                      (params->win.width >> 2)) + 31) >> 5);
-       else
-               val |= (((params->win.width * 2) + 31) >> 5);
-       regw(val, HSIZE);
-
-       /* Configure SDOFST register  */
-       if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
-               if (params->image_invert_en) {
-                       /* For interlace inverse mode */
-                       regw(0x4B6D, SDOFST);
-                       dev_dbg(isif_cfg.dev, "Writing 0x4B6D to SDOFST...\n");
-               } else {
-                       /* For interlace non inverse mode */
-                       regw(0x0B6D, SDOFST);
-                       dev_dbg(isif_cfg.dev, "Writing 0x0B6D to SDOFST...\n");
-               }
-       } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
-               if (params->image_invert_en) {
-                       /* For progressive inverse mode */
-                       regw(0x4000, SDOFST);
-                       dev_dbg(isif_cfg.dev, "Writing 0x4000 to SDOFST...\n");
-               } else {
-                       /* For progressive non inverse mode */
-                       regw(0x0000, SDOFST);
-                       dev_dbg(isif_cfg.dev, "Writing 0x0000 to SDOFST...\n");
-               }
-       }
-
-       /* Configure video window */
-       isif_setwin(&params->win, params->frm_fmt, 1);
-
-       /* Configure Black Clamp */
-       isif_config_bclamp(&module_params->bclamp);
-
-       /* Configure Vertical Defection Pixel Correction */
-       if (isif_config_dfc(&module_params->dfc) < 0)
-               return -EFAULT;
-
-       if (!module_params->df_csc.df_or_csc)
-               /* Configure Color Space Conversion */
-               isif_config_csc(&module_params->df_csc);
-
-       isif_config_linearization(&module_params->linearize);
-
-       /* Configure Culling */
-       isif_config_culling(&module_params->culling);
-
-       /* Configure horizontal and vertical offsets(DFC,LSC,Gain) */
-       regw(module_params->horz_offset, DATAHOFST);
-       regw(module_params->vert_offset, DATAVOFST);
-
-       /* Setup test pattern if enabled */
-       if (params->config_params.test_pat_gen) {
-               /* Use the HD/VD pol settings from user */
-               sync.ccdpg_hdpol = params->hd_pol;
-               sync.ccdpg_vdpol = params->vd_pol;
-               dm365_vpss_set_sync_pol(sync);
-               frame_size.hlpfr = isif_cfg.bayer.win.width;
-               frame_size.pplen = isif_cfg.bayer.win.height;
-               dm365_vpss_set_pg_frame_size(frame_size);
-               vpss_select_ccdc_source(VPSS_PGLPBK);
-       }
-
-       dev_dbg(isif_cfg.dev, "\nEnd of isif_config_ycbcr...\n");
-       return 0;
-}
-
-static int isif_set_buftype(enum ccdc_buftype buf_type)
-{
-       if (isif_cfg.if_type == VPFE_RAW_BAYER)
-               isif_cfg.bayer.buf_type = buf_type;
-       else
-               isif_cfg.ycbcr.buf_type = buf_type;
-
-       return 0;
-
-}
-static enum ccdc_buftype isif_get_buftype(void)
-{
-       if (isif_cfg.if_type == VPFE_RAW_BAYER)
-               return isif_cfg.bayer.buf_type;
-
-       return isif_cfg.ycbcr.buf_type;
-}
-
-static int isif_enum_pix(u32 *pix, int i)
-{
-       int ret = -EINVAL;
-
-       if (isif_cfg.if_type == VPFE_RAW_BAYER) {
-               if (i < ARRAY_SIZE(isif_raw_bayer_pix_formats)) {
-                       *pix = isif_raw_bayer_pix_formats[i];
-                       ret = 0;
-               }
-       } else {
-               if (i < ARRAY_SIZE(isif_raw_yuv_pix_formats)) {
-                       *pix = isif_raw_yuv_pix_formats[i];
-                       ret = 0;
-               }
-       }
-
-       return ret;
-}
-
-static int isif_set_pixel_format(unsigned int pixfmt)
-{
-       if (isif_cfg.if_type == VPFE_RAW_BAYER) {
-               if (pixfmt == V4L2_PIX_FMT_SBGGR8) {
-                       if ((isif_cfg.bayer.config_params.compress.alg !=
-                            ISIF_ALAW) &&
-                           (isif_cfg.bayer.config_params.compress.alg !=
-                            ISIF_DPCM)) {
-                               dev_dbg(isif_cfg.dev,
-                                       "Either configure A-Law or DPCM\n");
-                               return -EINVAL;
-                       }
-                       isif_cfg.data_pack = ISIF_PACK_8BIT;
-               } else if (pixfmt == V4L2_PIX_FMT_SBGGR16) {
-                       isif_cfg.bayer.config_params.compress.alg =
-                                       ISIF_NO_COMPRESSION;
-                       isif_cfg.data_pack = ISIF_PACK_16BIT;
-               } else
-                       return -EINVAL;
-               isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
-       } else {
-               if (pixfmt == V4L2_PIX_FMT_YUYV)
-                       isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
-               else if (pixfmt == V4L2_PIX_FMT_UYVY)
-                       isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
-               else
-                       return -EINVAL;
-               isif_cfg.data_pack = ISIF_PACK_8BIT;
-       }
-       return 0;
-}
-
-static u32 isif_get_pixel_format(void)
-{
-       u32 pixfmt;
-
-       if (isif_cfg.if_type == VPFE_RAW_BAYER)
-               if (isif_cfg.bayer.config_params.compress.alg == ISIF_ALAW ||
-                   isif_cfg.bayer.config_params.compress.alg == ISIF_DPCM)
-                       pixfmt = V4L2_PIX_FMT_SBGGR8;
-               else
-                       pixfmt = V4L2_PIX_FMT_SBGGR16;
-       else {
-               if (isif_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
-                       pixfmt = V4L2_PIX_FMT_YUYV;
-               else
-                       pixfmt = V4L2_PIX_FMT_UYVY;
-       }
-       return pixfmt;
-}
-
-static int isif_set_image_window(struct v4l2_rect *win)
-{
-       if (isif_cfg.if_type == VPFE_RAW_BAYER) {
-               isif_cfg.bayer.win.top = win->top;
-               isif_cfg.bayer.win.left = win->left;
-               isif_cfg.bayer.win.width = win->width;
-               isif_cfg.bayer.win.height = win->height;
-       } else {
-               isif_cfg.ycbcr.win.top = win->top;
-               isif_cfg.ycbcr.win.left = win->left;
-               isif_cfg.ycbcr.win.width = win->width;
-               isif_cfg.ycbcr.win.height = win->height;
-       }
-       return 0;
-}
-
-static void isif_get_image_window(struct v4l2_rect *win)
-{
-       if (isif_cfg.if_type == VPFE_RAW_BAYER)
-               *win = isif_cfg.bayer.win;
-       else
-               *win = isif_cfg.ycbcr.win;
-}
-
-static unsigned int isif_get_line_length(void)
-{
-       unsigned int len;
-
-       if (isif_cfg.if_type == VPFE_RAW_BAYER) {
-               if (isif_cfg.data_pack == ISIF_PACK_8BIT)
-                       len = ((isif_cfg.bayer.win.width));
-               else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
-                       len = (((isif_cfg.bayer.win.width * 2) +
-                                (isif_cfg.bayer.win.width >> 2)));
-               else
-                       len = (((isif_cfg.bayer.win.width * 2)));
-       } else
-               len = (((isif_cfg.ycbcr.win.width * 2)));
-       return ALIGN(len, 32);
-}
-
-static int isif_set_frame_format(enum ccdc_frmfmt frm_fmt)
-{
-       if (isif_cfg.if_type == VPFE_RAW_BAYER)
-               isif_cfg.bayer.frm_fmt = frm_fmt;
-       else
-               isif_cfg.ycbcr.frm_fmt = frm_fmt;
-       return 0;
-}
-static enum ccdc_frmfmt isif_get_frame_format(void)
-{
-       if (isif_cfg.if_type == VPFE_RAW_BAYER)
-               return isif_cfg.bayer.frm_fmt;
-       return isif_cfg.ycbcr.frm_fmt;
-}
-
-static int isif_getfid(void)
-{
-       return (regr(MODESET) >> 15) & 0x1;
-}
-
-/* misc operations */
-static void isif_setfbaddr(unsigned long addr)
-{
-       regw((addr >> 21) & 0x07ff, CADU);
-       regw((addr >> 5) & 0x0ffff, CADL);
-}
-
-static int isif_set_hw_if_params(struct vpfe_hw_if_param *params)
-{
-       isif_cfg.if_type = params->if_type;
-
-       switch (params->if_type) {
-       case VPFE_BT656:
-       case VPFE_BT656_10BIT:
-       case VPFE_YCBCR_SYNC_8:
-               isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
-               isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
-               break;
-       case VPFE_BT1120:
-       case VPFE_YCBCR_SYNC_16:
-               isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_16BIT;
-               isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
-               break;
-       case VPFE_RAW_BAYER:
-               isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
-               break;
-       default:
-               dev_dbg(isif_cfg.dev, "Invalid interface type\n");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/* This function will configure ISIF for YCbCr parameters. */
-static int isif_config_ycbcr(void)
-{
-       struct isif_ycbcr_config *params = &isif_cfg.ycbcr;
-       u32 modeset = 0, ccdcfg = 0;
-
-       dev_dbg(isif_cfg.dev, "\nStarting isif_config_ycbcr...");
-
-       /* configure pixel format or input mode */
-       modeset = modeset | (params->pix_fmt << ISIF_INPUT_SHIFT) |
-                 (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
-                 (params->fid_pol << ISIF_FID_POL_SHIFT) |
-                 (params->hd_pol << ISIF_HD_POL_SHIFT) |
-                 (params->vd_pol << ISIF_VD_POL_SHIFT);
-
-       /* pack the data to 8-bit ISIFCFG */
-       switch (isif_cfg.if_type) {
-       case VPFE_BT656:
-               if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
-                       dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
-                       return -EINVAL;
-               }
-               modeset |= (VPFE_PINPOL_NEGATIVE << ISIF_VD_POL_SHIFT);
-               regw(3, REC656IF);
-               ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR;
-               break;
-       case VPFE_BT656_10BIT:
-               if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
-                       dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
-                       return -EINVAL;
-               }
-               /* setup BT.656, embedded sync  */
-               regw(3, REC656IF);
-               /* enable 10 bit mode in ccdcfg */
-               ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR |
-                       ISIF_BW656_ENABLE;
-               break;
-       case VPFE_BT1120:
-               if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
-                       dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
-                       return -EINVAL;
-               }
-               regw(3, REC656IF);
-               break;
-
-       case VPFE_YCBCR_SYNC_8:
-               ccdcfg |= ISIF_DATA_PACK8;
-               ccdcfg |= ISIF_YCINSWP_YCBCR;
-               if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
-                       dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
-                       return -EINVAL;
-               }
-               break;
-       case VPFE_YCBCR_SYNC_16:
-               if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
-                       dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
-                       return -EINVAL;
-               }
-               break;
-       default:
-               /* should never come here */
-               dev_dbg(isif_cfg.dev, "Invalid interface type\n");
-               return -EINVAL;
-       }
-
-       regw(modeset, MODESET);
-
-       /* Set up pix order */
-       ccdcfg |= params->pix_order << ISIF_PIX_ORDER_SHIFT;
-
-       regw(ccdcfg, CCDCFG);
-
-       /* configure video window */
-       if ((isif_cfg.if_type == VPFE_BT1120) ||
-           (isif_cfg.if_type == VPFE_YCBCR_SYNC_16))
-               isif_setwin(&params->win, params->frm_fmt, 1);
-       else
-               isif_setwin(&params->win, params->frm_fmt, 2);
-
-       /*
-        * 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->frm_fmt == CCDC_FRMFMT_INTERLACED) &&
-           (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED))
-               /* two fields are interleaved in memory */
-               regw(0x00000249, SDOFST);
-
-       return 0;
-}
-
-static int isif_configure(void)
-{
-       if (isif_cfg.if_type == VPFE_RAW_BAYER)
-               return isif_config_raw();
-       return isif_config_ycbcr();
-}
-
-static int isif_close(struct device *device)
-{
-       /* copy defaults to module params */
-       isif_cfg.bayer.config_params = isif_config_defaults;
-       return 0;
-}
-
-static const struct ccdc_hw_device isif_hw_dev = {
-       .name = "ISIF",
-       .owner = THIS_MODULE,
-       .hw_ops = {
-               .open = isif_open,
-               .close = isif_close,
-               .enable = isif_enable,
-               .enable_out_to_sdram = isif_enable_output_to_sdram,
-               .set_hw_if_params = isif_set_hw_if_params,
-               .configure = isif_configure,
-               .set_buftype = isif_set_buftype,
-               .get_buftype = isif_get_buftype,
-               .enum_pix = isif_enum_pix,
-               .set_pixel_format = isif_set_pixel_format,
-               .get_pixel_format = isif_get_pixel_format,
-               .set_frame_format = isif_set_frame_format,
-               .get_frame_format = isif_get_frame_format,
-               .set_image_window = isif_set_image_window,
-               .get_image_window = isif_get_image_window,
-               .get_line_length = isif_get_line_length,
-               .setfbaddr = isif_setfbaddr,
-               .getfid = isif_getfid,
-       },
-};
-
-static int isif_probe(struct platform_device *pdev)
-{
-       void (*setup_pinmux)(void);
-       struct resource *res;
-       void __iomem *addr;
-       int status = 0, i;
-
-       /* Platform data holds setup_pinmux function ptr */
-       if (!pdev->dev.platform_data)
-               return -ENODEV;
-
-       /*
-        * first try to register with vpfe. If not correct platform, then we
-        * don't have to iomap
-        */
-       status = vpfe_register_ccdc_device(&isif_hw_dev);
-       if (status < 0)
-               return status;
-
-       setup_pinmux = pdev->dev.platform_data;
-       /*
-        * setup Mux configuration for ccdc which may be different for
-        * different SoCs using this CCDC
-        */
-       setup_pinmux();
-
-       i = 0;
-       /* Get the ISIF base address, linearization table0 and table1 addr. */
-       while (i < 3) {
-               res = platform_get_resource(pdev, IORESOURCE_MEM, i);
-               if (!res) {
-                       status = -ENODEV;
-                       goto fail_nobase_res;
-               }
-               res = request_mem_region(res->start, resource_size(res),
-                                        res->name);
-               if (!res) {
-                       status = -EBUSY;
-                       goto fail_nobase_res;
-               }
-               addr = ioremap(res->start, resource_size(res));
-               if (!addr) {
-                       status = -ENOMEM;
-                       goto fail_base_iomap;
-               }
-               switch (i) {
-               case 0:
-                       /* ISIF base address */
-                       isif_cfg.base_addr = addr;
-                       break;
-               case 1:
-                       /* ISIF linear tbl0 address */
-                       isif_cfg.linear_tbl0_addr = addr;
-                       break;
-               default:
-                       /* ISIF linear tbl0 address */
-                       isif_cfg.linear_tbl1_addr = addr;
-                       break;
-               }
-               i++;
-       }
-       isif_cfg.dev = &pdev->dev;
-
-       printk(KERN_NOTICE "%s is registered with vpfe.\n",
-               isif_hw_dev.name);
-       return 0;
-fail_base_iomap:
-       release_mem_region(res->start, resource_size(res));
-       i--;
-fail_nobase_res:
-       if (isif_cfg.base_addr) {
-               iounmap(isif_cfg.base_addr);
-               isif_cfg.base_addr = NULL;
-       }
-       if (isif_cfg.linear_tbl0_addr) {
-               iounmap(isif_cfg.linear_tbl0_addr);
-               isif_cfg.linear_tbl0_addr = NULL;
-       }
-
-       while (i >= 0) {
-               res = platform_get_resource(pdev, IORESOURCE_MEM, i);
-               if (res)
-                       release_mem_region(res->start, resource_size(res));
-               i--;
-       }
-       vpfe_unregister_ccdc_device(&isif_hw_dev);
-       return status;
-}
-
-static int isif_remove(struct platform_device *pdev)
-{
-       struct resource *res;
-       int i = 0;
-
-       iounmap(isif_cfg.base_addr);
-       isif_cfg.base_addr = NULL;
-       iounmap(isif_cfg.linear_tbl0_addr);
-       isif_cfg.linear_tbl0_addr = NULL;
-       iounmap(isif_cfg.linear_tbl1_addr);
-       isif_cfg.linear_tbl1_addr = NULL;
-       while (i < 3) {
-               res = platform_get_resource(pdev, IORESOURCE_MEM, i);
-               if (res)
-                       release_mem_region(res->start, resource_size(res));
-               i++;
-       }
-       vpfe_unregister_ccdc_device(&isif_hw_dev);
-       return 0;
-}
-
-static struct platform_driver isif_driver = {
-       .driver = {
-               .name   = "isif",
-       },
-       .remove = isif_remove,
-       .probe = isif_probe,
-};
-
-module_platform_driver(isif_driver);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/davinci/isif_regs.h b/drivers/media/platform/davinci/isif_regs.h
deleted file mode 100644 (file)
index d68d388..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2008-2009 Texas Instruments Inc
- */
-#ifndef _ISIF_REGS_H
-#define _ISIF_REGS_H
-
-/* ISIF registers relative offsets */
-#define SYNCEN                                 0x00
-#define MODESET                                        0x04
-#define HDW                                    0x08
-#define VDW                                    0x0c
-#define PPLN                                   0x10
-#define LPFR                                   0x14
-#define SPH                                    0x18
-#define LNH                                    0x1c
-#define SLV0                                   0x20
-#define SLV1                                   0x24
-#define LNV                                    0x28
-#define CULH                                   0x2c
-#define CULV                                   0x30
-#define HSIZE                                  0x34
-#define SDOFST                                 0x38
-#define CADU                                   0x3c
-#define CADL                                   0x40
-#define LINCFG0                                        0x44
-#define LINCFG1                                        0x48
-#define CCOLP                                  0x4c
-#define CRGAIN                                 0x50
-#define CGRGAIN                                        0x54
-#define CGBGAIN                                        0x58
-#define CBGAIN                                 0x5c
-#define COFSTA                                 0x60
-#define FLSHCFG0                               0x64
-#define FLSHCFG1                               0x68
-#define FLSHCFG2                               0x6c
-#define VDINT0                                 0x70
-#define VDINT1                                 0x74
-#define VDINT2                                 0x78
-#define MISC                                   0x7c
-#define CGAMMAWD                               0x80
-#define REC656IF                               0x84
-#define CCDCFG                                 0x88
-/*****************************************************
-* Defect Correction registers
-*****************************************************/
-#define DFCCTL                                 0x8c
-#define VDFSATLV                               0x90
-#define DFCMEMCTL                              0x94
-#define DFCMEM0                                        0x98
-#define DFCMEM1                                        0x9c
-#define DFCMEM2                                        0xa0
-#define DFCMEM3                                        0xa4
-#define DFCMEM4                                        0xa8
-/****************************************************
-* Black Clamp registers
-****************************************************/
-#define CLAMPCFG                               0xac
-#define CLDCOFST                               0xb0
-#define CLSV                                   0xb4
-#define CLHWIN0                                        0xb8
-#define CLHWIN1                                        0xbc
-#define CLHWIN2                                        0xc0
-#define CLVRV                                  0xc4
-#define CLVWIN0                                        0xc8
-#define CLVWIN1                                        0xcc
-#define CLVWIN2                                        0xd0
-#define CLVWIN3                                        0xd4
-/****************************************************
-* Lense Shading Correction
-****************************************************/
-#define DATAHOFST                              0xd8
-#define DATAVOFST                              0xdc
-#define LSCHVAL                                        0xe0
-#define LSCVVAL                                        0xe4
-#define TWODLSCCFG                             0xe8
-#define TWODLSCOFST                            0xec
-#define TWODLSCINI                             0xf0
-#define TWODLSCGRBU                            0xf4
-#define TWODLSCGRBL                            0xf8
-#define TWODLSCGROF                            0xfc
-#define TWODLSCORBU                            0x100
-#define TWODLSCORBL                            0x104
-#define TWODLSCOROF                            0x108
-#define TWODLSCIRQEN                           0x10c
-#define TWODLSCIRQST                           0x110
-/****************************************************
-* Data formatter
-****************************************************/
-#define FMTCFG                                 0x114
-#define FMTPLEN                                        0x118
-#define FMTSPH                                 0x11c
-#define FMTLNH                                 0x120
-#define FMTSLV                                 0x124
-#define FMTLNV                                 0x128
-#define FMTRLEN                                        0x12c
-#define FMTHCNT                                        0x130
-#define FMTAPTR_BASE                           0x134
-/* Below macro for addresses FMTAPTR0 - FMTAPTR15 */
-#define FMTAPTR(i)                     (FMTAPTR_BASE + (i * 4))
-#define FMTPGMVF0                              0x174
-#define FMTPGMVF1                              0x178
-#define FMTPGMAPU0                             0x17c
-#define FMTPGMAPU1                             0x180
-#define FMTPGMAPS0                             0x184
-#define FMTPGMAPS1                             0x188
-#define FMTPGMAPS2                             0x18c
-#define FMTPGMAPS3                             0x190
-#define FMTPGMAPS4                             0x194
-#define FMTPGMAPS5                             0x198
-#define FMTPGMAPS6                             0x19c
-#define FMTPGMAPS7                             0x1a0
-/************************************************
-* Color Space Converter
-************************************************/
-#define CSCCTL                                 0x1a4
-#define CSCM0                                  0x1a8
-#define CSCM1                                  0x1ac
-#define CSCM2                                  0x1b0
-#define CSCM3                                  0x1b4
-#define CSCM4                                  0x1b8
-#define CSCM5                                  0x1bc
-#define CSCM6                                  0x1c0
-#define CSCM7                                  0x1c4
-#define OBWIN0                                 0x1c8
-#define OBWIN1                                 0x1cc
-#define OBWIN2                                 0x1d0
-#define OBWIN3                                 0x1d4
-#define OBVAL0                                 0x1d8
-#define OBVAL1                                 0x1dc
-#define OBVAL2                                 0x1e0
-#define OBVAL3                                 0x1e4
-#define OBVAL4                                 0x1e8
-#define OBVAL5                                 0x1ec
-#define OBVAL6                                 0x1f0
-#define OBVAL7                                 0x1f4
-#define CLKCTL                                 0x1f8
-
-/* Masks & Shifts below */
-#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
-
-/* gain - offset masks */
-#define GAIN_INTEGER_SHIFT                     9
-#define OFFSET_MASK                            0xFFF
-#define GAIN_SDRAM_EN_SHIFT                    12
-#define GAIN_IPIPE_EN_SHIFT                    13
-#define GAIN_H3A_EN_SHIFT                      14
-#define OFST_SDRAM_EN_SHIFT                    8
-#define OFST_IPIPE_EN_SHIFT                    9
-#define OFST_H3A_EN_SHIFT                      10
-#define GAIN_OFFSET_EN_MASK                    0x7700
-
-/* Culling */
-#define CULL_PAT_EVEN_LINE_SHIFT               8
-
-/* CCDCFG register */
-#define ISIF_YCINSWP_RAW                       (0x00 << 4)
-#define ISIF_YCINSWP_YCBCR                     (0x01 << 4)
-#define ISIF_CCDCFG_FIDMD_LATCH_VSYNC          (0x00 << 6)
-#define ISIF_CCDCFG_WENLOG_AND                 (0x00 << 8)
-#define ISIF_CCDCFG_TRGSEL_WEN                 (0x00 << 9)
-#define ISIF_CCDCFG_EXTRG_DISABLE              (0x00 << 10)
-#define ISIF_LATCH_ON_VSYNC_DISABLE            (0x01 << 15)
-#define ISIF_LATCH_ON_VSYNC_ENABLE             (0x00 << 15)
-#define ISIF_DATA_PACK_MASK                    3
-#define ISIF_DATA_PACK16                       0
-#define ISIF_DATA_PACK12                       1
-#define ISIF_DATA_PACK8                                2
-#define ISIF_PIX_ORDER_SHIFT                   11
-#define ISIF_BW656_ENABLE                      (0x01 << 5)
-
-/* MODESET registers */
-#define ISIF_VDHDOUT_INPUT                     (0x00 << 0)
-#define ISIF_INPUT_SHIFT                       12
-#define ISIF_RAW_INPUT_MODE                    0
-#define ISIF_FID_POL_SHIFT                     4
-#define ISIF_HD_POL_SHIFT                      3
-#define ISIF_VD_POL_SHIFT                      2
-#define ISIF_DATAPOL_NORMAL                    0
-#define ISIF_DATAPOL_SHIFT                     6
-#define ISIF_EXWEN_DISABLE                     0
-#define ISIF_EXWEN_SHIFT                       5
-#define ISIF_FRM_FMT_SHIFT                     7
-#define ISIF_DATASFT_SHIFT                     8
-#define ISIF_LPF_SHIFT                         14
-#define ISIF_LPF_MASK                          1
-
-/* GAMMAWD registers */
-#define ISIF_ALAW_GAMMA_WD_MASK                        0xF
-#define ISIF_ALAW_GAMMA_WD_SHIFT               1
-#define ISIF_ALAW_ENABLE                       1
-#define ISIF_GAMMAWD_CFA_SHIFT                 5
-
-/* HSIZE registers */
-#define ISIF_HSIZE_FLIP_MASK                   1
-#define ISIF_HSIZE_FLIP_SHIFT                  12
-
-/* MISC registers */
-#define ISIF_DPCM_EN_SHIFT                     12
-#define ISIF_DPCM_PREDICTOR_SHIFT              13
-
-/* Black clamp related */
-#define ISIF_BC_MODE_COLOR_SHIFT               4
-#define ISIF_HORZ_BC_MODE_SHIFT                        1
-#define ISIF_HORZ_BC_WIN_SEL_SHIFT             5
-#define ISIF_HORZ_BC_PIX_LIMIT_SHIFT           6
-#define ISIF_HORZ_BC_WIN_H_SIZE_SHIFT          8
-#define ISIF_HORZ_BC_WIN_V_SIZE_SHIFT          12
-#define        ISIF_VERT_BC_RST_VAL_SEL_SHIFT          4
-#define ISIF_VERT_BC_LINE_AVE_COEF_SHIFT       8
-
-/* VDFC registers */
-#define ISIF_VDFC_EN_SHIFT                     4
-#define ISIF_VDFC_CORR_MOD_SHIFT               5
-#define ISIF_VDFC_CORR_WHOLE_LN_SHIFT          7
-#define ISIF_VDFC_LEVEL_SHFT_SHIFT             8
-#define ISIF_VDFC_POS_MASK                     0x1FFF
-#define ISIF_DFCMEMCTL_DFCMARST_SHIFT          2
-
-/* CSC registers */
-#define ISIF_CSC_COEF_INTEG_MASK               7
-#define ISIF_CSC_COEF_DECIMAL_MASK             0x1f
-#define ISIF_CSC_COEF_INTEG_SHIFT              5
-#define ISIF_CSCM_MSB_SHIFT                    8
-#define ISIF_DF_CSC_SPH_MASK                   0x1FFF
-#define ISIF_DF_CSC_LNH_MASK                   0x1FFF
-#define ISIF_DF_CSC_SLV_MASK                   0x1FFF
-#define ISIF_DF_CSC_LNV_MASK                   0x1FFF
-#define ISIF_DF_NUMLINES                       0x7FFF
-#define ISIF_DF_NUMPIX                         0x1FFF
-
-/* Offsets for LSC/DFC/Gain */
-#define ISIF_DATA_H_OFFSET_MASK                        0x1FFF
-#define ISIF_DATA_V_OFFSET_MASK                        0x1FFF
-
-/* Linearization */
-#define ISIF_LIN_CORRSFT_SHIFT                 4
-#define ISIF_LIN_SCALE_FACT_INTEG_SHIFT                10
-
-
-/* Pattern registers */
-#define ISIF_PG_EN                             (1 << 3)
-#define ISIF_SEL_PG_SRC                                (3 << 4)
-#define ISIF_PG_VD_POL_SHIFT                   0
-#define ISIF_PG_HD_POL_SHIFT                   1
-
-/*random other junk*/
-#define ISIF_SYNCEN_VDHDEN_MASK                        (1 << 0)
-#define ISIF_SYNCEN_WEN_MASK                   (1 << 1)
-#define ISIF_SYNCEN_WEN_SHIFT                  1
-
-#endif
diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c
deleted file mode 100644 (file)
index 5f0aeb7..0000000
+++ /dev/null
@@ -1,840 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2010 Texas Instruments Inc
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include <media/v4l2-device.h>
-#include <media/davinci/vpbe_types.h>
-#include <media/davinci/vpbe.h>
-#include <media/davinci/vpss.h>
-#include <media/davinci/vpbe_venc.h>
-
-#define VPBE_DEFAULT_OUTPUT    "Composite"
-#define VPBE_DEFAULT_MODE      "ntsc"
-
-static char *def_output = VPBE_DEFAULT_OUTPUT;
-static char *def_mode = VPBE_DEFAULT_MODE;
-static int debug;
-
-module_param(def_output, charp, S_IRUGO);
-module_param(def_mode, charp, S_IRUGO);
-module_param(debug, int, 0644);
-
-MODULE_PARM_DESC(def_output, "vpbe output name (default:Composite)");
-MODULE_PARM_DESC(def_mode, "vpbe output mode name (default:ntsc");
-MODULE_PARM_DESC(debug, "Debug level 0-1");
-
-MODULE_DESCRIPTION("TI DMXXX VPBE Display controller");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Texas Instruments");
-
-/**
- * vpbe_current_encoder_info - Get config info for current encoder
- * @vpbe_dev: vpbe device ptr
- *
- * Return ptr to current encoder config info
- */
-static struct encoder_config_info*
-vpbe_current_encoder_info(struct vpbe_device *vpbe_dev)
-{
-       struct vpbe_config *cfg = vpbe_dev->cfg;
-       int index = vpbe_dev->current_sd_index;
-
-       return ((index == 0) ? &cfg->venc :
-                               &cfg->ext_encoders[index-1]);
-}
-
-/**
- * vpbe_find_encoder_sd_index - Given a name find encoder sd index
- *
- * @cfg: ptr to vpbe cfg
- * @index: index used by application
- *
- * Return sd index of the encoder
- */
-static int vpbe_find_encoder_sd_index(struct vpbe_config *cfg,
-                            int index)
-{
-       char *encoder_name = cfg->outputs[index].subdev_name;
-       int i;
-
-       /* Venc is always first */
-       if (!strcmp(encoder_name, cfg->venc.module_name))
-               return 0;
-
-       for (i = 0; i < cfg->num_ext_encoders; i++) {
-               if (!strcmp(encoder_name,
-                    cfg->ext_encoders[i].module_name))
-                       return i+1;
-       }
-
-       return -EINVAL;
-}
-
-/**
- * vpbe_enum_outputs - enumerate outputs
- * @vpbe_dev: vpbe device ptr
- * @output: ptr to v4l2_output structure
- *
- * Enumerates the outputs available at the vpbe display
- * returns the status, -EINVAL if end of output list
- */
-static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev,
-                            struct v4l2_output *output)
-{
-       struct vpbe_config *cfg = vpbe_dev->cfg;
-       unsigned int temp_index = output->index;
-
-       if (temp_index >= cfg->num_outputs)
-               return -EINVAL;
-
-       *output = cfg->outputs[temp_index].output;
-       output->index = temp_index;
-
-       return 0;
-}
-
-static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode,
-                             int output_index)
-{
-       struct vpbe_config *cfg = vpbe_dev->cfg;
-       struct vpbe_enc_mode_info var;
-       int curr_output = output_index;
-       int i;
-
-       if (!mode)
-               return -EINVAL;
-
-       for (i = 0; i < cfg->outputs[curr_output].num_modes; i++) {
-               var = cfg->outputs[curr_output].modes[i];
-               if (!strcmp(mode, var.name)) {
-                       vpbe_dev->current_timings = var;
-                       return 0;
-               }
-       }
-
-       return -EINVAL;
-}
-
-static int vpbe_get_current_mode_info(struct vpbe_device *vpbe_dev,
-                                     struct vpbe_enc_mode_info *mode_info)
-{
-       if (!mode_info)
-               return -EINVAL;
-
-       *mode_info = vpbe_dev->current_timings;
-
-       return 0;
-}
-
-/* Get std by std id */
-static int vpbe_get_std_info(struct vpbe_device *vpbe_dev,
-                            v4l2_std_id std_id)
-{
-       struct vpbe_config *cfg = vpbe_dev->cfg;
-       struct vpbe_enc_mode_info var;
-       int curr_output = vpbe_dev->current_out_index;
-       int i;
-
-       for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
-               var = cfg->outputs[curr_output].modes[i];
-               if ((var.timings_type & VPBE_ENC_STD) &&
-                 (var.std_id & std_id)) {
-                       vpbe_dev->current_timings = var;
-                       return 0;
-               }
-       }
-
-       return -EINVAL;
-}
-
-static int vpbe_get_std_info_by_name(struct vpbe_device *vpbe_dev,
-                               char *std_name)
-{
-       struct vpbe_config *cfg = vpbe_dev->cfg;
-       struct vpbe_enc_mode_info var;
-       int curr_output = vpbe_dev->current_out_index;
-       int i;
-
-       for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
-               var = cfg->outputs[curr_output].modes[i];
-               if (!strcmp(var.name, std_name)) {
-                       vpbe_dev->current_timings = var;
-                       return 0;
-               }
-       }
-
-       return -EINVAL;
-}
-
-/**
- * vpbe_set_output - Set output
- * @vpbe_dev: vpbe device ptr
- * @index: index of output
- *
- * Set vpbe output to the output specified by the index
- */
-static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index)
-{
-       struct encoder_config_info *curr_enc_info =
-                       vpbe_current_encoder_info(vpbe_dev);
-       struct vpbe_config *cfg = vpbe_dev->cfg;
-       struct venc_platform_data *venc_device = vpbe_dev->venc_device;
-       int enc_out_index;
-       int sd_index;
-       int ret;
-
-       if (index >= cfg->num_outputs)
-               return -EINVAL;
-
-       mutex_lock(&vpbe_dev->lock);
-
-       sd_index = vpbe_dev->current_sd_index;
-       enc_out_index = cfg->outputs[index].output.index;
-       /*
-        * Currently we switch the encoder based on output selected
-        * by the application. If media controller is implemented later
-        * there is will be an API added to setup_link between venc
-        * and external encoder. So in that case below comparison always
-        * match and encoder will not be switched. But if application
-        * chose not to use media controller, then this provides current
-        * way of switching encoder at the venc output.
-        */
-       if (strcmp(curr_enc_info->module_name,
-                  cfg->outputs[index].subdev_name)) {
-               /* Need to switch the encoder at the output */
-               sd_index = vpbe_find_encoder_sd_index(cfg, index);
-               if (sd_index < 0) {
-                       ret = -EINVAL;
-                       goto unlock;
-               }
-
-               ret = venc_device->setup_if_config(cfg->outputs[index].if_params);
-               if (ret)
-                       goto unlock;
-       }
-
-       /* Set output at the encoder */
-       ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
-                                      s_routing, 0, enc_out_index, 0);
-       if (ret)
-               goto unlock;
-
-       /*
-        * It is assumed that venc or external encoder will set a default
-        * mode in the sub device. For external encoder or LCD pannel output,
-        * we also need to set up the lcd port for the required mode. So setup
-        * the lcd port for the default mode that is configured in the board
-        * arch/arm/mach-davinci/board-dm355-evm.setup file for the external
-        * encoder.
-        */
-       ret = vpbe_get_mode_info(vpbe_dev,
-                                cfg->outputs[index].default_mode, index);
-       if (!ret) {
-               struct osd_state *osd_device = vpbe_dev->osd_device;
-
-               osd_device->ops.set_left_margin(osd_device,
-                       vpbe_dev->current_timings.left_margin);
-               osd_device->ops.set_top_margin(osd_device,
-               vpbe_dev->current_timings.upper_margin);
-               vpbe_dev->current_sd_index = sd_index;
-               vpbe_dev->current_out_index = index;
-       }
-unlock:
-       mutex_unlock(&vpbe_dev->lock);
-       return ret;
-}
-
-static int vpbe_set_default_output(struct vpbe_device *vpbe_dev)
-{
-       struct vpbe_config *cfg = vpbe_dev->cfg;
-       int i;
-
-       for (i = 0; i < cfg->num_outputs; i++) {
-               if (!strcmp(def_output,
-                           cfg->outputs[i].output.name)) {
-                       int ret = vpbe_set_output(vpbe_dev, i);
-
-                       if (!ret)
-                               vpbe_dev->current_out_index = i;
-                       return ret;
-               }
-       }
-       return 0;
-}
-
-/**
- * vpbe_get_output - Get output
- * @vpbe_dev: vpbe device ptr
- *
- * return current vpbe output to the the index
- */
-static unsigned int vpbe_get_output(struct vpbe_device *vpbe_dev)
-{
-       return vpbe_dev->current_out_index;
-}
-
-/*
- * vpbe_s_dv_timings - Set the given preset timings in the encoder
- *
- * Sets the timings if supported by the current encoder. Return the status.
- * 0 - success & -EINVAL on error
- */
-static int vpbe_s_dv_timings(struct vpbe_device *vpbe_dev,
-                   struct v4l2_dv_timings *dv_timings)
-{
-       struct vpbe_config *cfg = vpbe_dev->cfg;
-       int out_index = vpbe_dev->current_out_index;
-       struct vpbe_output *output = &cfg->outputs[out_index];
-       int sd_index = vpbe_dev->current_sd_index;
-       int ret, i;
-
-
-       if (!(cfg->outputs[out_index].output.capabilities &
-           V4L2_OUT_CAP_DV_TIMINGS))
-               return -ENODATA;
-
-       for (i = 0; i < output->num_modes; i++) {
-               if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS &&
-                   !memcmp(&output->modes[i].dv_timings,
-                               dv_timings, sizeof(*dv_timings)))
-                       break;
-       }
-       if (i >= output->num_modes)
-               return -EINVAL;
-       vpbe_dev->current_timings = output->modes[i];
-       mutex_lock(&vpbe_dev->lock);
-
-       ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
-                                       s_dv_timings, dv_timings);
-       if (!ret && vpbe_dev->amp) {
-               /* Call amplifier subdevice */
-               ret = v4l2_subdev_call(vpbe_dev->amp, video,
-                               s_dv_timings, dv_timings);
-       }
-       /* set the lcd controller output for the given mode */
-       if (!ret) {
-               struct osd_state *osd_device = vpbe_dev->osd_device;
-
-               osd_device->ops.set_left_margin(osd_device,
-               vpbe_dev->current_timings.left_margin);
-               osd_device->ops.set_top_margin(osd_device,
-               vpbe_dev->current_timings.upper_margin);
-       }
-       mutex_unlock(&vpbe_dev->lock);
-
-       return ret;
-}
-
-/*
- * vpbe_g_dv_timings - Get the timings in the current encoder
- *
- * Get the timings in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int vpbe_g_dv_timings(struct vpbe_device *vpbe_dev,
-                    struct v4l2_dv_timings *dv_timings)
-{
-       struct vpbe_config *cfg = vpbe_dev->cfg;
-       int out_index = vpbe_dev->current_out_index;
-
-       if (!(cfg->outputs[out_index].output.capabilities &
-               V4L2_OUT_CAP_DV_TIMINGS))
-               return -ENODATA;
-
-       if (vpbe_dev->current_timings.timings_type &
-         VPBE_ENC_DV_TIMINGS) {
-               *dv_timings = vpbe_dev->current_timings.dv_timings;
-               return 0;
-       }
-
-       return -EINVAL;
-}
-
-/*
- * vpbe_enum_dv_timings - Enumerate the dv timings in the current encoder
- *
- * Get the timings in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int vpbe_enum_dv_timings(struct vpbe_device *vpbe_dev,
-                        struct v4l2_enum_dv_timings *timings)
-{
-       struct vpbe_config *cfg = vpbe_dev->cfg;
-       int out_index = vpbe_dev->current_out_index;
-       struct vpbe_output *output = &cfg->outputs[out_index];
-       int j = 0;
-       int i;
-
-       if (!(output->output.capabilities & V4L2_OUT_CAP_DV_TIMINGS))
-               return -ENODATA;
-
-       for (i = 0; i < output->num_modes; i++) {
-               if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS) {
-                       if (j == timings->index)
-                               break;
-                       j++;
-               }
-       }
-
-       if (i == output->num_modes)
-               return -EINVAL;
-       timings->timings = output->modes[i].dv_timings;
-       return 0;
-}
-
-/*
- * vpbe_s_std - Set the given standard in the encoder
- *
- * Sets the standard if supported by the current encoder. Return the status.
- * 0 - success & -EINVAL on error
- */
-static int vpbe_s_std(struct vpbe_device *vpbe_dev, v4l2_std_id std_id)
-{
-       struct vpbe_config *cfg = vpbe_dev->cfg;
-       int out_index = vpbe_dev->current_out_index;
-       int sd_index = vpbe_dev->current_sd_index;
-       int ret;
-
-       if (!(cfg->outputs[out_index].output.capabilities &
-               V4L2_OUT_CAP_STD))
-               return -ENODATA;
-
-       ret = vpbe_get_std_info(vpbe_dev, std_id);
-       if (ret)
-               return ret;
-
-       mutex_lock(&vpbe_dev->lock);
-
-       ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
-                              s_std_output, std_id);
-       /* set the lcd controller output for the given mode */
-       if (!ret) {
-               struct osd_state *osd_device = vpbe_dev->osd_device;
-
-               osd_device->ops.set_left_margin(osd_device,
-               vpbe_dev->current_timings.left_margin);
-               osd_device->ops.set_top_margin(osd_device,
-               vpbe_dev->current_timings.upper_margin);
-       }
-       mutex_unlock(&vpbe_dev->lock);
-
-       return ret;
-}
-
-/*
- * vpbe_g_std - Get the standard in the current encoder
- *
- * Get the standard in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int vpbe_g_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
-{
-       struct vpbe_enc_mode_info *cur_timings = &vpbe_dev->current_timings;
-       struct vpbe_config *cfg = vpbe_dev->cfg;
-       int out_index = vpbe_dev->current_out_index;
-
-       if (!(cfg->outputs[out_index].output.capabilities & V4L2_OUT_CAP_STD))
-               return -ENODATA;
-
-       if (cur_timings->timings_type & VPBE_ENC_STD) {
-               *std_id = cur_timings->std_id;
-               return 0;
-       }
-
-       return -EINVAL;
-}
-
-/*
- * vpbe_set_mode - Set mode in the current encoder using mode info
- *
- * Use the mode string to decide what timings to set in the encoder
- * This is typically useful when fbset command is used to change the current
- * timings by specifying a string to indicate the timings.
- */
-static int vpbe_set_mode(struct vpbe_device *vpbe_dev,
-                        struct vpbe_enc_mode_info *mode_info)
-{
-       struct vpbe_enc_mode_info *preset_mode = NULL;
-       struct vpbe_config *cfg = vpbe_dev->cfg;
-       struct v4l2_dv_timings dv_timings;
-       struct osd_state *osd_device;
-       int out_index = vpbe_dev->current_out_index;
-       int i;
-
-       if (!mode_info || !mode_info->name)
-               return -EINVAL;
-
-       for (i = 0; i < cfg->outputs[out_index].num_modes; i++) {
-               if (!strcmp(mode_info->name,
-                    cfg->outputs[out_index].modes[i].name)) {
-                       preset_mode = &cfg->outputs[out_index].modes[i];
-                       /*
-                        * it may be one of the 3 timings type. Check and
-                        * invoke right API
-                        */
-                       if (preset_mode->timings_type & VPBE_ENC_STD)
-                               return vpbe_s_std(vpbe_dev,
-                                                preset_mode->std_id);
-                       if (preset_mode->timings_type &
-                                               VPBE_ENC_DV_TIMINGS) {
-                               dv_timings =
-                                       preset_mode->dv_timings;
-                               return vpbe_s_dv_timings(vpbe_dev, &dv_timings);
-                       }
-               }
-       }
-
-       /* Only custom timing should reach here */
-       if (!preset_mode)
-               return -EINVAL;
-
-       mutex_lock(&vpbe_dev->lock);
-
-       osd_device = vpbe_dev->osd_device;
-       vpbe_dev->current_timings = *preset_mode;
-       osd_device->ops.set_left_margin(osd_device,
-               vpbe_dev->current_timings.left_margin);
-       osd_device->ops.set_top_margin(osd_device,
-               vpbe_dev->current_timings.upper_margin);
-
-       mutex_unlock(&vpbe_dev->lock);
-       return 0;
-}
-
-static int vpbe_set_default_mode(struct vpbe_device *vpbe_dev)
-{
-       int ret;
-
-       ret = vpbe_get_std_info_by_name(vpbe_dev, def_mode);
-       if (ret)
-               return ret;
-
-       /* set the default mode in the encoder */
-       return vpbe_set_mode(vpbe_dev, &vpbe_dev->current_timings);
-}
-
-static int platform_device_get(struct device *dev, void *data)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct vpbe_device *vpbe_dev = data;
-
-       if (strstr(pdev->name, "vpbe-osd"))
-               vpbe_dev->osd_device = platform_get_drvdata(pdev);
-       if (strstr(pdev->name, "vpbe-venc"))
-               vpbe_dev->venc_device = dev_get_platdata(&pdev->dev);
-
-       return 0;
-}
-
-/**
- * vpbe_initialize() - Initialize the vpbe display controller
- * @dev: Master and slave device ptr
- * @vpbe_dev: vpbe device ptr
- *
- * Master frame buffer device drivers calls this to initialize vpbe
- * display controller. This will then registers v4l2 device and the sub
- * devices and sets a current encoder sub device for display. v4l2 display
- * device driver is the master and frame buffer display device driver is
- * the slave. Frame buffer display driver checks the initialized during
- * probe and exit if not initialized. Returns status.
- */
-static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
-{
-       struct encoder_config_info *enc_info;
-       struct amp_config_info *amp_info;
-       struct v4l2_subdev **enc_subdev;
-       struct osd_state *osd_device;
-       struct i2c_adapter *i2c_adap;
-       int num_encoders;
-       int ret = 0;
-       int err;
-       int i;
-
-       /*
-        * v4l2 abd FBDev frame buffer devices will get the vpbe_dev pointer
-        * from the platform device by iteration of platform drivers and
-        * matching with device name
-        */
-       if (!vpbe_dev || !dev) {
-               printk(KERN_ERR "Null device pointers.\n");
-               return -ENODEV;
-       }
-
-       if (vpbe_dev->initialized)
-               return 0;
-
-       mutex_lock(&vpbe_dev->lock);
-
-       if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
-               /* We have dac clock available for platform */
-               vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac");
-               if (IS_ERR(vpbe_dev->dac_clk)) {
-                       ret =  PTR_ERR(vpbe_dev->dac_clk);
-                       goto fail_mutex_unlock;
-               }
-               if (clk_prepare_enable(vpbe_dev->dac_clk)) {
-                       ret =  -ENODEV;
-                       clk_put(vpbe_dev->dac_clk);
-                       goto fail_mutex_unlock;
-               }
-       }
-
-       /* first enable vpss clocks */
-       vpss_enable_clock(VPSS_VPBE_CLOCK, 1);
-
-       /* First register a v4l2 device */
-       ret = v4l2_device_register(dev, &vpbe_dev->v4l2_dev);
-       if (ret) {
-               v4l2_err(dev->driver,
-                       "Unable to register v4l2 device.\n");
-               goto fail_clk_put;
-       }
-       v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n");
-
-       err = bus_for_each_dev(&platform_bus_type, NULL, vpbe_dev,
-                              platform_device_get);
-       if (err < 0) {
-               ret = err;
-               goto fail_dev_unregister;
-       }
-
-       vpbe_dev->venc = venc_sub_dev_init(&vpbe_dev->v4l2_dev,
-                                          vpbe_dev->cfg->venc.module_name);
-       /* register venc sub device */
-       if (!vpbe_dev->venc) {
-               v4l2_err(&vpbe_dev->v4l2_dev,
-                       "vpbe unable to init venc sub device\n");
-               ret = -ENODEV;
-               goto fail_dev_unregister;
-       }
-       /* initialize osd device */
-       osd_device = vpbe_dev->osd_device;
-       if (osd_device->ops.initialize) {
-               err = osd_device->ops.initialize(osd_device);
-               if (err) {
-                       v4l2_err(&vpbe_dev->v4l2_dev,
-                                "unable to initialize the OSD device");
-                       ret = -ENOMEM;
-                       goto fail_dev_unregister;
-               }
-       }
-
-       /*
-        * Register any external encoders that are configured. At index 0 we
-        * store venc sd index.
-        */
-       num_encoders = vpbe_dev->cfg->num_ext_encoders + 1;
-       vpbe_dev->encoders = kmalloc_array(num_encoders,
-                                          sizeof(*vpbe_dev->encoders),
-                                          GFP_KERNEL);
-       if (!vpbe_dev->encoders) {
-               ret = -ENOMEM;
-               goto fail_dev_unregister;
-       }
-
-       i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id);
-       for (i = 0; i < (vpbe_dev->cfg->num_ext_encoders + 1); i++) {
-               if (i == 0) {
-                       /* venc is at index 0 */
-                       enc_subdev = &vpbe_dev->encoders[i];
-                       *enc_subdev = vpbe_dev->venc;
-                       continue;
-               }
-               enc_info = &vpbe_dev->cfg->ext_encoders[i];
-               if (enc_info->is_i2c) {
-                       enc_subdev = &vpbe_dev->encoders[i];
-                       *enc_subdev = v4l2_i2c_new_subdev_board(
-                                               &vpbe_dev->v4l2_dev, i2c_adap,
-                                               &enc_info->board_info, NULL);
-                       if (*enc_subdev)
-                               v4l2_info(&vpbe_dev->v4l2_dev,
-                                         "v4l2 sub device %s registered\n",
-                                         enc_info->module_name);
-                       else {
-                               v4l2_err(&vpbe_dev->v4l2_dev, "encoder %s failed to register",
-                                        enc_info->module_name);
-                               ret = -ENODEV;
-                               goto fail_kfree_encoders;
-                       }
-               } else
-                       v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders currently not supported");
-       }
-       /* Add amplifier subdevice for dm365 */
-       if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) &&
-          vpbe_dev->cfg->amp) {
-               amp_info = vpbe_dev->cfg->amp;
-               if (amp_info->is_i2c) {
-                       vpbe_dev->amp = v4l2_i2c_new_subdev_board(
-                       &vpbe_dev->v4l2_dev, i2c_adap,
-                       &amp_info->board_info, NULL);
-                       if (!vpbe_dev->amp) {
-                               v4l2_err(&vpbe_dev->v4l2_dev,
-                                        "amplifier %s failed to register",
-                                        amp_info->module_name);
-                               ret = -ENODEV;
-                               goto fail_kfree_encoders;
-                       }
-                       v4l2_info(&vpbe_dev->v4l2_dev,
-                                         "v4l2 sub device %s registered\n",
-                                         amp_info->module_name);
-               } else {
-                           vpbe_dev->amp = NULL;
-                           v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers currently not supported");
-               }
-       } else {
-           vpbe_dev->amp = NULL;
-       }
-
-       /* set the current encoder and output to that of venc by default */
-       vpbe_dev->current_sd_index = 0;
-       vpbe_dev->current_out_index = 0;
-
-       mutex_unlock(&vpbe_dev->lock);
-
-       printk(KERN_NOTICE "Setting default output to %s\n", def_output);
-       ret = vpbe_set_default_output(vpbe_dev);
-       if (ret) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default output %s",
-                        def_output);
-               goto fail_kfree_amp;
-       }
-
-       printk(KERN_NOTICE "Setting default mode to %s\n", def_mode);
-       ret = vpbe_set_default_mode(vpbe_dev);
-       if (ret) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default mode %s",
-                        def_mode);
-               goto fail_kfree_amp;
-       }
-       vpbe_dev->initialized = 1;
-       /* TBD handling of bootargs for default output and mode */
-       return 0;
-
-fail_kfree_amp:
-       mutex_lock(&vpbe_dev->lock);
-       kfree(vpbe_dev->amp);
-fail_kfree_encoders:
-       kfree(vpbe_dev->encoders);
-fail_dev_unregister:
-       v4l2_device_unregister(&vpbe_dev->v4l2_dev);
-fail_clk_put:
-       if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
-               clk_disable_unprepare(vpbe_dev->dac_clk);
-               clk_put(vpbe_dev->dac_clk);
-       }
-fail_mutex_unlock:
-       mutex_unlock(&vpbe_dev->lock);
-       return ret;
-}
-
-/**
- * vpbe_deinitialize() - de-initialize the vpbe display controller
- * @dev: Master and slave device ptr
- * @vpbe_dev: vpbe device ptr
- *
- * vpbe_master and slave frame buffer devices calls this to de-initialize
- * the display controller. It is called when master and slave device
- * driver modules are removed and no longer requires the display controller.
- */
-static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev)
-{
-       v4l2_device_unregister(&vpbe_dev->v4l2_dev);
-       if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
-               clk_disable_unprepare(vpbe_dev->dac_clk);
-               clk_put(vpbe_dev->dac_clk);
-       }
-
-       kfree(vpbe_dev->amp);
-       kfree(vpbe_dev->encoders);
-       vpbe_dev->initialized = 0;
-       /* disable vpss clocks */
-       vpss_enable_clock(VPSS_VPBE_CLOCK, 0);
-}
-
-static const struct vpbe_device_ops vpbe_dev_ops = {
-       .enum_outputs = vpbe_enum_outputs,
-       .set_output = vpbe_set_output,
-       .get_output = vpbe_get_output,
-       .s_dv_timings = vpbe_s_dv_timings,
-       .g_dv_timings = vpbe_g_dv_timings,
-       .enum_dv_timings = vpbe_enum_dv_timings,
-       .s_std = vpbe_s_std,
-       .g_std = vpbe_g_std,
-       .initialize = vpbe_initialize,
-       .deinitialize = vpbe_deinitialize,
-       .get_mode_info = vpbe_get_current_mode_info,
-       .set_mode = vpbe_set_mode,
-};
-
-static int vpbe_probe(struct platform_device *pdev)
-{
-       struct vpbe_device *vpbe_dev;
-       struct vpbe_config *cfg;
-
-       if (!pdev->dev.platform_data) {
-               v4l2_err(pdev->dev.driver, "No platform data\n");
-               return -ENODEV;
-       }
-       cfg = pdev->dev.platform_data;
-
-       if (!cfg->module_name[0] ||
-           !cfg->osd.module_name[0] ||
-           !cfg->venc.module_name[0]) {
-               v4l2_err(pdev->dev.driver, "vpbe display module names not defined\n");
-               return -EINVAL;
-       }
-
-       vpbe_dev = kzalloc(sizeof(*vpbe_dev), GFP_KERNEL);
-       if (!vpbe_dev)
-               return -ENOMEM;
-
-       vpbe_dev->cfg = cfg;
-       vpbe_dev->ops = vpbe_dev_ops;
-       vpbe_dev->pdev = &pdev->dev;
-
-       if (cfg->outputs->num_modes > 0)
-               vpbe_dev->current_timings = vpbe_dev->cfg->outputs[0].modes[0];
-       else {
-               kfree(vpbe_dev);
-               return -ENODEV;
-       }
-
-       /* set the driver data in platform device */
-       platform_set_drvdata(pdev, vpbe_dev);
-       mutex_init(&vpbe_dev->lock);
-
-       return 0;
-}
-
-static int vpbe_remove(struct platform_device *device)
-{
-       struct vpbe_device *vpbe_dev = platform_get_drvdata(device);
-
-       kfree(vpbe_dev);
-
-       return 0;
-}
-
-static struct platform_driver vpbe_driver = {
-       .driver = {
-               .name   = "vpbe_controller",
-       },
-       .probe = vpbe_probe,
-       .remove = vpbe_remove,
-};
-
-module_platform_driver(vpbe_driver);
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
deleted file mode 100644 (file)
index bf3c3e7..0000000
+++ /dev/null
@@ -1,1512 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/string.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/mm.h>
-#include <linux/mutex.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-
-
-#include <media/v4l2-dev.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <media/davinci/vpbe_display.h>
-#include <media/davinci/vpbe_types.h>
-#include <media/davinci/vpbe.h>
-#include <media/davinci/vpbe_venc.h>
-#include <media/davinci/vpbe_osd.h>
-#include "vpbe_venc_regs.h"
-
-#define VPBE_DISPLAY_DRIVER "vpbe-v4l2"
-
-static int debug;
-
-#define VPBE_DEFAULT_NUM_BUFS 3
-
-module_param(debug, int, 0644);
-
-static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
-                       struct vpbe_layer *layer);
-
-static int venc_is_second_field(struct vpbe_display *disp_dev)
-{
-       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
-       int ret, val;
-
-       ret = v4l2_subdev_call(vpbe_dev->venc,
-                              core,
-                              command,
-                              VENC_GET_FLD,
-                              &val);
-       if (ret < 0) {
-               v4l2_err(&vpbe_dev->v4l2_dev,
-                        "Error in getting Field ID 0\n");
-               return 1;
-       }
-       return val;
-}
-
-static void vpbe_isr_even_field(struct vpbe_display *disp_obj,
-                               struct vpbe_layer *layer)
-{
-       if (layer->cur_frm == layer->next_frm)
-               return;
-
-       layer->cur_frm->vb.vb2_buf.timestamp = ktime_get_ns();
-       vb2_buffer_done(&layer->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
-       /* Make cur_frm pointing to next_frm */
-       layer->cur_frm = layer->next_frm;
-}
-
-static void vpbe_isr_odd_field(struct vpbe_display *disp_obj,
-                               struct vpbe_layer *layer)
-{
-       struct osd_state *osd_device = disp_obj->osd_device;
-       unsigned long addr;
-
-       spin_lock(&disp_obj->dma_queue_lock);
-       if (list_empty(&layer->dma_queue) ||
-               (layer->cur_frm != layer->next_frm)) {
-               spin_unlock(&disp_obj->dma_queue_lock);
-               return;
-       }
-       /*
-        * one field is displayed configure
-        * the next frame if it is available
-        * otherwise hold on current frame
-        * Get next from the buffer queue
-        */
-       layer->next_frm = list_entry(layer->dma_queue.next,
-                         struct  vpbe_disp_buffer, list);
-       /* Remove that from the buffer queue */
-       list_del(&layer->next_frm->list);
-       spin_unlock(&disp_obj->dma_queue_lock);
-       /* Mark state of the frame to active */
-       layer->next_frm->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
-       addr = vb2_dma_contig_plane_dma_addr(&layer->next_frm->vb.vb2_buf, 0);
-       osd_device->ops.start_layer(osd_device,
-                       layer->layer_info.id,
-                       addr,
-                       disp_obj->cbcr_ofst);
-}
-
-/* interrupt service routine */
-static irqreturn_t venc_isr(int irq, void *arg)
-{
-       struct vpbe_display *disp_dev = (struct vpbe_display *)arg;
-       struct vpbe_layer *layer;
-       static unsigned last_event;
-       unsigned event = 0;
-       int fid;
-       int i;
-
-       if (!arg || !disp_dev->dev[0])
-               return IRQ_HANDLED;
-
-       if (venc_is_second_field(disp_dev))
-               event |= VENC_SECOND_FIELD;
-       else
-               event |= VENC_FIRST_FIELD;
-
-       if (event == (last_event & ~VENC_END_OF_FRAME)) {
-               /*
-               * If the display is non-interlaced, then we need to flag the
-               * end-of-frame event at every interrupt regardless of the
-               * value of the FIDST bit.  We can conclude that the display is
-               * non-interlaced if the value of the FIDST bit is unchanged
-               * from the previous interrupt.
-               */
-               event |= VENC_END_OF_FRAME;
-       } else if (event == VENC_SECOND_FIELD) {
-               /* end-of-frame for interlaced display */
-               event |= VENC_END_OF_FRAME;
-       }
-       last_event = event;
-
-       for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
-               layer = disp_dev->dev[i];
-
-               if (!vb2_start_streaming_called(&layer->buffer_queue))
-                       continue;
-
-               if (layer->layer_first_int) {
-                       layer->layer_first_int = 0;
-                       continue;
-               }
-               /* Check the field format */
-               if ((V4L2_FIELD_NONE == layer->pix_fmt.field) &&
-                       (event & VENC_END_OF_FRAME)) {
-                       /* Progressive mode */
-
-                       vpbe_isr_even_field(disp_dev, layer);
-                       vpbe_isr_odd_field(disp_dev, layer);
-               } else {
-               /* Interlaced mode */
-
-                       layer->field_id ^= 1;
-                       if (event & VENC_FIRST_FIELD)
-                               fid = 0;
-                       else
-                               fid = 1;
-
-                       /*
-                       * If field id does not match with store
-                       * field id
-                       */
-                       if (fid != layer->field_id) {
-                               /* Make them in sync */
-                               layer->field_id = fid;
-                               continue;
-                       }
-                       /*
-                       * device field id and local field id are
-                       * in sync. If this is even field
-                       */
-                       if (0 == fid)
-                               vpbe_isr_even_field(disp_dev, layer);
-                       else  /* odd field */
-                               vpbe_isr_odd_field(disp_dev, layer);
-               }
-       }
-
-       return IRQ_HANDLED;
-}
-
-/*
- * vpbe_buffer_prepare()
- * This is the callback function called from vb2_qbuf() function
- * the buffer is prepared and user space virtual address is converted into
- * physical address
- */
-static int vpbe_buffer_prepare(struct vb2_buffer *vb)
-{
-       struct vb2_queue *q = vb->vb2_queue;
-       struct vpbe_layer *layer = vb2_get_drv_priv(q);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-       unsigned long addr;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-                               "vpbe_buffer_prepare\n");
-
-       vb2_set_plane_payload(vb, 0, layer->pix_fmt.sizeimage);
-       if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
-               return -EINVAL;
-
-       addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-       if (!IS_ALIGNED(addr, 8)) {
-               v4l2_err(&vpbe_dev->v4l2_dev,
-                        "buffer_prepare:offset is not aligned to 32 bytes\n");
-               return -EINVAL;
-       }
-       return 0;
-}
-
-/*
- * vpbe_buffer_setup()
- * This function allocates memory for the buffers
- */
-static int
-vpbe_buffer_queue_setup(struct vb2_queue *vq,
-                       unsigned int *nbuffers, unsigned int *nplanes,
-                       unsigned int sizes[], struct device *alloc_devs[])
-
-{
-       /* Get the file handle object and layer object */
-       struct vpbe_layer *layer = vb2_get_drv_priv(vq);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n");
-
-       /* Store number of buffers allocated in numbuffer member */
-       if (vq->num_buffers + *nbuffers < VPBE_DEFAULT_NUM_BUFS)
-               *nbuffers = VPBE_DEFAULT_NUM_BUFS - vq->num_buffers;
-
-       if (*nplanes)
-               return sizes[0] < layer->pix_fmt.sizeimage ? -EINVAL : 0;
-
-       *nplanes = 1;
-       sizes[0] = layer->pix_fmt.sizeimage;
-
-       return 0;
-}
-
-/*
- * vpbe_buffer_queue()
- * This function adds the buffer to DMA queue
- */
-static void vpbe_buffer_queue(struct vb2_buffer *vb)
-{
-       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-       /* Get the file handle object and layer object */
-       struct vpbe_disp_buffer *buf = container_of(vbuf,
-                               struct vpbe_disp_buffer, vb);
-       struct vpbe_layer *layer = vb2_get_drv_priv(vb->vb2_queue);
-       struct vpbe_display *disp = layer->disp_dev;
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-       unsigned long flags;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-                       "vpbe_buffer_queue\n");
-
-       /* add the buffer to the DMA queue */
-       spin_lock_irqsave(&disp->dma_queue_lock, flags);
-       list_add_tail(&buf->list, &layer->dma_queue);
-       spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
-}
-
-static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-       struct vpbe_layer *layer = vb2_get_drv_priv(vq);
-       struct osd_state *osd_device = layer->disp_dev->osd_device;
-       int ret;
-
-       osd_device->ops.disable_layer(osd_device, layer->layer_info.id);
-
-       /* Get the next frame from the buffer queue */
-       layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next,
-                               struct vpbe_disp_buffer, list);
-       /* Remove buffer from the buffer queue */
-       list_del(&layer->cur_frm->list);
-       /* Mark state of the current frame to active */
-       layer->cur_frm->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
-       /* Initialize field_id and started member */
-       layer->field_id = 0;
-
-       /* Set parameters in OSD and VENC */
-       ret = vpbe_set_osd_display_params(layer->disp_dev, layer);
-       if (ret < 0) {
-               struct vpbe_disp_buffer *buf, *tmp;
-
-               vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
-                               VB2_BUF_STATE_QUEUED);
-               list_for_each_entry_safe(buf, tmp, &layer->dma_queue, list) {
-                       list_del(&buf->list);
-                       vb2_buffer_done(&buf->vb.vb2_buf,
-                                       VB2_BUF_STATE_QUEUED);
-               }
-
-               return ret;
-       }
-
-       /*
-        * if request format is yuv420 semiplanar, need to
-        * enable both video windows
-        */
-       layer->layer_first_int = 1;
-
-       return ret;
-}
-
-static void vpbe_stop_streaming(struct vb2_queue *vq)
-{
-       struct vpbe_layer *layer = vb2_get_drv_priv(vq);
-       struct osd_state *osd_device = layer->disp_dev->osd_device;
-       struct vpbe_display *disp = layer->disp_dev;
-       unsigned long flags;
-
-       if (!vb2_is_streaming(vq))
-               return;
-
-       osd_device->ops.disable_layer(osd_device, layer->layer_info.id);
-
-       /* release all active buffers */
-       spin_lock_irqsave(&disp->dma_queue_lock, flags);
-       if (layer->cur_frm == layer->next_frm) {
-               vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
-                               VB2_BUF_STATE_ERROR);
-       } else {
-               if (layer->cur_frm)
-                       vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
-                                       VB2_BUF_STATE_ERROR);
-               if (layer->next_frm)
-                       vb2_buffer_done(&layer->next_frm->vb.vb2_buf,
-                                       VB2_BUF_STATE_ERROR);
-       }
-
-       while (!list_empty(&layer->dma_queue)) {
-               layer->next_frm = list_entry(layer->dma_queue.next,
-                                               struct vpbe_disp_buffer, list);
-               list_del(&layer->next_frm->list);
-               vb2_buffer_done(&layer->next_frm->vb.vb2_buf,
-                               VB2_BUF_STATE_ERROR);
-       }
-       spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
-}
-
-static const struct vb2_ops video_qops = {
-       .queue_setup = vpbe_buffer_queue_setup,
-       .wait_prepare = vb2_ops_wait_prepare,
-       .wait_finish = vb2_ops_wait_finish,
-       .buf_prepare = vpbe_buffer_prepare,
-       .start_streaming = vpbe_start_streaming,
-       .stop_streaming = vpbe_stop_streaming,
-       .buf_queue = vpbe_buffer_queue,
-};
-
-static
-struct vpbe_layer*
-_vpbe_display_get_other_win_layer(struct vpbe_display *disp_dev,
-                       struct vpbe_layer *layer)
-{
-       enum vpbe_display_device_id thiswin, otherwin;
-       thiswin = layer->device_id;
-
-       otherwin = (thiswin == VPBE_DISPLAY_DEVICE_0) ?
-       VPBE_DISPLAY_DEVICE_1 : VPBE_DISPLAY_DEVICE_0;
-       return disp_dev->dev[otherwin];
-}
-
-static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
-                       struct vpbe_layer *layer)
-{
-       struct osd_layer_config *cfg  = &layer->layer_info.config;
-       struct osd_state *osd_device = disp_dev->osd_device;
-       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
-       unsigned long addr;
-       int ret;
-
-       addr = vb2_dma_contig_plane_dma_addr(&layer->cur_frm->vb.vb2_buf, 0);
-       /* Set address in the display registers */
-       osd_device->ops.start_layer(osd_device,
-                                   layer->layer_info.id,
-                                   addr,
-                                   disp_dev->cbcr_ofst);
-
-       ret = osd_device->ops.enable_layer(osd_device,
-                               layer->layer_info.id, 0);
-       if (ret < 0) {
-               v4l2_err(&vpbe_dev->v4l2_dev,
-                       "Error in enabling osd window layer 0\n");
-               return -1;
-       }
-
-       /* Enable the window */
-       layer->layer_info.enable = 1;
-       if (cfg->pixfmt == PIXFMT_NV12) {
-               struct vpbe_layer *otherlayer =
-                       _vpbe_display_get_other_win_layer(disp_dev, layer);
-
-               ret = osd_device->ops.enable_layer(osd_device,
-                               otherlayer->layer_info.id, 1);
-               if (ret < 0) {
-                       v4l2_err(&vpbe_dev->v4l2_dev,
-                               "Error in enabling osd window layer 1\n");
-                       return -1;
-               }
-               otherlayer->layer_info.enable = 1;
-       }
-       return 0;
-}
-
-static void
-vpbe_disp_calculate_scale_factor(struct vpbe_display *disp_dev,
-                       struct vpbe_layer *layer,
-                       int expected_xsize, int expected_ysize)
-{
-       struct display_layer_info *layer_info = &layer->layer_info;
-       struct v4l2_pix_format *pixfmt = &layer->pix_fmt;
-       struct osd_layer_config *cfg  = &layer->layer_info.config;
-       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
-       int calculated_xsize;
-       int h_exp = 0;
-       int v_exp = 0;
-       int h_scale;
-       int v_scale;
-
-       v4l2_std_id standard_id = vpbe_dev->current_timings.std_id;
-
-       /*
-        * Application initially set the image format. Current display
-        * size is obtained from the vpbe display controller. expected_xsize
-        * and expected_ysize are set through S_SELECTION ioctl. Based on this,
-        * driver will calculate the scale factors for vertical and
-        * horizontal direction so that the image is displayed scaled
-        * and expanded. Application uses expansion to display the image
-        * in a square pixel. Otherwise it is displayed using displays
-        * pixel aspect ratio.It is expected that application chooses
-        * the crop coordinates for cropped or scaled display. if crop
-        * size is less than the image size, it is displayed cropped or
-        * it is displayed scaled and/or expanded.
-        *
-        * to begin with, set the crop window same as expected. Later we
-        * will override with scaled window size
-        */
-
-       cfg->xsize = pixfmt->width;
-       cfg->ysize = pixfmt->height;
-       layer_info->h_zoom = ZOOM_X1;   /* no horizontal zoom */
-       layer_info->v_zoom = ZOOM_X1;   /* no horizontal zoom */
-       layer_info->h_exp = H_EXP_OFF;  /* no horizontal zoom */
-       layer_info->v_exp = V_EXP_OFF;  /* no horizontal zoom */
-
-       if (pixfmt->width < expected_xsize) {
-               h_scale = vpbe_dev->current_timings.xres / pixfmt->width;
-               if (h_scale < 2)
-                       h_scale = 1;
-               else if (h_scale >= 4)
-                       h_scale = 4;
-               else
-                       h_scale = 2;
-               cfg->xsize *= h_scale;
-               if (cfg->xsize < expected_xsize) {
-                       if ((standard_id & V4L2_STD_525_60) ||
-                       (standard_id & V4L2_STD_625_50)) {
-                               calculated_xsize = (cfg->xsize *
-                                       VPBE_DISPLAY_H_EXP_RATIO_N) /
-                                       VPBE_DISPLAY_H_EXP_RATIO_D;
-                               if (calculated_xsize <= expected_xsize) {
-                                       h_exp = 1;
-                                       cfg->xsize = calculated_xsize;
-                               }
-                       }
-               }
-               if (h_scale == 2)
-                       layer_info->h_zoom = ZOOM_X2;
-               else if (h_scale == 4)
-                       layer_info->h_zoom = ZOOM_X4;
-               if (h_exp)
-                       layer_info->h_exp = H_EXP_9_OVER_8;
-       } else {
-               /* no scaling, only cropping. Set display area to crop area */
-               cfg->xsize = expected_xsize;
-       }
-
-       if (pixfmt->height < expected_ysize) {
-               v_scale = expected_ysize / pixfmt->height;
-               if (v_scale < 2)
-                       v_scale = 1;
-               else if (v_scale >= 4)
-                       v_scale = 4;
-               else
-                       v_scale = 2;
-               cfg->ysize *= v_scale;
-               if (cfg->ysize < expected_ysize) {
-                       if ((standard_id & V4L2_STD_625_50)) {
-                               calculated_xsize = (cfg->ysize *
-                                       VPBE_DISPLAY_V_EXP_RATIO_N) /
-                                       VPBE_DISPLAY_V_EXP_RATIO_D;
-                               if (calculated_xsize <= expected_ysize) {
-                                       v_exp = 1;
-                                       cfg->ysize = calculated_xsize;
-                               }
-                       }
-               }
-               if (v_scale == 2)
-                       layer_info->v_zoom = ZOOM_X2;
-               else if (v_scale == 4)
-                       layer_info->v_zoom = ZOOM_X4;
-               if (v_exp)
-                       layer_info->v_exp = V_EXP_6_OVER_5;
-       } else {
-               /* no scaling, only cropping. Set display area to crop area */
-               cfg->ysize = expected_ysize;
-       }
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-               "crop display xsize = %d, ysize = %d\n",
-               cfg->xsize, cfg->ysize);
-}
-
-static void vpbe_disp_adj_position(struct vpbe_display *disp_dev,
-                       struct vpbe_layer *layer,
-                       int top, int left)
-{
-       struct osd_layer_config *cfg = &layer->layer_info.config;
-       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
-
-       cfg->xpos = min((unsigned int)left,
-                       vpbe_dev->current_timings.xres - cfg->xsize);
-       cfg->ypos = min((unsigned int)top,
-                       vpbe_dev->current_timings.yres - cfg->ysize);
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-               "new xpos = %d, ypos = %d\n",
-               cfg->xpos, cfg->ypos);
-}
-
-static void vpbe_disp_check_window_params(struct vpbe_display *disp_dev,
-                       struct v4l2_rect *c)
-{
-       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
-
-       if ((c->width == 0) ||
-         ((c->width + c->left) > vpbe_dev->current_timings.xres))
-               c->width = vpbe_dev->current_timings.xres - c->left;
-
-       if ((c->height == 0) || ((c->height + c->top) >
-         vpbe_dev->current_timings.yres))
-               c->height = vpbe_dev->current_timings.yres - c->top;
-
-       /* window height must be even for interlaced display */
-       if (vpbe_dev->current_timings.interlaced)
-               c->height &= (~0x01);
-
-}
-
-/*
- * vpbe_try_format()
- * If user application provides width and height, and have bytesperline set
- * to zero, driver calculates bytesperline and sizeimage based on hardware
- * limits.
- */
-static int vpbe_try_format(struct vpbe_display *disp_dev,
-                       struct v4l2_pix_format *pixfmt, int check)
-{
-       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
-       int min_height = 1;
-       int min_width = 32;
-       int max_height;
-       int max_width;
-       int bpp;
-
-       if ((pixfmt->pixelformat != V4L2_PIX_FMT_UYVY) &&
-           (pixfmt->pixelformat != V4L2_PIX_FMT_NV12))
-               /* choose default as V4L2_PIX_FMT_UYVY */
-               pixfmt->pixelformat = V4L2_PIX_FMT_UYVY;
-
-       /* Check the field format */
-       if ((pixfmt->field != V4L2_FIELD_INTERLACED) &&
-               (pixfmt->field != V4L2_FIELD_NONE)) {
-               if (vpbe_dev->current_timings.interlaced)
-                       pixfmt->field = V4L2_FIELD_INTERLACED;
-               else
-                       pixfmt->field = V4L2_FIELD_NONE;
-       }
-
-       if (pixfmt->field == V4L2_FIELD_INTERLACED)
-               min_height = 2;
-
-       if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
-               bpp = 1;
-       else
-               bpp = 2;
-
-       max_width = vpbe_dev->current_timings.xres;
-       max_height = vpbe_dev->current_timings.yres;
-
-       min_width /= bpp;
-
-       if (!pixfmt->width || (pixfmt->width < min_width) ||
-               (pixfmt->width > max_width)) {
-               pixfmt->width = vpbe_dev->current_timings.xres;
-       }
-
-       if (!pixfmt->height || (pixfmt->height  < min_height) ||
-               (pixfmt->height  > max_height)) {
-               pixfmt->height = vpbe_dev->current_timings.yres;
-       }
-
-       if (pixfmt->bytesperline < (pixfmt->width * bpp))
-               pixfmt->bytesperline = pixfmt->width * bpp;
-
-       /* Make the bytesperline 32 byte aligned */
-       pixfmt->bytesperline = ((pixfmt->width * bpp + 31) & ~31);
-
-       if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
-               pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height +
-                               (pixfmt->bytesperline * pixfmt->height >> 1);
-       else
-               pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
-
-       return 0;
-}
-
-static int vpbe_display_querycap(struct file *file, void  *priv,
-                              struct v4l2_capability *cap)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-
-       snprintf(cap->driver, sizeof(cap->driver), "%s",
-               dev_name(vpbe_dev->pdev));
-       snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
-                dev_name(vpbe_dev->pdev));
-       strscpy(cap->card, vpbe_dev->cfg->module_name, sizeof(cap->card));
-
-       return 0;
-}
-
-static int vpbe_display_s_selection(struct file *file, void *priv,
-                            struct v4l2_selection *sel)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_display *disp_dev = layer->disp_dev;
-       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
-       struct osd_layer_config *cfg = &layer->layer_info.config;
-       struct osd_state *osd_device = disp_dev->osd_device;
-       struct v4l2_rect rect = sel->r;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-               "VIDIOC_S_SELECTION, layer id = %d\n", layer->device_id);
-
-       if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
-           sel->target != V4L2_SEL_TGT_CROP)
-               return -EINVAL;
-
-       if (rect.top < 0)
-               rect.top = 0;
-       if (rect.left < 0)
-               rect.left = 0;
-
-       vpbe_disp_check_window_params(disp_dev, &rect);
-
-       osd_device->ops.get_layer_config(osd_device,
-                       layer->layer_info.id, cfg);
-
-       vpbe_disp_calculate_scale_factor(disp_dev, layer,
-                                       rect.width,
-                                       rect.height);
-       vpbe_disp_adj_position(disp_dev, layer, rect.top,
-                                       rect.left);
-       ret = osd_device->ops.set_layer_config(osd_device,
-                               layer->layer_info.id, cfg);
-       if (ret < 0) {
-               v4l2_err(&vpbe_dev->v4l2_dev,
-                       "Error in set layer config:\n");
-               return -EINVAL;
-       }
-
-       /* apply zooming and h or v expansion */
-       osd_device->ops.set_zoom(osd_device,
-                       layer->layer_info.id,
-                       layer->layer_info.h_zoom,
-                       layer->layer_info.v_zoom);
-       ret = osd_device->ops.set_vid_expansion(osd_device,
-                       layer->layer_info.h_exp,
-                       layer->layer_info.v_exp);
-       if (ret < 0) {
-               v4l2_err(&vpbe_dev->v4l2_dev,
-               "Error in set vid expansion:\n");
-               return -EINVAL;
-       }
-
-       if ((layer->layer_info.h_zoom != ZOOM_X1) ||
-               (layer->layer_info.v_zoom != ZOOM_X1) ||
-               (layer->layer_info.h_exp != H_EXP_OFF) ||
-               (layer->layer_info.v_exp != V_EXP_OFF))
-               /* Enable expansion filter */
-               osd_device->ops.set_interpolation_filter(osd_device, 1);
-       else
-               osd_device->ops.set_interpolation_filter(osd_device, 0);
-
-       sel->r = rect;
-       return 0;
-}
-
-static int vpbe_display_g_selection(struct file *file, void *priv,
-                                   struct v4l2_selection *sel)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct osd_layer_config *cfg = &layer->layer_info.config;
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-       struct osd_state *osd_device = layer->disp_dev->osd_device;
-       struct v4l2_rect *rect = &sel->r;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-                       "VIDIOC_G_SELECTION, layer id = %d\n",
-                       layer->device_id);
-
-       if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
-               return -EINVAL;
-
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP:
-               osd_device->ops.get_layer_config(osd_device,
-                                                layer->layer_info.id, cfg);
-               rect->top = cfg->ypos;
-               rect->left = cfg->xpos;
-               rect->width = cfg->xsize;
-               rect->height = cfg->ysize;
-               break;
-       case V4L2_SEL_TGT_CROP_DEFAULT:
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-               rect->left = 0;
-               rect->top = 0;
-               rect->width = vpbe_dev->current_timings.xres;
-               rect->height = vpbe_dev->current_timings.yres;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int vpbe_display_g_pixelaspect(struct file *file, void *priv,
-                                     int type, struct v4l2_fract *f)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_CROPCAP ioctl\n");
-
-       if (type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
-               return -EINVAL;
-
-       *f = vpbe_dev->current_timings.aspect;
-       return 0;
-}
-
-static int vpbe_display_g_fmt(struct file *file, void *priv,
-                               struct v4l2_format *fmt)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-                       "VIDIOC_G_FMT, layer id = %d\n",
-                       layer->device_id);
-
-       /* If buffer type is video output */
-       if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
-               return -EINVAL;
-       }
-       /* Fill in the information about format */
-       fmt->fmt.pix = layer->pix_fmt;
-
-       return 0;
-}
-
-static int vpbe_display_enum_fmt(struct file *file, void  *priv,
-                                  struct v4l2_fmtdesc *fmt)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-                               "VIDIOC_ENUM_FMT, layer id = %d\n",
-                               layer->device_id);
-       if (fmt->index > 1) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "Invalid format index\n");
-               return -EINVAL;
-       }
-
-       /* Fill in the information about format */
-       if (fmt->index == 0)
-               fmt->pixelformat = V4L2_PIX_FMT_UYVY;
-       else
-               fmt->pixelformat = V4L2_PIX_FMT_NV12;
-
-       return 0;
-}
-
-static int vpbe_display_s_fmt(struct file *file, void *priv,
-                               struct v4l2_format *fmt)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_display *disp_dev = layer->disp_dev;
-       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
-       struct osd_layer_config *cfg  = &layer->layer_info.config;
-       struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-       struct osd_state *osd_device = disp_dev->osd_device;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-                       "VIDIOC_S_FMT, layer id = %d\n",
-                       layer->device_id);
-
-       if (vb2_is_busy(&layer->buffer_queue))
-               return -EBUSY;
-
-       if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
-               v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "invalid type\n");
-               return -EINVAL;
-       }
-       /* Check for valid pixel format */
-       ret = vpbe_try_format(disp_dev, pixfmt, 1);
-       if (ret)
-               return ret;
-
-       /* YUV420 is requested, check availability of the
-       other video window */
-
-       layer->pix_fmt = *pixfmt;
-       if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12) {
-               struct vpbe_layer *otherlayer;
-
-               otherlayer = _vpbe_display_get_other_win_layer(disp_dev, layer);
-               /* if other layer is available, only
-                * claim it, do not configure it
-                */
-               ret = osd_device->ops.request_layer(osd_device,
-                                                   otherlayer->layer_info.id);
-               if (ret < 0) {
-                       v4l2_err(&vpbe_dev->v4l2_dev,
-                                "Display Manager failed to allocate layer\n");
-                       return -EBUSY;
-               }
-       }
-
-       /* Get osd layer config */
-       osd_device->ops.get_layer_config(osd_device,
-                       layer->layer_info.id, cfg);
-       /* Store the pixel format in the layer object */
-       cfg->xsize = pixfmt->width;
-       cfg->ysize = pixfmt->height;
-       cfg->line_length = pixfmt->bytesperline;
-       cfg->ypos = 0;
-       cfg->xpos = 0;
-       cfg->interlaced = vpbe_dev->current_timings.interlaced;
-
-       if (V4L2_PIX_FMT_UYVY == pixfmt->pixelformat)
-               cfg->pixfmt = PIXFMT_YCBCRI;
-
-       /* Change of the default pixel format for both video windows */
-       if (V4L2_PIX_FMT_NV12 == pixfmt->pixelformat) {
-               struct vpbe_layer *otherlayer;
-               cfg->pixfmt = PIXFMT_NV12;
-               otherlayer = _vpbe_display_get_other_win_layer(disp_dev,
-                                                               layer);
-               otherlayer->layer_info.config.pixfmt = PIXFMT_NV12;
-       }
-
-       /* Set the layer config in the osd window */
-       ret = osd_device->ops.set_layer_config(osd_device,
-                               layer->layer_info.id, cfg);
-       if (ret < 0) {
-               v4l2_err(&vpbe_dev->v4l2_dev,
-                               "Error in S_FMT params:\n");
-               return -EINVAL;
-       }
-
-       /* Readback and fill the local copy of current pix format */
-       osd_device->ops.get_layer_config(osd_device,
-                       layer->layer_info.id, cfg);
-
-       return 0;
-}
-
-static int vpbe_display_try_fmt(struct file *file, void *priv,
-                                 struct v4l2_format *fmt)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_display *disp_dev = layer->disp_dev;
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-       struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_TRY_FMT\n");
-
-       if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
-               return -EINVAL;
-       }
-
-       /* Check for valid field format */
-       return  vpbe_try_format(disp_dev, pixfmt, 0);
-
-}
-
-/*
- * vpbe_display_s_std - Set the given standard in the encoder
- *
- * Sets the standard if supported by the current encoder. Return the status.
- * 0 - success & -EINVAL on error
- */
-static int vpbe_display_s_std(struct file *file, void *priv,
-                               v4l2_std_id std_id)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_STD\n");
-
-       if (vb2_is_busy(&layer->buffer_queue))
-               return -EBUSY;
-
-       if (vpbe_dev->ops.s_std) {
-               ret = vpbe_dev->ops.s_std(vpbe_dev, std_id);
-               if (ret) {
-                       v4l2_err(&vpbe_dev->v4l2_dev,
-                       "Failed to set standard for sub devices\n");
-                       return -EINVAL;
-               }
-       } else {
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/*
- * vpbe_display_g_std - Get the standard in the current encoder
- *
- * Get the standard in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int vpbe_display_g_std(struct file *file, void *priv,
-                               v4l2_std_id *std_id)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_STD\n");
-
-       /* Get the standard from the current encoder */
-       if (vpbe_dev->current_timings.timings_type & VPBE_ENC_STD) {
-               *std_id = vpbe_dev->current_timings.std_id;
-               return 0;
-       }
-
-       return -EINVAL;
-}
-
-/*
- * vpbe_display_enum_output - enumerate outputs
- *
- * Enumerates the outputs available at the vpbe display
- * returns the status, -EINVAL if end of output list
- */
-static int vpbe_display_enum_output(struct file *file, void *priv,
-                                   struct v4l2_output *output)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_OUTPUT\n");
-
-       /* Enumerate outputs */
-       if (!vpbe_dev->ops.enum_outputs)
-               return -EINVAL;
-
-       ret = vpbe_dev->ops.enum_outputs(vpbe_dev, output);
-       if (ret) {
-               v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-                       "Failed to enumerate outputs\n");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/*
- * vpbe_display_s_output - Set output to
- * the output specified by the index
- */
-static int vpbe_display_s_output(struct file *file, void *priv,
-                               unsigned int i)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_OUTPUT\n");
-
-       if (vb2_is_busy(&layer->buffer_queue))
-               return -EBUSY;
-
-       if (!vpbe_dev->ops.set_output)
-               return -EINVAL;
-
-       ret = vpbe_dev->ops.set_output(vpbe_dev, i);
-       if (ret) {
-               v4l2_err(&vpbe_dev->v4l2_dev,
-                       "Failed to set output for sub devices\n");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/*
- * vpbe_display_g_output - Get output from subdevice
- * for a given by the index
- */
-static int vpbe_display_g_output(struct file *file, void *priv,
-                               unsigned int *i)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_OUTPUT\n");
-       /* Get the standard from the current encoder */
-       *i = vpbe_dev->current_out_index;
-
-       return 0;
-}
-
-/*
- * vpbe_display_enum_dv_timings - Enumerate the dv timings
- *
- * enum the timings in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int
-vpbe_display_enum_dv_timings(struct file *file, void *priv,
-                       struct v4l2_enum_dv_timings *timings)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_TIMINGS\n");
-
-       /* Enumerate outputs */
-       if (!vpbe_dev->ops.enum_dv_timings)
-               return -EINVAL;
-
-       ret = vpbe_dev->ops.enum_dv_timings(vpbe_dev, timings);
-       if (ret) {
-               v4l2_err(&vpbe_dev->v4l2_dev,
-                       "Failed to enumerate dv timings info\n");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/*
- * vpbe_display_s_dv_timings - Set the dv timings
- *
- * Set the timings in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int
-vpbe_display_s_dv_timings(struct file *file, void *priv,
-                               struct v4l2_dv_timings *timings)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_TIMINGS\n");
-
-       if (vb2_is_busy(&layer->buffer_queue))
-               return -EBUSY;
-
-       /* Set the given standard in the encoder */
-       if (!vpbe_dev->ops.s_dv_timings)
-               return -EINVAL;
-
-       ret = vpbe_dev->ops.s_dv_timings(vpbe_dev, timings);
-       if (ret) {
-               v4l2_err(&vpbe_dev->v4l2_dev,
-                       "Failed to set the dv timings info\n");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/*
- * vpbe_display_g_dv_timings - Set the dv timings
- *
- * Get the timings in the current encoder. Return the status. 0 - success
- * -EINVAL on error
- */
-static int
-vpbe_display_g_dv_timings(struct file *file, void *priv,
-                               struct v4l2_dv_timings *dv_timings)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_DV_TIMINGS\n");
-
-       /* Get the given standard in the encoder */
-
-       if (vpbe_dev->current_timings.timings_type &
-                               VPBE_ENC_DV_TIMINGS) {
-               *dv_timings = vpbe_dev->current_timings.dv_timings;
-       } else {
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/*
- * vpbe_display_open()
- * It creates object of file handle structure and stores it in private_data
- * member of filepointer
- */
-static int vpbe_display_open(struct file *file)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct vpbe_display *disp_dev = layer->disp_dev;
-       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
-       struct osd_state *osd_device = disp_dev->osd_device;
-       int err;
-
-       /* creating context for file descriptor */
-       err = v4l2_fh_open(file);
-       if (err) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "v4l2_fh_open failed\n");
-               return err;
-       }
-
-       /* leaving if layer is already initialized */
-       if (!v4l2_fh_is_singular_file(file))
-               return err;
-
-       if (!layer->usrs) {
-               if (mutex_lock_interruptible(&layer->opslock))
-                       return -ERESTARTSYS;
-               /* First claim the layer for this device */
-               err = osd_device->ops.request_layer(osd_device,
-                                               layer->layer_info.id);
-               mutex_unlock(&layer->opslock);
-               if (err < 0) {
-                       /* Couldn't get layer */
-                       v4l2_err(&vpbe_dev->v4l2_dev,
-                               "Display Manager failed to allocate layer\n");
-                       v4l2_fh_release(file);
-                       return -EINVAL;
-               }
-       }
-       /* Increment layer usrs counter */
-       layer->usrs++;
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-                       "vpbe display device opened successfully\n");
-       return 0;
-}
-
-/*
- * vpbe_display_release()
- * This function deletes buffer queue, frees the buffers and the davinci
- * display file * handle
- */
-static int vpbe_display_release(struct file *file)
-{
-       struct vpbe_layer *layer = video_drvdata(file);
-       struct osd_layer_config *cfg  = &layer->layer_info.config;
-       struct vpbe_display *disp_dev = layer->disp_dev;
-       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
-       struct osd_state *osd_device = disp_dev->osd_device;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_release\n");
-
-       mutex_lock(&layer->opslock);
-
-       osd_device->ops.disable_layer(osd_device,
-                       layer->layer_info.id);
-       /* Decrement layer usrs counter */
-       layer->usrs--;
-       /* If this file handle has initialize encoder device, reset it */
-       if (!layer->usrs) {
-               if (cfg->pixfmt == PIXFMT_NV12) {
-                       struct vpbe_layer *otherlayer;
-                       otherlayer =
-                       _vpbe_display_get_other_win_layer(disp_dev, layer);
-                       osd_device->ops.disable_layer(osd_device,
-                                       otherlayer->layer_info.id);
-                       osd_device->ops.release_layer(osd_device,
-                                       otherlayer->layer_info.id);
-               }
-               osd_device->ops.disable_layer(osd_device,
-                               layer->layer_info.id);
-               osd_device->ops.release_layer(osd_device,
-                               layer->layer_info.id);
-       }
-
-       _vb2_fop_release(file, NULL);
-       mutex_unlock(&layer->opslock);
-
-       disp_dev->cbcr_ofst = 0;
-
-       return 0;
-}
-
-/* vpbe capture ioctl operations */
-static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
-       .vidioc_querycap         = vpbe_display_querycap,
-       .vidioc_g_fmt_vid_out    = vpbe_display_g_fmt,
-       .vidioc_enum_fmt_vid_out = vpbe_display_enum_fmt,
-       .vidioc_s_fmt_vid_out    = vpbe_display_s_fmt,
-       .vidioc_try_fmt_vid_out  = vpbe_display_try_fmt,
-
-       .vidioc_reqbufs          = vb2_ioctl_reqbufs,
-       .vidioc_create_bufs      = vb2_ioctl_create_bufs,
-       .vidioc_querybuf         = vb2_ioctl_querybuf,
-       .vidioc_qbuf             = vb2_ioctl_qbuf,
-       .vidioc_dqbuf            = vb2_ioctl_dqbuf,
-       .vidioc_streamon         = vb2_ioctl_streamon,
-       .vidioc_streamoff        = vb2_ioctl_streamoff,
-       .vidioc_expbuf           = vb2_ioctl_expbuf,
-
-       .vidioc_g_pixelaspect    = vpbe_display_g_pixelaspect,
-       .vidioc_g_selection      = vpbe_display_g_selection,
-       .vidioc_s_selection      = vpbe_display_s_selection,
-
-       .vidioc_s_std            = vpbe_display_s_std,
-       .vidioc_g_std            = vpbe_display_g_std,
-
-       .vidioc_enum_output      = vpbe_display_enum_output,
-       .vidioc_s_output         = vpbe_display_s_output,
-       .vidioc_g_output         = vpbe_display_g_output,
-
-       .vidioc_s_dv_timings     = vpbe_display_s_dv_timings,
-       .vidioc_g_dv_timings     = vpbe_display_g_dv_timings,
-       .vidioc_enum_dv_timings  = vpbe_display_enum_dv_timings,
-};
-
-static const struct v4l2_file_operations vpbe_fops = {
-       .owner = THIS_MODULE,
-       .open = vpbe_display_open,
-       .release = vpbe_display_release,
-       .unlocked_ioctl = video_ioctl2,
-       .mmap = vb2_fop_mmap,
-       .poll =  vb2_fop_poll,
-};
-
-static int vpbe_device_get(struct device *dev, void *data)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct vpbe_display *vpbe_disp  = data;
-
-       if (strcmp("vpbe_controller", pdev->name) == 0)
-               vpbe_disp->vpbe_dev = platform_get_drvdata(pdev);
-
-       if (strstr(pdev->name, "vpbe-osd"))
-               vpbe_disp->osd_device = platform_get_drvdata(pdev);
-
-       return 0;
-}
-
-static int init_vpbe_layer(int i, struct vpbe_display *disp_dev,
-                          struct platform_device *pdev)
-{
-       struct vpbe_layer *vpbe_display_layer = NULL;
-       struct video_device *vbd = NULL;
-
-       /* Allocate memory for four plane display objects */
-       disp_dev->dev[i] = kzalloc(sizeof(*disp_dev->dev[i]), GFP_KERNEL);
-       if (!disp_dev->dev[i])
-               return  -ENOMEM;
-
-       spin_lock_init(&disp_dev->dev[i]->irqlock);
-       mutex_init(&disp_dev->dev[i]->opslock);
-
-       /* Get the pointer to the layer object */
-       vpbe_display_layer = disp_dev->dev[i];
-       vbd = &vpbe_display_layer->video_dev;
-       /* Initialize field of video device */
-       vbd->release    = video_device_release_empty;
-       vbd->fops       = &vpbe_fops;
-       vbd->ioctl_ops  = &vpbe_ioctl_ops;
-       vbd->minor      = -1;
-       vbd->v4l2_dev   = &disp_dev->vpbe_dev->v4l2_dev;
-       vbd->lock       = &vpbe_display_layer->opslock;
-       vbd->vfl_dir    = VFL_DIR_TX;
-       vbd->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
-
-       if (disp_dev->vpbe_dev->current_timings.timings_type &
-                       VPBE_ENC_STD)
-               vbd->tvnorms = (V4L2_STD_525_60 | V4L2_STD_625_50);
-
-       snprintf(vbd->name, sizeof(vbd->name),
-                       "DaVinci_VPBE Display_DRIVER_V%d.%d.%d",
-                       (VPBE_DISPLAY_VERSION_CODE >> 16) & 0xff,
-                       (VPBE_DISPLAY_VERSION_CODE >> 8) & 0xff,
-                       (VPBE_DISPLAY_VERSION_CODE) & 0xff);
-
-       vpbe_display_layer->device_id = i;
-
-       vpbe_display_layer->layer_info.id =
-               ((i == VPBE_DISPLAY_DEVICE_0) ? WIN_VID0 : WIN_VID1);
-
-
-       return 0;
-}
-
-static int register_device(struct vpbe_layer *vpbe_display_layer,
-                          struct vpbe_display *disp_dev,
-                          struct platform_device *pdev)
-{
-       int err;
-
-       v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
-                 "Trying to register VPBE display device.\n");
-       v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
-                 "layer=%p,layer->video_dev=%p\n",
-                 vpbe_display_layer,
-                 &vpbe_display_layer->video_dev);
-
-       vpbe_display_layer->video_dev.queue = &vpbe_display_layer->buffer_queue;
-       err = video_register_device(&vpbe_display_layer->video_dev,
-                                   VFL_TYPE_VIDEO,
-                                   -1);
-       if (err)
-               return -ENODEV;
-
-       vpbe_display_layer->disp_dev = disp_dev;
-       /* set the driver data in platform device */
-       platform_set_drvdata(pdev, disp_dev);
-       video_set_drvdata(&vpbe_display_layer->video_dev,
-                         vpbe_display_layer);
-
-       return 0;
-}
-
-
-
-/*
- * vpbe_display_probe()
- * This function creates device entries by register itself to the V4L2 driver
- * and initializes fields of each layer objects
- */
-static int vpbe_display_probe(struct platform_device *pdev)
-{
-       struct vpbe_display *disp_dev;
-       struct v4l2_device *v4l2_dev;
-       struct resource *res = NULL;
-       struct vb2_queue *q;
-       int k;
-       int i;
-       int err;
-       int irq;
-
-       printk(KERN_DEBUG "vpbe_display_probe\n");
-       /* Allocate memory for vpbe_display */
-       disp_dev = devm_kzalloc(&pdev->dev, sizeof(*disp_dev), GFP_KERNEL);
-       if (!disp_dev)
-               return -ENOMEM;
-
-       spin_lock_init(&disp_dev->dma_queue_lock);
-       /*
-        * Scan all the platform devices to find the vpbe
-        * controller device and get the vpbe_dev object
-        */
-       err = bus_for_each_dev(&platform_bus_type, NULL, disp_dev,
-                       vpbe_device_get);
-       if (err < 0)
-               return err;
-
-       v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev;
-       /* Initialize the vpbe display controller */
-       if (disp_dev->vpbe_dev->ops.initialize) {
-               err = disp_dev->vpbe_dev->ops.initialize(&pdev->dev,
-                                                        disp_dev->vpbe_dev);
-               if (err) {
-                       v4l2_err(v4l2_dev, "Error initing vpbe\n");
-                       err = -ENOMEM;
-                       goto probe_out;
-               }
-       }
-
-       for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
-               if (init_vpbe_layer(i, disp_dev, pdev)) {
-                       err = -ENODEV;
-                       goto probe_out;
-               }
-       }
-
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!res) {
-               v4l2_err(v4l2_dev, "Unable to get VENC interrupt resource\n");
-               err = -ENODEV;
-               goto probe_out;
-       }
-
-       irq = res->start;
-       err = devm_request_irq(&pdev->dev, irq, venc_isr, 0,
-                              VPBE_DISPLAY_DRIVER, disp_dev);
-       if (err) {
-               v4l2_err(v4l2_dev, "VPBE IRQ request failed\n");
-               goto probe_out;
-       }
-
-       for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
-               /* initialize vb2 queue */
-               q = &disp_dev->dev[i]->buffer_queue;
-               memset(q, 0, sizeof(*q));
-               q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-               q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
-               q->drv_priv = disp_dev->dev[i];
-               q->ops = &video_qops;
-               q->mem_ops = &vb2_dma_contig_memops;
-               q->buf_struct_size = sizeof(struct vpbe_disp_buffer);
-               q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-               q->min_buffers_needed = 1;
-               q->lock = &disp_dev->dev[i]->opslock;
-               q->dev = disp_dev->vpbe_dev->pdev;
-               err = vb2_queue_init(q);
-               if (err) {
-                       v4l2_err(v4l2_dev, "vb2_queue_init() failed\n");
-                       goto probe_out;
-               }
-
-               INIT_LIST_HEAD(&disp_dev->dev[i]->dma_queue);
-
-               if (register_device(disp_dev->dev[i], disp_dev, pdev)) {
-                       err = -ENODEV;
-                       goto probe_out;
-               }
-       }
-
-       v4l2_dbg(1, debug, v4l2_dev,
-                "Successfully completed the probing of vpbe v4l2 device\n");
-
-       return 0;
-
-probe_out:
-       for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) {
-               /* Unregister video device */
-               if (disp_dev->dev[k]) {
-                       video_unregister_device(&disp_dev->dev[k]->video_dev);
-                       kfree(disp_dev->dev[k]);
-               }
-       }
-       return err;
-}
-
-/*
- * vpbe_display_remove()
- * It un-register hardware layer from V4L2 driver
- */
-static int vpbe_display_remove(struct platform_device *pdev)
-{
-       struct vpbe_layer *vpbe_display_layer;
-       struct vpbe_display *disp_dev = platform_get_drvdata(pdev);
-       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
-       int i;
-
-       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_remove\n");
-
-       /* deinitialize the vpbe display controller */
-       if (vpbe_dev->ops.deinitialize)
-               vpbe_dev->ops.deinitialize(&pdev->dev, vpbe_dev);
-       /* un-register device */
-       for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
-               /* Get the pointer to the layer object */
-               vpbe_display_layer = disp_dev->dev[i];
-               /* Unregister video device */
-               video_unregister_device(&vpbe_display_layer->video_dev);
-
-       }
-       for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
-               kfree(disp_dev->dev[i]);
-               disp_dev->dev[i] = NULL;
-       }
-
-       return 0;
-}
-
-static struct platform_driver vpbe_display_driver = {
-       .driver = {
-               .name = VPBE_DISPLAY_DRIVER,
-               .bus = &platform_bus_type,
-       },
-       .probe = vpbe_display_probe,
-       .remove = vpbe_display_remove,
-};
-
-module_platform_driver(vpbe_display_driver);
-
-MODULE_DESCRIPTION("TI DM644x/DM355/DM365 VPBE Display controller");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Texas Instruments");
diff --git a/drivers/media/platform/davinci/vpbe_osd.c b/drivers/media/platform/davinci/vpbe_osd.c
deleted file mode 100644 (file)
index 32f7ef5..0000000
+++ /dev/null
@@ -1,1582 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2007-2010 Texas Instruments Inc
- * Copyright (C) 2007 MontaVista Software, Inc.
- *
- * Andy Lowe (alowe@mvista.com), MontaVista Software
- * - Initial version
- * Murali Karicheri (mkaricheri@gmail.com), Texas Instruments Ltd.
- * - ported to sub device interface
- */
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/slab.h>
-
-#include <media/davinci/vpss.h>
-#include <media/v4l2-device.h>
-#include <media/davinci/vpbe_types.h>
-#include <media/davinci/vpbe_osd.h>
-
-#include <linux/io.h>
-#include "vpbe_osd_regs.h"
-
-#define MODULE_NAME    "davinci-vpbe-osd"
-
-static const struct platform_device_id vpbe_osd_devtype[] = {
-       {
-               .name = DM644X_VPBE_OSD_SUBDEV_NAME,
-               .driver_data = VPBE_VERSION_1,
-       }, {
-               .name = DM365_VPBE_OSD_SUBDEV_NAME,
-               .driver_data = VPBE_VERSION_2,
-       }, {
-               .name = DM355_VPBE_OSD_SUBDEV_NAME,
-               .driver_data = VPBE_VERSION_3,
-       },
-       {
-               /* sentinel */
-       }
-};
-
-MODULE_DEVICE_TABLE(platform, vpbe_osd_devtype);
-
-/* register access routines */
-static inline u32 __always_unused osd_read(struct osd_state *sd, u32 offset)
-{
-       struct osd_state *osd = sd;
-
-       return readl(osd->osd_base + offset);
-}
-
-static inline u32 osd_write(struct osd_state *sd, u32 val, u32 offset)
-{
-       struct osd_state *osd = sd;
-
-       writel(val, osd->osd_base + offset);
-
-       return val;
-}
-
-static inline u32 osd_set(struct osd_state *sd, u32 mask, u32 offset)
-{
-       struct osd_state *osd = sd;
-
-       void __iomem *addr = osd->osd_base + offset;
-       u32 val = readl(addr) | mask;
-
-       writel(val, addr);
-
-       return val;
-}
-
-static inline u32 osd_clear(struct osd_state *sd, u32 mask, u32 offset)
-{
-       struct osd_state *osd = sd;
-
-       void __iomem *addr = osd->osd_base + offset;
-       u32 val = readl(addr) & ~mask;
-
-       writel(val, addr);
-
-       return val;
-}
-
-static inline u32 osd_modify(struct osd_state *sd, u32 mask, u32 val,
-                                u32 offset)
-{
-       struct osd_state *osd = sd;
-
-       void __iomem *addr = osd->osd_base + offset;
-       u32 new_val = (readl(addr) & ~mask) | (val & mask);
-
-       writel(new_val, addr);
-
-       return new_val;
-}
-
-/* define some macros for layer and pixfmt classification */
-#define is_osd_win(layer) (((layer) == WIN_OSD0) || ((layer) == WIN_OSD1))
-#define is_vid_win(layer) (((layer) == WIN_VID0) || ((layer) == WIN_VID1))
-#define is_rgb_pixfmt(pixfmt) \
-       (((pixfmt) == PIXFMT_RGB565) || ((pixfmt) == PIXFMT_RGB888))
-#define is_yc_pixfmt(pixfmt) \
-       (((pixfmt) == PIXFMT_YCBCRI) || ((pixfmt) == PIXFMT_YCRCBI) || \
-       ((pixfmt) == PIXFMT_NV12))
-#define MAX_WIN_SIZE OSD_VIDWIN0XP_V0X
-#define MAX_LINE_LENGTH (OSD_VIDWIN0OFST_V0LO << 5)
-
-/**
- * _osd_dm6446_vid0_pingpong() - field inversion fix for DM6446
- * @sd: ptr to struct osd_state
- * @field_inversion: inversion flag
- * @fb_base_phys: frame buffer address
- * @lconfig: ptr to layer config
- *
- * This routine implements a workaround for the field signal inversion silicon
- * erratum described in Advisory 1.3.8 for the DM6446.  The fb_base_phys and
- * lconfig parameters apply to the vid0 window.  This routine should be called
- * whenever the vid0 layer configuration or start address is modified, or when
- * the OSD field inversion setting is modified.
- * Returns: 1 if the ping-pong buffers need to be toggled in the vsync isr, or
- *          0 otherwise
- */
-static int _osd_dm6446_vid0_pingpong(struct osd_state *sd,
-                                    int field_inversion,
-                                    unsigned long fb_base_phys,
-                                    const struct osd_layer_config *lconfig)
-{
-       struct osd_platform_data *pdata;
-
-       pdata = (struct osd_platform_data *)sd->dev->platform_data;
-       if (pdata != NULL && pdata->field_inv_wa_enable) {
-
-               if (!field_inversion || !lconfig->interlaced) {
-                       osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR);
-                       osd_write(sd, fb_base_phys & ~0x1F, OSD_PPVWIN0ADR);
-                       osd_modify(sd, OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, 0,
-                                  OSD_MISCCTL);
-                       return 0;
-               } else {
-                       unsigned miscctl = OSD_MISCCTL_PPRV;
-
-                       osd_write(sd,
-                               (fb_base_phys & ~0x1F) - lconfig->line_length,
-                               OSD_VIDWIN0ADR);
-                       osd_write(sd,
-                               (fb_base_phys & ~0x1F) + lconfig->line_length,
-                               OSD_PPVWIN0ADR);
-                       osd_modify(sd,
-                               OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, miscctl,
-                               OSD_MISCCTL);
-
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-static void _osd_set_field_inversion(struct osd_state *sd, int enable)
-{
-       unsigned fsinv = 0;
-
-       if (enable)
-               fsinv = OSD_MODE_FSINV;
-
-       osd_modify(sd, OSD_MODE_FSINV, fsinv, OSD_MODE);
-}
-
-static void _osd_set_blink_attribute(struct osd_state *sd, int enable,
-                                    enum osd_blink_interval blink)
-{
-       u32 osdatrmd = 0;
-
-       if (enable) {
-               osdatrmd |= OSD_OSDATRMD_BLNK;
-               osdatrmd |= blink << OSD_OSDATRMD_BLNKINT_SHIFT;
-       }
-       /* caller must ensure that OSD1 is configured in attribute mode */
-       osd_modify(sd, OSD_OSDATRMD_BLNKINT | OSD_OSDATRMD_BLNK, osdatrmd,
-                 OSD_OSDATRMD);
-}
-
-static void _osd_set_rom_clut(struct osd_state *sd,
-                             enum osd_rom_clut rom_clut)
-{
-       if (rom_clut == ROM_CLUT0)
-               osd_clear(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL);
-       else
-               osd_set(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL);
-}
-
-static void _osd_set_palette_map(struct osd_state *sd,
-                                enum osd_win_layer osdwin,
-                                unsigned char pixel_value,
-                                unsigned char clut_index,
-                                enum osd_pix_format pixfmt)
-{
-       static const int map_2bpp[] = { 0, 5, 10, 15 };
-       static const int map_1bpp[] = { 0, 15 };
-       int bmp_offset;
-       int bmp_shift;
-       int bmp_mask;
-       int bmp_reg;
-
-       switch (pixfmt) {
-       case PIXFMT_1BPP:
-               bmp_reg = map_1bpp[pixel_value & 0x1];
-               break;
-       case PIXFMT_2BPP:
-               bmp_reg = map_2bpp[pixel_value & 0x3];
-               break;
-       case PIXFMT_4BPP:
-               bmp_reg = pixel_value & 0xf;
-               break;
-       default:
-               return;
-       }
-
-       switch (osdwin) {
-       case OSDWIN_OSD0:
-               bmp_offset = OSD_W0BMP01 + (bmp_reg >> 1) * sizeof(u32);
-               break;
-       case OSDWIN_OSD1:
-               bmp_offset = OSD_W1BMP01 + (bmp_reg >> 1) * sizeof(u32);
-               break;
-       default:
-               return;
-       }
-
-       if (bmp_reg & 1) {
-               bmp_shift = 8;
-               bmp_mask = 0xff << 8;
-       } else {
-               bmp_shift = 0;
-               bmp_mask = 0xff;
-       }
-
-       osd_modify(sd, bmp_mask, clut_index << bmp_shift, bmp_offset);
-}
-
-static void _osd_set_rec601_attenuation(struct osd_state *sd,
-                                       enum osd_win_layer osdwin, int enable)
-{
-       switch (osdwin) {
-       case OSDWIN_OSD0:
-               osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
-                         enable ? OSD_OSDWIN0MD_ATN0E : 0,
-                         OSD_OSDWIN0MD);
-               if (sd->vpbe_type == VPBE_VERSION_1)
-                       osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
-                                 enable ? OSD_OSDWIN0MD_ATN0E : 0,
-                                 OSD_OSDWIN0MD);
-               else if ((sd->vpbe_type == VPBE_VERSION_3) ||
-                          (sd->vpbe_type == VPBE_VERSION_2))
-                       osd_modify(sd, OSD_EXTMODE_ATNOSD0EN,
-                                 enable ? OSD_EXTMODE_ATNOSD0EN : 0,
-                                 OSD_EXTMODE);
-               break;
-       case OSDWIN_OSD1:
-               osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
-                         enable ? OSD_OSDWIN1MD_ATN1E : 0,
-                         OSD_OSDWIN1MD);
-               if (sd->vpbe_type == VPBE_VERSION_1)
-                       osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
-                                 enable ? OSD_OSDWIN1MD_ATN1E : 0,
-                                 OSD_OSDWIN1MD);
-               else if ((sd->vpbe_type == VPBE_VERSION_3) ||
-                          (sd->vpbe_type == VPBE_VERSION_2))
-                       osd_modify(sd, OSD_EXTMODE_ATNOSD1EN,
-                                 enable ? OSD_EXTMODE_ATNOSD1EN : 0,
-                                 OSD_EXTMODE);
-               break;
-       }
-}
-
-static void _osd_set_blending_factor(struct osd_state *sd,
-                                    enum osd_win_layer osdwin,
-                                    enum osd_blending_factor blend)
-{
-       switch (osdwin) {
-       case OSDWIN_OSD0:
-               osd_modify(sd, OSD_OSDWIN0MD_BLND0,
-                         blend << OSD_OSDWIN0MD_BLND0_SHIFT, OSD_OSDWIN0MD);
-               break;
-       case OSDWIN_OSD1:
-               osd_modify(sd, OSD_OSDWIN1MD_BLND1,
-                         blend << OSD_OSDWIN1MD_BLND1_SHIFT, OSD_OSDWIN1MD);
-               break;
-       }
-}
-
-static void _osd_enable_rgb888_pixblend(struct osd_state *sd,
-                                       enum osd_win_layer osdwin)
-{
-
-       osd_modify(sd, OSD_MISCCTL_BLDSEL, 0, OSD_MISCCTL);
-       switch (osdwin) {
-       case OSDWIN_OSD0:
-               osd_modify(sd, OSD_EXTMODE_OSD0BLDCHR,
-                         OSD_EXTMODE_OSD0BLDCHR, OSD_EXTMODE);
-               break;
-       case OSDWIN_OSD1:
-               osd_modify(sd, OSD_EXTMODE_OSD1BLDCHR,
-                         OSD_EXTMODE_OSD1BLDCHR, OSD_EXTMODE);
-               break;
-       }
-}
-
-static void _osd_enable_color_key(struct osd_state *sd,
-                                 enum osd_win_layer osdwin,
-                                 unsigned colorkey,
-                                 enum osd_pix_format pixfmt)
-{
-       switch (pixfmt) {
-       case PIXFMT_1BPP:
-       case PIXFMT_2BPP:
-       case PIXFMT_4BPP:
-       case PIXFMT_8BPP:
-               if (sd->vpbe_type == VPBE_VERSION_3) {
-                       switch (osdwin) {
-                       case OSDWIN_OSD0:
-                               osd_modify(sd, OSD_TRANSPBMPIDX_BMP0,
-                                         colorkey <<
-                                         OSD_TRANSPBMPIDX_BMP0_SHIFT,
-                                         OSD_TRANSPBMPIDX);
-                               break;
-                       case OSDWIN_OSD1:
-                               osd_modify(sd, OSD_TRANSPBMPIDX_BMP1,
-                                         colorkey <<
-                                         OSD_TRANSPBMPIDX_BMP1_SHIFT,
-                                         OSD_TRANSPBMPIDX);
-                               break;
-                       }
-               }
-               break;
-       case PIXFMT_RGB565:
-               if (sd->vpbe_type == VPBE_VERSION_1)
-                       osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS,
-                                 OSD_TRANSPVAL);
-               else if (sd->vpbe_type == VPBE_VERSION_3)
-                       osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
-                                 OSD_TRANSPVALL);
-               break;
-       case PIXFMT_YCBCRI:
-       case PIXFMT_YCRCBI:
-               if (sd->vpbe_type == VPBE_VERSION_3)
-                       osd_modify(sd, OSD_TRANSPVALU_Y, colorkey,
-                                  OSD_TRANSPVALU);
-               break;
-       case PIXFMT_RGB888:
-               if (sd->vpbe_type == VPBE_VERSION_3) {
-                       osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
-                                 OSD_TRANSPVALL);
-                       osd_modify(sd, OSD_TRANSPVALU_RGBU, colorkey >> 16,
-                                 OSD_TRANSPVALU);
-               }
-               break;
-       default:
-               break;
-       }
-
-       switch (osdwin) {
-       case OSDWIN_OSD0:
-               osd_set(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD);
-               break;
-       case OSDWIN_OSD1:
-               osd_set(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD);
-               break;
-       }
-}
-
-static void _osd_disable_color_key(struct osd_state *sd,
-                                  enum osd_win_layer osdwin)
-{
-       switch (osdwin) {
-       case OSDWIN_OSD0:
-               osd_clear(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD);
-               break;
-       case OSDWIN_OSD1:
-               osd_clear(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD);
-               break;
-       }
-}
-
-static void _osd_set_osd_clut(struct osd_state *sd,
-                             enum osd_win_layer osdwin,
-                             enum osd_clut clut)
-{
-       u32 winmd = 0;
-
-       switch (osdwin) {
-       case OSDWIN_OSD0:
-               if (clut == RAM_CLUT)
-                       winmd |= OSD_OSDWIN0MD_CLUTS0;
-               osd_modify(sd, OSD_OSDWIN0MD_CLUTS0, winmd, OSD_OSDWIN0MD);
-               break;
-       case OSDWIN_OSD1:
-               if (clut == RAM_CLUT)
-                       winmd |= OSD_OSDWIN1MD_CLUTS1;
-               osd_modify(sd, OSD_OSDWIN1MD_CLUTS1, winmd, OSD_OSDWIN1MD);
-               break;
-       }
-}
-
-static void _osd_set_zoom(struct osd_state *sd, enum osd_layer layer,
-                         enum osd_zoom_factor h_zoom,
-                         enum osd_zoom_factor v_zoom)
-{
-       u32 winmd = 0;
-
-       switch (layer) {
-       case WIN_OSD0:
-               winmd |= (h_zoom << OSD_OSDWIN0MD_OHZ0_SHIFT);
-               winmd |= (v_zoom << OSD_OSDWIN0MD_OVZ0_SHIFT);
-               osd_modify(sd, OSD_OSDWIN0MD_OHZ0 | OSD_OSDWIN0MD_OVZ0, winmd,
-                         OSD_OSDWIN0MD);
-               break;
-       case WIN_VID0:
-               winmd |= (h_zoom << OSD_VIDWINMD_VHZ0_SHIFT);
-               winmd |= (v_zoom << OSD_VIDWINMD_VVZ0_SHIFT);
-               osd_modify(sd, OSD_VIDWINMD_VHZ0 | OSD_VIDWINMD_VVZ0, winmd,
-                         OSD_VIDWINMD);
-               break;
-       case WIN_OSD1:
-               winmd |= (h_zoom << OSD_OSDWIN1MD_OHZ1_SHIFT);
-               winmd |= (v_zoom << OSD_OSDWIN1MD_OVZ1_SHIFT);
-               osd_modify(sd, OSD_OSDWIN1MD_OHZ1 | OSD_OSDWIN1MD_OVZ1, winmd,
-                         OSD_OSDWIN1MD);
-               break;
-       case WIN_VID1:
-               winmd |= (h_zoom << OSD_VIDWINMD_VHZ1_SHIFT);
-               winmd |= (v_zoom << OSD_VIDWINMD_VVZ1_SHIFT);
-               osd_modify(sd, OSD_VIDWINMD_VHZ1 | OSD_VIDWINMD_VVZ1, winmd,
-                         OSD_VIDWINMD);
-               break;
-       }
-}
-
-static void _osd_disable_layer(struct osd_state *sd, enum osd_layer layer)
-{
-       switch (layer) {
-       case WIN_OSD0:
-               osd_clear(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD);
-               break;
-       case WIN_VID0:
-               osd_clear(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD);
-               break;
-       case WIN_OSD1:
-               /* disable attribute mode as well as disabling the window */
-               osd_clear(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1,
-                         OSD_OSDWIN1MD);
-               break;
-       case WIN_VID1:
-               osd_clear(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD);
-               break;
-       }
-}
-
-static void osd_disable_layer(struct osd_state *sd, enum osd_layer layer)
-{
-       struct osd_state *osd = sd;
-       struct osd_window_state *win = &osd->win[layer];
-       unsigned long flags;
-
-       spin_lock_irqsave(&osd->lock, flags);
-
-       if (!win->is_enabled) {
-               spin_unlock_irqrestore(&osd->lock, flags);
-               return;
-       }
-       win->is_enabled = 0;
-
-       _osd_disable_layer(sd, layer);
-
-       spin_unlock_irqrestore(&osd->lock, flags);
-}
-
-static void _osd_enable_attribute_mode(struct osd_state *sd)
-{
-       /* enable attribute mode for OSD1 */
-       osd_set(sd, OSD_OSDWIN1MD_OASW, OSD_OSDWIN1MD);
-}
-
-static void _osd_enable_layer(struct osd_state *sd, enum osd_layer layer)
-{
-       switch (layer) {
-       case WIN_OSD0:
-               osd_set(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD);
-               break;
-       case WIN_VID0:
-               osd_set(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD);
-               break;
-       case WIN_OSD1:
-               /* enable OSD1 and disable attribute mode */
-               osd_modify(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1,
-                         OSD_OSDWIN1MD_OACT1, OSD_OSDWIN1MD);
-               break;
-       case WIN_VID1:
-               osd_set(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD);
-               break;
-       }
-}
-
-static int osd_enable_layer(struct osd_state *sd, enum osd_layer layer,
-                           int otherwin)
-{
-       struct osd_state *osd = sd;
-       struct osd_window_state *win = &osd->win[layer];
-       struct osd_layer_config *cfg = &win->lconfig;
-       unsigned long flags;
-
-       spin_lock_irqsave(&osd->lock, flags);
-
-       /*
-        * use otherwin flag to know this is the other vid window
-        * in YUV420 mode, if is, skip this check
-        */
-       if (!otherwin && (!win->is_allocated ||
-                       !win->fb_base_phys ||
-                       !cfg->line_length ||
-                       !cfg->xsize ||
-                       !cfg->ysize)) {
-               spin_unlock_irqrestore(&osd->lock, flags);
-               return -1;
-       }
-
-       if (win->is_enabled) {
-               spin_unlock_irqrestore(&osd->lock, flags);
-               return 0;
-       }
-       win->is_enabled = 1;
-
-       if (cfg->pixfmt != PIXFMT_OSD_ATTR)
-               _osd_enable_layer(sd, layer);
-       else {
-               _osd_enable_attribute_mode(sd);
-               _osd_set_blink_attribute(sd, osd->is_blinking, osd->blink);
-       }
-
-       spin_unlock_irqrestore(&osd->lock, flags);
-
-       return 0;
-}
-
-#define OSD_SRC_ADDR_HIGH4     0x7800000
-#define OSD_SRC_ADDR_HIGH7     0x7F0000
-#define OSD_SRCADD_OFSET_SFT   23
-#define OSD_SRCADD_ADD_SFT     16
-#define OSD_WINADL_MASK                0xFFFF
-#define OSD_WINOFST_MASK       0x1000
-#define VPBE_REG_BASE          0x80000000
-
-static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer,
-                            unsigned long fb_base_phys,
-                            unsigned long cbcr_ofst)
-{
-
-       if (sd->vpbe_type == VPBE_VERSION_1) {
-               switch (layer) {
-               case WIN_OSD0:
-                       osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR);
-                       break;
-               case WIN_VID0:
-                       osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR);
-                       break;
-               case WIN_OSD1:
-                       osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR);
-                       break;
-               case WIN_VID1:
-                       osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR);
-                       break;
-             }
-       } else if (sd->vpbe_type == VPBE_VERSION_3) {
-               unsigned long fb_offset_32 =
-                   (fb_base_phys - VPBE_REG_BASE) >> 5;
-
-               switch (layer) {
-               case WIN_OSD0:
-                       osd_modify(sd, OSD_OSDWINADH_O0AH,
-                                 fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
-                                                  OSD_OSDWINADH_O0AH_SHIFT),
-                                 OSD_OSDWINADH);
-                       osd_write(sd, fb_offset_32 & OSD_OSDWIN0ADL_O0AL,
-                                 OSD_OSDWIN0ADL);
-                       break;
-               case WIN_VID0:
-                       osd_modify(sd, OSD_VIDWINADH_V0AH,
-                                 fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
-                                                  OSD_VIDWINADH_V0AH_SHIFT),
-                                 OSD_VIDWINADH);
-                       osd_write(sd, fb_offset_32 & OSD_VIDWIN0ADL_V0AL,
-                                 OSD_VIDWIN0ADL);
-                       break;
-               case WIN_OSD1:
-                       osd_modify(sd, OSD_OSDWINADH_O1AH,
-                                 fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
-                                                  OSD_OSDWINADH_O1AH_SHIFT),
-                                 OSD_OSDWINADH);
-                       osd_write(sd, fb_offset_32 & OSD_OSDWIN1ADL_O1AL,
-                                 OSD_OSDWIN1ADL);
-                       break;
-               case WIN_VID1:
-                       osd_modify(sd, OSD_VIDWINADH_V1AH,
-                                 fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
-                                                  OSD_VIDWINADH_V1AH_SHIFT),
-                                 OSD_VIDWINADH);
-                       osd_write(sd, fb_offset_32 & OSD_VIDWIN1ADL_V1AL,
-                                 OSD_VIDWIN1ADL);
-                       break;
-               }
-       } else if (sd->vpbe_type == VPBE_VERSION_2) {
-               struct osd_window_state *win = &sd->win[layer];
-               unsigned long fb_offset_32, cbcr_offset_32;
-
-               fb_offset_32 = fb_base_phys - VPBE_REG_BASE;
-               if (cbcr_ofst)
-                       cbcr_offset_32 = cbcr_ofst;
-               else
-                       cbcr_offset_32 = win->lconfig.line_length *
-                                        win->lconfig.ysize;
-               cbcr_offset_32 += fb_offset_32;
-               fb_offset_32 = fb_offset_32 >> 5;
-               cbcr_offset_32 = cbcr_offset_32 >> 5;
-               /*
-                * DM365: start address is 27-bit long address b26 - b23 are
-                * in offset register b12 - b9, and * bit 26 has to be '1'
-                */
-               if (win->lconfig.pixfmt == PIXFMT_NV12) {
-                       switch (layer) {
-                       case WIN_VID0:
-                       case WIN_VID1:
-                               /* Y is in VID0 */
-                               osd_modify(sd, OSD_VIDWIN0OFST_V0AH,
-                                        ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
-                                        (OSD_SRCADD_OFSET_SFT -
-                                        OSD_WINOFST_AH_SHIFT)) |
-                                        OSD_WINOFST_MASK, OSD_VIDWIN0OFST);
-                               osd_modify(sd, OSD_VIDWINADH_V0AH,
-                                         (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
-                                         (OSD_SRCADD_ADD_SFT -
-                                         OSD_VIDWINADH_V0AH_SHIFT),
-                                          OSD_VIDWINADH);
-                               osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
-                                         OSD_VIDWIN0ADL);
-                               /* CbCr is in VID1 */
-                               osd_modify(sd, OSD_VIDWIN1OFST_V1AH,
-                                        ((cbcr_offset_32 &
-                                        OSD_SRC_ADDR_HIGH4) >>
-                                        (OSD_SRCADD_OFSET_SFT -
-                                        OSD_WINOFST_AH_SHIFT)) |
-                                        OSD_WINOFST_MASK, OSD_VIDWIN1OFST);
-                               osd_modify(sd, OSD_VIDWINADH_V1AH,
-                                         (cbcr_offset_32 &
-                                         OSD_SRC_ADDR_HIGH7) >>
-                                         (OSD_SRCADD_ADD_SFT -
-                                         OSD_VIDWINADH_V1AH_SHIFT),
-                                         OSD_VIDWINADH);
-                               osd_write(sd, cbcr_offset_32 & OSD_WINADL_MASK,
-                                         OSD_VIDWIN1ADL);
-                               break;
-                       default:
-                               break;
-                       }
-               }
-
-               switch (layer) {
-               case WIN_OSD0:
-                       osd_modify(sd, OSD_OSDWIN0OFST_O0AH,
-                                ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
-                                (OSD_SRCADD_OFSET_SFT -
-                                OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK,
-                                 OSD_OSDWIN0OFST);
-                       osd_modify(sd, OSD_OSDWINADH_O0AH,
-                                (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
-                                (OSD_SRCADD_ADD_SFT -
-                                OSD_OSDWINADH_O0AH_SHIFT), OSD_OSDWINADH);
-                       osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
-                                       OSD_OSDWIN0ADL);
-                       break;
-               case WIN_VID0:
-                       if (win->lconfig.pixfmt != PIXFMT_NV12) {
-                               osd_modify(sd, OSD_VIDWIN0OFST_V0AH,
-                                        ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
-                                        (OSD_SRCADD_OFSET_SFT -
-                                        OSD_WINOFST_AH_SHIFT)) |
-                                        OSD_WINOFST_MASK, OSD_VIDWIN0OFST);
-                               osd_modify(sd, OSD_VIDWINADH_V0AH,
-                                         (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
-                                         (OSD_SRCADD_ADD_SFT -
-                                         OSD_VIDWINADH_V0AH_SHIFT),
-                                         OSD_VIDWINADH);
-                               osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
-                                         OSD_VIDWIN0ADL);
-                       }
-                       break;
-               case WIN_OSD1:
-                       osd_modify(sd, OSD_OSDWIN1OFST_O1AH,
-                                ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
-                                (OSD_SRCADD_OFSET_SFT -
-                                OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK,
-                                 OSD_OSDWIN1OFST);
-                       osd_modify(sd, OSD_OSDWINADH_O1AH,
-                                 (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
-                                 (OSD_SRCADD_ADD_SFT -
-                                 OSD_OSDWINADH_O1AH_SHIFT),
-                                 OSD_OSDWINADH);
-                       osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
-                                       OSD_OSDWIN1ADL);
-                       break;
-               case WIN_VID1:
-                       if (win->lconfig.pixfmt != PIXFMT_NV12) {
-                               osd_modify(sd, OSD_VIDWIN1OFST_V1AH,
-                                        ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
-                                        (OSD_SRCADD_OFSET_SFT -
-                                        OSD_WINOFST_AH_SHIFT)) |
-                                        OSD_WINOFST_MASK, OSD_VIDWIN1OFST);
-                               osd_modify(sd, OSD_VIDWINADH_V1AH,
-                                         (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
-                                         (OSD_SRCADD_ADD_SFT -
-                                         OSD_VIDWINADH_V1AH_SHIFT),
-                                         OSD_VIDWINADH);
-                               osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
-                                         OSD_VIDWIN1ADL);
-                       }
-                       break;
-               }
-       }
-}
-
-static void osd_start_layer(struct osd_state *sd, enum osd_layer layer,
-                           unsigned long fb_base_phys,
-                           unsigned long cbcr_ofst)
-{
-       struct osd_state *osd = sd;
-       struct osd_window_state *win = &osd->win[layer];
-       struct osd_layer_config *cfg = &win->lconfig;
-       unsigned long flags;
-
-       spin_lock_irqsave(&osd->lock, flags);
-
-       win->fb_base_phys = fb_base_phys & ~0x1F;
-       _osd_start_layer(sd, layer, fb_base_phys, cbcr_ofst);
-
-       if (layer == WIN_VID0) {
-               osd->pingpong =
-                   _osd_dm6446_vid0_pingpong(sd, osd->field_inversion,
-                                                      win->fb_base_phys,
-                                                      cfg);
-       }
-
-       spin_unlock_irqrestore(&osd->lock, flags);
-}
-
-static void osd_get_layer_config(struct osd_state *sd, enum osd_layer layer,
-                                struct osd_layer_config *lconfig)
-{
-       struct osd_state *osd = sd;
-       struct osd_window_state *win = &osd->win[layer];
-       unsigned long flags;
-
-       spin_lock_irqsave(&osd->lock, flags);
-
-       *lconfig = win->lconfig;
-
-       spin_unlock_irqrestore(&osd->lock, flags);
-}
-
-/**
- * try_layer_config() - Try a specific configuration for the layer
- * @sd: ptr to struct osd_state
- * @layer: layer to configure
- * @lconfig: layer configuration to try
- *
- * If the requested lconfig is completely rejected and the value of lconfig on
- * exit is the current lconfig, then try_layer_config() returns 1.  Otherwise,
- * try_layer_config() returns 0.  A return value of 0 does not necessarily mean
- * that the value of lconfig on exit is identical to the value of lconfig on
- * entry, but merely that it represents a change from the current lconfig.
- */
-static int try_layer_config(struct osd_state *sd, enum osd_layer layer,
-                           struct osd_layer_config *lconfig)
-{
-       struct osd_state *osd = sd;
-       struct osd_window_state *win = &osd->win[layer];
-       int bad_config = 0;
-
-       /* verify that the pixel format is compatible with the layer */
-       switch (lconfig->pixfmt) {
-       case PIXFMT_1BPP:
-       case PIXFMT_2BPP:
-       case PIXFMT_4BPP:
-       case PIXFMT_8BPP:
-       case PIXFMT_RGB565:
-               if (osd->vpbe_type == VPBE_VERSION_1)
-                       bad_config = !is_vid_win(layer);
-               break;
-       case PIXFMT_YCBCRI:
-       case PIXFMT_YCRCBI:
-               bad_config = !is_vid_win(layer);
-               break;
-       case PIXFMT_RGB888:
-               if (osd->vpbe_type == VPBE_VERSION_1)
-                       bad_config = !is_vid_win(layer);
-               else if ((osd->vpbe_type == VPBE_VERSION_3) ||
-                        (osd->vpbe_type == VPBE_VERSION_2))
-                       bad_config = !is_osd_win(layer);
-               break;
-       case PIXFMT_NV12:
-               if (osd->vpbe_type != VPBE_VERSION_2)
-                       bad_config = 1;
-               else
-                       bad_config = is_osd_win(layer);
-               break;
-       case PIXFMT_OSD_ATTR:
-               bad_config = (layer != WIN_OSD1);
-               break;
-       default:
-               bad_config = 1;
-               break;
-       }
-       if (bad_config) {
-               /*
-                * The requested pixel format is incompatible with the layer,
-                * so keep the current layer configuration.
-                */
-               *lconfig = win->lconfig;
-               return bad_config;
-       }
-
-       /* DM6446: */
-       /* only one OSD window at a time can use RGB pixel formats */
-       if ((osd->vpbe_type == VPBE_VERSION_1) &&
-           is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) {
-               enum osd_pix_format pixfmt;
-
-               if (layer == WIN_OSD0)
-                       pixfmt = osd->win[WIN_OSD1].lconfig.pixfmt;
-               else
-                       pixfmt = osd->win[WIN_OSD0].lconfig.pixfmt;
-
-               if (is_rgb_pixfmt(pixfmt)) {
-                       /*
-                        * The other OSD window is already configured for an
-                        * RGB, so keep the current layer configuration.
-                        */
-                       *lconfig = win->lconfig;
-                       return 1;
-               }
-       }
-
-       /* DM6446: only one video window at a time can use RGB888 */
-       if ((osd->vpbe_type == VPBE_VERSION_1) && is_vid_win(layer) &&
-               lconfig->pixfmt == PIXFMT_RGB888) {
-               enum osd_pix_format pixfmt;
-
-               if (layer == WIN_VID0)
-                       pixfmt = osd->win[WIN_VID1].lconfig.pixfmt;
-               else
-                       pixfmt = osd->win[WIN_VID0].lconfig.pixfmt;
-
-               if (pixfmt == PIXFMT_RGB888) {
-                       /*
-                        * The other video window is already configured for
-                        * RGB888, so keep the current layer configuration.
-                        */
-                       *lconfig = win->lconfig;
-                       return 1;
-               }
-       }
-
-       /* window dimensions must be non-zero */
-       if (!lconfig->line_length || !lconfig->xsize || !lconfig->ysize) {
-               *lconfig = win->lconfig;
-               return 1;
-       }
-
-       /* round line_length up to a multiple of 32 */
-       lconfig->line_length = ((lconfig->line_length + 31) / 32) * 32;
-       lconfig->line_length =
-           min(lconfig->line_length, (unsigned)MAX_LINE_LENGTH);
-       lconfig->xsize = min(lconfig->xsize, (unsigned)MAX_WIN_SIZE);
-       lconfig->ysize = min(lconfig->ysize, (unsigned)MAX_WIN_SIZE);
-       lconfig->xpos = min(lconfig->xpos, (unsigned)MAX_WIN_SIZE);
-       lconfig->ypos = min(lconfig->ypos, (unsigned)MAX_WIN_SIZE);
-       lconfig->interlaced = (lconfig->interlaced != 0);
-       if (lconfig->interlaced) {
-               /* ysize and ypos must be even for interlaced displays */
-               lconfig->ysize &= ~1;
-               lconfig->ypos &= ~1;
-       }
-
-       return 0;
-}
-
-static void _osd_disable_vid_rgb888(struct osd_state *sd)
-{
-       /*
-        * The DM6446 supports RGB888 pixel format in a single video window.
-        * This routine disables RGB888 pixel format for both video windows.
-        * The caller must ensure that neither video window is currently
-        * configured for RGB888 pixel format.
-        */
-       if (sd->vpbe_type == VPBE_VERSION_1)
-               osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL);
-}
-
-static void _osd_enable_vid_rgb888(struct osd_state *sd,
-                                  enum osd_layer layer)
-{
-       /*
-        * The DM6446 supports RGB888 pixel format in a single video window.
-        * This routine enables RGB888 pixel format for the specified video
-        * window.  The caller must ensure that the other video window is not
-        * currently configured for RGB888 pixel format, as this routine will
-        * disable RGB888 pixel format for the other window.
-        */
-       if (sd->vpbe_type == VPBE_VERSION_1) {
-               if (layer == WIN_VID0)
-                       osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
-                                 OSD_MISCCTL_RGBEN, OSD_MISCCTL);
-               else if (layer == WIN_VID1)
-                       osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
-                                 OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
-                                 OSD_MISCCTL);
-       }
-}
-
-static void _osd_set_cbcr_order(struct osd_state *sd,
-                               enum osd_pix_format pixfmt)
-{
-       /*
-        * The caller must ensure that all windows using YC pixfmt use the same
-        * Cb/Cr order.
-        */
-       if (pixfmt == PIXFMT_YCBCRI)
-               osd_clear(sd, OSD_MODE_CS, OSD_MODE);
-       else if (pixfmt == PIXFMT_YCRCBI)
-               osd_set(sd, OSD_MODE_CS, OSD_MODE);
-}
-
-static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
-                                 const struct osd_layer_config *lconfig)
-{
-       u32 winmd = 0, winmd_mask = 0, bmw = 0;
-
-       _osd_set_cbcr_order(sd, lconfig->pixfmt);
-
-       switch (layer) {
-       case WIN_OSD0:
-               if (sd->vpbe_type == VPBE_VERSION_1) {
-                       winmd_mask |= OSD_OSDWIN0MD_RGB0E;
-                       if (lconfig->pixfmt == PIXFMT_RGB565)
-                               winmd |= OSD_OSDWIN0MD_RGB0E;
-               } else if ((sd->vpbe_type == VPBE_VERSION_3) ||
-                 (sd->vpbe_type == VPBE_VERSION_2)) {
-                       winmd_mask |= OSD_OSDWIN0MD_BMP0MD;
-                       switch (lconfig->pixfmt) {
-                       case PIXFMT_RGB565:
-                                       winmd |= (1 <<
-                                       OSD_OSDWIN0MD_BMP0MD_SHIFT);
-                                       break;
-                       case PIXFMT_RGB888:
-                               winmd |= (2 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
-                               _osd_enable_rgb888_pixblend(sd, OSDWIN_OSD0);
-                               break;
-                       case PIXFMT_YCBCRI:
-                       case PIXFMT_YCRCBI:
-                               winmd |= (3 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
-                               break;
-                       default:
-                               break;
-                       }
-               }
-
-               winmd_mask |= OSD_OSDWIN0MD_BMW0 | OSD_OSDWIN0MD_OFF0;
-
-               switch (lconfig->pixfmt) {
-               case PIXFMT_1BPP:
-                       bmw = 0;
-                       break;
-               case PIXFMT_2BPP:
-                       bmw = 1;
-                       break;
-               case PIXFMT_4BPP:
-                       bmw = 2;
-                       break;
-               case PIXFMT_8BPP:
-                       bmw = 3;
-                       break;
-               default:
-                       break;
-               }
-               winmd |= (bmw << OSD_OSDWIN0MD_BMW0_SHIFT);
-
-               if (lconfig->interlaced)
-                       winmd |= OSD_OSDWIN0MD_OFF0;
-
-               osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN0MD);
-               osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN0OFST);
-               osd_write(sd, lconfig->xpos, OSD_OSDWIN0XP);
-               osd_write(sd, lconfig->xsize, OSD_OSDWIN0XL);
-               if (lconfig->interlaced) {
-                       osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN0YP);
-                       osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN0YL);
-               } else {
-                       osd_write(sd, lconfig->ypos, OSD_OSDWIN0YP);
-                       osd_write(sd, lconfig->ysize, OSD_OSDWIN0YL);
-               }
-               break;
-       case WIN_VID0:
-               winmd_mask |= OSD_VIDWINMD_VFF0;
-               if (lconfig->interlaced)
-                       winmd |= OSD_VIDWINMD_VFF0;
-
-               osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD);
-               osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN0OFST);
-               osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP);
-               osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL);
-               /*
-                * For YUV420P format the register contents are
-                * duplicated in both VID registers
-                */
-               if ((sd->vpbe_type == VPBE_VERSION_2) &&
-                               (lconfig->pixfmt == PIXFMT_NV12)) {
-                       /* other window also */
-                       if (lconfig->interlaced) {
-                               winmd_mask |= OSD_VIDWINMD_VFF1;
-                               winmd |= OSD_VIDWINMD_VFF1;
-                               osd_modify(sd, winmd_mask, winmd,
-                                         OSD_VIDWINMD);
-                       }
-
-                       osd_modify(sd, OSD_MISCCTL_S420D,
-                                   OSD_MISCCTL_S420D, OSD_MISCCTL);
-                       osd_write(sd, lconfig->line_length >> 5,
-                                 OSD_VIDWIN1OFST);
-                       osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP);
-                       osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL);
-                       /*
-                         * if NV21 pixfmt and line length not 32B
-                         * aligned (e.g. NTSC), Need to set window
-                         * X pixel size to be 32B aligned as well
-                         */
-                       if (lconfig->xsize % 32) {
-                               osd_write(sd,
-                                         ((lconfig->xsize + 31) & ~31),
-                                         OSD_VIDWIN1XL);
-                               osd_write(sd,
-                                         ((lconfig->xsize + 31) & ~31),
-                                         OSD_VIDWIN0XL);
-                       }
-               } else if ((sd->vpbe_type == VPBE_VERSION_2) &&
-                               (lconfig->pixfmt != PIXFMT_NV12)) {
-                       osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D,
-                                               OSD_MISCCTL);
-               }
-
-               if (lconfig->interlaced) {
-                       osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN0YP);
-                       osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN0YL);
-                       if ((sd->vpbe_type == VPBE_VERSION_2) &&
-                               lconfig->pixfmt == PIXFMT_NV12) {
-                               osd_write(sd, lconfig->ypos >> 1,
-                                         OSD_VIDWIN1YP);
-                               osd_write(sd, lconfig->ysize >> 1,
-                                         OSD_VIDWIN1YL);
-                       }
-               } else {
-                       osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP);
-                       osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL);
-                       if ((sd->vpbe_type == VPBE_VERSION_2) &&
-                               lconfig->pixfmt == PIXFMT_NV12) {
-                               osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP);
-                               osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL);
-                       }
-               }
-               break;
-       case WIN_OSD1:
-               /*
-                * The caller must ensure that OSD1 is disabled prior to
-                * switching from a normal mode to attribute mode or from
-                * attribute mode to a normal mode.
-                */
-               if (lconfig->pixfmt == PIXFMT_OSD_ATTR) {
-                       if (sd->vpbe_type == VPBE_VERSION_1) {
-                               winmd_mask |= OSD_OSDWIN1MD_ATN1E |
-                               OSD_OSDWIN1MD_RGB1E | OSD_OSDWIN1MD_CLUTS1 |
-                               OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1;
-                       } else {
-                               winmd_mask |= OSD_OSDWIN1MD_BMP1MD |
-                               OSD_OSDWIN1MD_CLUTS1 | OSD_OSDWIN1MD_BLND1 |
-                               OSD_OSDWIN1MD_TE1;
-                       }
-               } else {
-                       if (sd->vpbe_type == VPBE_VERSION_1) {
-                               winmd_mask |= OSD_OSDWIN1MD_RGB1E;
-                               if (lconfig->pixfmt == PIXFMT_RGB565)
-                                       winmd |= OSD_OSDWIN1MD_RGB1E;
-                       } else if ((sd->vpbe_type == VPBE_VERSION_3)
-                                  || (sd->vpbe_type == VPBE_VERSION_2)) {
-                               winmd_mask |= OSD_OSDWIN1MD_BMP1MD;
-                               switch (lconfig->pixfmt) {
-                               case PIXFMT_RGB565:
-                                       winmd |=
-                                           (1 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
-                                       break;
-                               case PIXFMT_RGB888:
-                                       winmd |=
-                                           (2 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
-                                       _osd_enable_rgb888_pixblend(sd,
-                                                       OSDWIN_OSD1);
-                                       break;
-                               case PIXFMT_YCBCRI:
-                               case PIXFMT_YCRCBI:
-                                       winmd |=
-                                           (3 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-
-                       winmd_mask |= OSD_OSDWIN1MD_BMW1;
-                       switch (lconfig->pixfmt) {
-                       case PIXFMT_1BPP:
-                               bmw = 0;
-                               break;
-                       case PIXFMT_2BPP:
-                               bmw = 1;
-                               break;
-                       case PIXFMT_4BPP:
-                               bmw = 2;
-                               break;
-                       case PIXFMT_8BPP:
-                               bmw = 3;
-                               break;
-                       default:
-                               break;
-                       }
-                       winmd |= (bmw << OSD_OSDWIN1MD_BMW1_SHIFT);
-               }
-
-               winmd_mask |= OSD_OSDWIN1MD_OFF1;
-               if (lconfig->interlaced)
-                       winmd |= OSD_OSDWIN1MD_OFF1;
-
-               osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN1MD);
-               osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN1OFST);
-               osd_write(sd, lconfig->xpos, OSD_OSDWIN1XP);
-               osd_write(sd, lconfig->xsize, OSD_OSDWIN1XL);
-               if (lconfig->interlaced) {
-                       osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN1YP);
-                       osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN1YL);
-               } else {
-                       osd_write(sd, lconfig->ypos, OSD_OSDWIN1YP);
-                       osd_write(sd, lconfig->ysize, OSD_OSDWIN1YL);
-               }
-               break;
-       case WIN_VID1:
-               winmd_mask |= OSD_VIDWINMD_VFF1;
-               if (lconfig->interlaced)
-                       winmd |= OSD_VIDWINMD_VFF1;
-
-               osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD);
-               osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN1OFST);
-               osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP);
-               osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL);
-               /*
-                * For YUV420P format the register contents are
-                * duplicated in both VID registers
-                */
-               if (sd->vpbe_type == VPBE_VERSION_2) {
-                       if (lconfig->pixfmt == PIXFMT_NV12) {
-                               /* other window also */
-                               if (lconfig->interlaced) {
-                                       winmd_mask |= OSD_VIDWINMD_VFF0;
-                                       winmd |= OSD_VIDWINMD_VFF0;
-                                       osd_modify(sd, winmd_mask, winmd,
-                                                 OSD_VIDWINMD);
-                               }
-                               osd_modify(sd, OSD_MISCCTL_S420D,
-                                          OSD_MISCCTL_S420D, OSD_MISCCTL);
-                               osd_write(sd, lconfig->line_length >> 5,
-                                         OSD_VIDWIN0OFST);
-                               osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP);
-                               osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL);
-                       } else {
-                               osd_modify(sd, OSD_MISCCTL_S420D,
-                                          ~OSD_MISCCTL_S420D, OSD_MISCCTL);
-                       }
-               }
-
-               if (lconfig->interlaced) {
-                       osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN1YP);
-                       osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN1YL);
-                       if ((sd->vpbe_type == VPBE_VERSION_2) &&
-                               lconfig->pixfmt == PIXFMT_NV12) {
-                               osd_write(sd, lconfig->ypos >> 1,
-                                         OSD_VIDWIN0YP);
-                               osd_write(sd, lconfig->ysize >> 1,
-                                         OSD_VIDWIN0YL);
-                       }
-               } else {
-                       osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP);
-                       osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL);
-                       if ((sd->vpbe_type == VPBE_VERSION_2) &&
-                               lconfig->pixfmt == PIXFMT_NV12) {
-                               osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP);
-                               osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL);
-                       }
-               }
-               break;
-       }
-}
-
-static int osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
-                               struct osd_layer_config *lconfig)
-{
-       struct osd_state *osd = sd;
-       struct osd_window_state *win = &osd->win[layer];
-       struct osd_layer_config *cfg = &win->lconfig;
-       unsigned long flags;
-       int reject_config;
-
-       spin_lock_irqsave(&osd->lock, flags);
-
-       reject_config = try_layer_config(sd, layer, lconfig);
-       if (reject_config) {
-               spin_unlock_irqrestore(&osd->lock, flags);
-               return reject_config;
-       }
-
-       /* update the current Cb/Cr order */
-       if (is_yc_pixfmt(lconfig->pixfmt))
-               osd->yc_pixfmt = lconfig->pixfmt;
-
-       /*
-        * If we are switching OSD1 from normal mode to attribute mode or from
-        * attribute mode to normal mode, then we must disable the window.
-        */
-       if (layer == WIN_OSD1) {
-               if (((lconfig->pixfmt == PIXFMT_OSD_ATTR) &&
-                 (cfg->pixfmt != PIXFMT_OSD_ATTR)) ||
-                 ((lconfig->pixfmt != PIXFMT_OSD_ATTR) &&
-                 (cfg->pixfmt == PIXFMT_OSD_ATTR))) {
-                       win->is_enabled = 0;
-                       _osd_disable_layer(sd, layer);
-               }
-       }
-
-       _osd_set_layer_config(sd, layer, lconfig);
-
-       if (layer == WIN_OSD1) {
-               struct osd_osdwin_state *osdwin_state =
-                   &osd->osdwin[OSDWIN_OSD1];
-
-               if ((lconfig->pixfmt != PIXFMT_OSD_ATTR) &&
-                 (cfg->pixfmt == PIXFMT_OSD_ATTR)) {
-                       /*
-                        * We just switched OSD1 from attribute mode to normal
-                        * mode, so we must initialize the CLUT select, the
-                        * blend factor, transparency colorkey enable, and
-                        * attenuation enable (DM6446 only) bits in the
-                        * OSDWIN1MD register.
-                        */
-                       _osd_set_osd_clut(sd, OSDWIN_OSD1,
-                                                  osdwin_state->clut);
-                       _osd_set_blending_factor(sd, OSDWIN_OSD1,
-                                                         osdwin_state->blend);
-                       if (osdwin_state->colorkey_blending) {
-                               _osd_enable_color_key(sd, OSDWIN_OSD1,
-                                                              osdwin_state->
-                                                              colorkey,
-                                                              lconfig->pixfmt);
-                       } else
-                               _osd_disable_color_key(sd, OSDWIN_OSD1);
-                       _osd_set_rec601_attenuation(sd, OSDWIN_OSD1,
-                                                   osdwin_state->
-                                                   rec601_attenuation);
-               } else if ((lconfig->pixfmt == PIXFMT_OSD_ATTR) &&
-                 (cfg->pixfmt != PIXFMT_OSD_ATTR)) {
-                       /*
-                        * We just switched OSD1 from normal mode to attribute
-                        * mode, so we must initialize the blink enable and
-                        * blink interval bits in the OSDATRMD register.
-                        */
-                       _osd_set_blink_attribute(sd, osd->is_blinking,
-                                                         osd->blink);
-               }
-       }
-
-       /*
-        * If we just switched to a 1-, 2-, or 4-bits-per-pixel bitmap format
-        * then configure a default palette map.
-        */
-       if ((lconfig->pixfmt != cfg->pixfmt) &&
-         ((lconfig->pixfmt == PIXFMT_1BPP) ||
-         (lconfig->pixfmt == PIXFMT_2BPP) ||
-         (lconfig->pixfmt == PIXFMT_4BPP))) {
-               enum osd_win_layer osdwin =
-                   ((layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1);
-               struct osd_osdwin_state *osdwin_state =
-                   &osd->osdwin[osdwin];
-               unsigned char clut_index;
-               unsigned char clut_entries = 0;
-
-               switch (lconfig->pixfmt) {
-               case PIXFMT_1BPP:
-                       clut_entries = 2;
-                       break;
-               case PIXFMT_2BPP:
-                       clut_entries = 4;
-                       break;
-               case PIXFMT_4BPP:
-                       clut_entries = 16;
-                       break;
-               default:
-                       break;
-               }
-               /*
-                * The default palette map maps the pixel value to the clut
-                * index, i.e. pixel value 0 maps to clut entry 0, pixel value
-                * 1 maps to clut entry 1, etc.
-                */
-               for (clut_index = 0; clut_index < 16; clut_index++) {
-                       osdwin_state->palette_map[clut_index] = clut_index;
-                       if (clut_index < clut_entries) {
-                               _osd_set_palette_map(sd, osdwin, clut_index,
-                                                    clut_index,
-                                                    lconfig->pixfmt);
-                       }
-               }
-       }
-
-       *cfg = *lconfig;
-       /* DM6446: configure the RGB888 enable and window selection */
-       if (osd->win[WIN_VID0].lconfig.pixfmt == PIXFMT_RGB888)
-               _osd_enable_vid_rgb888(sd, WIN_VID0);
-       else if (osd->win[WIN_VID1].lconfig.pixfmt == PIXFMT_RGB888)
-               _osd_enable_vid_rgb888(sd, WIN_VID1);
-       else
-               _osd_disable_vid_rgb888(sd);
-
-       if (layer == WIN_VID0) {
-               osd->pingpong =
-                   _osd_dm6446_vid0_pingpong(sd, osd->field_inversion,
-                                                      win->fb_base_phys,
-                                                      cfg);
-       }
-
-       spin_unlock_irqrestore(&osd->lock, flags);
-
-       return 0;
-}
-
-static void osd_init_layer(struct osd_state *sd, enum osd_layer layer)
-{
-       struct osd_state *osd = sd;
-       struct osd_window_state *win = &osd->win[layer];
-       enum osd_win_layer osdwin;
-       struct osd_osdwin_state *osdwin_state;
-       struct osd_layer_config *cfg = &win->lconfig;
-       unsigned long flags;
-
-       spin_lock_irqsave(&osd->lock, flags);
-
-       win->is_enabled = 0;
-       _osd_disable_layer(sd, layer);
-
-       win->h_zoom = ZOOM_X1;
-       win->v_zoom = ZOOM_X1;
-       _osd_set_zoom(sd, layer, win->h_zoom, win->v_zoom);
-
-       win->fb_base_phys = 0;
-       _osd_start_layer(sd, layer, win->fb_base_phys, 0);
-
-       cfg->line_length = 0;
-       cfg->xsize = 0;
-       cfg->ysize = 0;
-       cfg->xpos = 0;
-       cfg->ypos = 0;
-       cfg->interlaced = 0;
-       switch (layer) {
-       case WIN_OSD0:
-       case WIN_OSD1:
-               osdwin = (layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1;
-               osdwin_state = &osd->osdwin[osdwin];
-               /*
-                * Other code relies on the fact that OSD windows default to a
-                * bitmap pixel format when they are deallocated, so don't
-                * change this default pixel format.
-                */
-               cfg->pixfmt = PIXFMT_8BPP;
-               _osd_set_layer_config(sd, layer, cfg);
-               osdwin_state->clut = RAM_CLUT;
-               _osd_set_osd_clut(sd, osdwin, osdwin_state->clut);
-               osdwin_state->colorkey_blending = 0;
-               _osd_disable_color_key(sd, osdwin);
-               osdwin_state->blend = OSD_8_VID_0;
-               _osd_set_blending_factor(sd, osdwin, osdwin_state->blend);
-               osdwin_state->rec601_attenuation = 0;
-               _osd_set_rec601_attenuation(sd, osdwin,
-                                                    osdwin_state->
-                                                    rec601_attenuation);
-               if (osdwin == OSDWIN_OSD1) {
-                       osd->is_blinking = 0;
-                       osd->blink = BLINK_X1;
-               }
-               break;
-       case WIN_VID0:
-       case WIN_VID1:
-               cfg->pixfmt = osd->yc_pixfmt;
-               _osd_set_layer_config(sd, layer, cfg);
-               break;
-       }
-
-       spin_unlock_irqrestore(&osd->lock, flags);
-}
-
-static void osd_release_layer(struct osd_state *sd, enum osd_layer layer)
-{
-       struct osd_state *osd = sd;
-       struct osd_window_state *win = &osd->win[layer];
-       unsigned long flags;
-
-       spin_lock_irqsave(&osd->lock, flags);
-
-       if (!win->is_allocated) {
-               spin_unlock_irqrestore(&osd->lock, flags);
-               return;
-       }
-
-       spin_unlock_irqrestore(&osd->lock, flags);
-       osd_init_layer(sd, layer);
-       spin_lock_irqsave(&osd->lock, flags);
-
-       win->is_allocated = 0;
-
-       spin_unlock_irqrestore(&osd->lock, flags);
-}
-
-static int osd_request_layer(struct osd_state *sd, enum osd_layer layer)
-{
-       struct osd_state *osd = sd;
-       struct osd_window_state *win = &osd->win[layer];
-       unsigned long flags;
-
-       spin_lock_irqsave(&osd->lock, flags);
-
-       if (win->is_allocated) {
-               spin_unlock_irqrestore(&osd->lock, flags);
-               return -1;
-       }
-       win->is_allocated = 1;
-
-       spin_unlock_irqrestore(&osd->lock, flags);
-
-       return 0;
-}
-
-static void _osd_init(struct osd_state *sd)
-{
-       osd_write(sd, 0, OSD_MODE);
-       osd_write(sd, 0, OSD_VIDWINMD);
-       osd_write(sd, 0, OSD_OSDWIN0MD);
-       osd_write(sd, 0, OSD_OSDWIN1MD);
-       osd_write(sd, 0, OSD_RECTCUR);
-       osd_write(sd, 0, OSD_MISCCTL);
-       if (sd->vpbe_type == VPBE_VERSION_3) {
-               osd_write(sd, 0, OSD_VBNDRY);
-               osd_write(sd, 0, OSD_EXTMODE);
-               osd_write(sd, OSD_MISCCTL_DMANG, OSD_MISCCTL);
-       }
-}
-
-static void osd_set_left_margin(struct osd_state *sd, u32 val)
-{
-       osd_write(sd, val, OSD_BASEPX);
-}
-
-static void osd_set_top_margin(struct osd_state *sd, u32 val)
-{
-       osd_write(sd, val, OSD_BASEPY);
-}
-
-static int osd_initialize(struct osd_state *osd)
-{
-       if (osd == NULL)
-               return -ENODEV;
-       _osd_init(osd);
-
-       /* set default Cb/Cr order */
-       osd->yc_pixfmt = PIXFMT_YCBCRI;
-
-       if (osd->vpbe_type == VPBE_VERSION_3) {
-               /*
-                * ROM CLUT1 on the DM355 is similar (identical?) to ROM CLUT0
-                * on the DM6446, so make ROM_CLUT1 the default on the DM355.
-                */
-               osd->rom_clut = ROM_CLUT1;
-       }
-
-       _osd_set_field_inversion(osd, osd->field_inversion);
-       _osd_set_rom_clut(osd, osd->rom_clut);
-
-       osd_init_layer(osd, WIN_OSD0);
-       osd_init_layer(osd, WIN_VID0);
-       osd_init_layer(osd, WIN_OSD1);
-       osd_init_layer(osd, WIN_VID1);
-
-       return 0;
-}
-
-static const struct vpbe_osd_ops osd_ops = {
-       .initialize = osd_initialize,
-       .request_layer = osd_request_layer,
-       .release_layer = osd_release_layer,
-       .enable_layer = osd_enable_layer,
-       .disable_layer = osd_disable_layer,
-       .set_layer_config = osd_set_layer_config,
-       .get_layer_config = osd_get_layer_config,
-       .start_layer = osd_start_layer,
-       .set_left_margin = osd_set_left_margin,
-       .set_top_margin = osd_set_top_margin,
-};
-
-static int osd_probe(struct platform_device *pdev)
-{
-       const struct platform_device_id *pdev_id;
-       struct osd_state *osd;
-       struct resource *res;
-
-       pdev_id = platform_get_device_id(pdev);
-       if (!pdev_id)
-               return -EINVAL;
-
-       osd = devm_kzalloc(&pdev->dev, sizeof(struct osd_state), GFP_KERNEL);
-       if (osd == NULL)
-               return -ENOMEM;
-
-
-       osd->dev = &pdev->dev;
-       osd->vpbe_type = pdev_id->driver_data;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       osd->osd_base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(osd->osd_base))
-               return PTR_ERR(osd->osd_base);
-
-       osd->osd_base_phys = res->start;
-       osd->osd_size = resource_size(res);
-       spin_lock_init(&osd->lock);
-       osd->ops = osd_ops;
-       platform_set_drvdata(pdev, osd);
-       dev_notice(osd->dev, "OSD sub device probe success\n");
-
-       return 0;
-}
-
-static int osd_remove(struct platform_device *pdev)
-{
-       return 0;
-}
-
-static struct platform_driver osd_driver = {
-       .probe          = osd_probe,
-       .remove         = osd_remove,
-       .driver         = {
-               .name   = MODULE_NAME,
-       },
-       .id_table       = vpbe_osd_devtype
-};
-
-module_platform_driver(osd_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("DaVinci OSD Manager Driver");
-MODULE_AUTHOR("Texas Instruments");
diff --git a/drivers/media/platform/davinci/vpbe_osd_regs.h b/drivers/media/platform/davinci/vpbe_osd_regs.h
deleted file mode 100644 (file)
index cecd599..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2006-2010 Texas Instruments Inc
- */
-#ifndef _VPBE_OSD_REGS_H
-#define _VPBE_OSD_REGS_H
-
-/* VPBE Global Registers */
-#define VPBE_PID                               0x0
-#define VPBE_PCR                               0x4
-
-/* VPSS CLock Registers */
-#define VPSSCLK_PID                            0x00
-#define VPSSCLK_CLKCTRL                                0x04
-
-/* VPSS Buffer Logic Registers */
-#define VPSSBL_PID                             0x00
-#define VPSSBL_PCR                             0x04
-#define VPSSBL_BCR                             0x08
-#define VPSSBL_INTSTAT                         0x0C
-#define VPSSBL_INTSEL                          0x10
-#define VPSSBL_EVTSEL                          0x14
-#define VPSSBL_MEMCTRL                         0x18
-#define VPSSBL_CCDCMUX                         0x1C
-
-/* DM365 ISP5 system configuration */
-#define ISP5_PID                               0x0
-#define ISP5_PCCR                              0x4
-#define ISP5_BCR                               0x8
-#define ISP5_INTSTAT                           0xC
-#define ISP5_INTSEL1                           0x10
-#define ISP5_INTSEL2                           0x14
-#define ISP5_INTSEL3                           0x18
-#define ISP5_EVTSEL                            0x1c
-#define ISP5_CCDCMUX                           0x20
-
-/* VPBE On-Screen Display Subsystem Registers (OSD) */
-#define OSD_MODE                               0x00
-#define OSD_VIDWINMD                           0x04
-#define OSD_OSDWIN0MD                          0x08
-#define OSD_OSDWIN1MD                          0x0C
-#define OSD_OSDATRMD                           0x0C
-#define OSD_RECTCUR                            0x10
-#define OSD_VIDWIN0OFST                                0x18
-#define OSD_VIDWIN1OFST                                0x1C
-#define OSD_OSDWIN0OFST                                0x20
-#define OSD_OSDWIN1OFST                                0x24
-#define OSD_VIDWINADH                          0x28
-#define OSD_VIDWIN0ADL                         0x2C
-#define OSD_VIDWIN0ADR                         0x2C
-#define OSD_VIDWIN1ADL                         0x30
-#define OSD_VIDWIN1ADR                         0x30
-#define OSD_OSDWINADH                          0x34
-#define OSD_OSDWIN0ADL                         0x38
-#define OSD_OSDWIN0ADR                         0x38
-#define OSD_OSDWIN1ADL                         0x3C
-#define OSD_OSDWIN1ADR                         0x3C
-#define OSD_BASEPX                             0x40
-#define OSD_BASEPY                             0x44
-#define OSD_VIDWIN0XP                          0x48
-#define OSD_VIDWIN0YP                          0x4C
-#define OSD_VIDWIN0XL                          0x50
-#define OSD_VIDWIN0YL                          0x54
-#define OSD_VIDWIN1XP                          0x58
-#define OSD_VIDWIN1YP                          0x5C
-#define OSD_VIDWIN1XL                          0x60
-#define OSD_VIDWIN1YL                          0x64
-#define OSD_OSDWIN0XP                          0x68
-#define OSD_OSDWIN0YP                          0x6C
-#define OSD_OSDWIN0XL                          0x70
-#define OSD_OSDWIN0YL                          0x74
-#define OSD_OSDWIN1XP                          0x78
-#define OSD_OSDWIN1YP                          0x7C
-#define OSD_OSDWIN1XL                          0x80
-#define OSD_OSDWIN1YL                          0x84
-#define OSD_CURXP                              0x88
-#define OSD_CURYP                              0x8C
-#define OSD_CURXL                              0x90
-#define OSD_CURYL                              0x94
-#define OSD_W0BMP01                            0xA0
-#define OSD_W0BMP23                            0xA4
-#define OSD_W0BMP45                            0xA8
-#define OSD_W0BMP67                            0xAC
-#define OSD_W0BMP89                            0xB0
-#define OSD_W0BMPAB                            0xB4
-#define OSD_W0BMPCD                            0xB8
-#define OSD_W0BMPEF                            0xBC
-#define OSD_W1BMP01                            0xC0
-#define OSD_W1BMP23                            0xC4
-#define OSD_W1BMP45                            0xC8
-#define OSD_W1BMP67                            0xCC
-#define OSD_W1BMP89                            0xD0
-#define OSD_W1BMPAB                            0xD4
-#define OSD_W1BMPCD                            0xD8
-#define OSD_W1BMPEF                            0xDC
-#define OSD_VBNDRY                             0xE0
-#define OSD_EXTMODE                            0xE4
-#define OSD_MISCCTL                            0xE8
-#define OSD_CLUTRAMYCB                         0xEC
-#define OSD_CLUTRAMCR                          0xF0
-#define OSD_TRANSPVAL                          0xF4
-#define OSD_TRANSPVALL                         0xF4
-#define OSD_TRANSPVALU                         0xF8
-#define OSD_TRANSPBMPIDX                       0xFC
-#define OSD_PPVWIN0ADR                         0xFC
-
-/* bit definitions */
-#define VPBE_PCR_VENC_DIV                      (1 << 1)
-#define VPBE_PCR_CLK_OFF                       (1 << 0)
-
-#define VPSSBL_INTSTAT_HSSIINT                 (1 << 14)
-#define VPSSBL_INTSTAT_CFALDINT                        (1 << 13)
-#define VPSSBL_INTSTAT_IPIPE_INT5              (1 << 12)
-#define VPSSBL_INTSTAT_IPIPE_INT4              (1 << 11)
-#define VPSSBL_INTSTAT_IPIPE_INT3              (1 << 10)
-#define VPSSBL_INTSTAT_IPIPE_INT2              (1 << 9)
-#define VPSSBL_INTSTAT_IPIPE_INT1              (1 << 8)
-#define VPSSBL_INTSTAT_IPIPE_INT0              (1 << 7)
-#define VPSSBL_INTSTAT_IPIPEIFINT              (1 << 6)
-#define VPSSBL_INTSTAT_OSDINT                  (1 << 5)
-#define VPSSBL_INTSTAT_VENCINT                 (1 << 4)
-#define VPSSBL_INTSTAT_H3AINT                  (1 << 3)
-#define VPSSBL_INTSTAT_CCDC_VDINT2             (1 << 2)
-#define VPSSBL_INTSTAT_CCDC_VDINT1             (1 << 1)
-#define VPSSBL_INTSTAT_CCDC_VDINT0             (1 << 0)
-
-/* DM365 ISP5 bit definitions */
-#define ISP5_INTSTAT_VENCINT                   (1 << 21)
-#define ISP5_INTSTAT_OSDINT                    (1 << 20)
-
-/* VMOD TVTYP options for HDMD=0 */
-#define SDTV_NTSC                              0
-#define SDTV_PAL                               1
-/* VMOD TVTYP options for HDMD=1 */
-#define HDTV_525P                              0
-#define HDTV_625P                              1
-#define HDTV_1080I                             2
-#define HDTV_720P                              3
-
-#define OSD_MODE_CS                            (1 << 15)
-#define OSD_MODE_OVRSZ                         (1 << 14)
-#define OSD_MODE_OHRSZ                         (1 << 13)
-#define OSD_MODE_EF                            (1 << 12)
-#define OSD_MODE_VVRSZ                         (1 << 11)
-#define OSD_MODE_VHRSZ                         (1 << 10)
-#define OSD_MODE_FSINV                         (1 << 9)
-#define OSD_MODE_BCLUT                         (1 << 8)
-#define OSD_MODE_CABG_SHIFT                    0
-#define OSD_MODE_CABG                          (0xff << 0)
-
-#define OSD_VIDWINMD_VFINV                     (1 << 15)
-#define OSD_VIDWINMD_V1EFC                     (1 << 14)
-#define OSD_VIDWINMD_VHZ1_SHIFT                        12
-#define OSD_VIDWINMD_VHZ1                      (3 << 12)
-#define OSD_VIDWINMD_VVZ1_SHIFT                        10
-#define OSD_VIDWINMD_VVZ1                      (3 << 10)
-#define OSD_VIDWINMD_VFF1                      (1 << 9)
-#define OSD_VIDWINMD_ACT1                      (1 << 8)
-#define OSD_VIDWINMD_V0EFC                     (1 << 6)
-#define OSD_VIDWINMD_VHZ0_SHIFT                        4
-#define OSD_VIDWINMD_VHZ0                      (3 << 4)
-#define OSD_VIDWINMD_VVZ0_SHIFT                        2
-#define OSD_VIDWINMD_VVZ0                      (3 << 2)
-#define OSD_VIDWINMD_VFF0                      (1 << 1)
-#define OSD_VIDWINMD_ACT0                      (1 << 0)
-
-#define OSD_OSDWIN0MD_ATN0E                    (1 << 14)
-#define OSD_OSDWIN0MD_RGB0E                    (1 << 13)
-#define OSD_OSDWIN0MD_BMP0MD_SHIFT             13
-#define OSD_OSDWIN0MD_BMP0MD                   (3 << 13)
-#define OSD_OSDWIN0MD_CLUTS0                   (1 << 12)
-#define OSD_OSDWIN0MD_OHZ0_SHIFT               10
-#define OSD_OSDWIN0MD_OHZ0                     (3 << 10)
-#define OSD_OSDWIN0MD_OVZ0_SHIFT               8
-#define OSD_OSDWIN0MD_OVZ0                     (3 << 8)
-#define OSD_OSDWIN0MD_BMW0_SHIFT               6
-#define OSD_OSDWIN0MD_BMW0                     (3 << 6)
-#define OSD_OSDWIN0MD_BLND0_SHIFT              3
-#define OSD_OSDWIN0MD_BLND0                    (7 << 3)
-#define OSD_OSDWIN0MD_TE0                      (1 << 2)
-#define OSD_OSDWIN0MD_OFF0                     (1 << 1)
-#define OSD_OSDWIN0MD_OACT0                    (1 << 0)
-
-#define OSD_OSDWIN1MD_OASW                     (1 << 15)
-#define OSD_OSDWIN1MD_ATN1E                    (1 << 14)
-#define OSD_OSDWIN1MD_RGB1E                    (1 << 13)
-#define OSD_OSDWIN1MD_BMP1MD_SHIFT             13
-#define OSD_OSDWIN1MD_BMP1MD                   (3 << 13)
-#define OSD_OSDWIN1MD_CLUTS1                   (1 << 12)
-#define OSD_OSDWIN1MD_OHZ1_SHIFT               10
-#define OSD_OSDWIN1MD_OHZ1                     (3 << 10)
-#define OSD_OSDWIN1MD_OVZ1_SHIFT               8
-#define OSD_OSDWIN1MD_OVZ1                     (3 << 8)
-#define OSD_OSDWIN1MD_BMW1_SHIFT               6
-#define OSD_OSDWIN1MD_BMW1                     (3 << 6)
-#define OSD_OSDWIN1MD_BLND1_SHIFT              3
-#define OSD_OSDWIN1MD_BLND1                    (7 << 3)
-#define OSD_OSDWIN1MD_TE1                      (1 << 2)
-#define OSD_OSDWIN1MD_OFF1                     (1 << 1)
-#define OSD_OSDWIN1MD_OACT1                    (1 << 0)
-
-#define OSD_OSDATRMD_OASW                      (1 << 15)
-#define OSD_OSDATRMD_OHZA_SHIFT                        10
-#define OSD_OSDATRMD_OHZA                      (3 << 10)
-#define OSD_OSDATRMD_OVZA_SHIFT                        8
-#define OSD_OSDATRMD_OVZA                      (3 << 8)
-#define OSD_OSDATRMD_BLNKINT_SHIFT             6
-#define OSD_OSDATRMD_BLNKINT                   (3 << 6)
-#define OSD_OSDATRMD_OFFA                      (1 << 1)
-#define OSD_OSDATRMD_BLNK                      (1 << 0)
-
-#define OSD_RECTCUR_RCAD_SHIFT                 8
-#define OSD_RECTCUR_RCAD                       (0xff << 8)
-#define OSD_RECTCUR_CLUTSR                     (1 << 7)
-#define OSD_RECTCUR_RCHW_SHIFT                 4
-#define OSD_RECTCUR_RCHW                       (7 << 4)
-#define OSD_RECTCUR_RCVW_SHIFT                 1
-#define OSD_RECTCUR_RCVW                       (7 << 1)
-#define OSD_RECTCUR_RCACT                      (1 << 0)
-
-#define OSD_VIDWIN0OFST_V0LO                   (0x1ff << 0)
-
-#define OSD_VIDWIN1OFST_V1LO                   (0x1ff << 0)
-
-#define OSD_OSDWIN0OFST_O0LO                   (0x1ff << 0)
-
-#define OSD_OSDWIN1OFST_O1LO                   (0x1ff << 0)
-
-#define OSD_WINOFST_AH_SHIFT                   9
-
-#define OSD_VIDWIN0OFST_V0AH                   (0xf << 9)
-#define OSD_VIDWIN1OFST_V1AH                   (0xf << 9)
-#define OSD_OSDWIN0OFST_O0AH                   (0xf << 9)
-#define OSD_OSDWIN1OFST_O1AH                   (0xf << 9)
-
-#define OSD_VIDWINADH_V1AH_SHIFT               8
-#define OSD_VIDWINADH_V1AH                     (0x7f << 8)
-#define OSD_VIDWINADH_V0AH_SHIFT               0
-#define OSD_VIDWINADH_V0AH                     (0x7f << 0)
-
-#define OSD_VIDWIN0ADL_V0AL                    (0xffff << 0)
-
-#define OSD_VIDWIN1ADL_V1AL                    (0xffff << 0)
-
-#define OSD_OSDWINADH_O1AH_SHIFT               8
-#define OSD_OSDWINADH_O1AH                     (0x7f << 8)
-#define OSD_OSDWINADH_O0AH_SHIFT               0
-#define OSD_OSDWINADH_O0AH                     (0x7f << 0)
-
-#define OSD_OSDWIN0ADL_O0AL                    (0xffff << 0)
-
-#define OSD_OSDWIN1ADL_O1AL                    (0xffff << 0)
-
-#define OSD_BASEPX_BPX                         (0x3ff << 0)
-
-#define OSD_BASEPY_BPY                         (0x1ff << 0)
-
-#define OSD_VIDWIN0XP_V0X                      (0x7ff << 0)
-
-#define OSD_VIDWIN0YP_V0Y                      (0x7ff << 0)
-
-#define OSD_VIDWIN0XL_V0W                      (0x7ff << 0)
-
-#define OSD_VIDWIN0YL_V0H                      (0x7ff << 0)
-
-#define OSD_VIDWIN1XP_V1X                      (0x7ff << 0)
-
-#define OSD_VIDWIN1YP_V1Y                      (0x7ff << 0)
-
-#define OSD_VIDWIN1XL_V1W                      (0x7ff << 0)
-
-#define OSD_VIDWIN1YL_V1H                      (0x7ff << 0)
-
-#define OSD_OSDWIN0XP_W0X                      (0x7ff << 0)
-
-#define OSD_OSDWIN0YP_W0Y                      (0x7ff << 0)
-
-#define OSD_OSDWIN0XL_W0W                      (0x7ff << 0)
-
-#define OSD_OSDWIN0YL_W0H                      (0x7ff << 0)
-
-#define OSD_OSDWIN1XP_W1X                      (0x7ff << 0)
-
-#define OSD_OSDWIN1YP_W1Y                      (0x7ff << 0)
-
-#define OSD_OSDWIN1XL_W1W                      (0x7ff << 0)
-
-#define OSD_OSDWIN1YL_W1H                      (0x7ff << 0)
-
-#define OSD_CURXP_RCSX                         (0x7ff << 0)
-
-#define OSD_CURYP_RCSY                         (0x7ff << 0)
-
-#define OSD_CURXL_RCSW                         (0x7ff << 0)
-
-#define OSD_CURYL_RCSH                         (0x7ff << 0)
-
-#define OSD_EXTMODE_EXPMDSEL                   (1 << 15)
-#define OSD_EXTMODE_SCRNHEXP_SHIFT             13
-#define OSD_EXTMODE_SCRNHEXP                   (3 << 13)
-#define OSD_EXTMODE_SCRNVEXP                   (1 << 12)
-#define OSD_EXTMODE_OSD1BLDCHR                 (1 << 11)
-#define OSD_EXTMODE_OSD0BLDCHR                 (1 << 10)
-#define OSD_EXTMODE_ATNOSD1EN                  (1 << 9)
-#define OSD_EXTMODE_ATNOSD0EN                  (1 << 8)
-#define OSD_EXTMODE_OSDHRSZ15                  (1 << 7)
-#define OSD_EXTMODE_VIDHRSZ15                  (1 << 6)
-#define OSD_EXTMODE_ZMFILV1HEN                 (1 << 5)
-#define OSD_EXTMODE_ZMFILV1VEN                 (1 << 4)
-#define OSD_EXTMODE_ZMFILV0HEN                 (1 << 3)
-#define OSD_EXTMODE_ZMFILV0VEN                 (1 << 2)
-#define OSD_EXTMODE_EXPFILHEN                  (1 << 1)
-#define OSD_EXTMODE_EXPFILVEN                  (1 << 0)
-
-#define OSD_MISCCTL_BLDSEL                     (1 << 15)
-#define OSD_MISCCTL_S420D                      (1 << 14)
-#define OSD_MISCCTL_BMAPT                      (1 << 13)
-#define OSD_MISCCTL_DM365M                     (1 << 12)
-#define OSD_MISCCTL_RGBEN                      (1 << 7)
-#define OSD_MISCCTL_RGBWIN                     (1 << 6)
-#define OSD_MISCCTL_DMANG                      (1 << 6)
-#define OSD_MISCCTL_TMON                       (1 << 5)
-#define OSD_MISCCTL_RSEL                       (1 << 4)
-#define OSD_MISCCTL_CPBSY                      (1 << 3)
-#define OSD_MISCCTL_PPSW                       (1 << 2)
-#define OSD_MISCCTL_PPRV                       (1 << 1)
-
-#define OSD_CLUTRAMYCB_Y_SHIFT                 8
-#define OSD_CLUTRAMYCB_Y                       (0xff << 8)
-#define OSD_CLUTRAMYCB_CB_SHIFT                        0
-#define OSD_CLUTRAMYCB_CB                      (0xff << 0)
-
-#define OSD_CLUTRAMCR_CR_SHIFT                 8
-#define OSD_CLUTRAMCR_CR                       (0xff << 8)
-#define OSD_CLUTRAMCR_CADDR_SHIFT              0
-#define OSD_CLUTRAMCR_CADDR                    (0xff << 0)
-
-#define OSD_TRANSPVAL_RGBTRANS                 (0xffff << 0)
-
-#define OSD_TRANSPVALL_RGBL                    (0xffff << 0)
-
-#define OSD_TRANSPVALU_Y_SHIFT                 8
-#define OSD_TRANSPVALU_Y                       (0xff << 8)
-#define OSD_TRANSPVALU_RGBU_SHIFT              0
-#define OSD_TRANSPVALU_RGBU                    (0xff << 0)
-
-#define OSD_TRANSPBMPIDX_BMP1_SHIFT            8
-#define OSD_TRANSPBMPIDX_BMP1                  (0xff << 8)
-#define OSD_TRANSPBMPIDX_BMP0_SHIFT            0
-#define OSD_TRANSPBMPIDX_BMP0                  0xff
-
-#endif                         /* _DAVINCI_VPBE_H_ */
diff --git a/drivers/media/platform/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c
deleted file mode 100644 (file)
index 4c8e31d..0000000
+++ /dev/null
@@ -1,676 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2010 Texas Instruments Inc
- */
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ctype.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-
-#include <linux/platform_data/i2c-davinci.h>
-
-#include <linux/io.h>
-
-#include <media/davinci/vpbe_types.h>
-#include <media/davinci/vpbe_venc.h>
-#include <media/davinci/vpss.h>
-#include <media/v4l2-device.h>
-
-#include "vpbe_venc_regs.h"
-
-#define MODULE_NAME    "davinci-vpbe-venc"
-
-static const struct platform_device_id vpbe_venc_devtype[] = {
-       {
-               .name = DM644X_VPBE_VENC_SUBDEV_NAME,
-               .driver_data = VPBE_VERSION_1,
-       }, {
-               .name = DM365_VPBE_VENC_SUBDEV_NAME,
-               .driver_data = VPBE_VERSION_2,
-       }, {
-               .name = DM355_VPBE_VENC_SUBDEV_NAME,
-               .driver_data = VPBE_VERSION_3,
-       },
-       {
-               /* sentinel */
-       }
-};
-
-MODULE_DEVICE_TABLE(platform, vpbe_venc_devtype);
-
-static int debug = 2;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level 0-2");
-
-struct venc_state {
-       struct v4l2_subdev sd;
-       struct venc_callback *callback;
-       struct venc_platform_data *pdata;
-       struct device *pdev;
-       u32 output;
-       v4l2_std_id std;
-       spinlock_t lock;
-       void __iomem *venc_base;
-       void __iomem *vdaccfg_reg;
-       enum vpbe_version venc_type;
-};
-
-static inline struct venc_state *to_state(struct v4l2_subdev *sd)
-{
-       return container_of(sd, struct venc_state, sd);
-}
-
-static inline u32 venc_read(struct v4l2_subdev *sd, u32 offset)
-{
-       struct venc_state *venc = to_state(sd);
-
-       return readl(venc->venc_base + offset);
-}
-
-static inline u32 venc_write(struct v4l2_subdev *sd, u32 offset, u32 val)
-{
-       struct venc_state *venc = to_state(sd);
-
-       writel(val, (venc->venc_base + offset));
-
-       return val;
-}
-
-static inline u32 venc_modify(struct v4l2_subdev *sd, u32 offset,
-                                u32 val, u32 mask)
-{
-       u32 new_val = (venc_read(sd, offset) & ~mask) | (val & mask);
-
-       venc_write(sd, offset, new_val);
-
-       return new_val;
-}
-
-static inline u32 vdaccfg_write(struct v4l2_subdev *sd, u32 val)
-{
-       struct venc_state *venc = to_state(sd);
-
-       writel(val, venc->vdaccfg_reg);
-
-       val = readl(venc->vdaccfg_reg);
-
-       return val;
-}
-
-#define VDAC_COMPONENT 0x543
-#define VDAC_S_VIDEO   0x210
-/* This function sets the dac of the VPBE for various outputs
- */
-static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index)
-{
-       switch (out_index) {
-       case 0:
-               v4l2_dbg(debug, 1, sd, "Setting output to Composite\n");
-               venc_write(sd, VENC_DACSEL, 0);
-               break;
-       case 1:
-               v4l2_dbg(debug, 1, sd, "Setting output to Component\n");
-               venc_write(sd, VENC_DACSEL, VDAC_COMPONENT);
-               break;
-       case 2:
-               v4l2_dbg(debug, 1, sd, "Setting output to S-video\n");
-               venc_write(sd, VENC_DACSEL, VDAC_S_VIDEO);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable)
-{
-       struct venc_state *venc = to_state(sd);
-
-       v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n");
-
-       if (benable) {
-               venc_write(sd, VENC_VMOD, 0);
-               venc_write(sd, VENC_CVBS, 0);
-               venc_write(sd, VENC_LCDOUT, 0);
-               venc_write(sd, VENC_HSPLS, 0);
-               venc_write(sd, VENC_HSTART, 0);
-               venc_write(sd, VENC_HVALID, 0);
-               venc_write(sd, VENC_HINT, 0);
-               venc_write(sd, VENC_VSPLS, 0);
-               venc_write(sd, VENC_VSTART, 0);
-               venc_write(sd, VENC_VVALID, 0);
-               venc_write(sd, VENC_VINT, 0);
-               venc_write(sd, VENC_YCCCTL, 0);
-               venc_write(sd, VENC_DACSEL, 0);
-
-       } else {
-               venc_write(sd, VENC_VMOD, 0);
-               /* disable VCLK output pin enable */
-               venc_write(sd, VENC_VIDCTL, 0x141);
-
-               /* Disable output sync pins */
-               venc_write(sd, VENC_SYNCCTL, 0);
-
-               /* Disable DCLOCK */
-               venc_write(sd, VENC_DCLKCTL, 0);
-               venc_write(sd, VENC_DRGBX1, 0x0000057C);
-
-               /* Disable LCD output control (accepting default polarity) */
-               venc_write(sd, VENC_LCDOUT, 0);
-               if (venc->venc_type != VPBE_VERSION_3)
-                       venc_write(sd, VENC_CMPNT, 0x100);
-               venc_write(sd, VENC_HSPLS, 0);
-               venc_write(sd, VENC_HINT, 0);
-               venc_write(sd, VENC_HSTART, 0);
-               venc_write(sd, VENC_HVALID, 0);
-
-               venc_write(sd, VENC_VSPLS, 0);
-               venc_write(sd, VENC_VINT, 0);
-               venc_write(sd, VENC_VSTART, 0);
-               venc_write(sd, VENC_VVALID, 0);
-
-               venc_write(sd, VENC_HSDLY, 0);
-               venc_write(sd, VENC_VSDLY, 0);
-
-               venc_write(sd, VENC_YCCCTL, 0);
-               venc_write(sd, VENC_VSTARTA, 0);
-
-               /* Set OSD clock and OSD Sync Adavance registers */
-               venc_write(sd, VENC_OSDCLK0, 1);
-               venc_write(sd, VENC_OSDCLK1, 2);
-       }
-}
-
-static void
-venc_enable_vpss_clock(int venc_type,
-                      enum vpbe_enc_timings_type type,
-                      unsigned int pclock)
-{
-       if (venc_type == VPBE_VERSION_1)
-               return;
-
-       if (venc_type == VPBE_VERSION_2 && (type == VPBE_ENC_STD || (type ==
-           VPBE_ENC_DV_TIMINGS && pclock <= 27000000))) {
-               vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
-               vpss_enable_clock(VPSS_VPBE_CLOCK, 1);
-               return;
-       }
-
-       if (venc_type == VPBE_VERSION_3 && type == VPBE_ENC_STD)
-               vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 0);
-}
-
-#define VDAC_CONFIG_SD_V3      0x0E21A6B6
-#define VDAC_CONFIG_SD_V2      0x081141CF
-/*
- * setting NTSC mode
- */
-static int venc_set_ntsc(struct v4l2_subdev *sd)
-{
-       struct venc_state *venc = to_state(sd);
-       struct venc_platform_data *pdata = venc->pdata;
-
-       v4l2_dbg(debug, 2, sd, "venc_set_ntsc\n");
-
-       /* Setup clock at VPSS & VENC for SD */
-       vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
-       if (pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_525_60) < 0)
-               return -EINVAL;
-
-       venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_STD, V4L2_STD_525_60);
-       venc_enabledigitaloutput(sd, 0);
-
-       if (venc->venc_type == VPBE_VERSION_3) {
-               venc_write(sd, VENC_CLKCTL, 0x01);
-               venc_write(sd, VENC_VIDCTL, 0);
-               vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
-       } else if (venc->venc_type == VPBE_VERSION_2) {
-               venc_write(sd, VENC_CLKCTL, 0x01);
-               venc_write(sd, VENC_VIDCTL, 0);
-               vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
-       } else {
-               /* to set VENC CLK DIV to 1 - final clock is 54 MHz */
-               venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
-               /* Set REC656 Mode */
-               venc_write(sd, VENC_YCCCTL, 0x1);
-               venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ);
-               venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS);
-       }
-
-       venc_write(sd, VENC_VMOD, 0);
-       venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
-                       VENC_VMOD_VIE);
-       venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
-       venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_TVTYP_SHIFT),
-                       VENC_VMOD_TVTYP);
-       venc_write(sd, VENC_DACTST, 0x0);
-       venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
-
-       return 0;
-}
-
-/*
- * setting PAL mode
- */
-static int venc_set_pal(struct v4l2_subdev *sd)
-{
-       struct venc_state *venc = to_state(sd);
-
-       v4l2_dbg(debug, 2, sd, "venc_set_pal\n");
-
-       /* Setup clock at VPSS & VENC for SD */
-       vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
-       if (venc->pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_625_50) < 0)
-               return -EINVAL;
-
-       venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_STD, V4L2_STD_625_50);
-       venc_enabledigitaloutput(sd, 0);
-
-       if (venc->venc_type == VPBE_VERSION_3) {
-               venc_write(sd, VENC_CLKCTL, 0x1);
-               venc_write(sd, VENC_VIDCTL, 0);
-               vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
-       } else if (venc->venc_type == VPBE_VERSION_2) {
-               venc_write(sd, VENC_CLKCTL, 0x1);
-               venc_write(sd, VENC_VIDCTL, 0);
-               vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
-       } else {
-               /* to set VENC CLK DIV to 1 - final clock is 54 MHz */
-               venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
-               /* Set REC656 Mode */
-               venc_write(sd, VENC_YCCCTL, 0x1);
-       }
-
-       venc_modify(sd, VENC_SYNCCTL, 1 << VENC_SYNCCTL_OVD_SHIFT,
-                       VENC_SYNCCTL_OVD);
-       venc_write(sd, VENC_VMOD, 0);
-       venc_modify(sd, VENC_VMOD,
-                       (1 << VENC_VMOD_VIE_SHIFT),
-                       VENC_VMOD_VIE);
-       venc_modify(sd, VENC_VMOD,
-                       (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
-       venc_modify(sd, VENC_VMOD,
-                       (1 << VENC_VMOD_TVTYP_SHIFT),
-                       VENC_VMOD_TVTYP);
-       venc_write(sd, VENC_DACTST, 0x0);
-       venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
-
-       return 0;
-}
-
-#define VDAC_CONFIG_HD_V2      0x081141EF
-/*
- * venc_set_480p59_94
- *
- * This function configures the video encoder to EDTV(525p) component setting.
- */
-static int venc_set_480p59_94(struct v4l2_subdev *sd)
-{
-       struct venc_state *venc = to_state(sd);
-       struct venc_platform_data *pdata = venc->pdata;
-
-       v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n");
-       if (venc->venc_type != VPBE_VERSION_1 &&
-           venc->venc_type != VPBE_VERSION_2)
-               return -EINVAL;
-
-       /* Setup clock at VPSS & VENC for SD */
-       if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 27000000) < 0)
-               return -EINVAL;
-
-       venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 27000000);
-       venc_enabledigitaloutput(sd, 0);
-
-       if (venc->venc_type == VPBE_VERSION_2)
-               vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
-       venc_write(sd, VENC_OSDCLK0, 0);
-       venc_write(sd, VENC_OSDCLK1, 1);
-
-       if (venc->venc_type == VPBE_VERSION_1) {
-               venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
-                           VENC_VDPRO_DAFRQ);
-               venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
-                           VENC_VDPRO_DAUPS);
-       }
-
-       venc_write(sd, VENC_VMOD, 0);
-       venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
-                   VENC_VMOD_VIE);
-       venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
-       venc_modify(sd, VENC_VMOD, (HDTV_525P << VENC_VMOD_TVTYP_SHIFT),
-                   VENC_VMOD_TVTYP);
-       venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
-                   VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
-
-       venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
-
-       return 0;
-}
-
-/*
- * venc_set_625p
- *
- * This function configures the video encoder to HDTV(625p) component setting
- */
-static int venc_set_576p50(struct v4l2_subdev *sd)
-{
-       struct venc_state *venc = to_state(sd);
-       struct venc_platform_data *pdata = venc->pdata;
-
-       v4l2_dbg(debug, 2, sd, "venc_set_576p50\n");
-
-       if (venc->venc_type != VPBE_VERSION_1 &&
-           venc->venc_type != VPBE_VERSION_2)
-               return -EINVAL;
-       /* Setup clock at VPSS & VENC for SD */
-       if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 27000000) < 0)
-               return -EINVAL;
-
-       venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 27000000);
-       venc_enabledigitaloutput(sd, 0);
-
-       if (venc->venc_type == VPBE_VERSION_2)
-               vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
-
-       venc_write(sd, VENC_OSDCLK0, 0);
-       venc_write(sd, VENC_OSDCLK1, 1);
-
-       if (venc->venc_type == VPBE_VERSION_1) {
-               venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
-                           VENC_VDPRO_DAFRQ);
-               venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
-                           VENC_VDPRO_DAUPS);
-       }
-
-       venc_write(sd, VENC_VMOD, 0);
-       venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
-                   VENC_VMOD_VIE);
-       venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
-       venc_modify(sd, VENC_VMOD, (HDTV_625P << VENC_VMOD_TVTYP_SHIFT),
-                   VENC_VMOD_TVTYP);
-
-       venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
-                   VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
-       venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
-
-       return 0;
-}
-
-/*
- * venc_set_720p60_internal - Setup 720p60 in venc for dm365 only
- */
-static int venc_set_720p60_internal(struct v4l2_subdev *sd)
-{
-       struct venc_state *venc = to_state(sd);
-       struct venc_platform_data *pdata = venc->pdata;
-
-       if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 74250000) < 0)
-               return -EINVAL;
-
-       venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 74250000);
-       venc_enabledigitaloutput(sd, 0);
-
-       venc_write(sd, VENC_OSDCLK0, 0);
-       venc_write(sd, VENC_OSDCLK1, 1);
-
-       venc_write(sd, VENC_VMOD, 0);
-       /* DM365 component HD mode */
-       venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
-           VENC_VMOD_VIE);
-       venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
-       venc_modify(sd, VENC_VMOD, (HDTV_720P << VENC_VMOD_TVTYP_SHIFT),
-                   VENC_VMOD_TVTYP);
-       venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
-       venc_write(sd, VENC_XHINTVL, 0);
-       return 0;
-}
-
-/*
- * venc_set_1080i30_internal - Setup 1080i30 in venc for dm365 only
- */
-static int venc_set_1080i30_internal(struct v4l2_subdev *sd)
-{
-       struct venc_state *venc = to_state(sd);
-       struct venc_platform_data *pdata = venc->pdata;
-
-       if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 74250000) < 0)
-               return -EINVAL;
-
-       venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 74250000);
-       venc_enabledigitaloutput(sd, 0);
-
-       venc_write(sd, VENC_OSDCLK0, 0);
-       venc_write(sd, VENC_OSDCLK1, 1);
-
-
-       venc_write(sd, VENC_VMOD, 0);
-       /* DM365 component HD mode */
-       venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
-                   VENC_VMOD_VIE);
-       venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
-       venc_modify(sd, VENC_VMOD, (HDTV_1080I << VENC_VMOD_TVTYP_SHIFT),
-                   VENC_VMOD_TVTYP);
-       venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
-       venc_write(sd, VENC_XHINTVL, 0);
-       return 0;
-}
-
-static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
-       v4l2_dbg(debug, 1, sd, "venc_s_std_output\n");
-
-       if (norm & V4L2_STD_525_60)
-               return venc_set_ntsc(sd);
-       else if (norm & V4L2_STD_625_50)
-               return venc_set_pal(sd);
-
-       return -EINVAL;
-}
-
-static int venc_s_dv_timings(struct v4l2_subdev *sd,
-                           struct v4l2_dv_timings *dv_timings)
-{
-       struct venc_state *venc = to_state(sd);
-       u32 height = dv_timings->bt.height;
-       int ret;
-
-       v4l2_dbg(debug, 1, sd, "venc_s_dv_timings\n");
-
-       if (height == 576)
-               return venc_set_576p50(sd);
-       else if (height == 480)
-               return venc_set_480p59_94(sd);
-       else if ((height == 720) &&
-                       (venc->venc_type == VPBE_VERSION_2)) {
-               /* TBD setup internal 720p mode here */
-               ret = venc_set_720p60_internal(sd);
-               /* for DM365 VPBE, there is DAC inside */
-               vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
-               return ret;
-       } else if ((height == 1080) &&
-               (venc->venc_type == VPBE_VERSION_2)) {
-               /* TBD setup internal 1080i mode here */
-               ret = venc_set_1080i30_internal(sd);
-               /* for DM365 VPBE, there is DAC inside */
-               vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
-               return ret;
-       }
-       return -EINVAL;
-}
-
-static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
-                         u32 config)
-{
-       struct venc_state *venc = to_state(sd);
-       int ret;
-
-       v4l2_dbg(debug, 1, sd, "venc_s_routing\n");
-
-       ret = venc_set_dac(sd, output);
-       if (!ret)
-               venc->output = output;
-
-       return ret;
-}
-
-static long venc_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-       u32 val;
-
-       switch (cmd) {
-       case VENC_GET_FLD:
-               val = venc_read(sd, VENC_VSTAT);
-               *((int *)arg) = ((val & VENC_VSTAT_FIDST) ==
-               VENC_VSTAT_FIDST);
-               break;
-       default:
-               v4l2_err(sd, "Wrong IOCTL cmd\n");
-               break;
-       }
-
-       return 0;
-}
-
-static const struct v4l2_subdev_core_ops venc_core_ops = {
-       .command      = venc_command,
-};
-
-static const struct v4l2_subdev_video_ops venc_video_ops = {
-       .s_routing = venc_s_routing,
-       .s_std_output = venc_s_std_output,
-       .s_dv_timings = venc_s_dv_timings,
-};
-
-static const struct v4l2_subdev_ops venc_ops = {
-       .core = &venc_core_ops,
-       .video = &venc_video_ops,
-};
-
-static int venc_initialize(struct v4l2_subdev *sd)
-{
-       struct venc_state *venc = to_state(sd);
-       int ret;
-
-       /* Set default to output to composite and std to NTSC */
-       venc->output = 0;
-       venc->std = V4L2_STD_525_60;
-
-       ret = venc_s_routing(sd, 0, venc->output, 0);
-       if (ret < 0) {
-               v4l2_err(sd, "Error setting output during init\n");
-               return -EINVAL;
-       }
-
-       ret = venc_s_std_output(sd, venc->std);
-       if (ret < 0) {
-               v4l2_err(sd, "Error setting std during init\n");
-               return -EINVAL;
-       }
-
-       return ret;
-}
-
-static int venc_device_get(struct device *dev, void *data)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct venc_state **venc = data;
-
-       if (strstr(pdev->name, "vpbe-venc") != NULL)
-               *venc = platform_get_drvdata(pdev);
-
-       return 0;
-}
-
-struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
-               const char *venc_name)
-{
-       struct venc_state *venc = NULL;
-
-       bus_for_each_dev(&platform_bus_type, NULL, &venc,
-                       venc_device_get);
-       if (venc == NULL)
-               return NULL;
-
-       v4l2_subdev_init(&venc->sd, &venc_ops);
-
-       strscpy(venc->sd.name, venc_name, sizeof(venc->sd.name));
-       if (v4l2_device_register_subdev(v4l2_dev, &venc->sd) < 0) {
-               v4l2_err(v4l2_dev,
-                       "vpbe unable to register venc sub device\n");
-               return NULL;
-       }
-       if (venc_initialize(&venc->sd)) {
-               v4l2_err(v4l2_dev,
-                       "vpbe venc initialization failed\n");
-               return NULL;
-       }
-
-       return &venc->sd;
-}
-EXPORT_SYMBOL(venc_sub_dev_init);
-
-static int venc_probe(struct platform_device *pdev)
-{
-       const struct platform_device_id *pdev_id;
-       struct venc_state *venc;
-
-       if (!pdev->dev.platform_data) {
-               dev_err(&pdev->dev, "No platform data for VENC sub device");
-               return -EINVAL;
-       }
-
-       pdev_id = platform_get_device_id(pdev);
-       if (!pdev_id)
-               return -EINVAL;
-
-       venc = devm_kzalloc(&pdev->dev, sizeof(struct venc_state), GFP_KERNEL);
-       if (venc == NULL)
-               return -ENOMEM;
-
-       venc->venc_type = pdev_id->driver_data;
-       venc->pdev = &pdev->dev;
-       venc->pdata = pdev->dev.platform_data;
-
-       venc->venc_base = devm_platform_ioremap_resource(pdev, 0);
-       if (IS_ERR(venc->venc_base))
-               return PTR_ERR(venc->venc_base);
-
-       if (venc->venc_type != VPBE_VERSION_1) {
-               venc->vdaccfg_reg = devm_platform_ioremap_resource(pdev, 1);
-               if (IS_ERR(venc->vdaccfg_reg))
-                       return PTR_ERR(venc->vdaccfg_reg);
-       }
-       spin_lock_init(&venc->lock);
-       platform_set_drvdata(pdev, venc);
-       dev_notice(venc->pdev, "VENC sub device probe success\n");
-
-       return 0;
-}
-
-static int venc_remove(struct platform_device *pdev)
-{
-       return 0;
-}
-
-static struct platform_driver venc_driver = {
-       .probe          = venc_probe,
-       .remove         = venc_remove,
-       .driver         = {
-               .name   = MODULE_NAME,
-       },
-       .id_table       = vpbe_venc_devtype
-};
-
-module_platform_driver(venc_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("VPBE VENC Driver");
-MODULE_AUTHOR("Texas Instruments");
diff --git a/drivers/media/platform/davinci/vpbe_venc_regs.h b/drivers/media/platform/davinci/vpbe_venc_regs.h
deleted file mode 100644 (file)
index 29d8fc3..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2006-2010 Texas Instruments Inc
- */
-#ifndef _VPBE_VENC_REGS_H
-#define _VPBE_VENC_REGS_H
-
-/* VPBE Video Encoder / Digital LCD Subsystem Registers (VENC) */
-#define VENC_VMOD                              0x00
-#define VENC_VIDCTL                            0x04
-#define VENC_VDPRO                             0x08
-#define VENC_SYNCCTL                           0x0C
-#define VENC_HSPLS                             0x10
-#define VENC_VSPLS                             0x14
-#define VENC_HINT                              0x18
-#define VENC_HSTART                            0x1C
-#define VENC_HVALID                            0x20
-#define VENC_VINT                              0x24
-#define VENC_VSTART                            0x28
-#define VENC_VVALID                            0x2C
-#define VENC_HSDLY                             0x30
-#define VENC_VSDLY                             0x34
-#define VENC_YCCCTL                            0x38
-#define VENC_RGBCTL                            0x3C
-#define VENC_RGBCLP                            0x40
-#define VENC_LINECTL                           0x44
-#define VENC_CULLLINE                          0x48
-#define VENC_LCDOUT                            0x4C
-#define VENC_BRTS                              0x50
-#define VENC_BRTW                              0x54
-#define VENC_ACCTL                             0x58
-#define VENC_PWMP                              0x5C
-#define VENC_PWMW                              0x60
-#define VENC_DCLKCTL                           0x64
-#define VENC_DCLKPTN0                          0x68
-#define VENC_DCLKPTN1                          0x6C
-#define VENC_DCLKPTN2                          0x70
-#define VENC_DCLKPTN3                          0x74
-#define VENC_DCLKPTN0A                         0x78
-#define VENC_DCLKPTN1A                         0x7C
-#define VENC_DCLKPTN2A                         0x80
-#define VENC_DCLKPTN3A                         0x84
-#define VENC_DCLKHS                            0x88
-#define VENC_DCLKHSA                           0x8C
-#define VENC_DCLKHR                            0x90
-#define VENC_DCLKVS                            0x94
-#define VENC_DCLKVR                            0x98
-#define VENC_CAPCTL                            0x9C
-#define VENC_CAPDO                             0xA0
-#define VENC_CAPDE                             0xA4
-#define VENC_ATR0                              0xA8
-#define VENC_ATR1                              0xAC
-#define VENC_ATR2                              0xB0
-#define VENC_VSTAT                             0xB8
-#define VENC_RAMADR                            0xBC
-#define VENC_RAMPORT                           0xC0
-#define VENC_DACTST                            0xC4
-#define VENC_YCOLVL                            0xC8
-#define VENC_SCPROG                            0xCC
-#define VENC_CVBS                              0xDC
-#define VENC_CMPNT                             0xE0
-#define VENC_ETMG0                             0xE4
-#define VENC_ETMG1                             0xE8
-#define VENC_ETMG2                             0xEC
-#define VENC_ETMG3                             0xF0
-#define VENC_DACSEL                            0xF4
-#define VENC_ARGBX0                            0x100
-#define VENC_ARGBX1                            0x104
-#define VENC_ARGBX2                            0x108
-#define VENC_ARGBX3                            0x10C
-#define VENC_ARGBX4                            0x110
-#define VENC_DRGBX0                            0x114
-#define VENC_DRGBX1                            0x118
-#define VENC_DRGBX2                            0x11C
-#define VENC_DRGBX3                            0x120
-#define VENC_DRGBX4                            0x124
-#define VENC_VSTARTA                           0x128
-#define VENC_OSDCLK0                           0x12C
-#define VENC_OSDCLK1                           0x130
-#define VENC_HVLDCL0                           0x134
-#define VENC_HVLDCL1                           0x138
-#define VENC_OSDHADV                           0x13C
-#define VENC_CLKCTL                            0x140
-#define VENC_GAMCTL                            0x144
-#define VENC_XHINTVL                           0x174
-
-/* bit definitions */
-#define VPBE_PCR_VENC_DIV                      (1 << 1)
-#define VPBE_PCR_CLK_OFF                       (1 << 0)
-
-#define VENC_VMOD_VDMD_SHIFT                   12
-#define VENC_VMOD_VDMD_YCBCR16                 0
-#define VENC_VMOD_VDMD_YCBCR8                  1
-#define VENC_VMOD_VDMD_RGB666                  2
-#define VENC_VMOD_VDMD_RGB8                    3
-#define VENC_VMOD_VDMD_EPSON                   4
-#define VENC_VMOD_VDMD_CASIO                   5
-#define VENC_VMOD_VDMD_UDISPQVGA               6
-#define VENC_VMOD_VDMD_STNLCD                  7
-#define VENC_VMOD_VIE_SHIFT                    1
-#define VENC_VMOD_VDMD                         (7 << 12)
-#define VENC_VMOD_ITLCL                                (1 << 11)
-#define VENC_VMOD_ITLC                         (1 << 10)
-#define VENC_VMOD_NSIT                         (1 << 9)
-#define VENC_VMOD_HDMD                         (1 << 8)
-#define VENC_VMOD_TVTYP_SHIFT                  6
-#define VENC_VMOD_TVTYP                                (3 << 6)
-#define VENC_VMOD_SLAVE                                (1 << 5)
-#define VENC_VMOD_VMD                          (1 << 4)
-#define VENC_VMOD_BLNK                         (1 << 3)
-#define VENC_VMOD_VIE                          (1 << 1)
-#define VENC_VMOD_VENC                         (1 << 0)
-
-/* VMOD TVTYP options for HDMD=0 */
-#define SDTV_NTSC                              0
-#define SDTV_PAL                               1
-/* VMOD TVTYP options for HDMD=1 */
-#define HDTV_525P                              0
-#define HDTV_625P                              1
-#define HDTV_1080I                             2
-#define HDTV_720P                              3
-
-#define VENC_VIDCTL_VCLKP                      (1 << 14)
-#define VENC_VIDCTL_VCLKE_SHIFT                        13
-#define VENC_VIDCTL_VCLKE                      (1 << 13)
-#define VENC_VIDCTL_VCLKZ_SHIFT                        12
-#define VENC_VIDCTL_VCLKZ                      (1 << 12)
-#define VENC_VIDCTL_SYDIR_SHIFT                        8
-#define VENC_VIDCTL_SYDIR                      (1 << 8)
-#define VENC_VIDCTL_DOMD_SHIFT                 4
-#define VENC_VIDCTL_DOMD                       (3 << 4)
-#define VENC_VIDCTL_YCDIR_SHIFT                        0
-#define VENC_VIDCTL_YCDIR                      (1 << 0)
-
-#define VENC_VDPRO_ATYCC_SHIFT                 5
-#define VENC_VDPRO_ATYCC                       (1 << 5)
-#define VENC_VDPRO_ATCOM_SHIFT                 4
-#define VENC_VDPRO_ATCOM                       (1 << 4)
-#define VENC_VDPRO_DAFRQ                       (1 << 3)
-#define VENC_VDPRO_DAUPS                       (1 << 2)
-#define VENC_VDPRO_CUPS                                (1 << 1)
-#define VENC_VDPRO_YUPS                                (1 << 0)
-
-#define VENC_SYNCCTL_VPL_SHIFT                 3
-#define VENC_SYNCCTL_VPL                       (1 << 3)
-#define VENC_SYNCCTL_HPL_SHIFT                 2
-#define VENC_SYNCCTL_HPL                       (1 << 2)
-#define VENC_SYNCCTL_SYEV_SHIFT                        1
-#define VENC_SYNCCTL_SYEV                      (1 << 1)
-#define VENC_SYNCCTL_SYEH_SHIFT                        0
-#define VENC_SYNCCTL_SYEH                      (1 << 0)
-#define VENC_SYNCCTL_OVD_SHIFT                 14
-#define VENC_SYNCCTL_OVD                       (1 << 14)
-
-#define VENC_DCLKCTL_DCKEC_SHIFT               11
-#define VENC_DCLKCTL_DCKEC                     (1 << 11)
-#define VENC_DCLKCTL_DCKPW_SHIFT               0
-#define VENC_DCLKCTL_DCKPW                     (0x3f << 0)
-
-#define VENC_VSTAT_FIDST                       (1 << 4)
-
-#define VENC_CMPNT_MRGB_SHIFT                  14
-#define VENC_CMPNT_MRGB                                (1 << 14)
-
-#endif                         /* _VPBE_VENC_REGS_H */
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
deleted file mode 100644 (file)
index 0a2226b..0000000
+++ /dev/null
@@ -1,1902 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2008-2009 Texas Instruments Inc
- *
- * Driver name : VPFE Capture driver
- *    VPFE Capture driver allows applications to capture and stream video
- *    frames on DaVinci SoCs (DM6446, DM355 etc) from a YUV source such as
- *    TVP5146 or  Raw Bayer RGB image data from an image sensor
- *    such as Microns' MT9T001, MT9T031 etc.
- *
- *    These SoCs have, in common, a Video Processing Subsystem (VPSS) that
- *    consists of a Video Processing Front End (VPFE) for capturing
- *    video/raw image data and Video Processing Back End (VPBE) for displaying
- *    YUV data through an in-built analog encoder or Digital LCD port. This
- *    driver is for capture through VPFE. A typical EVM using these SoCs have
- *    following high level configuration.
- *
- *    decoder(TVP5146/         YUV/
- *          MT9T001)   -->  Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
- *                             data input              |      |
- *                                                     V      |
- *                                                   SDRAM    |
- *                                                            V
- *                                                        Image Processor
- *                                                            |
- *                                                            V
- *                                                          SDRAM
- *    The data flow happens from a decoder connected to the VPFE over a
- *    YUV embedded (BT.656/BT.1120) or separate sync or raw bayer rgb interface
- *    and to the input of VPFE through an optional MUX (if more inputs are
- *    to be interfaced on the EVM). The input data is first passed through
- *    CCDC (CCD Controller, a.k.a Image Sensor Interface, ISIF). The CCDC
- *    does very little or no processing on YUV data and does pre-process Raw
- *    Bayer RGB data through modules such as Defect Pixel Correction (DFC)
- *    Color Space Conversion (CSC), data gain/offset etc. After this, data
- *    can be written to SDRAM or can be connected to the image processing
- *    block such as IPIPE (on DM355 only).
- *
- *    Features supported
- *             - MMAP IO
- *             - Capture using TVP5146 over BT.656
- *             - support for interfacing decoders using sub device model
- *             - Work with DM355 or DM6446 CCDC to do Raw Bayer RGB/YUV
- *               data capture to SDRAM.
- *    TODO list
- *             - Support multiple REQBUF after open
- *             - Support for de-allocating buffers through REQBUF
- *             - Support for Raw Bayer RGB capture
- *             - Support for chaining Image Processor
- *             - Support for static allocation of buffers
- *             - Support for USERPTR IO
- *             - Support for STREAMON before QBUF
- *             - Support for control ioctls
- */
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <media/v4l2-common.h>
-#include <linux/io.h>
-#include <media/davinci/vpfe_capture.h>
-#include "ccdc_hw_device.h"
-
-static int debug;
-static u32 numbuffers = 3;
-static u32 bufsize = (720 * 576 * 2);
-
-module_param(numbuffers, uint, S_IRUGO);
-module_param(bufsize, uint, S_IRUGO);
-module_param(debug, int, 0644);
-
-MODULE_PARM_DESC(numbuffers, "buffer count (default:3)");
-MODULE_PARM_DESC(bufsize, "buffer size in bytes (default:720 x 576 x 2)");
-MODULE_PARM_DESC(debug, "Debug level 0-1");
-
-MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Texas Instruments");
-
-/* standard information */
-struct vpfe_standard {
-       v4l2_std_id std_id;
-       unsigned int width;
-       unsigned int height;
-       struct v4l2_fract pixelaspect;
-       /* 0 - progressive, 1 - interlaced */
-       int frame_format;
-};
-
-/* ccdc configuration */
-struct ccdc_config {
-       /* This make sure vpfe is probed and ready to go */
-       int vpfe_probed;
-       /* name of ccdc device */
-       char name[32];
-};
-
-/* data structures */
-static struct vpfe_config_params config_params = {
-       .min_numbuffers = 3,
-       .numbuffers = 3,
-       .min_bufsize = 720 * 480 * 2,
-       .device_bufsize = 720 * 576 * 2,
-};
-
-/* ccdc device registered */
-static const struct ccdc_hw_device *ccdc_dev;
-/* lock for accessing ccdc information */
-static DEFINE_MUTEX(ccdc_lock);
-/* ccdc configuration */
-static struct ccdc_config *ccdc_cfg;
-
-static const struct vpfe_standard vpfe_standards[] = {
-       {V4L2_STD_525_60, 720, 480, {11, 10}, 1},
-       {V4L2_STD_625_50, 720, 576, {54, 59}, 1},
-};
-
-/* Used when raw Bayer image from ccdc is directly captured to SDRAM */
-static const struct vpfe_pixel_format vpfe_pix_fmts[] = {
-       {
-               .pixelformat = V4L2_PIX_FMT_SBGGR8,
-               .bpp = 1,
-       },
-       {
-               .pixelformat = V4L2_PIX_FMT_SBGGR16,
-               .bpp = 2,
-       },
-       {
-               .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
-               .bpp = 1,
-       },
-       {
-               .pixelformat = V4L2_PIX_FMT_UYVY,
-               .bpp = 2,
-       },
-       {
-               .pixelformat = V4L2_PIX_FMT_YUYV,
-               .bpp = 2,
-       },
-       {
-               .pixelformat = V4L2_PIX_FMT_NV12,
-               .bpp = 1,
-       },
-};
-
-/*
- * vpfe_lookup_pix_format()
- * lookup an entry in the vpfe pix format table based on pix_format
- */
-static const struct vpfe_pixel_format *vpfe_lookup_pix_format(u32 pix_format)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(vpfe_pix_fmts); i++) {
-               if (pix_format == vpfe_pix_fmts[i].pixelformat)
-                       return &vpfe_pix_fmts[i];
-       }
-       return NULL;
-}
-
-/*
- * vpfe_register_ccdc_device. CCDC module calls this to
- * register with vpfe capture
- */
-int vpfe_register_ccdc_device(const struct ccdc_hw_device *dev)
-{
-       int ret = 0;
-       printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name);
-
-       if (!dev->hw_ops.open ||
-           !dev->hw_ops.enable ||
-           !dev->hw_ops.set_hw_if_params ||
-           !dev->hw_ops.configure ||
-           !dev->hw_ops.set_buftype ||
-           !dev->hw_ops.get_buftype ||
-           !dev->hw_ops.enum_pix ||
-           !dev->hw_ops.set_frame_format ||
-           !dev->hw_ops.get_frame_format ||
-           !dev->hw_ops.get_pixel_format ||
-           !dev->hw_ops.set_pixel_format ||
-           !dev->hw_ops.set_image_window ||
-           !dev->hw_ops.get_image_window ||
-           !dev->hw_ops.get_line_length ||
-           !dev->hw_ops.getfid)
-               return -EINVAL;
-
-       mutex_lock(&ccdc_lock);
-       if (!ccdc_cfg) {
-               /*
-                * TODO. Will this ever happen? if so, we need to fix it.
-                * Probably we need to add the request to a linked list and
-                * walk through it during vpfe probe
-                */
-               printk(KERN_ERR "vpfe capture not initialized\n");
-               ret = -EFAULT;
-               goto unlock;
-       }
-
-       if (strcmp(dev->name, ccdc_cfg->name)) {
-               /* ignore this ccdc */
-               ret = -EINVAL;
-               goto unlock;
-       }
-
-       if (ccdc_dev) {
-               printk(KERN_ERR "ccdc already registered\n");
-               ret = -EINVAL;
-               goto unlock;
-       }
-
-       ccdc_dev = dev;
-unlock:
-       mutex_unlock(&ccdc_lock);
-       return ret;
-}
-EXPORT_SYMBOL(vpfe_register_ccdc_device);
-
-/*
- * vpfe_unregister_ccdc_device. CCDC module calls this to
- * unregister with vpfe capture
- */
-void vpfe_unregister_ccdc_device(const struct ccdc_hw_device *dev)
-{
-       if (!dev) {
-               printk(KERN_ERR "invalid ccdc device ptr\n");
-               return;
-       }
-
-       printk(KERN_NOTICE "vpfe_unregister_ccdc_device, dev->name = %s\n",
-               dev->name);
-
-       if (strcmp(dev->name, ccdc_cfg->name)) {
-               /* ignore this ccdc */
-               return;
-       }
-
-       mutex_lock(&ccdc_lock);
-       ccdc_dev = NULL;
-       mutex_unlock(&ccdc_lock);
-}
-EXPORT_SYMBOL(vpfe_unregister_ccdc_device);
-
-/*
- * vpfe_config_ccdc_image_format()
- * For a pix format, configure ccdc to setup the capture
- */
-static int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe_dev)
-{
-       enum ccdc_frmfmt frm_fmt = CCDC_FRMFMT_INTERLACED;
-       int ret = 0;
-
-       if (ccdc_dev->hw_ops.set_pixel_format(
-                       vpfe_dev->fmt.fmt.pix.pixelformat) < 0) {
-               v4l2_err(&vpfe_dev->v4l2_dev,
-                       "couldn't set pix format in ccdc\n");
-               return -EINVAL;
-       }
-       /* configure the image window */
-       ccdc_dev->hw_ops.set_image_window(&vpfe_dev->crop);
-
-       switch (vpfe_dev->fmt.fmt.pix.field) {
-       case V4L2_FIELD_INTERLACED:
-               /* do nothing, since it is default */
-               ret = ccdc_dev->hw_ops.set_buftype(
-                               CCDC_BUFTYPE_FLD_INTERLEAVED);
-               break;
-       case V4L2_FIELD_NONE:
-               frm_fmt = CCDC_FRMFMT_PROGRESSIVE;
-               /* buffer type only applicable for interlaced scan */
-               break;
-       case V4L2_FIELD_SEQ_TB:
-               ret = ccdc_dev->hw_ops.set_buftype(
-                               CCDC_BUFTYPE_FLD_SEPARATED);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* set the frame format */
-       if (!ret)
-               ret = ccdc_dev->hw_ops.set_frame_format(frm_fmt);
-       return ret;
-}
-/*
- * vpfe_config_image_format()
- * For a given standard, this functions sets up the default
- * pix format & crop values in the vpfe device and ccdc.  It first
- * starts with defaults based values from the standard table.
- * It then checks if sub device supports get_fmt and then override the
- * values based on that.Sets crop values to match with scan resolution
- * starting at 0,0. It calls vpfe_config_ccdc_image_format() set the
- * values in ccdc
- */
-static int vpfe_config_image_format(struct vpfe_device *vpfe_dev,
-                                   v4l2_std_id std_id)
-{
-       struct vpfe_subdev_info *sdinfo = vpfe_dev->current_subdev;
-       struct v4l2_subdev_format fmt = {
-               .which = V4L2_SUBDEV_FORMAT_ACTIVE,
-       };
-       struct v4l2_mbus_framefmt *mbus_fmt = &fmt.format;
-       struct v4l2_pix_format *pix = &vpfe_dev->fmt.fmt.pix;
-       int i, ret;
-
-       for (i = 0; i < ARRAY_SIZE(vpfe_standards); i++) {
-               if (vpfe_standards[i].std_id & std_id) {
-                       vpfe_dev->std_info.active_pixels =
-                                       vpfe_standards[i].width;
-                       vpfe_dev->std_info.active_lines =
-                                       vpfe_standards[i].height;
-                       vpfe_dev->std_info.frame_format =
-                                       vpfe_standards[i].frame_format;
-                       vpfe_dev->std_index = i;
-                       break;
-               }
-       }
-
-       if (i ==  ARRAY_SIZE(vpfe_standards)) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "standard not supported\n");
-               return -EINVAL;
-       }
-
-       vpfe_dev->crop.top = 0;
-       vpfe_dev->crop.left = 0;
-       vpfe_dev->crop.width = vpfe_dev->std_info.active_pixels;
-       vpfe_dev->crop.height = vpfe_dev->std_info.active_lines;
-       pix->width = vpfe_dev->crop.width;
-       pix->height = vpfe_dev->crop.height;
-
-       /* first field and frame format based on standard frame format */
-       if (vpfe_dev->std_info.frame_format) {
-               pix->field = V4L2_FIELD_INTERLACED;
-               /* assume V4L2_PIX_FMT_UYVY as default */
-               pix->pixelformat = V4L2_PIX_FMT_UYVY;
-               v4l2_fill_mbus_format(mbus_fmt, pix,
-                               MEDIA_BUS_FMT_YUYV10_2X10);
-       } else {
-               pix->field = V4L2_FIELD_NONE;
-               /* assume V4L2_PIX_FMT_SBGGR8 */
-               pix->pixelformat = V4L2_PIX_FMT_SBGGR8;
-               v4l2_fill_mbus_format(mbus_fmt, pix,
-                               MEDIA_BUS_FMT_SBGGR8_1X8);
-       }
-
-       /* if sub device supports get_fmt, override the defaults */
-       ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
-                       sdinfo->grp_id, pad, get_fmt, NULL, &fmt);
-
-       if (ret && ret != -ENOIOCTLCMD) {
-               v4l2_err(&vpfe_dev->v4l2_dev,
-                       "error in getting get_fmt from sub device\n");
-               return ret;
-       }
-       v4l2_fill_pix_format(pix, mbus_fmt);
-       pix->bytesperline = pix->width * 2;
-       pix->sizeimage = pix->bytesperline * pix->height;
-
-       /* Sets the values in CCDC */
-       ret = vpfe_config_ccdc_image_format(vpfe_dev);
-       if (ret)
-               return ret;
-
-       /* Update the values of sizeimage and bytesperline */
-       pix->bytesperline = ccdc_dev->hw_ops.get_line_length();
-       pix->sizeimage = pix->bytesperline * pix->height;
-
-       return 0;
-}
-
-static int vpfe_initialize_device(struct vpfe_device *vpfe_dev)
-{
-       int ret;
-
-       /* set first input of current subdevice as the current input */
-       vpfe_dev->current_input = 0;
-
-       /* set default standard */
-       vpfe_dev->std_index = 0;
-
-       /* Configure the default format information */
-       ret = vpfe_config_image_format(vpfe_dev,
-                               vpfe_standards[vpfe_dev->std_index].std_id);
-       if (ret)
-               return ret;
-
-       /* now open the ccdc device to initialize it */
-       mutex_lock(&ccdc_lock);
-       if (!ccdc_dev) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "ccdc device not registered\n");
-               ret = -ENODEV;
-               goto unlock;
-       }
-
-       if (!try_module_get(ccdc_dev->owner)) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "Couldn't lock ccdc module\n");
-               ret = -ENODEV;
-               goto unlock;
-       }
-       ret = ccdc_dev->hw_ops.open(vpfe_dev->pdev);
-       if (!ret)
-               vpfe_dev->initialized = 1;
-
-       /* Clear all VPFE/CCDC interrupts */
-       if (vpfe_dev->cfg->clr_intr)
-               vpfe_dev->cfg->clr_intr(-1);
-
-unlock:
-       mutex_unlock(&ccdc_lock);
-       return ret;
-}
-
-/*
- * vpfe_open : It creates object of file handle structure and
- * stores it in private_data  member of filepointer
- */
-static int vpfe_open(struct file *file)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct video_device *vdev = video_devdata(file);
-       struct vpfe_fh *fh;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n");
-
-       if (!vpfe_dev->cfg->num_subdevs) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "No decoder registered\n");
-               return -ENODEV;
-       }
-
-       /* Allocate memory for the file handle object */
-       fh = kmalloc(sizeof(*fh), GFP_KERNEL);
-       if (!fh)
-               return -ENOMEM;
-
-       /* store pointer to fh in private_data member of file */
-       file->private_data = fh;
-       fh->vpfe_dev = vpfe_dev;
-       v4l2_fh_init(&fh->fh, vdev);
-       mutex_lock(&vpfe_dev->lock);
-       /* If decoder is not initialized. initialize it */
-       if (!vpfe_dev->initialized) {
-               if (vpfe_initialize_device(vpfe_dev)) {
-                       mutex_unlock(&vpfe_dev->lock);
-                       v4l2_fh_exit(&fh->fh);
-                       kfree(fh);
-                       return -ENODEV;
-               }
-       }
-       /* Increment device usrs counter */
-       vpfe_dev->usrs++;
-       /* Set io_allowed member to false */
-       fh->io_allowed = 0;
-       v4l2_fh_add(&fh->fh);
-       mutex_unlock(&vpfe_dev->lock);
-       return 0;
-}
-
-static void vpfe_schedule_next_buffer(struct vpfe_device *vpfe_dev)
-{
-       unsigned long addr;
-
-       vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
-                                       struct videobuf_buffer, queue);
-       list_del(&vpfe_dev->next_frm->queue);
-       vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE;
-       addr = videobuf_to_dma_contig(vpfe_dev->next_frm);
-
-       ccdc_dev->hw_ops.setfbaddr(addr);
-}
-
-static void vpfe_schedule_bottom_field(struct vpfe_device *vpfe_dev)
-{
-       unsigned long addr;
-
-       addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
-       addr += vpfe_dev->field_off;
-       ccdc_dev->hw_ops.setfbaddr(addr);
-}
-
-static void vpfe_process_buffer_complete(struct vpfe_device *vpfe_dev)
-{
-       vpfe_dev->cur_frm->ts = ktime_get_ns();
-       vpfe_dev->cur_frm->state = VIDEOBUF_DONE;
-       vpfe_dev->cur_frm->size = vpfe_dev->fmt.fmt.pix.sizeimage;
-       wake_up_interruptible(&vpfe_dev->cur_frm->done);
-       vpfe_dev->cur_frm = vpfe_dev->next_frm;
-}
-
-/* ISR for VINT0*/
-static irqreturn_t vpfe_isr(int irq, void *dev_id)
-{
-       struct vpfe_device *vpfe_dev = dev_id;
-       enum v4l2_field field;
-       int fid;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nStarting vpfe_isr...\n");
-       field = vpfe_dev->fmt.fmt.pix.field;
-
-       /* if streaming not started, don't do anything */
-       if (!vpfe_dev->started)
-               goto clear_intr;
-
-       /* only for 6446 this will be applicable */
-       if (ccdc_dev->hw_ops.reset)
-               ccdc_dev->hw_ops.reset();
-
-       if (field == V4L2_FIELD_NONE) {
-               /* handle progressive frame capture */
-               v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
-                       "frame format is progressive...\n");
-               if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
-                       vpfe_process_buffer_complete(vpfe_dev);
-               goto clear_intr;
-       }
-
-       /* interlaced or TB capture check which field we are in hardware */
-       fid = ccdc_dev->hw_ops.getfid();
-
-       /* switch the software maintained field id */
-       vpfe_dev->field_id ^= 1;
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "field id = %x:%x.\n",
-               fid, vpfe_dev->field_id);
-       if (fid == vpfe_dev->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_dev->cur_frm != vpfe_dev->next_frm)
-                               vpfe_process_buffer_complete(vpfe_dev);
-                       /*
-                        * based on whether the two fields are stored
-                        * interleavely or separately in memory, reconfigure
-                        * the CCDC memory address
-                        */
-                       if (field == V4L2_FIELD_SEQ_TB)
-                               vpfe_schedule_bottom_field(vpfe_dev);
-                       goto clear_intr;
-               }
-               /*
-                * 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
-                */
-               spin_lock(&vpfe_dev->dma_queue_lock);
-               if (!list_empty(&vpfe_dev->dma_queue) &&
-                   vpfe_dev->cur_frm == vpfe_dev->next_frm)
-                       vpfe_schedule_next_buffer(vpfe_dev);
-               spin_unlock(&vpfe_dev->dma_queue_lock);
-       } else if (fid == 0) {
-               /*
-                * out of sync. Recover from any hardware out-of-sync.
-                * May loose one frame
-                */
-               vpfe_dev->field_id = fid;
-       }
-clear_intr:
-       if (vpfe_dev->cfg->clr_intr)
-               vpfe_dev->cfg->clr_intr(irq);
-
-       return IRQ_HANDLED;
-}
-
-/* vdint1_isr - isr handler for VINT1 interrupt */
-static irqreturn_t vdint1_isr(int irq, void *dev_id)
-{
-       struct vpfe_device *vpfe_dev = dev_id;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nInside vdint1_isr...\n");
-
-       /* if streaming not started, don't do anything */
-       if (!vpfe_dev->started) {
-               if (vpfe_dev->cfg->clr_intr)
-                       vpfe_dev->cfg->clr_intr(irq);
-               return IRQ_HANDLED;
-       }
-
-       spin_lock(&vpfe_dev->dma_queue_lock);
-       if ((vpfe_dev->fmt.fmt.pix.field == V4L2_FIELD_NONE) &&
-           !list_empty(&vpfe_dev->dma_queue) &&
-           vpfe_dev->cur_frm == vpfe_dev->next_frm)
-               vpfe_schedule_next_buffer(vpfe_dev);
-       spin_unlock(&vpfe_dev->dma_queue_lock);
-
-       if (vpfe_dev->cfg->clr_intr)
-               vpfe_dev->cfg->clr_intr(irq);
-
-       return IRQ_HANDLED;
-}
-
-static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
-{
-       enum ccdc_frmfmt frame_format;
-
-       frame_format = ccdc_dev->hw_ops.get_frame_format();
-       if (frame_format == CCDC_FRMFMT_PROGRESSIVE)
-               free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
-}
-
-static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
-{
-       enum ccdc_frmfmt frame_format;
-
-       frame_format = ccdc_dev->hw_ops.get_frame_format();
-       if (frame_format == CCDC_FRMFMT_PROGRESSIVE) {
-               return request_irq(vpfe_dev->ccdc_irq1, vdint1_isr,
-                                   0, "vpfe_capture1",
-                                   vpfe_dev);
-       }
-       return 0;
-}
-
-/* vpfe_stop_ccdc_capture: stop streaming in ccdc/isif */
-static void vpfe_stop_ccdc_capture(struct vpfe_device *vpfe_dev)
-{
-       vpfe_dev->started = 0;
-       ccdc_dev->hw_ops.enable(0);
-       if (ccdc_dev->hw_ops.enable_out_to_sdram)
-               ccdc_dev->hw_ops.enable_out_to_sdram(0);
-}
-
-/*
- * vpfe_release : This function deletes buffer queue, frees the
- * buffers and the vpfe file  handle
- */
-static int vpfe_release(struct file *file)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct vpfe_fh *fh = file->private_data;
-       struct vpfe_subdev_info *sdinfo;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_release\n");
-
-       /* Get the device lock */
-       mutex_lock(&vpfe_dev->lock);
-       /* if this instance is doing IO */
-       if (fh->io_allowed) {
-               if (vpfe_dev->started) {
-                       sdinfo = vpfe_dev->current_subdev;
-                       ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
-                                                        sdinfo->grp_id,
-                                                        video, s_stream, 0);
-                       if (ret && (ret != -ENOIOCTLCMD))
-                               v4l2_err(&vpfe_dev->v4l2_dev,
-                               "stream off failed in subdev\n");
-                       vpfe_stop_ccdc_capture(vpfe_dev);
-                       vpfe_detach_irq(vpfe_dev);
-                       videobuf_streamoff(&vpfe_dev->buffer_queue);
-               }
-               vpfe_dev->io_usrs = 0;
-               vpfe_dev->numbuffers = config_params.numbuffers;
-               videobuf_stop(&vpfe_dev->buffer_queue);
-               videobuf_mmap_free(&vpfe_dev->buffer_queue);
-       }
-
-       /* Decrement device usrs counter */
-       vpfe_dev->usrs--;
-       v4l2_fh_del(&fh->fh);
-       v4l2_fh_exit(&fh->fh);
-       /* If this is the last file handle */
-       if (!vpfe_dev->usrs) {
-               vpfe_dev->initialized = 0;
-               if (ccdc_dev->hw_ops.close)
-                       ccdc_dev->hw_ops.close(vpfe_dev->pdev);
-               module_put(ccdc_dev->owner);
-       }
-       mutex_unlock(&vpfe_dev->lock);
-       file->private_data = NULL;
-       /* Free memory allocated to file handle object */
-       kfree(fh);
-       return 0;
-}
-
-/*
- * vpfe_mmap : It is used to map kernel space buffers
- * into user spaces
- */
-static int vpfe_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       /* Get the device object and file handle object */
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_mmap\n");
-
-       return videobuf_mmap_mapper(&vpfe_dev->buffer_queue, vma);
-}
-
-/*
- * vpfe_poll: It is used for select/poll system call
- */
-static __poll_t vpfe_poll(struct file *file, poll_table *wait)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_poll\n");
-
-       if (vpfe_dev->started)
-               return videobuf_poll_stream(file,
-                                           &vpfe_dev->buffer_queue, wait);
-       return 0;
-}
-
-/* vpfe capture driver file operations */
-static const struct v4l2_file_operations vpfe_fops = {
-       .owner = THIS_MODULE,
-       .open = vpfe_open,
-       .release = vpfe_release,
-       .unlocked_ioctl = video_ioctl2,
-       .mmap = vpfe_mmap,
-       .poll = vpfe_poll
-};
-
-/*
- * vpfe_check_format()
- * This function adjust the input pixel format as per hardware
- * capabilities and update the same in pixfmt.
- * Following algorithm used :-
- *
- *     If given pixformat is not in the vpfe list of pix formats or not
- *     supported by the hardware, current value of pixformat in the device
- *     is used
- *     If given field is not supported, then current field is used. If field
- *     is different from current, then it is matched with that from sub device.
- *     Minimum height is 2 lines for interlaced or tb field and 1 line for
- *     progressive. Maximum height is clamped to active active lines of scan
- *     Minimum width is 32 bytes in memory and width is clamped to active
- *     pixels of scan.
- *     bytesperline is a multiple of 32.
- */
-static const struct vpfe_pixel_format *
-       vpfe_check_format(struct vpfe_device *vpfe_dev,
-                         struct v4l2_pix_format *pixfmt)
-{
-       u32 min_height = 1, min_width = 32, max_width, max_height;
-       const struct vpfe_pixel_format *vpfe_pix_fmt;
-       u32 pix;
-       int temp, found;
-
-       vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
-       if (!vpfe_pix_fmt) {
-               /*
-                * use current pixel format in the vpfe device. We
-                * will find this pix format in the table
-                */
-               pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
-               vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
-       }
-
-       /* check if hw supports it */
-       temp = 0;
-       found = 0;
-       while (ccdc_dev->hw_ops.enum_pix(&pix, temp) >= 0) {
-               if (vpfe_pix_fmt->pixelformat == pix) {
-                       found = 1;
-                       break;
-               }
-               temp++;
-       }
-
-       if (!found) {
-               /* use current pixel format */
-               pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
-               /*
-                * Since this is currently used in the vpfe device, we
-                * will find this pix format in the table
-                */
-               vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
-       }
-
-       /* check what field format is supported */
-       if (pixfmt->field == V4L2_FIELD_ANY) {
-               /* if field is any, use current value as default */
-               pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
-       }
-
-       /*
-        * if field is not same as current field in the vpfe device
-        * try matching the field with the sub device field
-        */
-       if (vpfe_dev->fmt.fmt.pix.field != pixfmt->field) {
-               /*
-                * If field value is not in the supported fields, use current
-                * field used in the device as default
-                */
-               switch (pixfmt->field) {
-               case V4L2_FIELD_INTERLACED:
-               case V4L2_FIELD_SEQ_TB:
-                       /* if sub device is supporting progressive, use that */
-                       if (!vpfe_dev->std_info.frame_format)
-                               pixfmt->field = V4L2_FIELD_NONE;
-                       break;
-               case V4L2_FIELD_NONE:
-                       if (vpfe_dev->std_info.frame_format)
-                               pixfmt->field = V4L2_FIELD_INTERLACED;
-                       break;
-
-               default:
-                       /* use current field as default */
-                       pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
-                       break;
-               }
-       }
-
-       /* Now adjust image resolutions supported */
-       if (pixfmt->field == V4L2_FIELD_INTERLACED ||
-           pixfmt->field == V4L2_FIELD_SEQ_TB)
-               min_height = 2;
-
-       max_width = vpfe_dev->std_info.active_pixels;
-       max_height = vpfe_dev->std_info.active_lines;
-       min_width /= vpfe_pix_fmt->bpp;
-
-       v4l2_info(&vpfe_dev->v4l2_dev, "width = %d, height = %d, bpp = %d\n",
-                 pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp);
-
-       pixfmt->width = clamp((pixfmt->width), min_width, max_width);
-       pixfmt->height = clamp((pixfmt->height), min_height, max_height);
-
-       /* If interlaced, adjust height to be a multiple of 2 */
-       if (pixfmt->field == V4L2_FIELD_INTERLACED)
-               pixfmt->height &= (~1);
-       /*
-        * recalculate bytesperline and sizeimage since width
-        * and height might have changed
-        */
-       pixfmt->bytesperline = (((pixfmt->width * vpfe_pix_fmt->bpp) + 31)
-                               & ~31);
-       if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
-               pixfmt->sizeimage =
-                       pixfmt->bytesperline * pixfmt->height +
-                       ((pixfmt->bytesperline * pixfmt->height) >> 1);
-       else
-               pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
-
-       v4l2_info(&vpfe_dev->v4l2_dev, "adjusted width = %d, height = %d, bpp = %d, bytesperline = %d, sizeimage = %d\n",
-                pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp,
-                pixfmt->bytesperline, pixfmt->sizeimage);
-       return vpfe_pix_fmt;
-}
-
-static int vpfe_querycap(struct file *file, void  *priv,
-                              struct v4l2_capability *cap)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querycap\n");
-
-       strscpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
-       strscpy(cap->bus_info, "VPFE", sizeof(cap->bus_info));
-       strscpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card));
-       return 0;
-}
-
-static int vpfe_g_fmt_vid_cap(struct file *file, void *priv,
-                               struct v4l2_format *fmt)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_fmt_vid_cap\n");
-       /* Fill in the information about format */
-       *fmt = vpfe_dev->fmt;
-       return 0;
-}
-
-static int vpfe_enum_fmt_vid_cap(struct file *file, void  *priv,
-                                  struct v4l2_fmtdesc *fmt)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       const struct vpfe_pixel_format *pix_fmt;
-       u32 pix;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt_vid_cap\n");
-
-       if (ccdc_dev->hw_ops.enum_pix(&pix, fmt->index) < 0)
-               return -EINVAL;
-
-       /* Fill in the information about format */
-       pix_fmt = vpfe_lookup_pix_format(pix);
-       if (pix_fmt) {
-               fmt->pixelformat = pix_fmt->pixelformat;
-               return 0;
-       }
-       return -EINVAL;
-}
-
-static int vpfe_s_fmt_vid_cap(struct file *file, void *priv,
-                               struct v4l2_format *fmt)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       const struct vpfe_pixel_format *pix_fmts;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt_vid_cap\n");
-
-       /* If streaming is started, return error */
-       if (vpfe_dev->started) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is started\n");
-               return -EBUSY;
-       }
-
-       /* Check for valid frame format */
-       pix_fmts = vpfe_check_format(vpfe_dev, &fmt->fmt.pix);
-       if (!pix_fmts)
-               return -EINVAL;
-
-       /* store the pixel format in the device  object */
-       ret = mutex_lock_interruptible(&vpfe_dev->lock);
-       if (ret)
-               return ret;
-
-       /* First detach any IRQ if currently attached */
-       vpfe_detach_irq(vpfe_dev);
-       vpfe_dev->fmt = *fmt;
-       /* set image capture parameters in the ccdc */
-       ret = vpfe_config_ccdc_image_format(vpfe_dev);
-       mutex_unlock(&vpfe_dev->lock);
-       return ret;
-}
-
-static int vpfe_try_fmt_vid_cap(struct file *file, void *priv,
-                                 struct v4l2_format *f)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       const struct vpfe_pixel_format *pix_fmts;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt_vid_cap\n");
-
-       pix_fmts = vpfe_check_format(vpfe_dev, &f->fmt.pix);
-       if (!pix_fmts)
-               return -EINVAL;
-       return 0;
-}
-
-/*
- * vpfe_get_subdev_input_index - Get subdev index and subdev input index for a
- * given app input index
- */
-static int vpfe_get_subdev_input_index(struct vpfe_device *vpfe_dev,
-                                       int *subdev_index,
-                                       int *subdev_input_index,
-                                       int app_input_index)
-{
-       struct vpfe_config *cfg = vpfe_dev->cfg;
-       struct vpfe_subdev_info *sdinfo;
-       int i, j = 0;
-
-       for (i = 0; i < cfg->num_subdevs; i++) {
-               sdinfo = &cfg->sub_devs[i];
-               if (app_input_index < (j + sdinfo->num_inputs)) {
-                       *subdev_index = i;
-                       *subdev_input_index = app_input_index - j;
-                       return 0;
-               }
-               j += sdinfo->num_inputs;
-       }
-       return -EINVAL;
-}
-
-/*
- * vpfe_get_app_input - Get app input index for a given subdev input index
- * driver stores the input index of the current sub device and translate it
- * when application request the current input
- */
-static int vpfe_get_app_input_index(struct vpfe_device *vpfe_dev,
-                                   int *app_input_index)
-{
-       struct vpfe_config *cfg = vpfe_dev->cfg;
-       struct vpfe_subdev_info *sdinfo;
-       int i, j = 0;
-
-       for (i = 0; i < cfg->num_subdevs; i++) {
-               sdinfo = &cfg->sub_devs[i];
-               if (!strcmp(sdinfo->name, vpfe_dev->current_subdev->name)) {
-                       if (vpfe_dev->current_input >= sdinfo->num_inputs)
-                               return -1;
-                       *app_input_index = j + vpfe_dev->current_input;
-                       return 0;
-               }
-               j += sdinfo->num_inputs;
-       }
-       return -EINVAL;
-}
-
-static int vpfe_enum_input(struct file *file, void *priv,
-                                struct v4l2_input *inp)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct vpfe_subdev_info *sdinfo;
-       int subdev, index ;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_input\n");
-
-       if (vpfe_get_subdev_input_index(vpfe_dev,
-                                       &subdev,
-                                       &index,
-                                       inp->index) < 0) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "input information not found for the subdev\n");
-               return -EINVAL;
-       }
-       sdinfo = &vpfe_dev->cfg->sub_devs[subdev];
-       *inp = sdinfo->inputs[index];
-       return 0;
-}
-
-static int vpfe_g_input(struct file *file, void *priv, unsigned int *index)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_input\n");
-
-       return vpfe_get_app_input_index(vpfe_dev, index);
-}
-
-
-static int vpfe_s_input(struct file *file, void *priv, unsigned int index)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct v4l2_subdev *sd;
-       struct vpfe_subdev_info *sdinfo;
-       int subdev_index, inp_index;
-       struct vpfe_route *route;
-       u32 input, output;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n");
-
-       ret = mutex_lock_interruptible(&vpfe_dev->lock);
-       if (ret)
-               return ret;
-
-       /*
-        * If streaming is started return device busy
-        * error
-        */
-       if (vpfe_dev->started) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is on\n");
-               ret = -EBUSY;
-               goto unlock_out;
-       }
-       ret = vpfe_get_subdev_input_index(vpfe_dev,
-                                         &subdev_index,
-                                         &inp_index,
-                                         index);
-       if (ret < 0) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "invalid input index\n");
-               goto unlock_out;
-       }
-
-       sdinfo = &vpfe_dev->cfg->sub_devs[subdev_index];
-       sd = vpfe_dev->sd[subdev_index];
-       route = &sdinfo->routes[inp_index];
-       if (route && sdinfo->can_route) {
-               input = route->input;
-               output = route->output;
-       } else {
-               input = 0;
-               output = 0;
-       }
-
-       if (sd)
-               ret = v4l2_subdev_call(sd, video, s_routing, input, output, 0);
-
-       if (ret) {
-               v4l2_err(&vpfe_dev->v4l2_dev,
-                       "vpfe_doioctl:error in setting input in decoder\n");
-               ret = -EINVAL;
-               goto unlock_out;
-       }
-       vpfe_dev->current_subdev = sdinfo;
-       if (sd)
-               vpfe_dev->v4l2_dev.ctrl_handler = sd->ctrl_handler;
-       vpfe_dev->current_input = index;
-       vpfe_dev->std_index = 0;
-
-       /* set the bus/interface parameter for the sub device in ccdc */
-       ret = ccdc_dev->hw_ops.set_hw_if_params(&sdinfo->ccdc_if_params);
-       if (ret)
-               goto unlock_out;
-
-       /* set the default image parameters in the device */
-       ret = vpfe_config_image_format(vpfe_dev,
-                               vpfe_standards[vpfe_dev->std_index].std_id);
-unlock_out:
-       mutex_unlock(&vpfe_dev->lock);
-       return ret;
-}
-
-static int vpfe_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct vpfe_subdev_info *sdinfo;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querystd\n");
-
-       ret = mutex_lock_interruptible(&vpfe_dev->lock);
-       sdinfo = vpfe_dev->current_subdev;
-       if (ret)
-               return ret;
-       /* Call querystd function of decoder device */
-       ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
-                                        video, querystd, std_id);
-       mutex_unlock(&vpfe_dev->lock);
-       return ret;
-}
-
-static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id std_id)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct vpfe_subdev_info *sdinfo;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n");
-
-       /* Call decoder driver function to set the standard */
-       ret = mutex_lock_interruptible(&vpfe_dev->lock);
-       if (ret)
-               return ret;
-
-       sdinfo = vpfe_dev->current_subdev;
-       /* If streaming is started, return device busy error */
-       if (vpfe_dev->started) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "streaming is started\n");
-               ret = -EBUSY;
-               goto unlock_out;
-       }
-
-       ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
-                                        video, s_std, std_id);
-       if (ret < 0) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n");
-               goto unlock_out;
-       }
-       ret = vpfe_config_image_format(vpfe_dev, std_id);
-
-unlock_out:
-       mutex_unlock(&vpfe_dev->lock);
-       return ret;
-}
-
-static int vpfe_g_std(struct file *file, void *priv, v4l2_std_id *std_id)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_std\n");
-
-       *std_id = vpfe_standards[vpfe_dev->std_index].std_id;
-       return 0;
-}
-/*
- *  Videobuf operations
- */
-static int vpfe_videobuf_setup(struct videobuf_queue *vq,
-                               unsigned int *count,
-                               unsigned int *size)
-{
-       struct vpfe_fh *fh = vq->priv_data;
-       struct vpfe_device *vpfe_dev = fh->vpfe_dev;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_setup\n");
-       *size = vpfe_dev->fmt.fmt.pix.sizeimage;
-       if (vpfe_dev->memory == V4L2_MEMORY_MMAP &&
-               vpfe_dev->fmt.fmt.pix.sizeimage > config_params.device_bufsize)
-               *size = config_params.device_bufsize;
-
-       if (*count < config_params.min_numbuffers)
-               *count = config_params.min_numbuffers;
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
-               "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)
-{
-       struct vpfe_fh *fh = vq->priv_data;
-       struct vpfe_device *vpfe_dev = fh->vpfe_dev;
-       unsigned long addr;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n");
-
-       /* If buffer is not initialized, initialize it */
-       if (VIDEOBUF_NEEDS_INIT == vb->state) {
-               vb->width = vpfe_dev->fmt.fmt.pix.width;
-               vb->height = vpfe_dev->fmt.fmt.pix.height;
-               vb->size = vpfe_dev->fmt.fmt.pix.sizeimage;
-               vb->field = field;
-
-               ret = videobuf_iolock(vq, vb, NULL);
-               if (ret < 0)
-                       return ret;
-
-               addr = videobuf_to_dma_contig(vb);
-               /* Make sure user addresses are aligned to 32 bytes */
-               if (!ALIGN(addr, 32))
-                       return -EINVAL;
-
-               vb->state = VIDEOBUF_PREPARED;
-       }
-       return 0;
-}
-
-static void vpfe_videobuf_queue(struct videobuf_queue *vq,
-                               struct videobuf_buffer *vb)
-{
-       /* Get the file handle object and device object */
-       struct vpfe_fh *fh = vq->priv_data;
-       struct vpfe_device *vpfe_dev = fh->vpfe_dev;
-       unsigned long flags;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_queue\n");
-
-       /* add the buffer to the DMA queue */
-       spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
-       list_add_tail(&vb->queue, &vpfe_dev->dma_queue);
-       spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
-
-       /* Change state of the buffer */
-       vb->state = VIDEOBUF_QUEUED;
-}
-
-static void vpfe_videobuf_release(struct videobuf_queue *vq,
-                                 struct videobuf_buffer *vb)
-{
-       struct vpfe_fh *fh = vq->priv_data;
-       struct vpfe_device *vpfe_dev = fh->vpfe_dev;
-       unsigned long flags;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_videobuf_release\n");
-
-       /*
-        * We need to flush the buffer from the dma queue since
-        * they are de-allocated
-        */
-       spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
-       INIT_LIST_HEAD(&vpfe_dev->dma_queue);
-       spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
-       videobuf_dma_contig_free(vq, vb);
-       vb->state = VIDEOBUF_NEEDS_INIT;
-}
-
-static const 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,
-};
-
-/*
- * vpfe_reqbufs. currently support REQBUF only once opening
- * the device.
- */
-static int vpfe_reqbufs(struct file *file, void *priv,
-                       struct v4l2_requestbuffers *req_buf)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct vpfe_fh *fh = file->private_data;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs\n");
-
-       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != req_buf->type) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buffer type\n");
-               return -EINVAL;
-       }
-
-       ret = mutex_lock_interruptible(&vpfe_dev->lock);
-       if (ret)
-               return ret;
-
-       if (vpfe_dev->io_usrs != 0) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n");
-               ret = -EBUSY;
-               goto unlock_out;
-       }
-
-       vpfe_dev->memory = req_buf->memory;
-       videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue,
-                               &vpfe_videobuf_qops,
-                               vpfe_dev->pdev,
-                               &vpfe_dev->irqlock,
-                               req_buf->type,
-                               vpfe_dev->fmt.fmt.pix.field,
-                               sizeof(struct videobuf_buffer),
-                               fh, NULL);
-
-       fh->io_allowed = 1;
-       vpfe_dev->io_usrs = 1;
-       INIT_LIST_HEAD(&vpfe_dev->dma_queue);
-       ret = videobuf_reqbufs(&vpfe_dev->buffer_queue, req_buf);
-unlock_out:
-       mutex_unlock(&vpfe_dev->lock);
-       return ret;
-}
-
-static int vpfe_querybuf(struct file *file, void *priv,
-                        struct v4l2_buffer *buf)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querybuf\n");
-
-       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
-               return  -EINVAL;
-       }
-
-       if (vpfe_dev->memory != V4L2_MEMORY_MMAP) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid memory\n");
-               return -EINVAL;
-       }
-       /* Call videobuf_querybuf to get information */
-       return videobuf_querybuf(&vpfe_dev->buffer_queue, buf);
-}
-
-static int vpfe_qbuf(struct file *file, void *priv,
-                    struct v4l2_buffer *p)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct vpfe_fh *fh = file->private_data;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_qbuf\n");
-
-       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != p->type) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
-               return -EINVAL;
-       }
-
-       /*
-        * If this file handle is not allowed to do IO,
-        * return error
-        */
-       if (!fh->io_allowed) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
-               return -EACCES;
-       }
-       return videobuf_qbuf(&vpfe_dev->buffer_queue, p);
-}
-
-static int vpfe_dqbuf(struct file *file, void *priv,
-                     struct v4l2_buffer *buf)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_dqbuf\n");
-
-       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
-               return -EINVAL;
-       }
-       return videobuf_dqbuf(&vpfe_dev->buffer_queue,
-                                     buf, file->f_flags & O_NONBLOCK);
-}
-
-/*
- * vpfe_calculate_offsets : This function calculates buffers offset
- * for top and bottom field
- */
-static void vpfe_calculate_offsets(struct vpfe_device *vpfe_dev)
-{
-       struct v4l2_rect image_win;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_calculate_offsets\n");
-
-       ccdc_dev->hw_ops.get_image_window(&image_win);
-       vpfe_dev->field_off = image_win.height * image_win.width;
-}
-
-/* vpfe_start_ccdc_capture: start streaming in ccdc/isif */
-static void vpfe_start_ccdc_capture(struct vpfe_device *vpfe_dev)
-{
-       ccdc_dev->hw_ops.enable(1);
-       if (ccdc_dev->hw_ops.enable_out_to_sdram)
-               ccdc_dev->hw_ops.enable_out_to_sdram(1);
-       vpfe_dev->started = 1;
-}
-
-/*
- * vpfe_streamon. Assume the DMA queue is not empty.
- * application is expected to call QBUF before calling
- * this ioctl. If not, driver returns error
- */
-static int vpfe_streamon(struct file *file, void *priv,
-                        enum v4l2_buf_type buf_type)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct vpfe_fh *fh = file->private_data;
-       struct vpfe_subdev_info *sdinfo;
-       unsigned long addr;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamon\n");
-
-       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
-               return -EINVAL;
-       }
-
-       /* If file handle is not allowed IO, return error */
-       if (!fh->io_allowed) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
-               return -EACCES;
-       }
-
-       sdinfo = vpfe_dev->current_subdev;
-       ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
-                                       video, s_stream, 1);
-
-       if (ret && (ret != -ENOIOCTLCMD)) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "stream on failed in subdev\n");
-               return -EINVAL;
-       }
-
-       /* If buffer queue is empty, return error */
-       if (list_empty(&vpfe_dev->buffer_queue.stream)) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "buffer queue is empty\n");
-               return -EIO;
-       }
-
-       /* Call videobuf_streamon to start streaming * in videobuf */
-       ret = videobuf_streamon(&vpfe_dev->buffer_queue);
-       if (ret)
-               return ret;
-
-
-       ret = mutex_lock_interruptible(&vpfe_dev->lock);
-       if (ret)
-               goto streamoff;
-       /* Get the next frame from the buffer queue */
-       vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
-                                       struct videobuf_buffer, queue);
-       vpfe_dev->cur_frm = vpfe_dev->next_frm;
-       /* Remove buffer from the buffer queue */
-       list_del(&vpfe_dev->cur_frm->queue);
-       /* Mark state of the current frame to active */
-       vpfe_dev->cur_frm->state = VIDEOBUF_ACTIVE;
-       /* Initialize field_id and started member */
-       vpfe_dev->field_id = 0;
-       addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
-
-       /* Calculate field offset */
-       vpfe_calculate_offsets(vpfe_dev);
-
-       if (vpfe_attach_irq(vpfe_dev) < 0) {
-               v4l2_err(&vpfe_dev->v4l2_dev,
-                        "Error in attaching interrupt handle\n");
-               ret = -EFAULT;
-               goto unlock_out;
-       }
-       if (ccdc_dev->hw_ops.configure() < 0) {
-               v4l2_err(&vpfe_dev->v4l2_dev,
-                        "Error in configuring ccdc\n");
-               ret = -EINVAL;
-               goto unlock_out;
-       }
-       ccdc_dev->hw_ops.setfbaddr((unsigned long)(addr));
-       vpfe_start_ccdc_capture(vpfe_dev);
-       mutex_unlock(&vpfe_dev->lock);
-       return ret;
-unlock_out:
-       mutex_unlock(&vpfe_dev->lock);
-streamoff:
-       videobuf_streamoff(&vpfe_dev->buffer_queue);
-       return ret;
-}
-
-static int vpfe_streamoff(struct file *file, void *priv,
-                         enum v4l2_buf_type buf_type)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct vpfe_fh *fh = file->private_data;
-       struct vpfe_subdev_info *sdinfo;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamoff\n");
-
-       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
-               return -EINVAL;
-       }
-
-       /* If io is allowed for this file handle, return error */
-       if (!fh->io_allowed) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
-               return -EACCES;
-       }
-
-       /* If streaming is not started, return error */
-       if (!vpfe_dev->started) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "device started\n");
-               return -EINVAL;
-       }
-
-       ret = mutex_lock_interruptible(&vpfe_dev->lock);
-       if (ret)
-               return ret;
-
-       vpfe_stop_ccdc_capture(vpfe_dev);
-       vpfe_detach_irq(vpfe_dev);
-
-       sdinfo = vpfe_dev->current_subdev;
-       ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
-                                       video, s_stream, 0);
-
-       if (ret && (ret != -ENOIOCTLCMD))
-               v4l2_err(&vpfe_dev->v4l2_dev, "stream off failed in subdev\n");
-       ret = videobuf_streamoff(&vpfe_dev->buffer_queue);
-       mutex_unlock(&vpfe_dev->lock);
-       return ret;
-}
-
-static int vpfe_g_pixelaspect(struct file *file, void *priv,
-                             int type, struct v4l2_fract *f)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_pixelaspect\n");
-
-       if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-               return -EINVAL;
-       /* If std_index is invalid, then just return (== 1:1 aspect) */
-       if (vpfe_dev->std_index >= ARRAY_SIZE(vpfe_standards))
-               return 0;
-
-       *f = vpfe_standards[vpfe_dev->std_index].pixelaspect;
-       return 0;
-}
-
-static int vpfe_g_selection(struct file *file, void *priv,
-                           struct v4l2_selection *sel)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_selection\n");
-
-       if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-               return -EINVAL;
-
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP:
-               sel->r = vpfe_dev->crop;
-               break;
-       case V4L2_SEL_TGT_CROP_DEFAULT:
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-               sel->r.width = vpfe_standards[vpfe_dev->std_index].width;
-               sel->r.height = vpfe_standards[vpfe_dev->std_index].height;
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int vpfe_s_selection(struct file *file, void *priv,
-                           struct v4l2_selection *sel)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct v4l2_rect rect = sel->r;
-       int ret;
-
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_selection\n");
-
-       if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-           sel->target != V4L2_SEL_TGT_CROP)
-               return -EINVAL;
-
-       if (vpfe_dev->started) {
-               /* make sure streaming is not started */
-               v4l2_err(&vpfe_dev->v4l2_dev,
-                       "Cannot change crop when streaming is ON\n");
-               return -EBUSY;
-       }
-
-       ret = mutex_lock_interruptible(&vpfe_dev->lock);
-       if (ret)
-               return ret;
-
-       if (rect.top < 0 || rect.left < 0) {
-               v4l2_err(&vpfe_dev->v4l2_dev,
-                       "doesn't support negative values for top & left\n");
-               ret = -EINVAL;
-               goto unlock_out;
-       }
-
-       /* adjust the width to 16 pixel boundary */
-       rect.width = ((rect.width + 15) & ~0xf);
-
-       /* make sure parameters are valid */
-       if ((rect.left + rect.width >
-               vpfe_dev->std_info.active_pixels) ||
-           (rect.top + rect.height >
-               vpfe_dev->std_info.active_lines)) {
-               v4l2_err(&vpfe_dev->v4l2_dev, "Error in S_SELECTION params\n");
-               ret = -EINVAL;
-               goto unlock_out;
-       }
-       ccdc_dev->hw_ops.set_image_window(&rect);
-       vpfe_dev->fmt.fmt.pix.width = rect.width;
-       vpfe_dev->fmt.fmt.pix.height = rect.height;
-       vpfe_dev->fmt.fmt.pix.bytesperline =
-               ccdc_dev->hw_ops.get_line_length();
-       vpfe_dev->fmt.fmt.pix.sizeimage =
-               vpfe_dev->fmt.fmt.pix.bytesperline *
-               vpfe_dev->fmt.fmt.pix.height;
-       vpfe_dev->crop = rect;
-       sel->r = rect;
-unlock_out:
-       mutex_unlock(&vpfe_dev->lock);
-       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_g_pixelaspect    = vpfe_g_pixelaspect,
-       .vidioc_g_selection      = vpfe_g_selection,
-       .vidioc_s_selection      = vpfe_s_selection,
-};
-
-static struct vpfe_device *vpfe_initialize(void)
-{
-       struct vpfe_device *vpfe_dev;
-
-       /* Default number of buffers should be 3 */
-       if ((numbuffers > 0) &&
-           (numbuffers < config_params.min_numbuffers))
-               numbuffers = config_params.min_numbuffers;
-
-       /*
-        * Set buffer size to min buffers size if invalid buffer size is
-        * given
-        */
-       if (bufsize < config_params.min_bufsize)
-               bufsize = config_params.min_bufsize;
-
-       config_params.numbuffers = numbuffers;
-
-       if (numbuffers)
-               config_params.device_bufsize = bufsize;
-
-       /* Allocate memory for device objects */
-       vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL);
-
-       return vpfe_dev;
-}
-
-/*
- * vpfe_probe : This function creates device entries by register
- * itself to the V4L2 driver and initializes fields of each
- * device objects
- */
-static int vpfe_probe(struct platform_device *pdev)
-{
-       struct vpfe_subdev_info *sdinfo;
-       struct vpfe_config *vpfe_cfg;
-       struct resource *res1;
-       struct vpfe_device *vpfe_dev;
-       struct i2c_adapter *i2c_adap;
-       struct video_device *vfd;
-       int ret, i, j;
-       int num_subdevs = 0;
-
-       /* Get the pointer to the device object */
-       vpfe_dev = vpfe_initialize();
-
-       if (!vpfe_dev) {
-               v4l2_err(pdev->dev.driver,
-                       "Failed to allocate memory for vpfe_dev\n");
-               return -ENOMEM;
-       }
-
-       vpfe_dev->pdev = &pdev->dev;
-
-       if (!pdev->dev.platform_data) {
-               v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
-               ret = -ENODEV;
-               goto probe_free_dev_mem;
-       }
-
-       vpfe_cfg = pdev->dev.platform_data;
-       vpfe_dev->cfg = vpfe_cfg;
-       if (!vpfe_cfg->ccdc || !vpfe_cfg->card_name || !vpfe_cfg->sub_devs) {
-               v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n");
-               ret = -ENOENT;
-               goto probe_free_dev_mem;
-       }
-
-       /* Allocate memory for ccdc configuration */
-       ccdc_cfg = kmalloc(sizeof(*ccdc_cfg), GFP_KERNEL);
-       if (!ccdc_cfg) {
-               ret = -ENOMEM;
-               goto probe_free_dev_mem;
-       }
-
-       mutex_lock(&ccdc_lock);
-
-       strscpy(ccdc_cfg->name, vpfe_cfg->ccdc, sizeof(ccdc_cfg->name));
-       /* Get VINT0 irq resource */
-       res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!res1) {
-               v4l2_err(pdev->dev.driver,
-                        "Unable to get interrupt for VINT0\n");
-               ret = -ENODEV;
-               goto probe_free_ccdc_cfg_mem;
-       }
-       vpfe_dev->ccdc_irq0 = res1->start;
-
-       /* Get VINT1 irq resource */
-       res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
-       if (!res1) {
-               v4l2_err(pdev->dev.driver,
-                        "Unable to get interrupt for VINT1\n");
-               ret = -ENODEV;
-               goto probe_free_ccdc_cfg_mem;
-       }
-       vpfe_dev->ccdc_irq1 = res1->start;
-
-       ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, 0,
-                         "vpfe_capture0", vpfe_dev);
-
-       if (0 != ret) {
-               v4l2_err(pdev->dev.driver, "Unable to request interrupt\n");
-               goto probe_free_ccdc_cfg_mem;
-       }
-
-       vfd = &vpfe_dev->video_dev;
-       /* Initialize field of video device */
-       vfd->release            = video_device_release_empty;
-       vfd->fops               = &vpfe_fops;
-       vfd->ioctl_ops          = &vpfe_ioctl_ops;
-       vfd->tvnorms            = 0;
-       vfd->v4l2_dev           = &vpfe_dev->v4l2_dev;
-       vfd->device_caps        = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-       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);
-
-       ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev);
-       if (ret) {
-               v4l2_err(pdev->dev.driver,
-                       "Unable to register v4l2 device.\n");
-               goto probe_out_release_irq;
-       }
-       v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n");
-       spin_lock_init(&vpfe_dev->irqlock);
-       spin_lock_init(&vpfe_dev->dma_queue_lock);
-       mutex_init(&vpfe_dev->lock);
-
-       /* Initialize field of the device objects */
-       vpfe_dev->numbuffers = config_params.numbuffers;
-
-       /* register video device */
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
-               "trying to register vpfe device.\n");
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
-               "video_dev=%p\n", &vpfe_dev->video_dev);
-       vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       ret = video_register_device(&vpfe_dev->video_dev,
-                                   VFL_TYPE_VIDEO, -1);
-
-       if (ret) {
-               v4l2_err(pdev->dev.driver,
-                       "Unable to register video device.\n");
-               goto probe_out_v4l2_unregister;
-       }
-
-       v4l2_info(&vpfe_dev->v4l2_dev, "video device registered\n");
-       /* set the driver data in platform device */
-       platform_set_drvdata(pdev, vpfe_dev);
-       /* set driver private data */
-       video_set_drvdata(&vpfe_dev->video_dev, vpfe_dev);
-       i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id);
-       num_subdevs = vpfe_cfg->num_subdevs;
-       vpfe_dev->sd = kmalloc_array(num_subdevs,
-                                    sizeof(*vpfe_dev->sd),
-                                    GFP_KERNEL);
-       if (!vpfe_dev->sd) {
-               ret = -ENOMEM;
-               goto probe_out_video_unregister;
-       }
-
-       for (i = 0; i < num_subdevs; i++) {
-               struct v4l2_input *inps;
-
-               sdinfo = &vpfe_cfg->sub_devs[i];
-
-               /* Load up the subdevice */
-               vpfe_dev->sd[i] =
-                       v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
-                                                 i2c_adap,
-                                                 &sdinfo->board_info,
-                                                 NULL);
-               if (vpfe_dev->sd[i]) {
-                       v4l2_info(&vpfe_dev->v4l2_dev,
-                                 "v4l2 sub device %s registered\n",
-                                 sdinfo->name);
-                       vpfe_dev->sd[i]->grp_id = sdinfo->grp_id;
-                       /* update tvnorms from the sub devices */
-                       for (j = 0; j < sdinfo->num_inputs; j++) {
-                               inps = &sdinfo->inputs[j];
-                               vfd->tvnorms |= inps->std;
-                       }
-               } else {
-                       v4l2_info(&vpfe_dev->v4l2_dev,
-                                 "v4l2 sub device %s register fails\n",
-                                 sdinfo->name);
-                       ret = -ENXIO;
-                       goto probe_sd_out;
-               }
-       }
-
-       /* set first sub device as current one */
-       vpfe_dev->current_subdev = &vpfe_cfg->sub_devs[0];
-       vpfe_dev->v4l2_dev.ctrl_handler = vpfe_dev->sd[0]->ctrl_handler;
-
-       /* We have at least one sub device to work with */
-       mutex_unlock(&ccdc_lock);
-       return 0;
-
-probe_sd_out:
-       kfree(vpfe_dev->sd);
-probe_out_video_unregister:
-       video_unregister_device(&vpfe_dev->video_dev);
-probe_out_v4l2_unregister:
-       v4l2_device_unregister(&vpfe_dev->v4l2_dev);
-probe_out_release_irq:
-       free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
-probe_free_ccdc_cfg_mem:
-       kfree(ccdc_cfg);
-       mutex_unlock(&ccdc_lock);
-probe_free_dev_mem:
-       kfree(vpfe_dev);
-       return ret;
-}
-
-/*
- * vpfe_remove : It un-register device from V4L2 driver
- */
-static int vpfe_remove(struct platform_device *pdev)
-{
-       struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
-
-       v4l2_info(pdev->dev.driver, "vpfe_remove\n");
-
-       free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
-       kfree(vpfe_dev->sd);
-       v4l2_device_unregister(&vpfe_dev->v4l2_dev);
-       video_unregister_device(&vpfe_dev->video_dev);
-       kfree(vpfe_dev);
-       kfree(ccdc_cfg);
-       return 0;
-}
-
-static int vpfe_suspend(struct device *dev)
-{
-       return 0;
-}
-
-static int vpfe_resume(struct device *dev)
-{
-       return 0;
-}
-
-static const struct dev_pm_ops vpfe_dev_pm_ops = {
-       .suspend = vpfe_suspend,
-       .resume = vpfe_resume,
-};
-
-static struct platform_driver vpfe_driver = {
-       .driver = {
-               .name = CAPTURE_DRV_NAME,
-               .pm = &vpfe_dev_pm_ops,
-       },
-       .probe = vpfe_probe,
-       .remove = vpfe_remove,
-};
-
-module_platform_driver(vpfe_driver);
diff --git a/drivers/media/platform/davinci/vpif.c b/drivers/media/platform/davinci/vpif.c
deleted file mode 100644 (file)
index 97ef770..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * vpif - Video Port Interface driver
- * VPIF is a receiver and transmitter for video data. It has two channels(0, 1)
- * that receiving video byte stream and two channels(2, 3) for video output.
- * The hardware supports SDTV, HDTV formats, raw data capture.
- * Currently, the driver supports NTSC and PAL standards.
- *
- * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com/
- *
- * 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 version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/spinlock.h>
-#include <linux/v4l2-dv-timings.h>
-#include <linux/of_graph.h>
-
-#include "vpif.h"
-
-MODULE_DESCRIPTION("TI DaVinci Video Port Interface driver");
-MODULE_LICENSE("GPL");
-
-#define VPIF_DRIVER_NAME       "vpif"
-MODULE_ALIAS("platform:" VPIF_DRIVER_NAME);
-
-#define VPIF_CH0_MAX_MODES     22
-#define VPIF_CH1_MAX_MODES     2
-#define VPIF_CH2_MAX_MODES     15
-#define VPIF_CH3_MAX_MODES     2
-
-struct vpif_data {
-       struct platform_device *capture;
-       struct platform_device *display;
-};
-
-DEFINE_SPINLOCK(vpif_lock);
-EXPORT_SYMBOL_GPL(vpif_lock);
-
-void __iomem *vpif_base;
-EXPORT_SYMBOL_GPL(vpif_base);
-
-/*
- * vpif_ch_params: video standard configuration parameters for vpif
- *
- * The table must include all presets from supported subdevices.
- */
-const struct vpif_channel_config_params vpif_ch_params[] = {
-       /* HDTV formats */
-       {
-               .name = "480p59_94",
-               .width = 720,
-               .height = 480,
-               .frm_fmt = 1,
-               .ycmux_mode = 0,
-               .eav2sav = 138-8,
-               .sav2eav = 720,
-               .l1 = 1,
-               .l3 = 43,
-               .l5 = 523,
-               .vsize = 525,
-               .capture_format = 0,
-               .vbi_supported = 0,
-               .hd_sd = 1,
-               .dv_timings = V4L2_DV_BT_CEA_720X480P59_94,
-       },
-       {
-               .name = "576p50",
-               .width = 720,
-               .height = 576,
-               .frm_fmt = 1,
-               .ycmux_mode = 0,
-               .eav2sav = 144-8,
-               .sav2eav = 720,
-               .l1 = 1,
-               .l3 = 45,
-               .l5 = 621,
-               .vsize = 625,
-               .capture_format = 0,
-               .vbi_supported = 0,
-               .hd_sd = 1,
-               .dv_timings = V4L2_DV_BT_CEA_720X576P50,
-       },
-       {
-               .name = "720p50",
-               .width = 1280,
-               .height = 720,
-               .frm_fmt = 1,
-               .ycmux_mode = 0,
-               .eav2sav = 700-8,
-               .sav2eav = 1280,
-               .l1 = 1,
-               .l3 = 26,
-               .l5 = 746,
-               .vsize = 750,
-               .capture_format = 0,
-               .vbi_supported = 0,
-               .hd_sd = 1,
-               .dv_timings = V4L2_DV_BT_CEA_1280X720P50,
-       },
-       {
-               .name = "720p60",
-               .width = 1280,
-               .height = 720,
-               .frm_fmt = 1,
-               .ycmux_mode = 0,
-               .eav2sav = 370 - 8,
-               .sav2eav = 1280,
-               .l1 = 1,
-               .l3 = 26,
-               .l5 = 746,
-               .vsize = 750,
-               .capture_format = 0,
-               .vbi_supported = 0,
-               .hd_sd = 1,
-               .dv_timings = V4L2_DV_BT_CEA_1280X720P60,
-       },
-       {
-               .name = "1080I50",
-               .width = 1920,
-               .height = 1080,
-               .frm_fmt = 0,
-               .ycmux_mode = 0,
-               .eav2sav = 720 - 8,
-               .sav2eav = 1920,
-               .l1 = 1,
-               .l3 = 21,
-               .l5 = 561,
-               .l7 = 563,
-               .l9 = 584,
-               .l11 = 1124,
-               .vsize = 1125,
-               .capture_format = 0,
-               .vbi_supported = 0,
-               .hd_sd = 1,
-               .dv_timings = V4L2_DV_BT_CEA_1920X1080I50,
-       },
-       {
-               .name = "1080I60",
-               .width = 1920,
-               .height = 1080,
-               .frm_fmt = 0,
-               .ycmux_mode = 0,
-               .eav2sav = 280 - 8,
-               .sav2eav = 1920,
-               .l1 = 1,
-               .l3 = 21,
-               .l5 = 561,
-               .l7 = 563,
-               .l9 = 584,
-               .l11 = 1124,
-               .vsize = 1125,
-               .capture_format = 0,
-               .vbi_supported = 0,
-               .hd_sd = 1,
-               .dv_timings = V4L2_DV_BT_CEA_1920X1080I60,
-       },
-       {
-               .name = "1080p60",
-               .width = 1920,
-               .height = 1080,
-               .frm_fmt = 1,
-               .ycmux_mode = 0,
-               .eav2sav = 280 - 8,
-               .sav2eav = 1920,
-               .l1 = 1,
-               .l3 = 42,
-               .l5 = 1122,
-               .vsize = 1125,
-               .capture_format = 0,
-               .vbi_supported = 0,
-               .hd_sd = 1,
-               .dv_timings = V4L2_DV_BT_CEA_1920X1080P60,
-       },
-
-       /* SDTV formats */
-       {
-               .name = "NTSC_M",
-               .width = 720,
-               .height = 480,
-               .frm_fmt = 0,
-               .ycmux_mode = 1,
-               .eav2sav = 268,
-               .sav2eav = 1440,
-               .l1 = 1,
-               .l3 = 23,
-               .l5 = 263,
-               .l7 = 266,
-               .l9 = 286,
-               .l11 = 525,
-               .vsize = 525,
-               .capture_format = 0,
-               .vbi_supported = 1,
-               .hd_sd = 0,
-               .stdid = V4L2_STD_525_60,
-       },
-       {
-               .name = "PAL_BDGHIK",
-               .width = 720,
-               .height = 576,
-               .frm_fmt = 0,
-               .ycmux_mode = 1,
-               .eav2sav = 280,
-               .sav2eav = 1440,
-               .l1 = 1,
-               .l3 = 23,
-               .l5 = 311,
-               .l7 = 313,
-               .l9 = 336,
-               .l11 = 624,
-               .vsize = 625,
-               .capture_format = 0,
-               .vbi_supported = 1,
-               .hd_sd = 0,
-               .stdid = V4L2_STD_625_50,
-       },
-};
-EXPORT_SYMBOL_GPL(vpif_ch_params);
-
-const unsigned int vpif_ch_params_count = ARRAY_SIZE(vpif_ch_params);
-EXPORT_SYMBOL_GPL(vpif_ch_params_count);
-
-static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val)
-{
-       if (val)
-               vpif_set_bit(reg, bit);
-       else
-               vpif_clr_bit(reg, bit);
-}
-
-/* This structure is used to keep track of VPIF size register's offsets */
-struct vpif_registers {
-       u32 h_cfg, v_cfg_00, v_cfg_01, v_cfg_02, v_cfg, ch_ctrl;
-       u32 line_offset, vanc0_strt, vanc0_size, vanc1_strt;
-       u32 vanc1_size, width_mask, len_mask;
-       u8 max_modes;
-};
-
-static const struct vpif_registers vpifregs[VPIF_NUM_CHANNELS] = {
-       /* Channel0 */
-       {
-               VPIF_CH0_H_CFG, VPIF_CH0_V_CFG_00, VPIF_CH0_V_CFG_01,
-               VPIF_CH0_V_CFG_02, VPIF_CH0_V_CFG_03, VPIF_CH0_CTRL,
-               VPIF_CH0_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
-               VPIF_CH0_MAX_MODES,
-       },
-       /* Channel1 */
-       {
-               VPIF_CH1_H_CFG, VPIF_CH1_V_CFG_00, VPIF_CH1_V_CFG_01,
-               VPIF_CH1_V_CFG_02, VPIF_CH1_V_CFG_03, VPIF_CH1_CTRL,
-               VPIF_CH1_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
-               VPIF_CH1_MAX_MODES,
-       },
-       /* Channel2 */
-       {
-               VPIF_CH2_H_CFG, VPIF_CH2_V_CFG_00, VPIF_CH2_V_CFG_01,
-               VPIF_CH2_V_CFG_02, VPIF_CH2_V_CFG_03, VPIF_CH2_CTRL,
-               VPIF_CH2_IMG_ADD_OFST, VPIF_CH2_VANC0_STRT, VPIF_CH2_VANC0_SIZE,
-               VPIF_CH2_VANC1_STRT, VPIF_CH2_VANC1_SIZE, 0x7FF, 0x7FF,
-               VPIF_CH2_MAX_MODES
-       },
-       /* Channel3 */
-       {
-               VPIF_CH3_H_CFG, VPIF_CH3_V_CFG_00, VPIF_CH3_V_CFG_01,
-               VPIF_CH3_V_CFG_02, VPIF_CH3_V_CFG_03, VPIF_CH3_CTRL,
-               VPIF_CH3_IMG_ADD_OFST, VPIF_CH3_VANC0_STRT, VPIF_CH3_VANC0_SIZE,
-               VPIF_CH3_VANC1_STRT, VPIF_CH3_VANC1_SIZE, 0x7FF, 0x7FF,
-               VPIF_CH3_MAX_MODES
-       },
-};
-
-/* vpif_set_mode_info:
- * This function is used to set horizontal and vertical config parameters
- * As per the standard in the channel, configure the values of L1, L3,
- * L5, L7  L9, L11 in VPIF Register , also write width and height
- */
-static void vpif_set_mode_info(const struct vpif_channel_config_params *config,
-                               u8 channel_id, u8 config_channel_id)
-{
-       u32 value;
-
-       value = (config->eav2sav & vpifregs[config_channel_id].width_mask);
-       value <<= VPIF_CH_LEN_SHIFT;
-       value |= (config->sav2eav & vpifregs[config_channel_id].width_mask);
-       regw(value, vpifregs[channel_id].h_cfg);
-
-       value = (config->l1 & vpifregs[config_channel_id].len_mask);
-       value <<= VPIF_CH_LEN_SHIFT;
-       value |= (config->l3 & vpifregs[config_channel_id].len_mask);
-       regw(value, vpifregs[channel_id].v_cfg_00);
-
-       value = (config->l5 & vpifregs[config_channel_id].len_mask);
-       value <<= VPIF_CH_LEN_SHIFT;
-       value |= (config->l7 & vpifregs[config_channel_id].len_mask);
-       regw(value, vpifregs[channel_id].v_cfg_01);
-
-       value = (config->l9 & vpifregs[config_channel_id].len_mask);
-       value <<= VPIF_CH_LEN_SHIFT;
-       value |= (config->l11 & vpifregs[config_channel_id].len_mask);
-       regw(value, vpifregs[channel_id].v_cfg_02);
-
-       value = (config->vsize & vpifregs[config_channel_id].len_mask);
-       regw(value, vpifregs[channel_id].v_cfg);
-}
-
-/* config_vpif_params
- * Function to set the parameters of a channel
- * Mainly modifies the channel ciontrol register
- * It sets frame format, yc mux mode
- */
-static void config_vpif_params(struct vpif_params *vpifparams,
-                               u8 channel_id, u8 found)
-{
-       const struct vpif_channel_config_params *config = &vpifparams->std_info;
-       u32 value, ch_nip, reg;
-       u8 start, end;
-       int i;
-
-       start = channel_id;
-       end = channel_id + found;
-
-       for (i = start; i < end; i++) {
-               reg = vpifregs[i].ch_ctrl;
-               if (channel_id < 2)
-                       ch_nip = VPIF_CAPTURE_CH_NIP;
-               else
-                       ch_nip = VPIF_DISPLAY_CH_NIP;
-
-               vpif_wr_bit(reg, ch_nip, config->frm_fmt);
-               vpif_wr_bit(reg, VPIF_CH_YC_MUX_BIT, config->ycmux_mode);
-               vpif_wr_bit(reg, VPIF_CH_INPUT_FIELD_FRAME_BIT,
-                                       vpifparams->video_params.storage_mode);
-
-               /* Set raster scanning SDR Format */
-               vpif_clr_bit(reg, VPIF_CH_SDR_FMT_BIT);
-               vpif_wr_bit(reg, VPIF_CH_DATA_MODE_BIT, config->capture_format);
-
-               if (channel_id > 1)     /* Set the Pixel enable bit */
-                       vpif_set_bit(reg, VPIF_DISPLAY_PIX_EN_BIT);
-               else if (config->capture_format) {
-                       /* Set the polarity of various pins */
-                       vpif_wr_bit(reg, VPIF_CH_FID_POLARITY_BIT,
-                                       vpifparams->iface.fid_pol);
-                       vpif_wr_bit(reg, VPIF_CH_V_VALID_POLARITY_BIT,
-                                       vpifparams->iface.vd_pol);
-                       vpif_wr_bit(reg, VPIF_CH_H_VALID_POLARITY_BIT,
-                                       vpifparams->iface.hd_pol);
-
-                       value = regr(reg);
-                       /* Set data width */
-                       value &= ~(0x3u <<
-                                       VPIF_CH_DATA_WIDTH_BIT);
-                       value |= ((vpifparams->params.data_sz) <<
-                                                    VPIF_CH_DATA_WIDTH_BIT);
-                       regw(value, reg);
-               }
-
-               /* Write the pitch in the driver */
-               regw((vpifparams->video_params.hpitch),
-                                               vpifregs[i].line_offset);
-       }
-}
-
-/* vpif_set_video_params
- * This function is used to set video parameters in VPIF register
- */
-int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id)
-{
-       const struct vpif_channel_config_params *config = &vpifparams->std_info;
-       int found = 1;
-
-       vpif_set_mode_info(config, channel_id, channel_id);
-       if (!config->ycmux_mode) {
-               /* YC are on separate channels (HDTV formats) */
-               vpif_set_mode_info(config, channel_id + 1, channel_id);
-               found = 2;
-       }
-
-       config_vpif_params(vpifparams, channel_id, found);
-
-       regw(0x80, VPIF_REQ_SIZE);
-       regw(0x01, VPIF_EMULATION_CTRL);
-
-       return found;
-}
-EXPORT_SYMBOL(vpif_set_video_params);
-
-void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
-                               u8 channel_id)
-{
-       u32 value;
-
-       value = 0x3F8 & (vbiparams->hstart0);
-       value |= 0x3FFFFFF & ((vbiparams->vstart0) << 16);
-       regw(value, vpifregs[channel_id].vanc0_strt);
-
-       value = 0x3F8 & (vbiparams->hstart1);
-       value |= 0x3FFFFFF & ((vbiparams->vstart1) << 16);
-       regw(value, vpifregs[channel_id].vanc1_strt);
-
-       value = 0x3F8 & (vbiparams->hsize0);
-       value |= 0x3FFFFFF & ((vbiparams->vsize0) << 16);
-       regw(value, vpifregs[channel_id].vanc0_size);
-
-       value = 0x3F8 & (vbiparams->hsize1);
-       value |= 0x3FFFFFF & ((vbiparams->vsize1) << 16);
-       regw(value, vpifregs[channel_id].vanc1_size);
-
-}
-EXPORT_SYMBOL(vpif_set_vbi_display_params);
-
-int vpif_channel_getfid(u8 channel_id)
-{
-       return (regr(vpifregs[channel_id].ch_ctrl) & VPIF_CH_FID_MASK)
-                                       >> VPIF_CH_FID_SHIFT;
-}
-EXPORT_SYMBOL(vpif_channel_getfid);
-
-static void vpif_pdev_release(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-
-       kfree(pdev);
-}
-
-static int vpif_probe(struct platform_device *pdev)
-{
-       static struct resource res_irq;
-       struct platform_device *pdev_capture, *pdev_display;
-       struct device_node *endpoint = NULL;
-       struct vpif_data *data;
-       int ret;
-       int irq;
-
-       vpif_base = devm_platform_ioremap_resource(pdev, 0);
-       if (IS_ERR(vpif_base))
-               return PTR_ERR(vpif_base);
-
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-
-       platform_set_drvdata(pdev, data);
-
-       pm_runtime_enable(&pdev->dev);
-       pm_runtime_get(&pdev->dev);
-
-       /*
-        * If VPIF Node has endpoints, assume "new" DT support,
-        * where capture and display drivers don't have DT nodes
-        * so their devices need to be registered manually here
-        * for their legacy platform_drivers to work.
-        */
-       endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
-                                             endpoint);
-       if (!endpoint)
-               return 0;
-
-       /*
-        * For DT platforms, manually create platform_devices for
-        * capture/display drivers.
-        */
-       irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               ret = irq;
-               goto err_put_rpm;
-       }
-       res_irq = (struct resource)DEFINE_RES_IRQ_NAMED(irq, of_node_full_name(pdev->dev.of_node));
-       res_irq.flags |= irq_get_trigger_type(irq);
-
-       pdev_capture = kzalloc(sizeof(*pdev_capture), GFP_KERNEL);
-       if (!pdev_capture) {
-               ret = -ENOMEM;
-               goto err_put_rpm;
-       }
-
-       pdev_capture->name = "vpif_capture";
-       pdev_capture->id = -1;
-       pdev_capture->resource = &res_irq;
-       pdev_capture->num_resources = 1;
-       pdev_capture->dev.dma_mask = pdev->dev.dma_mask;
-       pdev_capture->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
-       pdev_capture->dev.parent = &pdev->dev;
-       pdev_capture->dev.release = vpif_pdev_release;
-
-       ret = platform_device_register(pdev_capture);
-       if (ret)
-               goto err_put_pdev_capture;
-
-       pdev_display = kzalloc(sizeof(*pdev_display), GFP_KERNEL);
-       if (!pdev_display) {
-               ret = -ENOMEM;
-               goto err_put_pdev_capture;
-       }
-
-       pdev_display->name = "vpif_display";
-       pdev_display->id = -1;
-       pdev_display->resource = &res_irq;
-       pdev_display->num_resources = 1;
-       pdev_display->dev.dma_mask = pdev->dev.dma_mask;
-       pdev_display->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
-       pdev_display->dev.parent = &pdev->dev;
-       pdev_display->dev.release = vpif_pdev_release;
-
-       ret = platform_device_register(pdev_display);
-       if (ret)
-               goto err_put_pdev_display;
-
-       data->capture = pdev_capture;
-       data->display = pdev_display;
-
-       return 0;
-
-err_put_pdev_display:
-       platform_device_put(pdev_display);
-err_put_pdev_capture:
-       platform_device_put(pdev_capture);
-err_put_rpm:
-       pm_runtime_put(&pdev->dev);
-       pm_runtime_disable(&pdev->dev);
-       kfree(data);
-
-       return ret;
-}
-
-static int vpif_remove(struct platform_device *pdev)
-{
-       struct vpif_data *data = platform_get_drvdata(pdev);
-
-       if (data->capture)
-               platform_device_unregister(data->capture);
-       if (data->display)
-               platform_device_unregister(data->display);
-
-       pm_runtime_put(&pdev->dev);
-       pm_runtime_disable(&pdev->dev);
-
-       kfree(data);
-
-       return 0;
-}
-
-#ifdef CONFIG_PM
-static int vpif_suspend(struct device *dev)
-{
-       pm_runtime_put(dev);
-       return 0;
-}
-
-static int vpif_resume(struct device *dev)
-{
-       pm_runtime_get(dev);
-       return 0;
-}
-
-static const struct dev_pm_ops vpif_pm = {
-       .suspend        = vpif_suspend,
-       .resume         = vpif_resume,
-};
-
-#define vpif_pm_ops (&vpif_pm)
-#else
-#define vpif_pm_ops NULL
-#endif
-
-#if IS_ENABLED(CONFIG_OF)
-static const struct of_device_id vpif_of_match[] = {
-       { .compatible = "ti,da850-vpif", },
-       { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, vpif_of_match);
-#endif
-
-static struct platform_driver vpif_driver = {
-       .driver = {
-               .of_match_table = of_match_ptr(vpif_of_match),
-               .name   = VPIF_DRIVER_NAME,
-               .pm     = vpif_pm_ops,
-       },
-       .remove = vpif_remove,
-       .probe = vpif_probe,
-};
-
-static void vpif_exit(void)
-{
-       platform_driver_unregister(&vpif_driver);
-}
-
-static int __init vpif_init(void)
-{
-       return platform_driver_register(&vpif_driver);
-}
-subsys_initcall(vpif_init);
-module_exit(vpif_exit);
-
diff --git a/drivers/media/platform/davinci/vpif.h b/drivers/media/platform/davinci/vpif.h
deleted file mode 100644 (file)
index c6d1d89..0000000
+++ /dev/null
@@ -1,688 +0,0 @@
-/*
- * VPIF header file
- *
- * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com/
- *
- * 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 version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef VPIF_H
-#define VPIF_H
-
-#include <linux/io.h>
-#include <linux/videodev2.h>
-#include <media/davinci/vpif_types.h>
-
-/* Maximum channel allowed */
-#define VPIF_NUM_CHANNELS              (4)
-#define VPIF_CAPTURE_NUM_CHANNELS      (2)
-#define VPIF_DISPLAY_NUM_CHANNELS      (2)
-
-/* Macros to read/write registers */
-extern void __iomem *vpif_base;
-extern spinlock_t vpif_lock;
-
-#define regr(reg)               readl((reg) + vpif_base)
-#define regw(value, reg)        writel(value, (reg + vpif_base))
-
-/* Register Address Offsets */
-#define VPIF_PID                       (0x0000)
-#define VPIF_CH0_CTRL                  (0x0004)
-#define VPIF_CH1_CTRL                  (0x0008)
-#define VPIF_CH2_CTRL                  (0x000C)
-#define VPIF_CH3_CTRL                  (0x0010)
-
-#define VPIF_INTEN                     (0x0020)
-#define VPIF_INTEN_SET                 (0x0024)
-#define VPIF_INTEN_CLR                 (0x0028)
-#define VPIF_STATUS                    (0x002C)
-#define VPIF_STATUS_CLR                        (0x0030)
-#define VPIF_EMULATION_CTRL            (0x0034)
-#define VPIF_REQ_SIZE                  (0x0038)
-
-#define VPIF_CH0_TOP_STRT_ADD_LUMA     (0x0040)
-#define VPIF_CH0_BTM_STRT_ADD_LUMA     (0x0044)
-#define VPIF_CH0_TOP_STRT_ADD_CHROMA   (0x0048)
-#define VPIF_CH0_BTM_STRT_ADD_CHROMA   (0x004c)
-#define VPIF_CH0_TOP_STRT_ADD_HANC     (0x0050)
-#define VPIF_CH0_BTM_STRT_ADD_HANC     (0x0054)
-#define VPIF_CH0_TOP_STRT_ADD_VANC     (0x0058)
-#define VPIF_CH0_BTM_STRT_ADD_VANC     (0x005c)
-#define VPIF_CH0_SP_CFG                        (0x0060)
-#define VPIF_CH0_IMG_ADD_OFST          (0x0064)
-#define VPIF_CH0_HANC_ADD_OFST         (0x0068)
-#define VPIF_CH0_H_CFG                 (0x006c)
-#define VPIF_CH0_V_CFG_00              (0x0070)
-#define VPIF_CH0_V_CFG_01              (0x0074)
-#define VPIF_CH0_V_CFG_02              (0x0078)
-#define VPIF_CH0_V_CFG_03              (0x007c)
-
-#define VPIF_CH1_TOP_STRT_ADD_LUMA     (0x0080)
-#define VPIF_CH1_BTM_STRT_ADD_LUMA     (0x0084)
-#define VPIF_CH1_TOP_STRT_ADD_CHROMA   (0x0088)
-#define VPIF_CH1_BTM_STRT_ADD_CHROMA   (0x008c)
-#define VPIF_CH1_TOP_STRT_ADD_HANC     (0x0090)
-#define VPIF_CH1_BTM_STRT_ADD_HANC     (0x0094)
-#define VPIF_CH1_TOP_STRT_ADD_VANC     (0x0098)
-#define VPIF_CH1_BTM_STRT_ADD_VANC     (0x009c)
-#define VPIF_CH1_SP_CFG                        (0x00a0)
-#define VPIF_CH1_IMG_ADD_OFST          (0x00a4)
-#define VPIF_CH1_HANC_ADD_OFST         (0x00a8)
-#define VPIF_CH1_H_CFG                 (0x00ac)
-#define VPIF_CH1_V_CFG_00              (0x00b0)
-#define VPIF_CH1_V_CFG_01              (0x00b4)
-#define VPIF_CH1_V_CFG_02              (0x00b8)
-#define VPIF_CH1_V_CFG_03              (0x00bc)
-
-#define VPIF_CH2_TOP_STRT_ADD_LUMA     (0x00c0)
-#define VPIF_CH2_BTM_STRT_ADD_LUMA     (0x00c4)
-#define VPIF_CH2_TOP_STRT_ADD_CHROMA   (0x00c8)
-#define VPIF_CH2_BTM_STRT_ADD_CHROMA   (0x00cc)
-#define VPIF_CH2_TOP_STRT_ADD_HANC     (0x00d0)
-#define VPIF_CH2_BTM_STRT_ADD_HANC     (0x00d4)
-#define VPIF_CH2_TOP_STRT_ADD_VANC     (0x00d8)
-#define VPIF_CH2_BTM_STRT_ADD_VANC     (0x00dc)
-#define VPIF_CH2_SP_CFG                        (0x00e0)
-#define VPIF_CH2_IMG_ADD_OFST          (0x00e4)
-#define VPIF_CH2_HANC_ADD_OFST         (0x00e8)
-#define VPIF_CH2_H_CFG                 (0x00ec)
-#define VPIF_CH2_V_CFG_00              (0x00f0)
-#define VPIF_CH2_V_CFG_01              (0x00f4)
-#define VPIF_CH2_V_CFG_02              (0x00f8)
-#define VPIF_CH2_V_CFG_03              (0x00fc)
-#define VPIF_CH2_HANC0_STRT            (0x0100)
-#define VPIF_CH2_HANC0_SIZE            (0x0104)
-#define VPIF_CH2_HANC1_STRT            (0x0108)
-#define VPIF_CH2_HANC1_SIZE            (0x010c)
-#define VPIF_CH2_VANC0_STRT            (0x0110)
-#define VPIF_CH2_VANC0_SIZE            (0x0114)
-#define VPIF_CH2_VANC1_STRT            (0x0118)
-#define VPIF_CH2_VANC1_SIZE            (0x011c)
-
-#define VPIF_CH3_TOP_STRT_ADD_LUMA     (0x0140)
-#define VPIF_CH3_BTM_STRT_ADD_LUMA     (0x0144)
-#define VPIF_CH3_TOP_STRT_ADD_CHROMA   (0x0148)
-#define VPIF_CH3_BTM_STRT_ADD_CHROMA   (0x014c)
-#define VPIF_CH3_TOP_STRT_ADD_HANC     (0x0150)
-#define VPIF_CH3_BTM_STRT_ADD_HANC     (0x0154)
-#define VPIF_CH3_TOP_STRT_ADD_VANC     (0x0158)
-#define VPIF_CH3_BTM_STRT_ADD_VANC     (0x015c)
-#define VPIF_CH3_SP_CFG                        (0x0160)
-#define VPIF_CH3_IMG_ADD_OFST          (0x0164)
-#define VPIF_CH3_HANC_ADD_OFST         (0x0168)
-#define VPIF_CH3_H_CFG                 (0x016c)
-#define VPIF_CH3_V_CFG_00              (0x0170)
-#define VPIF_CH3_V_CFG_01              (0x0174)
-#define VPIF_CH3_V_CFG_02              (0x0178)
-#define VPIF_CH3_V_CFG_03              (0x017c)
-#define VPIF_CH3_HANC0_STRT            (0x0180)
-#define VPIF_CH3_HANC0_SIZE            (0x0184)
-#define VPIF_CH3_HANC1_STRT            (0x0188)
-#define VPIF_CH3_HANC1_SIZE            (0x018c)
-#define VPIF_CH3_VANC0_STRT            (0x0190)
-#define VPIF_CH3_VANC0_SIZE            (0x0194)
-#define VPIF_CH3_VANC1_STRT            (0x0198)
-#define VPIF_CH3_VANC1_SIZE            (0x019c)
-
-#define VPIF_IODFT_CTRL                        (0x01c0)
-
-/* Functions for bit Manipulation */
-static inline void vpif_set_bit(u32 reg, u32 bit)
-{
-       regw((regr(reg)) | (0x01 << bit), reg);
-}
-
-static inline void vpif_clr_bit(u32 reg, u32 bit)
-{
-       regw(((regr(reg)) & ~(0x01 << bit)), reg);
-}
-
-/* Macro for Generating mask */
-#ifdef GENERATE_MASK
-#undef GENERATE_MASK
-#endif
-
-#define GENERATE_MASK(bits, pos) \
-               ((((0xFFFFFFFF) << (32 - bits)) >> (32 - bits)) << pos)
-
-/* Bit positions in the channel control registers */
-#define VPIF_CH_DATA_MODE_BIT  (2)
-#define VPIF_CH_YC_MUX_BIT     (3)
-#define VPIF_CH_SDR_FMT_BIT    (4)
-#define VPIF_CH_HANC_EN_BIT    (8)
-#define VPIF_CH_VANC_EN_BIT    (9)
-
-#define VPIF_CAPTURE_CH_NIP    (10)
-#define VPIF_DISPLAY_CH_NIP    (11)
-
-#define VPIF_DISPLAY_PIX_EN_BIT        (10)
-
-#define VPIF_CH_INPUT_FIELD_FRAME_BIT  (12)
-
-#define VPIF_CH_FID_POLARITY_BIT       (15)
-#define VPIF_CH_V_VALID_POLARITY_BIT   (14)
-#define VPIF_CH_H_VALID_POLARITY_BIT   (13)
-#define VPIF_CH_DATA_WIDTH_BIT         (28)
-
-#define VPIF_CH_CLK_EDGE_CTRL_BIT      (31)
-
-/* Mask various length */
-#define VPIF_CH_EAVSAV_MASK    GENERATE_MASK(13, 0)
-#define VPIF_CH_LEN_MASK       GENERATE_MASK(12, 0)
-#define VPIF_CH_WIDTH_MASK     GENERATE_MASK(13, 0)
-#define VPIF_CH_LEN_SHIFT      (16)
-
-/* VPIF masks for registers */
-#define VPIF_REQ_SIZE_MASK     (0x1ff)
-
-/* bit posotion of interrupt vpif_ch_intr register */
-#define VPIF_INTEN_FRAME_CH0   (0x00000001)
-#define VPIF_INTEN_FRAME_CH1   (0x00000002)
-#define VPIF_INTEN_FRAME_CH2   (0x00000004)
-#define VPIF_INTEN_FRAME_CH3   (0x00000008)
-
-/* bit position of clock and channel enable in vpif_chn_ctrl register */
-
-#define VPIF_CH0_CLK_EN                (0x00000002)
-#define VPIF_CH0_EN            (0x00000001)
-#define VPIF_CH1_CLK_EN                (0x00000002)
-#define VPIF_CH1_EN            (0x00000001)
-#define VPIF_CH2_CLK_EN                (0x00000002)
-#define VPIF_CH2_EN            (0x00000001)
-#define VPIF_CH3_CLK_EN                (0x00000002)
-#define VPIF_CH3_EN            (0x00000001)
-#define VPIF_CH_CLK_EN         (0x00000002)
-#define VPIF_CH_EN             (0x00000001)
-
-#define VPIF_INT_TOP   (0x00)
-#define VPIF_INT_BOTTOM        (0x01)
-#define VPIF_INT_BOTH  (0x02)
-
-#define VPIF_CH0_INT_CTRL_SHIFT        (6)
-#define VPIF_CH1_INT_CTRL_SHIFT        (6)
-#define VPIF_CH2_INT_CTRL_SHIFT        (6)
-#define VPIF_CH3_INT_CTRL_SHIFT        (6)
-#define VPIF_CH_INT_CTRL_SHIFT (6)
-
-#define VPIF_CH2_CLIP_ANC_EN   14
-#define VPIF_CH2_CLIP_ACTIVE_EN        13
-
-#define VPIF_CH3_CLIP_ANC_EN   14
-#define VPIF_CH3_CLIP_ACTIVE_EN        13
-
-/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
-#define channel0_intr_assert() (regw((regr(VPIF_CH0_CTRL)|\
-       (VPIF_INT_BOTH << VPIF_CH0_INT_CTRL_SHIFT)), VPIF_CH0_CTRL))
-
-/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
-#define channel1_intr_assert() (regw((regr(VPIF_CH1_CTRL)|\
-       (VPIF_INT_BOTH << VPIF_CH1_INT_CTRL_SHIFT)), VPIF_CH1_CTRL))
-
-/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
-#define channel2_intr_assert() (regw((regr(VPIF_CH2_CTRL)|\
-       (VPIF_INT_BOTH << VPIF_CH2_INT_CTRL_SHIFT)), VPIF_CH2_CTRL))
-
-/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
-#define channel3_intr_assert() (regw((regr(VPIF_CH3_CTRL)|\
-       (VPIF_INT_BOTH << VPIF_CH3_INT_CTRL_SHIFT)), VPIF_CH3_CTRL))
-
-#define VPIF_CH_FID_MASK       (0x20)
-#define VPIF_CH_FID_SHIFT      (5)
-
-#define VPIF_NTSC_VBI_START_FIELD0     (1)
-#define VPIF_NTSC_VBI_START_FIELD1     (263)
-#define VPIF_PAL_VBI_START_FIELD0      (624)
-#define VPIF_PAL_VBI_START_FIELD1      (311)
-
-#define VPIF_NTSC_HBI_START_FIELD0     (1)
-#define VPIF_NTSC_HBI_START_FIELD1     (263)
-#define VPIF_PAL_HBI_START_FIELD0      (624)
-#define VPIF_PAL_HBI_START_FIELD1      (311)
-
-#define VPIF_NTSC_VBI_COUNT_FIELD0     (20)
-#define VPIF_NTSC_VBI_COUNT_FIELD1     (19)
-#define VPIF_PAL_VBI_COUNT_FIELD0      (24)
-#define VPIF_PAL_VBI_COUNT_FIELD1      (25)
-
-#define VPIF_NTSC_HBI_COUNT_FIELD0     (263)
-#define VPIF_NTSC_HBI_COUNT_FIELD1     (262)
-#define VPIF_PAL_HBI_COUNT_FIELD0      (312)
-#define VPIF_PAL_HBI_COUNT_FIELD1      (313)
-
-#define VPIF_NTSC_VBI_SAMPLES_PER_LINE (720)
-#define VPIF_PAL_VBI_SAMPLES_PER_LINE  (720)
-#define VPIF_NTSC_HBI_SAMPLES_PER_LINE (268)
-#define VPIF_PAL_HBI_SAMPLES_PER_LINE  (280)
-
-#define VPIF_CH_VANC_EN                        (0x20)
-#define VPIF_DMA_REQ_SIZE              (0x080)
-#define VPIF_EMULATION_DISABLE         (0x01)
-
-extern u8 irq_vpif_capture_channel[VPIF_NUM_CHANNELS];
-
-/* inline function to enable/disable channel0 */
-static inline void enable_channel0(int enable)
-{
-       if (enable)
-               regw((regr(VPIF_CH0_CTRL) | (VPIF_CH0_EN)), VPIF_CH0_CTRL);
-       else
-               regw((regr(VPIF_CH0_CTRL) & (~VPIF_CH0_EN)), VPIF_CH0_CTRL);
-}
-
-/* inline function to enable/disable channel1 */
-static inline void enable_channel1(int enable)
-{
-       if (enable)
-               regw((regr(VPIF_CH1_CTRL) | (VPIF_CH1_EN)), VPIF_CH1_CTRL);
-       else
-               regw((regr(VPIF_CH1_CTRL) & (~VPIF_CH1_EN)), VPIF_CH1_CTRL);
-}
-
-/* inline function to enable interrupt for channel0 */
-static inline void channel0_intr_enable(int enable)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&vpif_lock, flags);
-
-       if (enable) {
-               regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
-               regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
-
-               regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH0), VPIF_INTEN);
-               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
-                                                       VPIF_INTEN_SET);
-       } else {
-               regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH0)), VPIF_INTEN);
-               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
-                                                       VPIF_INTEN_SET);
-       }
-       spin_unlock_irqrestore(&vpif_lock, flags);
-}
-
-/* inline function to enable interrupt for channel1 */
-static inline void channel1_intr_enable(int enable)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&vpif_lock, flags);
-
-       if (enable) {
-               regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
-               regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
-
-               regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH1), VPIF_INTEN);
-               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
-                                                       VPIF_INTEN_SET);
-       } else {
-               regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH1)), VPIF_INTEN);
-               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
-                                                       VPIF_INTEN_SET);
-       }
-       spin_unlock_irqrestore(&vpif_lock, flags);
-}
-
-/* inline function to set buffer addresses in case of Y/C non mux mode */
-static inline void ch0_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
-                                                unsigned long btm_strt_luma,
-                                                unsigned long top_strt_chroma,
-                                                unsigned long btm_strt_chroma)
-{
-       regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
-       regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
-       regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
-       regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
-}
-
-/* inline function to set buffer addresses in VPIF registers for video data */
-static inline void ch0_set_videobuf_addr(unsigned long top_strt_luma,
-                                        unsigned long btm_strt_luma,
-                                        unsigned long top_strt_chroma,
-                                        unsigned long btm_strt_chroma)
-{
-       regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
-       regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
-       regw(top_strt_chroma, VPIF_CH0_TOP_STRT_ADD_CHROMA);
-       regw(btm_strt_chroma, VPIF_CH0_BTM_STRT_ADD_CHROMA);
-}
-
-static inline void ch1_set_videobuf_addr(unsigned long top_strt_luma,
-                                        unsigned long btm_strt_luma,
-                                        unsigned long top_strt_chroma,
-                                        unsigned long btm_strt_chroma)
-{
-
-       regw(top_strt_luma, VPIF_CH1_TOP_STRT_ADD_LUMA);
-       regw(btm_strt_luma, VPIF_CH1_BTM_STRT_ADD_LUMA);
-       regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
-       regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
-}
-
-static inline void ch0_set_vbi_addr(unsigned long top_vbi,
-       unsigned long btm_vbi, unsigned long a, unsigned long b)
-{
-       regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_VANC);
-       regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_VANC);
-}
-
-static inline void ch0_set_hbi_addr(unsigned long top_vbi,
-       unsigned long btm_vbi, unsigned long a, unsigned long b)
-{
-       regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_HANC);
-       regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_HANC);
-}
-
-static inline void ch1_set_vbi_addr(unsigned long top_vbi,
-       unsigned long btm_vbi, unsigned long a, unsigned long b)
-{
-       regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_VANC);
-       regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_VANC);
-}
-
-static inline void ch1_set_hbi_addr(unsigned long top_vbi,
-       unsigned long btm_vbi, unsigned long a, unsigned long b)
-{
-       regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_HANC);
-       regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_HANC);
-}
-
-/* Inline function to enable raw vbi in the given channel */
-static inline void disable_raw_feature(u8 channel_id, u8 index)
-{
-       u32 ctrl_reg;
-       if (0 == channel_id)
-               ctrl_reg = VPIF_CH0_CTRL;
-       else
-               ctrl_reg = VPIF_CH1_CTRL;
-
-       if (1 == index)
-               vpif_clr_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
-       else
-               vpif_clr_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
-}
-
-static inline void enable_raw_feature(u8 channel_id, u8 index)
-{
-       u32 ctrl_reg;
-       if (0 == channel_id)
-               ctrl_reg = VPIF_CH0_CTRL;
-       else
-               ctrl_reg = VPIF_CH1_CTRL;
-
-       if (1 == index)
-               vpif_set_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
-       else
-               vpif_set_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
-}
-
-/* inline function to enable/disable channel2 */
-static inline void enable_channel2(int enable)
-{
-       if (enable) {
-               regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
-               regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_EN)), VPIF_CH2_CTRL);
-       } else {
-               regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
-               regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_EN)), VPIF_CH2_CTRL);
-       }
-}
-
-/* inline function to enable/disable channel3 */
-static inline void enable_channel3(int enable)
-{
-       if (enable) {
-               regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
-               regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_EN)), VPIF_CH3_CTRL);
-       } else {
-               regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
-               regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_EN)), VPIF_CH3_CTRL);
-       }
-}
-
-/* inline function to enable interrupt for channel2 */
-static inline void channel2_intr_enable(int enable)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&vpif_lock, flags);
-
-       if (enable) {
-               regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
-               regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
-               regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH2), VPIF_INTEN);
-               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
-                                                       VPIF_INTEN_SET);
-       } else {
-               regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH2)), VPIF_INTEN);
-               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
-                                                       VPIF_INTEN_SET);
-       }
-       spin_unlock_irqrestore(&vpif_lock, flags);
-}
-
-/* inline function to enable interrupt for channel3 */
-static inline void channel3_intr_enable(int enable)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&vpif_lock, flags);
-
-       if (enable) {
-               regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
-               regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
-
-               regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH3), VPIF_INTEN);
-               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
-                                                       VPIF_INTEN_SET);
-       } else {
-               regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH3)), VPIF_INTEN);
-               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
-                                                       VPIF_INTEN_SET);
-       }
-       spin_unlock_irqrestore(&vpif_lock, flags);
-}
-
-/* inline function to enable raw vbi data for channel2 */
-static inline void channel2_raw_enable(int enable, u8 index)
-{
-       u32 mask;
-
-       if (1 == index)
-               mask = VPIF_CH_VANC_EN_BIT;
-       else
-               mask = VPIF_CH_HANC_EN_BIT;
-
-       if (enable)
-               vpif_set_bit(VPIF_CH2_CTRL, mask);
-       else
-               vpif_clr_bit(VPIF_CH2_CTRL, mask);
-}
-
-/* inline function to enable raw vbi data for channel3*/
-static inline void channel3_raw_enable(int enable, u8 index)
-{
-       u32 mask;
-
-       if (1 == index)
-               mask = VPIF_CH_VANC_EN_BIT;
-       else
-               mask = VPIF_CH_HANC_EN_BIT;
-
-       if (enable)
-               vpif_set_bit(VPIF_CH3_CTRL, mask);
-       else
-               vpif_clr_bit(VPIF_CH3_CTRL, mask);
-}
-
-/* function to enable clipping (for both active and blanking regions) on ch 2 */
-static inline void channel2_clipping_enable(int enable)
-{
-       if (enable) {
-               vpif_set_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ANC_EN);
-               vpif_set_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ACTIVE_EN);
-       } else {
-               vpif_clr_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ANC_EN);
-               vpif_clr_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ACTIVE_EN);
-       }
-}
-
-/* function to enable clipping (for both active and blanking regions) on ch 3 */
-static inline void channel3_clipping_enable(int enable)
-{
-       if (enable) {
-               vpif_set_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ANC_EN);
-               vpif_set_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ACTIVE_EN);
-       } else {
-               vpif_clr_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ANC_EN);
-               vpif_clr_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ACTIVE_EN);
-       }
-}
-
-/* inline function to set buffer addresses in case of Y/C non mux mode */
-static inline void ch2_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
-                                                unsigned long btm_strt_luma,
-                                                unsigned long top_strt_chroma,
-                                                unsigned long btm_strt_chroma)
-{
-       regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
-       regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
-       regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
-       regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
-}
-
-/* inline function to set buffer addresses in VPIF registers for video data */
-static inline void ch2_set_videobuf_addr(unsigned long top_strt_luma,
-                                        unsigned long btm_strt_luma,
-                                        unsigned long top_strt_chroma,
-                                        unsigned long btm_strt_chroma)
-{
-       regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
-       regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
-       regw(top_strt_chroma, VPIF_CH2_TOP_STRT_ADD_CHROMA);
-       regw(btm_strt_chroma, VPIF_CH2_BTM_STRT_ADD_CHROMA);
-}
-
-static inline void ch3_set_videobuf_addr(unsigned long top_strt_luma,
-                                        unsigned long btm_strt_luma,
-                                        unsigned long top_strt_chroma,
-                                        unsigned long btm_strt_chroma)
-{
-       regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_LUMA);
-       regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_LUMA);
-       regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
-       regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
-}
-
-/* inline function to set buffer addresses in VPIF registers for vbi data */
-static inline void ch2_set_vbi_addr(unsigned long top_strt_luma,
-                                        unsigned long btm_strt_luma,
-                                        unsigned long top_strt_chroma,
-                                        unsigned long btm_strt_chroma)
-{
-       regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_VANC);
-       regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_VANC);
-}
-
-static inline void ch3_set_vbi_addr(unsigned long top_strt_luma,
-                                        unsigned long btm_strt_luma,
-                                        unsigned long top_strt_chroma,
-                                        unsigned long btm_strt_chroma)
-{
-       regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_VANC);
-       regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_VANC);
-}
-
-static inline int vpif_intr_status(int channel)
-{
-       int status = 0;
-       int mask;
-
-       if (channel < 0 || channel > 3)
-               return 0;
-
-       mask = 1 << channel;
-       status = regr(VPIF_STATUS) & mask;
-       regw(status, VPIF_STATUS_CLR);
-
-       return status;
-}
-
-#define VPIF_MAX_NAME  (30)
-
-/* This structure will store size parameters as per the mode selected by user */
-struct vpif_channel_config_params {
-       char name[VPIF_MAX_NAME];       /* Name of the mode */
-       u16 width;                      /* Indicates width of the image */
-       u16 height;                     /* Indicates height of the image */
-       u8 frm_fmt;                     /* Interlaced (0) or progressive (1) */
-       u8 ycmux_mode;                  /* This mode requires one (0) or two (1)
-                                          channels */
-       u16 eav2sav;                    /* length of eav 2 sav */
-       u16 sav2eav;                    /* length of sav 2 eav */
-       u16 l1, l3, l5, l7, l9, l11;    /* Other parameter configurations */
-       u16 vsize;                      /* Vertical size of the image */
-       u8 capture_format;              /* Indicates whether capture format
-                                        * is in BT or in CCD/CMOS */
-       u8  vbi_supported;              /* Indicates whether this mode
-                                        * supports capturing vbi or not */
-       u8 hd_sd;                       /* HDTV (1) or SDTV (0) format */
-       v4l2_std_id stdid;              /* SDTV format */
-       struct v4l2_dv_timings dv_timings;      /* HDTV format */
-};
-
-extern const unsigned int vpif_ch_params_count;
-extern const struct vpif_channel_config_params vpif_ch_params[];
-
-struct vpif_video_params;
-struct vpif_params;
-struct vpif_vbi_params;
-
-int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id);
-void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
-                                                       u8 channel_id);
-int vpif_channel_getfid(u8 channel_id);
-
-enum data_size {
-       _8BITS = 0,
-       _10BITS,
-       _12BITS,
-};
-
-/* Structure for vpif parameters for raw vbi data */
-struct vpif_vbi_params {
-       __u32 hstart0;  /* Horizontal start of raw vbi data for first field */
-       __u32 vstart0;  /* Vertical start of raw vbi data for first field */
-       __u32 hsize0;   /* Horizontal size of raw vbi data for first field */
-       __u32 vsize0;   /* Vertical size of raw vbi data for first field */
-       __u32 hstart1;  /* Horizontal start of raw vbi data for second field */
-       __u32 vstart1;  /* Vertical start of raw vbi data for second field */
-       __u32 hsize1;   /* Horizontal size of raw vbi data for second field */
-       __u32 vsize1;   /* Vertical size of raw vbi data for second field */
-};
-
-/* structure for vpif parameters */
-struct vpif_video_params {
-       __u8 storage_mode;      /* Indicates field or frame mode */
-       unsigned long hpitch;
-       v4l2_std_id stdid;
-};
-
-struct vpif_params {
-       struct vpif_interface iface;
-       struct vpif_video_params video_params;
-       struct vpif_channel_config_params std_info;
-       union param {
-               struct vpif_vbi_params  vbi_params;
-               enum data_size data_sz;
-       } params;
-};
-
-#endif                         /* End of #ifndef VPIF_H */
-
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
deleted file mode 100644 (file)
index bf76c5c..0000000
+++ /dev/null
@@ -1,1823 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2009 Texas Instruments Inc
- * Copyright (C) 2014 Lad, Prabhakar <prabhakar.csengg@gmail.com>
- *
- * TODO : add support for VBI & HBI data service
- *       add static buffer allocation
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/of_graph.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <media/v4l2-fwnode.h>
-#include <media/v4l2-ioctl.h>
-#include <media/i2c/tvp514x.h>
-#include <media/v4l2-mediabus.h>
-
-#include <linux/videodev2.h>
-
-#include "vpif.h"
-#include "vpif_capture.h"
-
-MODULE_DESCRIPTION("TI DaVinci VPIF Capture driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(VPIF_CAPTURE_VERSION);
-
-#define vpif_err(fmt, arg...)  v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
-#define vpif_dbg(level, debug, fmt, arg...)    \
-               v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
-
-static int debug = 1;
-
-module_param(debug, int, 0644);
-
-MODULE_PARM_DESC(debug, "Debug level 0-1");
-
-#define VPIF_DRIVER_NAME       "vpif_capture"
-MODULE_ALIAS("platform:" VPIF_DRIVER_NAME);
-
-/* global variables */
-static struct vpif_device vpif_obj = { {NULL} };
-static struct device *vpif_dev;
-static void vpif_calculate_offsets(struct channel_obj *ch);
-static void vpif_config_addr(struct channel_obj *ch, int muxmode);
-
-static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] = { {1, 1} };
-
-/* Is set to 1 in case of SDTV formats, 2 in case of HDTV formats. */
-static int ycmux_mode;
-
-static inline
-struct vpif_cap_buffer *to_vpif_buffer(struct vb2_v4l2_buffer *vb)
-{
-       return container_of(vb, struct vpif_cap_buffer, vb);
-}
-
-/**
- * vpif_buffer_prepare :  callback function for buffer prepare
- * @vb: ptr to vb2_buffer
- *
- * This is the callback function for buffer prepare when vb2_qbuf()
- * function is called. The buffer is prepared and user space virtual address
- * or user address is converted into  physical address
- */
-static int vpif_buffer_prepare(struct vb2_buffer *vb)
-{
-       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-       struct vb2_queue *q = vb->vb2_queue;
-       struct channel_obj *ch = vb2_get_drv_priv(q);
-       struct common_obj *common;
-       unsigned long addr;
-
-       vpif_dbg(2, debug, "vpif_buffer_prepare\n");
-
-       common = &ch->common[VPIF_VIDEO_INDEX];
-
-       vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
-       if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
-               return -EINVAL;
-
-       vbuf->field = common->fmt.fmt.pix.field;
-
-       addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-       if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
-               !IS_ALIGNED((addr + common->ybtm_off), 8) ||
-               !IS_ALIGNED((addr + common->ctop_off), 8) ||
-               !IS_ALIGNED((addr + common->cbtm_off), 8)) {
-               vpif_dbg(1, debug, "offset is not aligned\n");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/**
- * vpif_buffer_queue_setup : Callback function for buffer setup.
- * @vq: vb2_queue ptr
- * @nbuffers: ptr to number of buffers requested by application
- * @nplanes: contains number of distinct video planes needed to hold a frame
- * @sizes: contains the size (in bytes) of each plane.
- * @alloc_devs: ptr to allocation context
- *
- * This callback function is called when reqbuf() is called to adjust
- * the buffer count and buffer size
- */
-static int vpif_buffer_queue_setup(struct vb2_queue *vq,
-                               unsigned int *nbuffers, unsigned int *nplanes,
-                               unsigned int sizes[], struct device *alloc_devs[])
-{
-       struct channel_obj *ch = vb2_get_drv_priv(vq);
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       unsigned size = common->fmt.fmt.pix.sizeimage;
-
-       vpif_dbg(2, debug, "vpif_buffer_setup\n");
-
-       if (*nplanes) {
-               if (sizes[0] < size)
-                       return -EINVAL;
-               size = sizes[0];
-       }
-
-       if (vq->num_buffers + *nbuffers < 3)
-               *nbuffers = 3 - vq->num_buffers;
-
-       *nplanes = 1;
-       sizes[0] = size;
-
-       /* Calculate the offset for Y and C data in the buffer */
-       vpif_calculate_offsets(ch);
-
-       return 0;
-}
-
-/**
- * vpif_buffer_queue : Callback function to add buffer to DMA queue
- * @vb: ptr to vb2_buffer
- */
-static void vpif_buffer_queue(struct vb2_buffer *vb)
-{
-       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-       struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
-       struct vpif_cap_buffer *buf = to_vpif_buffer(vbuf);
-       struct common_obj *common;
-       unsigned long flags;
-
-       common = &ch->common[VPIF_VIDEO_INDEX];
-
-       vpif_dbg(2, debug, "vpif_buffer_queue\n");
-
-       spin_lock_irqsave(&common->irqlock, flags);
-       /* add the buffer to the DMA queue */
-       list_add_tail(&buf->list, &common->dma_queue);
-       spin_unlock_irqrestore(&common->irqlock, flags);
-}
-
-/**
- * vpif_start_streaming : Starts the DMA engine for streaming
- * @vq: ptr to vb2_buffer
- * @count: number of buffers
- */
-static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-       struct vpif_capture_config *vpif_config_data =
-                                       vpif_dev->platform_data;
-       struct channel_obj *ch = vb2_get_drv_priv(vq);
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct vpif_params *vpif = &ch->vpifparams;
-       struct vpif_cap_buffer *buf, *tmp;
-       unsigned long addr, flags;
-       int ret;
-
-       /* Initialize field_id */
-       ch->field_id = 0;
-
-       /* configure 1 or 2 channel mode */
-       if (vpif_config_data->setup_input_channel_mode) {
-               ret = vpif_config_data->
-                       setup_input_channel_mode(vpif->std_info.ycmux_mode);
-               if (ret < 0) {
-                       vpif_dbg(1, debug, "can't set vpif channel mode\n");
-                       goto err;
-               }
-       }
-
-       ret = v4l2_subdev_call(ch->sd, video, s_stream, 1);
-       if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
-               vpif_dbg(1, debug, "stream on failed in subdev\n");
-               goto err;
-       }
-
-       /* Call vpif_set_params function to set the parameters and addresses */
-       ret = vpif_set_video_params(vpif, ch->channel_id);
-       if (ret < 0) {
-               vpif_dbg(1, debug, "can't set video params\n");
-               goto err;
-       }
-
-       ycmux_mode = ret;
-       vpif_config_addr(ch, ret);
-
-       /* Get the next frame from the buffer queue */
-       spin_lock_irqsave(&common->irqlock, flags);
-       common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
-                                   struct vpif_cap_buffer, list);
-       /* Remove buffer from the buffer queue */
-       list_del(&common->cur_frm->list);
-       spin_unlock_irqrestore(&common->irqlock, flags);
-
-       addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb.vb2_buf, 0);
-
-       common->set_addr(addr + common->ytop_off,
-                        addr + common->ybtm_off,
-                        addr + common->ctop_off,
-                        addr + common->cbtm_off);
-
-       /**
-        * Set interrupt for both the fields in VPIF Register enable channel in
-        * VPIF register
-        */
-       channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
-       if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
-               channel0_intr_assert();
-               channel0_intr_enable(1);
-               enable_channel0(1);
-       }
-       if (VPIF_CHANNEL1_VIDEO == ch->channel_id ||
-               ycmux_mode == 2) {
-               channel1_intr_assert();
-               channel1_intr_enable(1);
-               enable_channel1(1);
-       }
-
-       return 0;
-
-err:
-       spin_lock_irqsave(&common->irqlock, flags);
-       list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
-               list_del(&buf->list);
-               vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
-       }
-       spin_unlock_irqrestore(&common->irqlock, flags);
-
-       return ret;
-}
-
-/**
- * vpif_stop_streaming : Stop the DMA engine
- * @vq: ptr to vb2_queue
- *
- * This callback stops the DMA engine and any remaining buffers
- * in the DMA queue are released.
- */
-static void vpif_stop_streaming(struct vb2_queue *vq)
-{
-       struct channel_obj *ch = vb2_get_drv_priv(vq);
-       struct common_obj *common;
-       unsigned long flags;
-       int ret;
-
-       common = &ch->common[VPIF_VIDEO_INDEX];
-
-       /* Disable channel as per its device type and channel id */
-       if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
-               enable_channel0(0);
-               channel0_intr_enable(0);
-       }
-       if (VPIF_CHANNEL1_VIDEO == ch->channel_id ||
-               ycmux_mode == 2) {
-               enable_channel1(0);
-               channel1_intr_enable(0);
-       }
-
-       ycmux_mode = 0;
-
-       ret = v4l2_subdev_call(ch->sd, video, s_stream, 0);
-       if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
-               vpif_dbg(1, debug, "stream off failed in subdev\n");
-
-       /* release all active buffers */
-       if (common->cur_frm == common->next_frm) {
-               vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
-                               VB2_BUF_STATE_ERROR);
-       } else {
-               if (common->cur_frm)
-                       vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
-                                       VB2_BUF_STATE_ERROR);
-               if (common->next_frm)
-                       vb2_buffer_done(&common->next_frm->vb.vb2_buf,
-                                       VB2_BUF_STATE_ERROR);
-       }
-
-       spin_lock_irqsave(&common->irqlock, flags);
-       while (!list_empty(&common->dma_queue)) {
-               common->next_frm = list_entry(common->dma_queue.next,
-                                               struct vpif_cap_buffer, list);
-               list_del(&common->next_frm->list);
-               vb2_buffer_done(&common->next_frm->vb.vb2_buf,
-                               VB2_BUF_STATE_ERROR);
-       }
-       spin_unlock_irqrestore(&common->irqlock, flags);
-}
-
-static const struct vb2_ops video_qops = {
-       .queue_setup            = vpif_buffer_queue_setup,
-       .buf_prepare            = vpif_buffer_prepare,
-       .start_streaming        = vpif_start_streaming,
-       .stop_streaming         = vpif_stop_streaming,
-       .buf_queue              = vpif_buffer_queue,
-       .wait_prepare           = vb2_ops_wait_prepare,
-       .wait_finish            = vb2_ops_wait_finish,
-};
-
-/**
- * vpif_process_buffer_complete: process a completed buffer
- * @common: ptr to common channel object
- *
- * This function time stamp the buffer and mark it as DONE. It also
- * wake up any process waiting on the QUEUE and set the next buffer
- * as current
- */
-static void vpif_process_buffer_complete(struct common_obj *common)
-{
-       common->cur_frm->vb.vb2_buf.timestamp = ktime_get_ns();
-       vb2_buffer_done(&common->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
-       /* Make curFrm pointing to nextFrm */
-       common->cur_frm = common->next_frm;
-}
-
-/**
- * vpif_schedule_next_buffer: set next buffer address for capture
- * @common : ptr to common channel object
- *
- * This function will get next buffer from the dma queue and
- * set the buffer address in the vpif register for capture.
- * the buffer is marked active
- */
-static void vpif_schedule_next_buffer(struct common_obj *common)
-{
-       unsigned long addr = 0;
-
-       spin_lock(&common->irqlock);
-       common->next_frm = list_entry(common->dma_queue.next,
-                                    struct vpif_cap_buffer, list);
-       /* Remove that buffer from the buffer queue */
-       list_del(&common->next_frm->list);
-       spin_unlock(&common->irqlock);
-       addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb.vb2_buf, 0);
-
-       /* Set top and bottom field addresses in VPIF registers */
-       common->set_addr(addr + common->ytop_off,
-                        addr + common->ybtm_off,
-                        addr + common->ctop_off,
-                        addr + common->cbtm_off);
-}
-
-/**
- * vpif_channel_isr : ISR handler for vpif capture
- * @irq: irq number
- * @dev_id: dev_id ptr
- *
- * It changes status of the captured buffer, takes next buffer from the queue
- * and sets its address in VPIF registers
- */
-static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
-{
-       struct vpif_device *dev = &vpif_obj;
-       struct common_obj *common;
-       struct channel_obj *ch;
-       int channel_id;
-       int fid = -1, i;
-
-       channel_id = *(int *)(dev_id);
-       if (!vpif_intr_status(channel_id))
-               return IRQ_NONE;
-
-       ch = dev->dev[channel_id];
-
-       for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) {
-               common = &ch->common[i];
-               /* skip If streaming is not started in this channel */
-               /* Check the field format */
-               if (1 == ch->vpifparams.std_info.frm_fmt ||
-                   common->fmt.fmt.pix.field == V4L2_FIELD_NONE) {
-                       /* Progressive mode */
-                       spin_lock(&common->irqlock);
-                       if (list_empty(&common->dma_queue)) {
-                               spin_unlock(&common->irqlock);
-                               continue;
-                       }
-                       spin_unlock(&common->irqlock);
-
-                       if (!channel_first_int[i][channel_id])
-                               vpif_process_buffer_complete(common);
-
-                       channel_first_int[i][channel_id] = 0;
-
-                       vpif_schedule_next_buffer(common);
-
-
-                       channel_first_int[i][channel_id] = 0;
-               } else {
-                       /**
-                        * Interlaced mode. If it is first interrupt, ignore
-                        * it
-                        */
-                       if (channel_first_int[i][channel_id]) {
-                               channel_first_int[i][channel_id] = 0;
-                               continue;
-                       }
-                       if (0 == i) {
-                               ch->field_id ^= 1;
-                               /* Get field id from VPIF registers */
-                               fid = vpif_channel_getfid(ch->channel_id);
-                               if (fid != ch->field_id) {
-                                       /**
-                                        * If field id does not match stored
-                                        * field id, make them in sync
-                                        */
-                                       if (0 == fid)
-                                               ch->field_id = fid;
-                                       return IRQ_HANDLED;
-                               }
-                       }
-                       /* device field id and local field id are in sync */
-                       if (0 == fid) {
-                               /* this is even field */
-                               if (common->cur_frm == common->next_frm)
-                                       continue;
-
-                               /* mark the current buffer as done */
-                               vpif_process_buffer_complete(common);
-                       } else if (1 == fid) {
-                               /* odd field */
-                               spin_lock(&common->irqlock);
-                               if (list_empty(&common->dma_queue) ||
-                                   (common->cur_frm != common->next_frm)) {
-                                       spin_unlock(&common->irqlock);
-                                       continue;
-                               }
-                               spin_unlock(&common->irqlock);
-
-                               vpif_schedule_next_buffer(common);
-                       }
-               }
-       }
-       return IRQ_HANDLED;
-}
-
-/**
- * vpif_update_std_info() - update standard related info
- * @ch: ptr to channel object
- *
- * For a given standard selected by application, update values
- * in the device data structures
- */
-static int vpif_update_std_info(struct channel_obj *ch)
-{
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct vpif_params *vpifparams = &ch->vpifparams;
-       const struct vpif_channel_config_params *config;
-       struct vpif_channel_config_params *std_info = &vpifparams->std_info;
-       struct video_obj *vid_ch = &ch->video;
-       int index;
-       struct v4l2_pix_format *pixfmt = &common->fmt.fmt.pix;
-
-       vpif_dbg(2, debug, "vpif_update_std_info\n");
-
-       /*
-        * if called after try_fmt or g_fmt, there will already be a size
-        * so use that by default.
-        */
-       if (pixfmt->width && pixfmt->height) {
-               if (pixfmt->field == V4L2_FIELD_ANY ||
-                   pixfmt->field == V4L2_FIELD_NONE)
-                       pixfmt->field = V4L2_FIELD_NONE;
-
-               vpifparams->iface.if_type = VPIF_IF_BT656;
-               if (pixfmt->pixelformat == V4L2_PIX_FMT_SGRBG10 ||
-                   pixfmt->pixelformat == V4L2_PIX_FMT_SBGGR8)
-                       vpifparams->iface.if_type = VPIF_IF_RAW_BAYER;
-
-               if (pixfmt->pixelformat == V4L2_PIX_FMT_SGRBG10)
-                       vpifparams->params.data_sz = 1; /* 10 bits/pixel.  */
-
-               /*
-                * For raw formats from camera sensors, we don't need
-                * the std_info from table lookup, so nothing else to do here.
-                */
-               if (vpifparams->iface.if_type == VPIF_IF_RAW_BAYER) {
-                       memset(std_info, 0, sizeof(struct vpif_channel_config_params));
-                       vpifparams->std_info.capture_format = 1; /* CCD/raw mode */
-                       return 0;
-               }
-       }
-
-       for (index = 0; index < vpif_ch_params_count; index++) {
-               config = &vpif_ch_params[index];
-               if (config->hd_sd == 0) {
-                       vpif_dbg(2, debug, "SD format\n");
-                       if (config->stdid & vid_ch->stdid) {
-                               memcpy(std_info, config, sizeof(*config));
-                               break;
-                       }
-               } else {
-                       vpif_dbg(2, debug, "HD format\n");
-                       if (!memcmp(&config->dv_timings, &vid_ch->dv_timings,
-                               sizeof(vid_ch->dv_timings))) {
-                               memcpy(std_info, config, sizeof(*config));
-                               break;
-                       }
-               }
-       }
-
-       /* standard not found */
-       if (index == vpif_ch_params_count)
-               return -EINVAL;
-
-       common->fmt.fmt.pix.width = std_info->width;
-       common->width = std_info->width;
-       common->fmt.fmt.pix.height = std_info->height;
-       common->height = std_info->height;
-       common->fmt.fmt.pix.sizeimage = common->height * common->width * 2;
-       common->fmt.fmt.pix.bytesperline = std_info->width;
-       vpifparams->video_params.hpitch = std_info->width;
-       vpifparams->video_params.storage_mode = std_info->frm_fmt;
-
-       if (vid_ch->stdid)
-               common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-       else
-               common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
-
-       if (ch->vpifparams.std_info.frm_fmt)
-               common->fmt.fmt.pix.field = V4L2_FIELD_NONE;
-       else
-               common->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
-
-       if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
-               common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
-       else
-               common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV16;
-
-       common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-       return 0;
-}
-
-/**
- * vpif_calculate_offsets : This function calculates buffers offsets
- * @ch : ptr to channel object
- *
- * This function calculates buffer offsets for Y and C in the top and
- * bottom field
- */
-static void vpif_calculate_offsets(struct channel_obj *ch)
-{
-       unsigned int hpitch, sizeimage;
-       struct video_obj *vid_ch = &(ch->video);
-       struct vpif_params *vpifparams = &ch->vpifparams;
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       enum v4l2_field field = common->fmt.fmt.pix.field;
-
-       vpif_dbg(2, debug, "vpif_calculate_offsets\n");
-
-       if (V4L2_FIELD_ANY == field) {
-               if (vpifparams->std_info.frm_fmt)
-                       vid_ch->buf_field = V4L2_FIELD_NONE;
-               else
-                       vid_ch->buf_field = V4L2_FIELD_INTERLACED;
-       } else
-               vid_ch->buf_field = common->fmt.fmt.pix.field;
-
-       sizeimage = common->fmt.fmt.pix.sizeimage;
-
-       hpitch = common->fmt.fmt.pix.bytesperline;
-
-       if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
-           (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
-               /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
-               common->ytop_off = 0;
-               common->ybtm_off = hpitch;
-               common->ctop_off = sizeimage / 2;
-               common->cbtm_off = sizeimage / 2 + hpitch;
-       } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
-               /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
-               common->ytop_off = 0;
-               common->ybtm_off = sizeimage / 4;
-               common->ctop_off = sizeimage / 2;
-               common->cbtm_off = common->ctop_off + sizeimage / 4;
-       } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
-               /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
-               common->ybtm_off = 0;
-               common->ytop_off = sizeimage / 4;
-               common->cbtm_off = sizeimage / 2;
-               common->ctop_off = common->cbtm_off + sizeimage / 4;
-       }
-       if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
-           (V4L2_FIELD_INTERLACED == vid_ch->buf_field))
-               vpifparams->video_params.storage_mode = 1;
-       else
-               vpifparams->video_params.storage_mode = 0;
-
-       if (1 == vpifparams->std_info.frm_fmt)
-               vpifparams->video_params.hpitch =
-                   common->fmt.fmt.pix.bytesperline;
-       else {
-               if ((field == V4L2_FIELD_ANY)
-                   || (field == V4L2_FIELD_INTERLACED))
-                       vpifparams->video_params.hpitch =
-                           common->fmt.fmt.pix.bytesperline * 2;
-               else
-                       vpifparams->video_params.hpitch =
-                           common->fmt.fmt.pix.bytesperline;
-       }
-
-       ch->vpifparams.video_params.stdid = vpifparams->std_info.stdid;
-}
-
-/**
- * vpif_config_addr() - function to configure buffer address in vpif
- * @ch: channel ptr
- * @muxmode: channel mux mode
- */
-static void vpif_config_addr(struct channel_obj *ch, int muxmode)
-{
-       struct common_obj *common;
-
-       vpif_dbg(2, debug, "vpif_config_addr\n");
-
-       common = &(ch->common[VPIF_VIDEO_INDEX]);
-
-       if (VPIF_CHANNEL1_VIDEO == ch->channel_id)
-               common->set_addr = ch1_set_videobuf_addr;
-       else if (2 == muxmode)
-               common->set_addr = ch0_set_videobuf_addr_yc_nmux;
-       else
-               common->set_addr = ch0_set_videobuf_addr;
-}
-
-/**
- * vpif_input_to_subdev() - Maps input to sub device
- * @vpif_cfg: global config ptr
- * @chan_cfg: channel config ptr
- * @input_index: Given input index from application
- *
- * lookup the sub device information for a given input index.
- * we report all the inputs to application. inputs table also
- * has sub device name for the each input
- */
-static int vpif_input_to_subdev(
-               struct vpif_capture_config *vpif_cfg,
-               struct vpif_capture_chan_config *chan_cfg,
-               int input_index)
-{
-       struct vpif_subdev_info *subdev_info;
-       const char *subdev_name;
-       int i;
-
-       vpif_dbg(2, debug, "vpif_input_to_subdev\n");
-
-       if (!chan_cfg)
-               return -1;
-       if (input_index >= chan_cfg->input_count)
-               return -1;
-       subdev_name = chan_cfg->inputs[input_index].subdev_name;
-       if (!subdev_name)
-               return -1;
-
-       /* loop through the sub device list to get the sub device info */
-       for (i = 0; i < vpif_cfg->subdev_count; i++) {
-               subdev_info = &vpif_cfg->subdev_info[i];
-               if (subdev_info && !strcmp(subdev_info->name, subdev_name))
-                       return i;
-       }
-       return -1;
-}
-
-/**
- * vpif_set_input() - Select an input
- * @vpif_cfg: global config ptr
- * @ch: channel
- * @index: Given input index from application
- *
- * Select the given input.
- */
-static int vpif_set_input(
-               struct vpif_capture_config *vpif_cfg,
-               struct channel_obj *ch,
-               int index)
-{
-       struct vpif_capture_chan_config *chan_cfg =
-                       &vpif_cfg->chan_config[ch->channel_id];
-       struct vpif_subdev_info *subdev_info = NULL;
-       struct v4l2_subdev *sd = NULL;
-       u32 input = 0, output = 0;
-       int sd_index;
-       int ret;
-
-       sd_index = vpif_input_to_subdev(vpif_cfg, chan_cfg, index);
-       if (sd_index >= 0) {
-               sd = vpif_obj.sd[sd_index];
-               subdev_info = &vpif_cfg->subdev_info[sd_index];
-       } else {
-               /* no subdevice, no input to setup */
-               return 0;
-       }
-
-       /* first setup input path from sub device to vpif */
-       if (sd && vpif_cfg->setup_input_path) {
-               ret = vpif_cfg->setup_input_path(ch->channel_id,
-                                      subdev_info->name);
-               if (ret < 0) {
-                       vpif_dbg(1, debug, "couldn't setup input path for the" \
-                       " sub device %s, for input index %d\n",
-                       subdev_info->name, index);
-                       return ret;
-               }
-       }
-
-       if (sd) {
-               input = chan_cfg->inputs[index].input_route;
-               output = chan_cfg->inputs[index].output_route;
-               ret = v4l2_subdev_call(sd, video, s_routing,
-                               input, output, 0);
-               if (ret < 0 && ret != -ENOIOCTLCMD) {
-                       vpif_dbg(1, debug, "Failed to set input\n");
-                       return ret;
-               }
-       }
-       ch->input_idx = index;
-       ch->sd = sd;
-       /* copy interface parameters to vpif */
-       ch->vpifparams.iface = chan_cfg->vpif_if;
-
-       /* update tvnorms from the sub device input info */
-       ch->video_dev.tvnorms = chan_cfg->inputs[index].input.std;
-       return 0;
-}
-
-/**
- * vpif_querystd() - querystd handler
- * @file: file ptr
- * @priv: file handle
- * @std_id: ptr to std id
- *
- * This function is called to detect standard at the selected input
- */
-static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
-{
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       int ret;
-
-       vpif_dbg(2, debug, "vpif_querystd\n");
-
-       /* Call querystd function of decoder device */
-       ret = v4l2_subdev_call(ch->sd, video, querystd, std_id);
-
-       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
-               return -ENODATA;
-       if (ret) {
-               vpif_dbg(1, debug, "Failed to query standard for sub devices\n");
-               return ret;
-       }
-
-       return 0;
-}
-
-/**
- * vpif_g_std() - get STD handler
- * @file: file ptr
- * @priv: file handle
- * @std: ptr to std id
- */
-static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
-{
-       struct vpif_capture_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct vpif_capture_chan_config *chan_cfg;
-       struct v4l2_input input;
-
-       vpif_dbg(2, debug, "vpif_g_std\n");
-
-       if (!config->chan_config[ch->channel_id].inputs)
-               return -ENODATA;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-       input = chan_cfg->inputs[ch->input_idx].input;
-       if (input.capabilities != V4L2_IN_CAP_STD)
-               return -ENODATA;
-
-       *std = ch->video.stdid;
-       return 0;
-}
-
-/**
- * vpif_s_std() - set STD handler
- * @file: file ptr
- * @priv: file handle
- * @std_id: ptr to std id
- */
-static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
-{
-       struct vpif_capture_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct vpif_capture_chan_config *chan_cfg;
-       struct v4l2_input input;
-       int ret;
-
-       vpif_dbg(2, debug, "vpif_s_std\n");
-
-       if (!config->chan_config[ch->channel_id].inputs)
-               return -ENODATA;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-       input = chan_cfg->inputs[ch->input_idx].input;
-       if (input.capabilities != V4L2_IN_CAP_STD)
-               return -ENODATA;
-
-       if (vb2_is_busy(&common->buffer_queue))
-               return -EBUSY;
-
-       /* Call encoder subdevice function to set the standard */
-       ch->video.stdid = std_id;
-       memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
-
-       /* Get the information about the standard */
-       if (vpif_update_std_info(ch)) {
-               vpif_err("Error getting the standard info\n");
-               return -EINVAL;
-       }
-
-       /* set standard in the sub device */
-       ret = v4l2_subdev_call(ch->sd, video, s_std, std_id);
-       if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
-               vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
-               return ret;
-       }
-       return 0;
-}
-
-/**
- * vpif_enum_input() - ENUMINPUT handler
- * @file: file ptr
- * @priv: file handle
- * @input: ptr to input structure
- */
-static int vpif_enum_input(struct file *file, void *priv,
-                               struct v4l2_input *input)
-{
-
-       struct vpif_capture_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct vpif_capture_chan_config *chan_cfg;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-
-       if (input->index >= chan_cfg->input_count)
-               return -EINVAL;
-
-       memcpy(input, &chan_cfg->inputs[input->index].input,
-               sizeof(*input));
-       return 0;
-}
-
-/**
- * vpif_g_input() - Get INPUT handler
- * @file: file ptr
- * @priv: file handle
- * @index: ptr to input index
- */
-static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
-{
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-
-       *index = ch->input_idx;
-       return 0;
-}
-
-/**
- * vpif_s_input() - Set INPUT handler
- * @file: file ptr
- * @priv: file handle
- * @index: input index
- */
-static int vpif_s_input(struct file *file, void *priv, unsigned int index)
-{
-       struct vpif_capture_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct vpif_capture_chan_config *chan_cfg;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-
-       if (index >= chan_cfg->input_count)
-               return -EINVAL;
-
-       if (vb2_is_busy(&common->buffer_queue))
-               return -EBUSY;
-
-       return vpif_set_input(config, ch, index);
-}
-
-/**
- * vpif_enum_fmt_vid_cap() - ENUM_FMT handler
- * @file: file ptr
- * @priv: file handle
- * @fmt: ptr to V4L2 format descriptor
- */
-static int vpif_enum_fmt_vid_cap(struct file *file, void  *priv,
-                                       struct v4l2_fmtdesc *fmt)
-{
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-
-       if (fmt->index != 0) {
-               vpif_dbg(1, debug, "Invalid format index\n");
-               return -EINVAL;
-       }
-
-       /* Fill in the information about format */
-       if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
-               fmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
-       else
-               fmt->pixelformat = V4L2_PIX_FMT_NV16;
-       return 0;
-}
-
-/**
- * vpif_try_fmt_vid_cap() - TRY_FMT handler
- * @file: file ptr
- * @priv: file handle
- * @fmt: ptr to v4l2 format structure
- */
-static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
-                               struct v4l2_format *fmt)
-{
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-       struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
-
-       common->fmt = *fmt;
-       vpif_update_std_info(ch);
-
-       pixfmt->field = common->fmt.fmt.pix.field;
-       pixfmt->colorspace = common->fmt.fmt.pix.colorspace;
-       pixfmt->bytesperline = common->fmt.fmt.pix.width;
-       pixfmt->width = common->fmt.fmt.pix.width;
-       pixfmt->height = common->fmt.fmt.pix.height;
-       pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2;
-       if (pixfmt->pixelformat == V4L2_PIX_FMT_SGRBG10) {
-               pixfmt->bytesperline = common->fmt.fmt.pix.width * 2;
-               pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
-       }
-
-       dev_dbg(vpif_dev, "%s: %d x %d; pitch=%d pixelformat=0x%08x, field=%d, size=%d\n", __func__,
-               pixfmt->width, pixfmt->height,
-               pixfmt->bytesperline, pixfmt->pixelformat,
-               pixfmt->field, pixfmt->sizeimage);
-
-       return 0;
-}
-
-
-/**
- * vpif_g_fmt_vid_cap() - Set INPUT handler
- * @file: file ptr
- * @priv: file handle
- * @fmt: ptr to v4l2 format structure
- */
-static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
-                               struct v4l2_format *fmt)
-{
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct v4l2_pix_format *pix_fmt = &fmt->fmt.pix;
-       struct v4l2_subdev_format format = {
-               .which = V4L2_SUBDEV_FORMAT_ACTIVE,
-       };
-       struct v4l2_mbus_framefmt *mbus_fmt = &format.format;
-       int ret;
-
-       /* Check the validity of the buffer type */
-       if (common->fmt.type != fmt->type)
-               return -EINVAL;
-
-       /* By default, use currently set fmt */
-       *fmt = common->fmt;
-
-       /* If subdev has get_fmt, use that to override */
-       ret = v4l2_subdev_call(ch->sd, pad, get_fmt, NULL, &format);
-       if (!ret && mbus_fmt->code) {
-               v4l2_fill_pix_format(pix_fmt, mbus_fmt);
-               pix_fmt->bytesperline = pix_fmt->width;
-               if (mbus_fmt->code == MEDIA_BUS_FMT_SGRBG10_1X10) {
-                       /* e.g. mt9v032 */
-                       pix_fmt->pixelformat = V4L2_PIX_FMT_SGRBG10;
-                       pix_fmt->bytesperline = pix_fmt->width * 2;
-               } else if (mbus_fmt->code == MEDIA_BUS_FMT_UYVY8_2X8) {
-                       /* e.g. tvp514x */
-                       pix_fmt->pixelformat = V4L2_PIX_FMT_NV16;
-                       pix_fmt->bytesperline = pix_fmt->width * 2;
-               } else {
-                       dev_warn(vpif_dev, "%s: Unhandled media-bus format 0x%x\n",
-                                __func__, mbus_fmt->code);
-               }
-               pix_fmt->sizeimage = pix_fmt->bytesperline * pix_fmt->height;
-               dev_dbg(vpif_dev, "%s: %d x %d; pitch=%d, pixelformat=0x%08x, code=0x%x, field=%d, size=%d\n", __func__,
-                       pix_fmt->width, pix_fmt->height,
-                       pix_fmt->bytesperline, pix_fmt->pixelformat,
-                       mbus_fmt->code, pix_fmt->field, pix_fmt->sizeimage);
-
-               common->fmt = *fmt;
-               vpif_update_std_info(ch);
-       }
-
-       return 0;
-}
-
-/**
- * vpif_s_fmt_vid_cap() - Set FMT handler
- * @file: file ptr
- * @priv: file handle
- * @fmt: ptr to v4l2 format structure
- */
-static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
-                               struct v4l2_format *fmt)
-{
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       int ret;
-
-       vpif_dbg(2, debug, "%s\n", __func__);
-
-       if (vb2_is_busy(&common->buffer_queue))
-               return -EBUSY;
-
-       ret = vpif_try_fmt_vid_cap(file, priv, fmt);
-       if (ret)
-               return ret;
-
-       /* store the format in the channel object */
-       common->fmt = *fmt;
-       return 0;
-}
-
-/**
- * vpif_querycap() - QUERYCAP handler
- * @file: file ptr
- * @priv: file handle
- * @cap: ptr to v4l2_capability structure
- */
-static int vpif_querycap(struct file *file, void  *priv,
-                               struct v4l2_capability *cap)
-{
-       struct vpif_capture_config *config = vpif_dev->platform_data;
-
-       strscpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));
-       snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
-                dev_name(vpif_dev));
-       strscpy(cap->card, config->card_name, sizeof(cap->card));
-
-       return 0;
-}
-
-/**
- * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler
- * @file: file ptr
- * @priv: file handle
- * @timings: input timings
- */
-static int
-vpif_enum_dv_timings(struct file *file, void *priv,
-                    struct v4l2_enum_dv_timings *timings)
-{
-       struct vpif_capture_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct vpif_capture_chan_config *chan_cfg;
-       struct v4l2_input input;
-       int ret;
-
-       if (!config->chan_config[ch->channel_id].inputs)
-               return -ENODATA;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-       input = chan_cfg->inputs[ch->input_idx].input;
-       if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)
-               return -ENODATA;
-
-       timings->pad = 0;
-
-       ret = v4l2_subdev_call(ch->sd, pad, enum_dv_timings, timings);
-       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
-               return -EINVAL;
-
-       return ret;
-}
-
-/**
- * vpif_query_dv_timings() - QUERY_DV_TIMINGS handler
- * @file: file ptr
- * @priv: file handle
- * @timings: input timings
- */
-static int
-vpif_query_dv_timings(struct file *file, void *priv,
-                     struct v4l2_dv_timings *timings)
-{
-       struct vpif_capture_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct vpif_capture_chan_config *chan_cfg;
-       struct v4l2_input input;
-       int ret;
-
-       if (!config->chan_config[ch->channel_id].inputs)
-               return -ENODATA;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-       input = chan_cfg->inputs[ch->input_idx].input;
-       if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)
-               return -ENODATA;
-
-       ret = v4l2_subdev_call(ch->sd, video, query_dv_timings, timings);
-       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
-               return -ENODATA;
-
-       return ret;
-}
-
-/**
- * vpif_s_dv_timings() - S_DV_TIMINGS handler
- * @file: file ptr
- * @priv: file handle
- * @timings: digital video timings
- */
-static int vpif_s_dv_timings(struct file *file, void *priv,
-               struct v4l2_dv_timings *timings)
-{
-       struct vpif_capture_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct vpif_params *vpifparams = &ch->vpifparams;
-       struct vpif_channel_config_params *std_info = &vpifparams->std_info;
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct video_obj *vid_ch = &ch->video;
-       struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt;
-       struct vpif_capture_chan_config *chan_cfg;
-       struct v4l2_input input;
-       int ret;
-
-       if (!config->chan_config[ch->channel_id].inputs)
-               return -ENODATA;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-       input = chan_cfg->inputs[ch->input_idx].input;
-       if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)
-               return -ENODATA;
-
-       if (timings->type != V4L2_DV_BT_656_1120) {
-               vpif_dbg(2, debug, "Timing type not defined\n");
-               return -EINVAL;
-       }
-
-       if (vb2_is_busy(&common->buffer_queue))
-               return -EBUSY;
-
-       /* Configure subdevice timings, if any */
-       ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings);
-       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
-               ret = 0;
-       if (ret < 0) {
-               vpif_dbg(2, debug, "Error setting custom DV timings\n");
-               return ret;
-       }
-
-       if (!(timings->bt.width && timings->bt.height &&
-                               (timings->bt.hbackporch ||
-                                timings->bt.hfrontporch ||
-                                timings->bt.hsync) &&
-                               timings->bt.vfrontporch &&
-                               (timings->bt.vbackporch ||
-                                timings->bt.vsync))) {
-               vpif_dbg(2, debug, "Timings for width, height, horizontal back porch, horizontal sync, horizontal front porch, vertical back porch, vertical sync and vertical back porch must be defined\n");
-               return -EINVAL;
-       }
-
-       vid_ch->dv_timings = *timings;
-
-       /* Configure video port timings */
-
-       std_info->eav2sav = V4L2_DV_BT_BLANKING_WIDTH(bt) - 8;
-       std_info->sav2eav = bt->width;
-
-       std_info->l1 = 1;
-       std_info->l3 = bt->vsync + bt->vbackporch + 1;
-
-       std_info->vsize = V4L2_DV_BT_FRAME_HEIGHT(bt);
-       if (bt->interlaced) {
-               if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
-                       std_info->l5 = std_info->vsize/2 -
-                               (bt->vfrontporch - 1);
-                       std_info->l7 = std_info->vsize/2 + 1;
-                       std_info->l9 = std_info->l7 + bt->il_vsync +
-                               bt->il_vbackporch + 1;
-                       std_info->l11 = std_info->vsize -
-                               (bt->il_vfrontporch - 1);
-               } else {
-                       vpif_dbg(2, debug, "Required timing values for interlaced BT format missing\n");
-                       return -EINVAL;
-               }
-       } else {
-               std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
-       }
-       strscpy(std_info->name, "Custom timings BT656/1120",
-               sizeof(std_info->name));
-       std_info->width = bt->width;
-       std_info->height = bt->height;
-       std_info->frm_fmt = bt->interlaced ? 0 : 1;
-       std_info->ycmux_mode = 0;
-       std_info->capture_format = 0;
-       std_info->vbi_supported = 0;
-       std_info->hd_sd = 1;
-       std_info->stdid = 0;
-
-       vid_ch->stdid = 0;
-       return 0;
-}
-
-/**
- * vpif_g_dv_timings() - G_DV_TIMINGS handler
- * @file: file ptr
- * @priv: file handle
- * @timings: digital video timings
- */
-static int vpif_g_dv_timings(struct file *file, void *priv,
-               struct v4l2_dv_timings *timings)
-{
-       struct vpif_capture_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct video_obj *vid_ch = &ch->video;
-       struct vpif_capture_chan_config *chan_cfg;
-       struct v4l2_input input;
-
-       if (!config->chan_config[ch->channel_id].inputs)
-               return -ENODATA;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-       input = chan_cfg->inputs[ch->input_idx].input;
-       if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)
-               return -ENODATA;
-
-       *timings = vid_ch->dv_timings;
-
-       return 0;
-}
-
-/*
- * vpif_log_status() - Status information
- * @file: file ptr
- * @priv: file handle
- *
- * Returns zero.
- */
-static int vpif_log_status(struct file *filep, void *priv)
-{
-       /* status for sub devices */
-       v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
-
-       return 0;
-}
-
-/* vpif capture ioctl operations */
-static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
-       .vidioc_querycap                = vpif_querycap,
-       .vidioc_enum_fmt_vid_cap        = vpif_enum_fmt_vid_cap,
-       .vidioc_g_fmt_vid_cap           = vpif_g_fmt_vid_cap,
-       .vidioc_s_fmt_vid_cap           = vpif_s_fmt_vid_cap,
-       .vidioc_try_fmt_vid_cap         = vpif_try_fmt_vid_cap,
-
-       .vidioc_enum_input              = vpif_enum_input,
-       .vidioc_s_input                 = vpif_s_input,
-       .vidioc_g_input                 = vpif_g_input,
-
-       .vidioc_reqbufs                 = vb2_ioctl_reqbufs,
-       .vidioc_create_bufs             = vb2_ioctl_create_bufs,
-       .vidioc_querybuf                = vb2_ioctl_querybuf,
-       .vidioc_qbuf                    = vb2_ioctl_qbuf,
-       .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
-       .vidioc_expbuf                  = vb2_ioctl_expbuf,
-       .vidioc_streamon                = vb2_ioctl_streamon,
-       .vidioc_streamoff               = vb2_ioctl_streamoff,
-
-       .vidioc_querystd                = vpif_querystd,
-       .vidioc_s_std                   = vpif_s_std,
-       .vidioc_g_std                   = vpif_g_std,
-
-       .vidioc_enum_dv_timings         = vpif_enum_dv_timings,
-       .vidioc_query_dv_timings        = vpif_query_dv_timings,
-       .vidioc_s_dv_timings            = vpif_s_dv_timings,
-       .vidioc_g_dv_timings            = vpif_g_dv_timings,
-
-       .vidioc_log_status              = vpif_log_status,
-};
-
-/* vpif file operations */
-static const struct v4l2_file_operations vpif_fops = {
-       .owner = THIS_MODULE,
-       .open = v4l2_fh_open,
-       .release = vb2_fop_release,
-       .unlocked_ioctl = video_ioctl2,
-       .mmap = vb2_fop_mmap,
-       .poll = vb2_fop_poll
-};
-
-/**
- * initialize_vpif() - Initialize vpif data structures
- *
- * Allocate memory for data structures and initialize them
- */
-static int initialize_vpif(void)
-{
-       int err, i, j;
-       int free_channel_objects_index;
-
-       /* Allocate memory for six channel objects */
-       for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
-               vpif_obj.dev[i] =
-                   kzalloc(sizeof(*vpif_obj.dev[i]), GFP_KERNEL);
-               /* If memory allocation fails, return error */
-               if (!vpif_obj.dev[i]) {
-                       free_channel_objects_index = i;
-                       err = -ENOMEM;
-                       goto vpif_init_free_channel_objects;
-               }
-       }
-       return 0;
-
-vpif_init_free_channel_objects:
-       for (j = 0; j < free_channel_objects_index; j++)
-               kfree(vpif_obj.dev[j]);
-       return err;
-}
-
-static inline void free_vpif_objs(void)
-{
-       int i;
-
-       for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++)
-               kfree(vpif_obj.dev[i]);
-}
-
-static int vpif_async_bound(struct v4l2_async_notifier *notifier,
-                           struct v4l2_subdev *subdev,
-                           struct v4l2_async_subdev *asd)
-{
-       int i;
-
-       for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) {
-               struct v4l2_async_subdev *_asd = vpif_obj.config->asd[i];
-               const struct fwnode_handle *fwnode = _asd->match.fwnode;
-
-               if (fwnode == subdev->fwnode) {
-                       vpif_obj.sd[i] = subdev;
-                       vpif_obj.config->chan_config->inputs[i].subdev_name =
-                               (char *)to_of_node(subdev->fwnode)->full_name;
-                       vpif_dbg(2, debug,
-                                "%s: setting input %d subdev_name = %s\n",
-                                __func__, i,
-                               vpif_obj.config->chan_config->inputs[i].subdev_name);
-                       return 0;
-               }
-       }
-
-       for (i = 0; i < vpif_obj.config->subdev_count; i++)
-               if (!strcmp(vpif_obj.config->subdev_info[i].name,
-                           subdev->name)) {
-                       vpif_obj.sd[i] = subdev;
-                       return 0;
-               }
-
-       return -EINVAL;
-}
-
-static int vpif_probe_complete(void)
-{
-       struct common_obj *common;
-       struct video_device *vdev;
-       struct channel_obj *ch;
-       struct vb2_queue *q;
-       int j, err, k;
-
-       for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
-               ch = vpif_obj.dev[j];
-               ch->channel_id = j;
-               common = &(ch->common[VPIF_VIDEO_INDEX]);
-               spin_lock_init(&common->irqlock);
-               mutex_init(&common->lock);
-
-               /* select input 0 */
-               err = vpif_set_input(vpif_obj.config, ch, 0);
-               if (err)
-                       goto probe_out;
-
-               /* set initial format */
-               ch->video.stdid = V4L2_STD_525_60;
-               memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
-               common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-               vpif_update_std_info(ch);
-
-               /* Initialize vb2 queue */
-               q = &common->buffer_queue;
-               q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-               q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
-               q->drv_priv = ch;
-               q->ops = &video_qops;
-               q->mem_ops = &vb2_dma_contig_memops;
-               q->buf_struct_size = sizeof(struct vpif_cap_buffer);
-               q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-               q->min_buffers_needed = 1;
-               q->lock = &common->lock;
-               q->dev = vpif_dev;
-
-               err = vb2_queue_init(q);
-               if (err) {
-                       vpif_err("vpif_capture: vb2_queue_init() failed\n");
-                       goto probe_out;
-               }
-
-               INIT_LIST_HEAD(&common->dma_queue);
-
-               /* Initialize the video_device structure */
-               vdev = &ch->video_dev;
-               strscpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
-               vdev->release = video_device_release_empty;
-               vdev->fops = &vpif_fops;
-               vdev->ioctl_ops = &vpif_ioctl_ops;
-               vdev->v4l2_dev = &vpif_obj.v4l2_dev;
-               vdev->vfl_dir = VFL_DIR_RX;
-               vdev->queue = q;
-               vdev->lock = &common->lock;
-               vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-               video_set_drvdata(&ch->video_dev, ch);
-               err = video_register_device(vdev,
-                                           VFL_TYPE_VIDEO, (j ? 1 : 0));
-               if (err)
-                       goto probe_out;
-       }
-
-       v4l2_info(&vpif_obj.v4l2_dev, "VPIF capture driver initialized\n");
-       return 0;
-
-probe_out:
-       for (k = 0; k < j; k++) {
-               /* Get the pointer to the channel object */
-               ch = vpif_obj.dev[k];
-               /* Unregister video device */
-               video_unregister_device(&ch->video_dev);
-       }
-
-       return err;
-}
-
-static int vpif_async_complete(struct v4l2_async_notifier *notifier)
-{
-       return vpif_probe_complete();
-}
-
-static const struct v4l2_async_notifier_operations vpif_async_ops = {
-       .bound = vpif_async_bound,
-       .complete = vpif_async_complete,
-};
-
-static struct vpif_capture_config *
-vpif_capture_get_pdata(struct platform_device *pdev)
-{
-       struct device_node *endpoint = NULL;
-       struct device_node *rem = NULL;
-       struct vpif_capture_config *pdata;
-       struct vpif_subdev_info *sdinfo;
-       struct vpif_capture_chan_config *chan;
-       unsigned int i;
-
-       v4l2_async_nf_init(&vpif_obj.notifier);
-
-       /*
-        * DT boot: OF node from parent device contains
-        * video ports & endpoints data.
-        */
-       if (pdev->dev.parent && pdev->dev.parent->of_node)
-               pdev->dev.of_node = pdev->dev.parent->of_node;
-       if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
-               return pdev->dev.platform_data;
-
-       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-       if (!pdata)
-               return NULL;
-       pdata->subdev_info =
-               devm_kcalloc(&pdev->dev,
-                            VPIF_CAPTURE_NUM_CHANNELS,
-                            sizeof(*pdata->subdev_info),
-                            GFP_KERNEL);
-
-       if (!pdata->subdev_info)
-               return NULL;
-
-       for (i = 0; i < VPIF_CAPTURE_NUM_CHANNELS; i++) {
-               struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
-               unsigned int flags;
-               int err;
-
-               endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
-                                                     endpoint);
-               if (!endpoint)
-                       break;
-
-               rem = of_graph_get_remote_port_parent(endpoint);
-               if (!rem) {
-                       dev_dbg(&pdev->dev, "Remote device at %pOF not found\n",
-                               endpoint);
-                       goto done;
-               }
-
-               sdinfo = &pdata->subdev_info[i];
-               chan = &pdata->chan_config[i];
-               chan->inputs = devm_kcalloc(&pdev->dev,
-                                           VPIF_CAPTURE_NUM_CHANNELS,
-                                           sizeof(*chan->inputs),
-                                           GFP_KERNEL);
-               if (!chan->inputs)
-                       goto err_cleanup;
-
-               chan->input_count++;
-               chan->inputs[i].input.type = V4L2_INPUT_TYPE_CAMERA;
-               chan->inputs[i].input.std = V4L2_STD_ALL;
-               chan->inputs[i].input.capabilities = V4L2_IN_CAP_STD;
-
-               err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
-                                                &bus_cfg);
-               if (err) {
-                       dev_err(&pdev->dev, "Could not parse the endpoint\n");
-                       of_node_put(rem);
-                       goto done;
-               }
-
-               dev_dbg(&pdev->dev, "Endpoint %pOF, bus_width = %d\n",
-                       endpoint, bus_cfg.bus.parallel.bus_width);
-
-               flags = bus_cfg.bus.parallel.flags;
-
-               if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
-                       chan->vpif_if.hd_pol = 1;
-
-               if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
-                       chan->vpif_if.vd_pol = 1;
-
-               dev_dbg(&pdev->dev, "Remote device %pOF found\n", rem);
-               sdinfo->name = rem->full_name;
-
-               pdata->asd[i] = v4l2_async_nf_add_fwnode(&vpif_obj.notifier,
-                                                        of_fwnode_handle(rem),
-                                                        struct
-                                                        v4l2_async_subdev);
-               if (IS_ERR(pdata->asd[i]))
-                       goto err_cleanup;
-
-               of_node_put(rem);
-       }
-
-done:
-       of_node_put(endpoint);
-       pdata->asd_sizes[0] = i;
-       pdata->subdev_count = i;
-       pdata->card_name = "DA850/OMAP-L138 Video Capture";
-
-       return pdata;
-
-err_cleanup:
-       of_node_put(rem);
-       of_node_put(endpoint);
-       v4l2_async_nf_cleanup(&vpif_obj.notifier);
-
-       return NULL;
-}
-
-/**
- * vpif_probe : This function probes the vpif capture driver
- * @pdev: platform device pointer
- *
- * This creates device entries by register itself to the V4L2 driver and
- * initializes fields of each channel objects
- */
-static __init int vpif_probe(struct platform_device *pdev)
-{
-       struct vpif_subdev_info *subdevdata;
-       struct i2c_adapter *i2c_adap;
-       int subdev_count;
-       int res_idx = 0;
-       int i, err;
-
-       pdev->dev.platform_data = vpif_capture_get_pdata(pdev);
-       if (!pdev->dev.platform_data) {
-               dev_warn(&pdev->dev, "Missing platform data.  Giving up.\n");
-               return -EINVAL;
-       }
-
-       vpif_dev = &pdev->dev;
-
-       err = initialize_vpif();
-       if (err) {
-               v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
-               goto cleanup;
-       }
-
-       err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
-       if (err) {
-               v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
-               goto vpif_free;
-       }
-
-       do {
-               int irq;
-
-               err = platform_get_irq_optional(pdev, res_idx);
-               if (err < 0 && err != -ENXIO)
-                       goto vpif_unregister;
-               if (err > 0)
-                       irq = err;
-               else
-                       break;
-
-               err = devm_request_irq(&pdev->dev, irq, vpif_channel_isr,
-                                      IRQF_SHARED, VPIF_DRIVER_NAME,
-                                      (void *)(&vpif_obj.dev[res_idx]->channel_id));
-               if (err)
-                       goto vpif_unregister;
-       } while (++res_idx);
-
-       vpif_obj.config = pdev->dev.platform_data;
-
-       subdev_count = vpif_obj.config->subdev_count;
-       vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL);
-       if (!vpif_obj.sd) {
-               err = -ENOMEM;
-               goto vpif_unregister;
-       }
-
-       if (!vpif_obj.config->asd_sizes[0]) {
-               int i2c_id = vpif_obj.config->i2c_adapter_id;
-
-               i2c_adap = i2c_get_adapter(i2c_id);
-               WARN_ON(!i2c_adap);
-               for (i = 0; i < subdev_count; i++) {
-                       subdevdata = &vpif_obj.config->subdev_info[i];
-                       vpif_obj.sd[i] =
-                               v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
-                                                         i2c_adap,
-                                                         &subdevdata->
-                                                         board_info,
-                                                         NULL);
-
-                       if (!vpif_obj.sd[i]) {
-                               vpif_err("Error registering v4l2 subdevice\n");
-                               err = -ENODEV;
-                               goto probe_subdev_out;
-                       }
-                       v4l2_info(&vpif_obj.v4l2_dev,
-                                 "registered sub device %s\n",
-                                  subdevdata->name);
-               }
-               err = vpif_probe_complete();
-               if (err)
-                       goto probe_subdev_out;
-       } else {
-               vpif_obj.notifier.ops = &vpif_async_ops;
-               err = v4l2_async_nf_register(&vpif_obj.v4l2_dev,
-                                            &vpif_obj.notifier);
-               if (err) {
-                       vpif_err("Error registering async notifier\n");
-                       err = -EINVAL;
-                       goto probe_subdev_out;
-               }
-       }
-
-       return 0;
-
-probe_subdev_out:
-       /* free sub devices memory */
-       kfree(vpif_obj.sd);
-vpif_unregister:
-       v4l2_device_unregister(&vpif_obj.v4l2_dev);
-vpif_free:
-       free_vpif_objs();
-cleanup:
-       v4l2_async_nf_cleanup(&vpif_obj.notifier);
-
-       return err;
-}
-
-/**
- * vpif_remove() - driver remove handler
- * @device: ptr to platform device structure
- *
- * The vidoe device is unregistered
- */
-static int vpif_remove(struct platform_device *device)
-{
-       struct channel_obj *ch;
-       int i;
-
-       v4l2_async_nf_unregister(&vpif_obj.notifier);
-       v4l2_async_nf_cleanup(&vpif_obj.notifier);
-       v4l2_device_unregister(&vpif_obj.v4l2_dev);
-
-       kfree(vpif_obj.sd);
-       /* un-register device */
-       for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
-               /* Get the pointer to the channel object */
-               ch = vpif_obj.dev[i];
-               /* Unregister video device */
-               video_unregister_device(&ch->video_dev);
-               kfree(vpif_obj.dev[i]);
-       }
-       return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-/**
- * vpif_suspend: vpif device suspend
- * @dev: pointer to &struct device
- */
-static int vpif_suspend(struct device *dev)
-{
-
-       struct common_obj *common;
-       struct channel_obj *ch;
-       int i;
-
-       for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
-               /* Get the pointer to the channel object */
-               ch = vpif_obj.dev[i];
-               common = &ch->common[VPIF_VIDEO_INDEX];
-
-               if (!vb2_start_streaming_called(&common->buffer_queue))
-                       continue;
-
-               mutex_lock(&common->lock);
-               /* Disable channel */
-               if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
-                       enable_channel0(0);
-                       channel0_intr_enable(0);
-               }
-               if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
-                       ycmux_mode == 2) {
-                       enable_channel1(0);
-                       channel1_intr_enable(0);
-               }
-               mutex_unlock(&common->lock);
-       }
-
-       return 0;
-}
-
-/*
- * vpif_resume: vpif device suspend
- */
-static int vpif_resume(struct device *dev)
-{
-       struct common_obj *common;
-       struct channel_obj *ch;
-       int i;
-
-       for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
-               /* Get the pointer to the channel object */
-               ch = vpif_obj.dev[i];
-               common = &ch->common[VPIF_VIDEO_INDEX];
-
-               if (!vb2_start_streaming_called(&common->buffer_queue))
-                       continue;
-
-               mutex_lock(&common->lock);
-               /* Enable channel */
-               if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
-                       enable_channel0(1);
-                       channel0_intr_enable(1);
-               }
-               if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
-                       ycmux_mode == 2) {
-                       enable_channel1(1);
-                       channel1_intr_enable(1);
-               }
-               mutex_unlock(&common->lock);
-       }
-
-       return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume);
-
-static __refdata struct platform_driver vpif_driver = {
-       .driver = {
-               .name   = VPIF_DRIVER_NAME,
-               .pm     = &vpif_pm_ops,
-       },
-       .probe = vpif_probe,
-       .remove = vpif_remove,
-};
-
-module_platform_driver(vpif_driver);
diff --git a/drivers/media/platform/davinci/vpif_capture.h b/drivers/media/platform/davinci/vpif_capture.h
deleted file mode 100644 (file)
index d5951f6..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2009 Texas Instruments Inc
- */
-
-#ifndef VPIF_CAPTURE_H
-#define VPIF_CAPTURE_H
-
-/* Header files */
-#include <media/videobuf2-dma-contig.h>
-#include <media/v4l2-device.h>
-
-#include "vpif.h"
-
-/* Macros */
-#define VPIF_CAPTURE_VERSION           "0.0.2"
-
-#define VPIF_VALID_FIELD(field)                (((V4L2_FIELD_ANY == field) || \
-       (V4L2_FIELD_NONE == field)) || \
-       (((V4L2_FIELD_INTERLACED == field) || \
-       (V4L2_FIELD_SEQ_TB == field)) || \
-       (V4L2_FIELD_SEQ_BT == field)))
-
-#define VPIF_CAPTURE_MAX_DEVICES       2
-#define VPIF_VIDEO_INDEX               0
-#define VPIF_NUMBER_OF_OBJECTS         1
-
-/* Enumerated data type to give id to each device per channel */
-enum vpif_channel_id {
-       VPIF_CHANNEL0_VIDEO = 0,
-       VPIF_CHANNEL1_VIDEO,
-};
-
-struct video_obj {
-       enum v4l2_field buf_field;
-       /* Currently selected or default standard */
-       v4l2_std_id stdid;
-       struct v4l2_dv_timings dv_timings;
-};
-
-struct vpif_cap_buffer {
-       struct vb2_v4l2_buffer vb;
-       struct list_head list;
-};
-
-struct common_obj {
-       /* Pointer pointing to current v4l2_buffer */
-       struct vpif_cap_buffer *cur_frm;
-       /* Pointer pointing to current v4l2_buffer */
-       struct vpif_cap_buffer *next_frm;
-       /* Used to store pixel format */
-       struct v4l2_format fmt;
-       /* Buffer queue used in video-buf */
-       struct vb2_queue buffer_queue;
-       /* Queue of filled frames */
-       struct list_head dma_queue;
-       /* Protects the dma_queue field */
-       spinlock_t irqlock;
-       /* lock used to access this structure */
-       struct mutex lock;
-       /* Function pointer to set the addresses */
-       void (*set_addr) (unsigned long, unsigned long, unsigned long,
-                         unsigned long);
-       /* offset where Y top starts from the starting of the buffer */
-       u32 ytop_off;
-       /* offset where Y bottom starts from the starting of the buffer */
-       u32 ybtm_off;
-       /* offset where C top starts from the starting of the buffer */
-       u32 ctop_off;
-       /* offset where C bottom starts from the starting of the buffer */
-       u32 cbtm_off;
-       /* Indicates width of the image data */
-       u32 width;
-       /* Indicates height of the image data */
-       u32 height;
-};
-
-struct channel_obj {
-       /* Identifies video device for this channel */
-       struct video_device video_dev;
-       /* Indicates id of the field which is being displayed */
-       u32 field_id;
-       /* flag to indicate whether decoder is initialized */
-       u8 initialized;
-       /* Identifies channel */
-       enum vpif_channel_id channel_id;
-       /* Current input */
-       u32 input_idx;
-       /* subdev corresponding to the current input, may be NULL */
-       struct v4l2_subdev *sd;
-       /* vpif configuration params */
-       struct vpif_params vpifparams;
-       /* common object array */
-       struct common_obj common[VPIF_NUMBER_OF_OBJECTS];
-       /* video object */
-       struct video_obj video;
-};
-
-struct vpif_device {
-       struct v4l2_device v4l2_dev;
-       struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS];
-       struct v4l2_subdev **sd;
-       struct v4l2_async_notifier notifier;
-       struct vpif_capture_config *config;
-};
-
-#endif                         /* VPIF_CAPTURE_H */
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
deleted file mode 100644 (file)
index fca148b..0000000
+++ /dev/null
@@ -1,1408 +0,0 @@
-/*
- * vpif-display - VPIF display driver
- * Display driver for TI DaVinci VPIF
- *
- * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com/
- * Copyright (C) 2014 Lad, Prabhakar <prabhakar.csengg@gmail.com>
- *
- * 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 version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <media/v4l2-ioctl.h>
-
-#include "vpif.h"
-#include "vpif_display.h"
-
-MODULE_DESCRIPTION("TI DaVinci VPIF Display driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(VPIF_DISPLAY_VERSION);
-
-#define VPIF_V4L2_STD (V4L2_STD_525_60 | V4L2_STD_625_50)
-
-#define vpif_err(fmt, arg...)  v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
-#define vpif_dbg(level, debug, fmt, arg...)    \
-               v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
-
-static int debug = 1;
-
-module_param(debug, int, 0644);
-
-MODULE_PARM_DESC(debug, "Debug level 0-1");
-
-#define VPIF_DRIVER_NAME       "vpif_display"
-MODULE_ALIAS("platform:" VPIF_DRIVER_NAME);
-
-/* Is set to 1 in case of SDTV formats, 2 in case of HDTV formats. */
-static int ycmux_mode;
-
-static u8 channel_first_int[VPIF_NUMOBJECTS][2] = { {1, 1} };
-
-static struct vpif_device vpif_obj = { {NULL} };
-static struct device *vpif_dev;
-static void vpif_calculate_offsets(struct channel_obj *ch);
-static void vpif_config_addr(struct channel_obj *ch, int muxmode);
-
-static inline
-struct vpif_disp_buffer *to_vpif_buffer(struct vb2_v4l2_buffer *vb)
-{
-       return container_of(vb, struct vpif_disp_buffer, vb);
-}
-
-/**
- * vpif_buffer_prepare :  callback function for buffer prepare
- * @vb: ptr to vb2_buffer
- *
- * This is the callback function for buffer prepare when vb2_qbuf()
- * function is called. The buffer is prepared and user space virtual address
- * or user address is converted into  physical address
- */
-static int vpif_buffer_prepare(struct vb2_buffer *vb)
-{
-       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-       struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
-       struct common_obj *common;
-
-       common = &ch->common[VPIF_VIDEO_INDEX];
-
-       vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
-       if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
-               return -EINVAL;
-
-       vbuf->field = common->fmt.fmt.pix.field;
-
-       if (vb->vb2_queue->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
-               unsigned long addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-
-               if (!ISALIGNED(addr + common->ytop_off) ||
-                       !ISALIGNED(addr + common->ybtm_off) ||
-                       !ISALIGNED(addr + common->ctop_off) ||
-                       !ISALIGNED(addr + common->cbtm_off)) {
-                       vpif_err("buffer offset not aligned to 8 bytes\n");
-                       return -EINVAL;
-               }
-       }
-
-       return 0;
-}
-
-/**
- * vpif_buffer_queue_setup : Callback function for buffer setup.
- * @vq: vb2_queue ptr
- * @nbuffers: ptr to number of buffers requested by application
- * @nplanes: contains number of distinct video planes needed to hold a frame
- * @sizes: contains the size (in bytes) of each plane.
- * @alloc_devs: ptr to allocation context
- *
- * This callback function is called when reqbuf() is called to adjust
- * the buffer count and buffer size
- */
-static int vpif_buffer_queue_setup(struct vb2_queue *vq,
-                               unsigned int *nbuffers, unsigned int *nplanes,
-                               unsigned int sizes[], struct device *alloc_devs[])
-{
-       struct channel_obj *ch = vb2_get_drv_priv(vq);
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       unsigned size = common->fmt.fmt.pix.sizeimage;
-
-       if (*nplanes) {
-               if (sizes[0] < size)
-                       return -EINVAL;
-               size = sizes[0];
-       }
-
-       if (vq->num_buffers + *nbuffers < 3)
-               *nbuffers = 3 - vq->num_buffers;
-
-       *nplanes = 1;
-       sizes[0] = size;
-
-       /* Calculate the offset for Y and C data  in the buffer */
-       vpif_calculate_offsets(ch);
-
-       return 0;
-}
-
-/**
- * vpif_buffer_queue : Callback function to add buffer to DMA queue
- * @vb: ptr to vb2_buffer
- *
- * This callback function queues the buffer to DMA engine
- */
-static void vpif_buffer_queue(struct vb2_buffer *vb)
-{
-       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-       struct vpif_disp_buffer *buf = to_vpif_buffer(vbuf);
-       struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
-       struct common_obj *common;
-       unsigned long flags;
-
-       common = &ch->common[VPIF_VIDEO_INDEX];
-
-       /* add the buffer to the DMA queue */
-       spin_lock_irqsave(&common->irqlock, flags);
-       list_add_tail(&buf->list, &common->dma_queue);
-       spin_unlock_irqrestore(&common->irqlock, flags);
-}
-
-/**
- * vpif_start_streaming : Starts the DMA engine for streaming
- * @vq: ptr to vb2_buffer
- * @count: number of buffers
- */
-static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-       struct vpif_display_config *vpif_config_data =
-                                       vpif_dev->platform_data;
-       struct channel_obj *ch = vb2_get_drv_priv(vq);
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct vpif_params *vpif = &ch->vpifparams;
-       struct vpif_disp_buffer *buf, *tmp;
-       unsigned long addr, flags;
-       int ret;
-
-       spin_lock_irqsave(&common->irqlock, flags);
-
-       /* Initialize field_id */
-       ch->field_id = 0;
-
-       /* clock settings */
-       if (vpif_config_data->set_clock) {
-               ret = vpif_config_data->set_clock(ch->vpifparams.std_info.
-               ycmux_mode, ch->vpifparams.std_info.hd_sd);
-               if (ret < 0) {
-                       vpif_err("can't set clock\n");
-                       goto err;
-               }
-       }
-
-       /* set the parameters and addresses */
-       ret = vpif_set_video_params(vpif, ch->channel_id + 2);
-       if (ret < 0)
-               goto err;
-
-       ycmux_mode = ret;
-       vpif_config_addr(ch, ret);
-       /* Get the next frame from the buffer queue */
-       common->next_frm = common->cur_frm =
-                           list_entry(common->dma_queue.next,
-                                      struct vpif_disp_buffer, list);
-
-       list_del(&common->cur_frm->list);
-       spin_unlock_irqrestore(&common->irqlock, flags);
-
-       addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb.vb2_buf, 0);
-       common->set_addr((addr + common->ytop_off),
-                           (addr + common->ybtm_off),
-                           (addr + common->ctop_off),
-                           (addr + common->cbtm_off));
-
-       /*
-        * Set interrupt for both the fields in VPIF
-        * Register enable channel in VPIF register
-        */
-       channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
-       if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
-               channel2_intr_assert();
-               channel2_intr_enable(1);
-               enable_channel2(1);
-               if (vpif_config_data->chan_config[VPIF_CHANNEL2_VIDEO].clip_en)
-                       channel2_clipping_enable(1);
-       }
-
-       if (VPIF_CHANNEL3_VIDEO == ch->channel_id || ycmux_mode == 2) {
-               channel3_intr_assert();
-               channel3_intr_enable(1);
-               enable_channel3(1);
-               if (vpif_config_data->chan_config[VPIF_CHANNEL3_VIDEO].clip_en)
-                       channel3_clipping_enable(1);
-       }
-
-       return 0;
-
-err:
-       list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
-               list_del(&buf->list);
-               vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
-       }
-       spin_unlock_irqrestore(&common->irqlock, flags);
-
-       return ret;
-}
-
-/**
- * vpif_stop_streaming : Stop the DMA engine
- * @vq: ptr to vb2_queue
- *
- * This callback stops the DMA engine and any remaining buffers
- * in the DMA queue are released.
- */
-static void vpif_stop_streaming(struct vb2_queue *vq)
-{
-       struct channel_obj *ch = vb2_get_drv_priv(vq);
-       struct common_obj *common;
-       unsigned long flags;
-
-       common = &ch->common[VPIF_VIDEO_INDEX];
-
-       /* Disable channel */
-       if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
-               enable_channel2(0);
-               channel2_intr_enable(0);
-       }
-       if (VPIF_CHANNEL3_VIDEO == ch->channel_id || ycmux_mode == 2) {
-               enable_channel3(0);
-               channel3_intr_enable(0);
-       }
-
-       /* release all active buffers */
-       spin_lock_irqsave(&common->irqlock, flags);
-       if (common->cur_frm == common->next_frm) {
-               vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
-                               VB2_BUF_STATE_ERROR);
-       } else {
-               if (common->cur_frm)
-                       vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
-                                       VB2_BUF_STATE_ERROR);
-               if (common->next_frm)
-                       vb2_buffer_done(&common->next_frm->vb.vb2_buf,
-                                       VB2_BUF_STATE_ERROR);
-       }
-
-       while (!list_empty(&common->dma_queue)) {
-               common->next_frm = list_entry(common->dma_queue.next,
-                                               struct vpif_disp_buffer, list);
-               list_del(&common->next_frm->list);
-               vb2_buffer_done(&common->next_frm->vb.vb2_buf,
-                               VB2_BUF_STATE_ERROR);
-       }
-       spin_unlock_irqrestore(&common->irqlock, flags);
-}
-
-static const struct vb2_ops video_qops = {
-       .queue_setup            = vpif_buffer_queue_setup,
-       .wait_prepare           = vb2_ops_wait_prepare,
-       .wait_finish            = vb2_ops_wait_finish,
-       .buf_prepare            = vpif_buffer_prepare,
-       .start_streaming        = vpif_start_streaming,
-       .stop_streaming         = vpif_stop_streaming,
-       .buf_queue              = vpif_buffer_queue,
-};
-
-static void process_progressive_mode(struct common_obj *common)
-{
-       unsigned long addr;
-
-       spin_lock(&common->irqlock);
-       /* Get the next buffer from buffer queue */
-       common->next_frm = list_entry(common->dma_queue.next,
-                               struct vpif_disp_buffer, list);
-       /* Remove that buffer from the buffer queue */
-       list_del(&common->next_frm->list);
-       spin_unlock(&common->irqlock);
-
-       /* Set top and bottom field addrs in VPIF registers */
-       addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb.vb2_buf, 0);
-       common->set_addr(addr + common->ytop_off,
-                                addr + common->ybtm_off,
-                                addr + common->ctop_off,
-                                addr + common->cbtm_off);
-}
-
-static void process_interlaced_mode(int fid, struct common_obj *common)
-{
-       /* device field id and local field id are in sync */
-       /* If this is even field */
-       if (0 == fid) {
-               if (common->cur_frm == common->next_frm)
-                       return;
-
-               /* one frame is displayed If next frame is
-                *  available, release cur_frm and move on */
-               /* Copy frame display time */
-               common->cur_frm->vb.vb2_buf.timestamp = ktime_get_ns();
-               /* Change status of the cur_frm */
-               vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
-                                       VB2_BUF_STATE_DONE);
-               /* Make cur_frm pointing to next_frm */
-               common->cur_frm = common->next_frm;
-
-       } else if (1 == fid) {  /* odd field */
-               spin_lock(&common->irqlock);
-               if (list_empty(&common->dma_queue)
-                   || (common->cur_frm != common->next_frm)) {
-                       spin_unlock(&common->irqlock);
-                       return;
-               }
-               spin_unlock(&common->irqlock);
-               /* one field is displayed configure the next
-                * frame if it is available else hold on current
-                * frame */
-               /* Get next from the buffer queue */
-               process_progressive_mode(common);
-       }
-}
-
-/*
- * vpif_channel_isr: It changes status of the displayed buffer, takes next
- * buffer from the queue and sets its address in VPIF registers
- */
-static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
-{
-       struct vpif_device *dev = &vpif_obj;
-       struct channel_obj *ch;
-       struct common_obj *common;
-       int fid = -1, i;
-       int channel_id;
-
-       channel_id = *(int *)(dev_id);
-       if (!vpif_intr_status(channel_id + 2))
-               return IRQ_NONE;
-
-       ch = dev->dev[channel_id];
-       for (i = 0; i < VPIF_NUMOBJECTS; i++) {
-               common = &ch->common[i];
-               /* If streaming is started in this channel */
-
-               if (1 == ch->vpifparams.std_info.frm_fmt) {
-                       spin_lock(&common->irqlock);
-                       if (list_empty(&common->dma_queue)) {
-                               spin_unlock(&common->irqlock);
-                               continue;
-                       }
-                       spin_unlock(&common->irqlock);
-
-                       /* Progressive mode */
-                       if (!channel_first_int[i][channel_id]) {
-                               /* Mark status of the cur_frm to
-                                * done and unlock semaphore on it */
-                               common->cur_frm->vb.vb2_buf.timestamp =
-                                               ktime_get_ns();
-                               vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
-                                               VB2_BUF_STATE_DONE);
-                               /* Make cur_frm pointing to next_frm */
-                               common->cur_frm = common->next_frm;
-                       }
-
-                       channel_first_int[i][channel_id] = 0;
-                       process_progressive_mode(common);
-               } else {
-                       /* Interlaced mode */
-                       /* If it is first interrupt, ignore it */
-
-                       if (channel_first_int[i][channel_id]) {
-                               channel_first_int[i][channel_id] = 0;
-                               continue;
-                       }
-
-                       if (0 == i) {
-                               ch->field_id ^= 1;
-                               /* Get field id from VPIF registers */
-                               fid = vpif_channel_getfid(ch->channel_id + 2);
-                               /* If fid does not match with stored field id */
-                               if (fid != ch->field_id) {
-                                       /* Make them in sync */
-                                       if (0 == fid)
-                                               ch->field_id = fid;
-
-                                       return IRQ_HANDLED;
-                               }
-                       }
-                       process_interlaced_mode(fid, common);
-               }
-       }
-
-       return IRQ_HANDLED;
-}
-
-static int vpif_update_std_info(struct channel_obj *ch)
-{
-       struct video_obj *vid_ch = &ch->video;
-       struct vpif_params *vpifparams = &ch->vpifparams;
-       struct vpif_channel_config_params *std_info = &vpifparams->std_info;
-       const struct vpif_channel_config_params *config;
-
-       int i;
-
-       for (i = 0; i < vpif_ch_params_count; i++) {
-               config = &vpif_ch_params[i];
-               if (config->hd_sd == 0) {
-                       vpif_dbg(2, debug, "SD format\n");
-                       if (config->stdid & vid_ch->stdid) {
-                               memcpy(std_info, config, sizeof(*config));
-                               break;
-                       }
-               }
-       }
-
-       if (i == vpif_ch_params_count) {
-               vpif_dbg(1, debug, "Format not found\n");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int vpif_update_resolution(struct channel_obj *ch)
-{
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct video_obj *vid_ch = &ch->video;
-       struct vpif_params *vpifparams = &ch->vpifparams;
-       struct vpif_channel_config_params *std_info = &vpifparams->std_info;
-
-       if (!vid_ch->stdid && !vid_ch->dv_timings.bt.height)
-               return -EINVAL;
-
-       if (vid_ch->stdid) {
-               if (vpif_update_std_info(ch))
-                       return -EINVAL;
-       }
-
-       common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
-       common->fmt.fmt.pix.width = std_info->width;
-       common->fmt.fmt.pix.height = std_info->height;
-       vpif_dbg(1, debug, "Pixel details: Width = %d,Height = %d\n",
-                       common->fmt.fmt.pix.width, common->fmt.fmt.pix.height);
-
-       /* Set height and width paramateres */
-       common->height = std_info->height;
-       common->width = std_info->width;
-       common->fmt.fmt.pix.sizeimage = common->height * common->width * 2;
-
-       if (vid_ch->stdid)
-               common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-       else
-               common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
-
-       if (ch->vpifparams.std_info.frm_fmt)
-               common->fmt.fmt.pix.field = V4L2_FIELD_NONE;
-       else
-               common->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
-
-       return 0;
-}
-
-/*
- * vpif_calculate_offsets: This function calculates buffers offset for Y and C
- * in the top and bottom field
- */
-static void vpif_calculate_offsets(struct channel_obj *ch)
-{
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct vpif_params *vpifparams = &ch->vpifparams;
-       enum v4l2_field field = common->fmt.fmt.pix.field;
-       struct video_obj *vid_ch = &ch->video;
-       unsigned int hpitch, sizeimage;
-
-       if (V4L2_FIELD_ANY == common->fmt.fmt.pix.field) {
-               if (ch->vpifparams.std_info.frm_fmt)
-                       vid_ch->buf_field = V4L2_FIELD_NONE;
-               else
-                       vid_ch->buf_field = V4L2_FIELD_INTERLACED;
-       } else {
-               vid_ch->buf_field = common->fmt.fmt.pix.field;
-       }
-
-       sizeimage = common->fmt.fmt.pix.sizeimage;
-
-       hpitch = common->fmt.fmt.pix.bytesperline;
-       if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
-           (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
-               common->ytop_off = 0;
-               common->ybtm_off = hpitch;
-               common->ctop_off = sizeimage / 2;
-               common->cbtm_off = sizeimage / 2 + hpitch;
-       } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
-               common->ytop_off = 0;
-               common->ybtm_off = sizeimage / 4;
-               common->ctop_off = sizeimage / 2;
-               common->cbtm_off = common->ctop_off + sizeimage / 4;
-       } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
-               common->ybtm_off = 0;
-               common->ytop_off = sizeimage / 4;
-               common->cbtm_off = sizeimage / 2;
-               common->ctop_off = common->cbtm_off + sizeimage / 4;
-       }
-
-       if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
-           (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
-               vpifparams->video_params.storage_mode = 1;
-       } else {
-               vpifparams->video_params.storage_mode = 0;
-       }
-
-       if (ch->vpifparams.std_info.frm_fmt == 1) {
-               vpifparams->video_params.hpitch =
-                   common->fmt.fmt.pix.bytesperline;
-       } else {
-               if ((field == V4L2_FIELD_ANY) ||
-                       (field == V4L2_FIELD_INTERLACED))
-                       vpifparams->video_params.hpitch =
-                           common->fmt.fmt.pix.bytesperline * 2;
-               else
-                       vpifparams->video_params.hpitch =
-                           common->fmt.fmt.pix.bytesperline;
-       }
-
-       ch->vpifparams.video_params.stdid = ch->vpifparams.std_info.stdid;
-}
-
-static void vpif_config_addr(struct channel_obj *ch, int muxmode)
-{
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
-       if (VPIF_CHANNEL3_VIDEO == ch->channel_id) {
-               common->set_addr = ch3_set_videobuf_addr;
-       } else {
-               if (2 == muxmode)
-                       common->set_addr = ch2_set_videobuf_addr_yc_nmux;
-               else
-                       common->set_addr = ch2_set_videobuf_addr;
-       }
-}
-
-/* functions implementing ioctls */
-/**
- * vpif_querycap() - QUERYCAP handler
- * @file: file ptr
- * @priv: file handle
- * @cap: ptr to v4l2_capability structure
- */
-static int vpif_querycap(struct file *file, void  *priv,
-                               struct v4l2_capability *cap)
-{
-       struct vpif_display_config *config = vpif_dev->platform_data;
-
-       strscpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));
-       snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
-                dev_name(vpif_dev));
-       strscpy(cap->card, config->card_name, sizeof(cap->card));
-
-       return 0;
-}
-
-static int vpif_enum_fmt_vid_out(struct file *file, void  *priv,
-                                       struct v4l2_fmtdesc *fmt)
-{
-       if (fmt->index != 0)
-               return -EINVAL;
-
-       /* Fill in the information about format */
-       fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
-       return 0;
-}
-
-static int vpif_g_fmt_vid_out(struct file *file, void *priv,
-                               struct v4l2_format *fmt)
-{
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
-       /* Check the validity of the buffer type */
-       if (common->fmt.type != fmt->type)
-               return -EINVAL;
-
-       if (vpif_update_resolution(ch))
-               return -EINVAL;
-       *fmt = common->fmt;
-       return 0;
-}
-
-static int vpif_try_fmt_vid_out(struct file *file, void *priv,
-                               struct v4l2_format *fmt)
-{
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-
-       /*
-        * to suppress v4l-compliance warnings silently correct
-        * the pixelformat
-        */
-       if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P)
-               pixfmt->pixelformat = common->fmt.fmt.pix.pixelformat;
-
-       if (vpif_update_resolution(ch))
-               return -EINVAL;
-
-       pixfmt->colorspace = common->fmt.fmt.pix.colorspace;
-       pixfmt->field = common->fmt.fmt.pix.field;
-       pixfmt->bytesperline = common->fmt.fmt.pix.width;
-       pixfmt->width = common->fmt.fmt.pix.width;
-       pixfmt->height = common->fmt.fmt.pix.height;
-       pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2;
-
-       return 0;
-}
-
-static int vpif_s_fmt_vid_out(struct file *file, void *priv,
-                               struct v4l2_format *fmt)
-{
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-       int ret;
-
-       if (vb2_is_busy(&common->buffer_queue))
-               return -EBUSY;
-
-       ret = vpif_try_fmt_vid_out(file, priv, fmt);
-       if (ret)
-               return ret;
-
-       /* store the pix format in the channel object */
-       common->fmt.fmt.pix = *pixfmt;
-
-       /* store the format in the channel object */
-       common->fmt = *fmt;
-       return 0;
-}
-
-static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
-{
-       struct vpif_display_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct vpif_display_chan_config *chan_cfg;
-       struct v4l2_output output;
-       int ret;
-
-       if (!config->chan_config[ch->channel_id].outputs)
-               return -ENODATA;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-       output = chan_cfg->outputs[ch->output_idx].output;
-       if (output.capabilities != V4L2_OUT_CAP_STD)
-               return -ENODATA;
-
-       if (vb2_is_busy(&common->buffer_queue))
-               return -EBUSY;
-
-
-       if (!(std_id & VPIF_V4L2_STD))
-               return -EINVAL;
-
-       /* Call encoder subdevice function to set the standard */
-       ch->video.stdid = std_id;
-       memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
-       /* Get the information about the standard */
-       if (vpif_update_resolution(ch))
-               return -EINVAL;
-
-       common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width;
-
-       ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
-                                               s_std_output, std_id);
-       if (ret < 0) {
-               vpif_err("Failed to set output standard\n");
-               return ret;
-       }
-
-       ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
-                                                       s_std, std_id);
-       if (ret < 0)
-               vpif_err("Failed to set standard for sub devices\n");
-       return ret;
-}
-
-static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
-{
-       struct vpif_display_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct vpif_display_chan_config *chan_cfg;
-       struct v4l2_output output;
-
-       if (!config->chan_config[ch->channel_id].outputs)
-               return -ENODATA;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-       output = chan_cfg->outputs[ch->output_idx].output;
-       if (output.capabilities != V4L2_OUT_CAP_STD)
-               return -ENODATA;
-
-       *std = ch->video.stdid;
-       return 0;
-}
-
-static int vpif_enum_output(struct file *file, void *fh,
-                               struct v4l2_output *output)
-{
-
-       struct vpif_display_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct vpif_display_chan_config *chan_cfg;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-       if (output->index >= chan_cfg->output_count) {
-               vpif_dbg(1, debug, "Invalid output index\n");
-               return -EINVAL;
-       }
-
-       *output = chan_cfg->outputs[output->index].output;
-       return 0;
-}
-
-/**
- * vpif_output_to_subdev() - Maps output to sub device
- * @vpif_cfg: global config ptr
- * @chan_cfg: channel config ptr
- * @index: Given output index from application
- *
- * lookup the sub device information for a given output index.
- * we report all the output to application. output table also
- * has sub device name for the each output
- */
-static int
-vpif_output_to_subdev(struct vpif_display_config *vpif_cfg,
-                     struct vpif_display_chan_config *chan_cfg, int index)
-{
-       struct vpif_subdev_info *subdev_info;
-       const char *subdev_name;
-       int i;
-
-       vpif_dbg(2, debug, "vpif_output_to_subdev\n");
-
-       if (!chan_cfg->outputs)
-               return -1;
-
-       subdev_name = chan_cfg->outputs[index].subdev_name;
-       if (!subdev_name)
-               return -1;
-
-       /* loop through the sub device list to get the sub device info */
-       for (i = 0; i < vpif_cfg->subdev_count; i++) {
-               subdev_info = &vpif_cfg->subdevinfo[i];
-               if (!strcmp(subdev_info->name, subdev_name))
-                       return i;
-       }
-       return -1;
-}
-
-/**
- * vpif_set_output() - Select an output
- * @vpif_cfg: global config ptr
- * @ch: channel
- * @index: Given output index from application
- *
- * Select the given output.
- */
-static int vpif_set_output(struct vpif_display_config *vpif_cfg,
-                     struct channel_obj *ch, int index)
-{
-       struct vpif_display_chan_config *chan_cfg =
-               &vpif_cfg->chan_config[ch->channel_id];
-       struct v4l2_subdev *sd = NULL;
-       u32 input = 0, output = 0;
-       int sd_index;
-       int ret;
-
-       sd_index = vpif_output_to_subdev(vpif_cfg, chan_cfg, index);
-       if (sd_index >= 0)
-               sd = vpif_obj.sd[sd_index];
-
-       if (sd) {
-               input = chan_cfg->outputs[index].input_route;
-               output = chan_cfg->outputs[index].output_route;
-               ret = v4l2_subdev_call(sd, video, s_routing, input, output, 0);
-               if (ret < 0 && ret != -ENOIOCTLCMD) {
-                       vpif_err("Failed to set output\n");
-                       return ret;
-               }
-
-       }
-       ch->output_idx = index;
-       ch->sd = sd;
-       if (chan_cfg->outputs)
-               /* update tvnorms from the sub device output info */
-               ch->video_dev.tvnorms = chan_cfg->outputs[index].output.std;
-       return 0;
-}
-
-static int vpif_s_output(struct file *file, void *priv, unsigned int i)
-{
-       struct vpif_display_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct vpif_display_chan_config *chan_cfg;
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
-       if (vb2_is_busy(&common->buffer_queue))
-               return -EBUSY;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-
-       if (i >= chan_cfg->output_count)
-               return -EINVAL;
-
-       return vpif_set_output(config, ch, i);
-}
-
-static int vpif_g_output(struct file *file, void *priv, unsigned int *i)
-{
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-
-       *i = ch->output_idx;
-
-       return 0;
-}
-
-/**
- * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler
- * @file: file ptr
- * @priv: file handle
- * @timings: input timings
- */
-static int
-vpif_enum_dv_timings(struct file *file, void *priv,
-                    struct v4l2_enum_dv_timings *timings)
-{
-       struct vpif_display_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct vpif_display_chan_config *chan_cfg;
-       struct v4l2_output output;
-       int ret;
-
-       if (!config->chan_config[ch->channel_id].outputs)
-               return -ENODATA;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-       output = chan_cfg->outputs[ch->output_idx].output;
-       if (output.capabilities != V4L2_OUT_CAP_DV_TIMINGS)
-               return -ENODATA;
-
-       timings->pad = 0;
-
-       ret = v4l2_subdev_call(ch->sd, pad, enum_dv_timings, timings);
-       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
-               return -EINVAL;
-       return ret;
-}
-
-/**
- * vpif_s_dv_timings() - S_DV_TIMINGS handler
- * @file: file ptr
- * @priv: file handle
- * @timings: digital video timings
- */
-static int vpif_s_dv_timings(struct file *file, void *priv,
-               struct v4l2_dv_timings *timings)
-{
-       struct vpif_display_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct vpif_params *vpifparams = &ch->vpifparams;
-       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-       struct vpif_channel_config_params *std_info = &vpifparams->std_info;
-       struct video_obj *vid_ch = &ch->video;
-       struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt;
-       struct vpif_display_chan_config *chan_cfg;
-       struct v4l2_output output;
-       int ret;
-
-       if (!config->chan_config[ch->channel_id].outputs)
-               return -ENODATA;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-       output = chan_cfg->outputs[ch->output_idx].output;
-       if (output.capabilities != V4L2_OUT_CAP_DV_TIMINGS)
-               return -ENODATA;
-
-       if (vb2_is_busy(&common->buffer_queue))
-               return -EBUSY;
-
-       if (timings->type != V4L2_DV_BT_656_1120) {
-               vpif_dbg(2, debug, "Timing type not defined\n");
-               return -EINVAL;
-       }
-
-       /* Configure subdevice timings, if any */
-       ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings);
-       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
-               ret = 0;
-       if (ret < 0) {
-               vpif_dbg(2, debug, "Error setting custom DV timings\n");
-               return ret;
-       }
-
-       if (!(timings->bt.width && timings->bt.height &&
-                               (timings->bt.hbackporch ||
-                                timings->bt.hfrontporch ||
-                                timings->bt.hsync) &&
-                               timings->bt.vfrontporch &&
-                               (timings->bt.vbackporch ||
-                                timings->bt.vsync))) {
-               vpif_dbg(2, debug, "Timings for width, height, horizontal back porch, horizontal sync, horizontal front porch, vertical back porch, vertical sync and vertical back porch must be defined\n");
-               return -EINVAL;
-       }
-
-       vid_ch->dv_timings = *timings;
-
-       /* Configure video port timings */
-
-       std_info->eav2sav = V4L2_DV_BT_BLANKING_WIDTH(bt) - 8;
-       std_info->sav2eav = bt->width;
-
-       std_info->l1 = 1;
-       std_info->l3 = bt->vsync + bt->vbackporch + 1;
-
-       std_info->vsize = V4L2_DV_BT_FRAME_HEIGHT(bt);
-       if (bt->interlaced) {
-               if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
-                       std_info->l5 = std_info->vsize/2 -
-                               (bt->vfrontporch - 1);
-                       std_info->l7 = std_info->vsize/2 + 1;
-                       std_info->l9 = std_info->l7 + bt->il_vsync +
-                               bt->il_vbackporch + 1;
-                       std_info->l11 = std_info->vsize -
-                               (bt->il_vfrontporch - 1);
-               } else {
-                       vpif_dbg(2, debug, "Required timing values for interlaced BT format missing\n");
-                       return -EINVAL;
-               }
-       } else {
-               std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
-       }
-       strscpy(std_info->name, "Custom timings BT656/1120",
-               sizeof(std_info->name));
-       std_info->width = bt->width;
-       std_info->height = bt->height;
-       std_info->frm_fmt = bt->interlaced ? 0 : 1;
-       std_info->ycmux_mode = 0;
-       std_info->capture_format = 0;
-       std_info->vbi_supported = 0;
-       std_info->hd_sd = 1;
-       std_info->stdid = 0;
-       vid_ch->stdid = 0;
-
-       return 0;
-}
-
-/**
- * vpif_g_dv_timings() - G_DV_TIMINGS handler
- * @file: file ptr
- * @priv: file handle
- * @timings: digital video timings
- */
-static int vpif_g_dv_timings(struct file *file, void *priv,
-               struct v4l2_dv_timings *timings)
-{
-       struct vpif_display_config *config = vpif_dev->platform_data;
-       struct video_device *vdev = video_devdata(file);
-       struct channel_obj *ch = video_get_drvdata(vdev);
-       struct vpif_display_chan_config *chan_cfg;
-       struct video_obj *vid_ch = &ch->video;
-       struct v4l2_output output;
-
-       if (!config->chan_config[ch->channel_id].outputs)
-               goto error;
-
-       chan_cfg = &config->chan_config[ch->channel_id];
-       output = chan_cfg->outputs[ch->output_idx].output;
-
-       if (output.capabilities != V4L2_OUT_CAP_DV_TIMINGS)
-               goto error;
-
-       *timings = vid_ch->dv_timings;
-
-       return 0;
-error:
-       return -ENODATA;
-}
-
-/*
- * vpif_log_status() - Status information
- * @file: file ptr
- * @priv: file handle
- *
- * Returns zero.
- */
-static int vpif_log_status(struct file *filep, void *priv)
-{
-       /* status for sub devices */
-       v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
-
-       return 0;
-}
-
-/* vpif display ioctl operations */
-static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
-       .vidioc_querycap                = vpif_querycap,
-       .vidioc_enum_fmt_vid_out        = vpif_enum_fmt_vid_out,
-       .vidioc_g_fmt_vid_out           = vpif_g_fmt_vid_out,
-       .vidioc_s_fmt_vid_out           = vpif_s_fmt_vid_out,
-       .vidioc_try_fmt_vid_out         = vpif_try_fmt_vid_out,
-
-       .vidioc_reqbufs                 = vb2_ioctl_reqbufs,
-       .vidioc_create_bufs             = vb2_ioctl_create_bufs,
-       .vidioc_querybuf                = vb2_ioctl_querybuf,
-       .vidioc_qbuf                    = vb2_ioctl_qbuf,
-       .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
-       .vidioc_expbuf                  = vb2_ioctl_expbuf,
-       .vidioc_streamon                = vb2_ioctl_streamon,
-       .vidioc_streamoff               = vb2_ioctl_streamoff,
-
-       .vidioc_s_std                   = vpif_s_std,
-       .vidioc_g_std                   = vpif_g_std,
-
-       .vidioc_enum_output             = vpif_enum_output,
-       .vidioc_s_output                = vpif_s_output,
-       .vidioc_g_output                = vpif_g_output,
-
-       .vidioc_enum_dv_timings         = vpif_enum_dv_timings,
-       .vidioc_s_dv_timings            = vpif_s_dv_timings,
-       .vidioc_g_dv_timings            = vpif_g_dv_timings,
-
-       .vidioc_log_status              = vpif_log_status,
-};
-
-static const struct v4l2_file_operations vpif_fops = {
-       .owner          = THIS_MODULE,
-       .open           = v4l2_fh_open,
-       .release        = vb2_fop_release,
-       .unlocked_ioctl = video_ioctl2,
-       .mmap           = vb2_fop_mmap,
-       .poll           = vb2_fop_poll
-};
-
-/*Configure the channels, buffer sizei, request irq */
-static int initialize_vpif(void)
-{
-       int free_channel_objects_index;
-       int err, i, j;
-
-       /* Allocate memory for six channel objects */
-       for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
-               vpif_obj.dev[i] =
-                   kzalloc(sizeof(struct channel_obj), GFP_KERNEL);
-               /* If memory allocation fails, return error */
-               if (!vpif_obj.dev[i]) {
-                       free_channel_objects_index = i;
-                       err = -ENOMEM;
-                       goto vpif_init_free_channel_objects;
-               }
-       }
-
-       return 0;
-
-vpif_init_free_channel_objects:
-       for (j = 0; j < free_channel_objects_index; j++)
-               kfree(vpif_obj.dev[j]);
-       return err;
-}
-
-static void free_vpif_objs(void)
-{
-       int i;
-
-       for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++)
-               kfree(vpif_obj.dev[i]);
-}
-
-static int vpif_probe_complete(void)
-{
-       struct common_obj *common;
-       struct video_device *vdev;
-       struct channel_obj *ch;
-       struct vb2_queue *q;
-       int j, err, k;
-
-       for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
-               ch = vpif_obj.dev[j];
-               /* Initialize field of the channel objects */
-               for (k = 0; k < VPIF_NUMOBJECTS; k++) {
-                       common = &ch->common[k];
-                       spin_lock_init(&common->irqlock);
-                       mutex_init(&common->lock);
-                       common->set_addr = NULL;
-                       common->ytop_off = 0;
-                       common->ybtm_off = 0;
-                       common->ctop_off = 0;
-                       common->cbtm_off = 0;
-                       common->cur_frm = NULL;
-                       common->next_frm = NULL;
-                       memset(&common->fmt, 0, sizeof(common->fmt));
-               }
-               ch->initialized = 0;
-               if (vpif_obj.config->subdev_count)
-                       ch->sd = vpif_obj.sd[0];
-               ch->channel_id = j;
-
-               memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
-
-               ch->common[VPIF_VIDEO_INDEX].fmt.type =
-                                               V4L2_BUF_TYPE_VIDEO_OUTPUT;
-
-               /* select output 0 */
-               err = vpif_set_output(vpif_obj.config, ch, 0);
-               if (err)
-                       goto probe_out;
-
-               /* set initial format */
-               ch->video.stdid = V4L2_STD_525_60;
-               memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
-               vpif_update_resolution(ch);
-
-               /* Initialize vb2 queue */
-               q = &common->buffer_queue;
-               q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-               q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
-               q->drv_priv = ch;
-               q->ops = &video_qops;
-               q->mem_ops = &vb2_dma_contig_memops;
-               q->buf_struct_size = sizeof(struct vpif_disp_buffer);
-               q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-               q->min_buffers_needed = 1;
-               q->lock = &common->lock;
-               q->dev = vpif_dev;
-               err = vb2_queue_init(q);
-               if (err) {
-                       vpif_err("vpif_display: vb2_queue_init() failed\n");
-                       goto probe_out;
-               }
-
-               INIT_LIST_HEAD(&common->dma_queue);
-
-               /* register video device */
-               vpif_dbg(1, debug, "channel=%p,channel->video_dev=%p\n",
-                        ch, &ch->video_dev);
-
-               /* Initialize the video_device structure */
-               vdev = &ch->video_dev;
-               strscpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
-               vdev->release = video_device_release_empty;
-               vdev->fops = &vpif_fops;
-               vdev->ioctl_ops = &vpif_ioctl_ops;
-               vdev->v4l2_dev = &vpif_obj.v4l2_dev;
-               vdev->vfl_dir = VFL_DIR_TX;
-               vdev->queue = q;
-               vdev->lock = &common->lock;
-               vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
-               video_set_drvdata(&ch->video_dev, ch);
-               err = video_register_device(vdev, VFL_TYPE_VIDEO,
-                                           (j ? 3 : 2));
-               if (err < 0)
-                       goto probe_out;
-       }
-
-       return 0;
-
-probe_out:
-       for (k = 0; k < j; k++) {
-               ch = vpif_obj.dev[k];
-               video_unregister_device(&ch->video_dev);
-       }
-       return err;
-}
-
-/*
- * vpif_probe: This function creates device entries by register itself to the
- * V4L2 driver and initializes fields of each channel objects
- */
-static __init int vpif_probe(struct platform_device *pdev)
-{
-       struct vpif_subdev_info *subdevdata;
-       struct i2c_adapter *i2c_adap;
-       int subdev_count;
-       int res_idx = 0;
-       int i, err;
-
-       if (!pdev->dev.platform_data) {
-               dev_warn(&pdev->dev, "Missing platform data.  Giving up.\n");
-               return -EINVAL;
-       }
-
-       vpif_dev = &pdev->dev;
-       err = initialize_vpif();
-
-       if (err) {
-               v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
-               return err;
-       }
-
-       err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
-       if (err) {
-               v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
-               goto vpif_free;
-       }
-
-       do {
-               int irq;
-
-               err = platform_get_irq_optional(pdev, res_idx);
-               if (err < 0 && err != -ENXIO)
-                       goto vpif_unregister;
-               if (err > 0)
-                       irq = err;
-               else
-                       break;
-
-               err = devm_request_irq(&pdev->dev, irq, vpif_channel_isr,
-                                      IRQF_SHARED, VPIF_DRIVER_NAME,
-                                      (void *)(&vpif_obj.dev[res_idx]->channel_id));
-               if (err) {
-                       vpif_err("VPIF IRQ request failed\n");
-                       goto vpif_unregister;
-               }
-       } while (++res_idx);
-
-       vpif_obj.config = pdev->dev.platform_data;
-       subdev_count = vpif_obj.config->subdev_count;
-       subdevdata = vpif_obj.config->subdevinfo;
-       vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL);
-       if (!vpif_obj.sd) {
-               err = -ENOMEM;
-               goto vpif_unregister;
-       }
-
-       i2c_adap = i2c_get_adapter(vpif_obj.config->i2c_adapter_id);
-       for (i = 0; i < subdev_count; i++) {
-               vpif_obj.sd[i] =
-                       v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
-                                                 i2c_adap,
-                                                 &subdevdata[i].board_info,
-                                                 NULL);
-               if (!vpif_obj.sd[i]) {
-                       vpif_err("Error registering v4l2 subdevice\n");
-                       err = -ENODEV;
-                       goto probe_subdev_out;
-               }
-
-               if (vpif_obj.sd[i])
-                       vpif_obj.sd[i]->grp_id = 1 << i;
-       }
-       err = vpif_probe_complete();
-       if (err)
-               goto probe_subdev_out;
-
-       return 0;
-
-probe_subdev_out:
-       kfree(vpif_obj.sd);
-vpif_unregister:
-       v4l2_device_unregister(&vpif_obj.v4l2_dev);
-vpif_free:
-       free_vpif_objs();
-
-       return err;
-}
-
-/*
- * vpif_remove: It un-register channels from V4L2 driver
- */
-static int vpif_remove(struct platform_device *device)
-{
-       struct channel_obj *ch;
-       int i;
-
-       v4l2_device_unregister(&vpif_obj.v4l2_dev);
-
-       kfree(vpif_obj.sd);
-       /* un-register device */
-       for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
-               /* Get the pointer to the channel object */
-               ch = vpif_obj.dev[i];
-               /* Unregister video device */
-               video_unregister_device(&ch->video_dev);
-       }
-       free_vpif_objs();
-
-       return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int vpif_suspend(struct device *dev)
-{
-       struct common_obj *common;
-       struct channel_obj *ch;
-       int i;
-
-       for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
-               /* Get the pointer to the channel object */
-               ch = vpif_obj.dev[i];
-               common = &ch->common[VPIF_VIDEO_INDEX];
-
-               if (!vb2_start_streaming_called(&common->buffer_queue))
-                       continue;
-
-               mutex_lock(&common->lock);
-               /* Disable channel */
-               if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
-                       enable_channel2(0);
-                       channel2_intr_enable(0);
-               }
-               if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
-                       ycmux_mode == 2) {
-                       enable_channel3(0);
-                       channel3_intr_enable(0);
-               }
-               mutex_unlock(&common->lock);
-       }
-
-       return 0;
-}
-
-static int vpif_resume(struct device *dev)
-{
-
-       struct common_obj *common;
-       struct channel_obj *ch;
-       int i;
-
-       for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
-               /* Get the pointer to the channel object */
-               ch = vpif_obj.dev[i];
-               common = &ch->common[VPIF_VIDEO_INDEX];
-
-               if (!vb2_start_streaming_called(&common->buffer_queue))
-                       continue;
-
-               mutex_lock(&common->lock);
-               /* Enable channel */
-               if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
-                       enable_channel2(1);
-                       channel2_intr_enable(1);
-               }
-               if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
-                               ycmux_mode == 2) {
-                       enable_channel3(1);
-                       channel3_intr_enable(1);
-               }
-               mutex_unlock(&common->lock);
-       }
-
-       return 0;
-}
-
-#endif
-
-static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume);
-
-static __refdata struct platform_driver vpif_driver = {
-       .driver = {
-                       .name   = VPIF_DRIVER_NAME,
-                       .pm     = &vpif_pm_ops,
-       },
-       .probe  = vpif_probe,
-       .remove = vpif_remove,
-};
-
-module_platform_driver(vpif_driver);
diff --git a/drivers/media/platform/davinci/vpif_display.h b/drivers/media/platform/davinci/vpif_display.h
deleted file mode 100644 (file)
index f98062e..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * VPIF display header file
- *
- * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com/
- *
- * 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 version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef VPIF_DISPLAY_H
-#define VPIF_DISPLAY_H
-
-/* Header files */
-#include <media/videobuf2-dma-contig.h>
-#include <media/v4l2-device.h>
-
-#include "vpif.h"
-
-/* Macros */
-#define VPIF_DISPLAY_VERSION   "0.0.2"
-
-#define VPIF_VALID_FIELD(field) \
-       (((V4L2_FIELD_ANY == field) || (V4L2_FIELD_NONE == field)) || \
-       (((V4L2_FIELD_INTERLACED == field) || (V4L2_FIELD_SEQ_TB == field)) || \
-       (V4L2_FIELD_SEQ_BT == field)))
-
-#define VPIF_DISPLAY_MAX_DEVICES       (2)
-#define VPIF_SLICED_BUF_SIZE           (256)
-#define VPIF_SLICED_MAX_SERVICES       (3)
-#define VPIF_VIDEO_INDEX               (0)
-#define VPIF_VBI_INDEX                 (1)
-#define VPIF_HBI_INDEX                 (2)
-
-/* Setting it to 1 as HBI/VBI support yet to be added , else 3*/
-#define VPIF_NUMOBJECTS        (1)
-
-/* Macros */
-#define ISALIGNED(a)    (0 == ((a) & 7))
-
-/* enumerated data types */
-/* Enumerated data type to give id to each device per channel */
-enum vpif_channel_id {
-       VPIF_CHANNEL2_VIDEO = 0,        /* Channel2 Video */
-       VPIF_CHANNEL3_VIDEO,            /* Channel3 Video */
-};
-
-/* structures */
-
-struct video_obj {
-       enum v4l2_field buf_field;
-       u32 latest_only;                /* indicate whether to return
-                                        * most recent displayed frame only */
-       v4l2_std_id stdid;              /* Currently selected or default
-                                        * standard */
-       struct v4l2_dv_timings dv_timings;
-};
-
-struct vpif_disp_buffer {
-       struct vb2_v4l2_buffer vb;
-       struct list_head list;
-};
-
-struct common_obj {
-       struct vpif_disp_buffer *cur_frm;       /* Pointer pointing to current
-                                                * vb2_buffer */
-       struct vpif_disp_buffer *next_frm;      /* Pointer pointing to next
-                                                * vb2_buffer */
-       struct v4l2_format fmt;                 /* Used to store the format */
-       struct vb2_queue buffer_queue;          /* Buffer queue used in
-                                                * video-buf */
-
-       struct list_head dma_queue;             /* Queue of filled frames */
-       spinlock_t irqlock;                     /* Used in video-buf */
-
-       /* channel specific parameters */
-       struct mutex lock;                      /* lock used to access this
-                                                * structure */
-       u32 ytop_off;                           /* offset of Y top from the
-                                                * starting of the buffer */
-       u32 ybtm_off;                           /* offset of Y bottom from the
-                                                * starting of the buffer */
-       u32 ctop_off;                           /* offset of C top from the
-                                                * starting of the buffer */
-       u32 cbtm_off;                           /* offset of C bottom from the
-                                                * starting of the buffer */
-       /* Function pointer to set the addresses */
-       void (*set_addr)(unsigned long, unsigned long,
-                               unsigned long, unsigned long);
-       u32 height;
-       u32 width;
-};
-
-struct channel_obj {
-       /* V4l2 specific parameters */
-       struct video_device video_dev;  /* Identifies video device for
-                                        * this channel */
-       u32 field_id;                   /* Indicates id of the field
-                                        * which is being displayed */
-       u8 initialized;                 /* flag to indicate whether
-                                        * encoder is initialized */
-       u32 output_idx;                 /* Current output index */
-       struct v4l2_subdev *sd;         /* Current output subdev(may be NULL) */
-
-       enum vpif_channel_id channel_id;/* Identifies channel */
-       struct vpif_params vpifparams;
-       struct common_obj common[VPIF_NUMOBJECTS];
-       struct video_obj video;
-};
-
-/* vpif device structure */
-struct vpif_device {
-       struct v4l2_device v4l2_dev;
-       struct channel_obj *dev[VPIF_DISPLAY_NUM_CHANNELS];
-       struct v4l2_subdev **sd;
-       struct vpif_display_config *config;
-};
-
-#endif                         /* VPIF_DISPLAY_H */
diff --git a/drivers/media/platform/davinci/vpss.c b/drivers/media/platform/davinci/vpss.c
deleted file mode 100644 (file)
index d15b991..0000000
+++ /dev/null
@@ -1,529 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2009 Texas Instruments.
- *
- * common vpss system module platform driver for all video drivers.
- */
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/pm_runtime.h>
-#include <linux/err.h>
-
-#include <media/davinci/vpss.h>
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("VPSS Driver");
-MODULE_AUTHOR("Texas Instruments");
-
-/* DM644x defines */
-#define DM644X_SBL_PCR_VPSS            (4)
-
-#define DM355_VPSSBL_INTSEL            0x10
-#define DM355_VPSSBL_EVTSEL            0x14
-/* vpss BL register offsets */
-#define DM355_VPSSBL_CCDCMUX           0x1c
-/* vpss CLK register offsets */
-#define DM355_VPSSCLK_CLKCTRL          0x04
-/* masks and shifts */
-#define VPSS_HSSISEL_SHIFT             4
-/*
- * VDINT0 - vpss_int0, VDINT1 - vpss_int1, H3A - vpss_int4,
- * IPIPE_INT1_SDR - vpss_int5
- */
-#define DM355_VPSSBL_INTSEL_DEFAULT    0xff83ff10
-/* VENCINT - vpss_int8 */
-#define DM355_VPSSBL_EVTSEL_DEFAULT    0x4
-
-#define DM365_ISP5_PCCR                                0x04
-#define DM365_ISP5_PCCR_BL_CLK_ENABLE          BIT(0)
-#define DM365_ISP5_PCCR_ISIF_CLK_ENABLE                BIT(1)
-#define DM365_ISP5_PCCR_H3A_CLK_ENABLE         BIT(2)
-#define DM365_ISP5_PCCR_RSZ_CLK_ENABLE         BIT(3)
-#define DM365_ISP5_PCCR_IPIPE_CLK_ENABLE       BIT(4)
-#define DM365_ISP5_PCCR_IPIPEIF_CLK_ENABLE     BIT(5)
-#define DM365_ISP5_PCCR_RSV                    BIT(6)
-
-#define DM365_ISP5_BCR                 0x08
-#define DM365_ISP5_BCR_ISIF_OUT_ENABLE BIT(1)
-
-#define DM365_ISP5_INTSEL1             0x10
-#define DM365_ISP5_INTSEL2             0x14
-#define DM365_ISP5_INTSEL3             0x18
-#define DM365_ISP5_CCDCMUX             0x20
-#define DM365_ISP5_PG_FRAME_SIZE       0x28
-#define DM365_VPBE_CLK_CTRL            0x00
-
-#define VPSS_CLK_CTRL                  0x01c40044
-#define VPSS_CLK_CTRL_VENCCLKEN                BIT(3)
-#define VPSS_CLK_CTRL_DACCLKEN         BIT(4)
-
-/*
- * vpss interrupts. VDINT0 - vpss_int0, VDINT1 - vpss_int1,
- * AF - vpss_int3
- */
-#define DM365_ISP5_INTSEL1_DEFAULT     0x0b1f0100
-/* AEW - vpss_int6, RSZ_INT_DMA - vpss_int5 */
-#define DM365_ISP5_INTSEL2_DEFAULT     0x1f0a0f1f
-/* VENC - vpss_int8 */
-#define DM365_ISP5_INTSEL3_DEFAULT     0x00000015
-
-/* masks and shifts for DM365*/
-#define DM365_CCDC_PG_VD_POL_SHIFT     0
-#define DM365_CCDC_PG_HD_POL_SHIFT     1
-
-#define CCD_SRC_SEL_MASK               (BIT_MASK(5) | BIT_MASK(4))
-#define CCD_SRC_SEL_SHIFT              4
-
-/* Different SoC platforms supported by this driver */
-enum vpss_platform_type {
-       DM644X,
-       DM355,
-       DM365,
-};
-
-/*
- * vpss operations. Depends on platform. Not all functions are available
- * on all platforms. The api, first check if a function is available before
- * invoking it. In the probe, the function ptrs are initialized based on
- * vpss name. vpss name can be "dm355_vpss", "dm644x_vpss" etc.
- */
-struct vpss_hw_ops {
-       /* enable clock */
-       int (*enable_clock)(enum vpss_clock_sel clock_sel, int en);
-       /* select input to ccdc */
-       void (*select_ccdc_source)(enum vpss_ccdc_source_sel src_sel);
-       /* clear wbl overflow bit */
-       int (*clear_wbl_overflow)(enum vpss_wbl_sel wbl_sel);
-       /* set sync polarity */
-       void (*set_sync_pol)(struct vpss_sync_pol);
-       /* set the PG_FRAME_SIZE register*/
-       void (*set_pg_frame_size)(struct vpss_pg_frame_size);
-       /* check and clear interrupt if occurred */
-       int (*dma_complete_interrupt)(void);
-};
-
-/* vpss configuration */
-struct vpss_oper_config {
-       __iomem void *vpss_regs_base0;
-       __iomem void *vpss_regs_base1;
-       __iomem void *vpss_regs_base2;
-       enum vpss_platform_type platform;
-       spinlock_t vpss_lock;
-       struct vpss_hw_ops hw_ops;
-};
-
-static struct vpss_oper_config oper_cfg;
-
-/* register access routines */
-static inline u32 bl_regr(u32 offset)
-{
-       return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
-}
-
-static inline void bl_regw(u32 val, u32 offset)
-{
-       __raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
-}
-
-static inline u32 vpss_regr(u32 offset)
-{
-       return __raw_readl(oper_cfg.vpss_regs_base1 + offset);
-}
-
-static inline void vpss_regw(u32 val, u32 offset)
-{
-       __raw_writel(val, oper_cfg.vpss_regs_base1 + offset);
-}
-
-/* For DM365 only */
-static inline u32 isp5_read(u32 offset)
-{
-       return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
-}
-
-/* For DM365 only */
-static inline void isp5_write(u32 val, u32 offset)
-{
-       __raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
-}
-
-static void dm365_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
-{
-       u32 temp = isp5_read(DM365_ISP5_CCDCMUX) & ~CCD_SRC_SEL_MASK;
-
-       /* if we are using pattern generator, enable it */
-       if (src_sel == VPSS_PGLPBK || src_sel == VPSS_CCDCPG)
-               temp |= 0x08;
-
-       temp |= (src_sel << CCD_SRC_SEL_SHIFT);
-       isp5_write(temp, DM365_ISP5_CCDCMUX);
-}
-
-static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
-{
-       bl_regw(src_sel << VPSS_HSSISEL_SHIFT, DM355_VPSSBL_CCDCMUX);
-}
-
-int vpss_dma_complete_interrupt(void)
-{
-       if (!oper_cfg.hw_ops.dma_complete_interrupt)
-               return 2;
-       return oper_cfg.hw_ops.dma_complete_interrupt();
-}
-EXPORT_SYMBOL(vpss_dma_complete_interrupt);
-
-int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
-{
-       if (!oper_cfg.hw_ops.select_ccdc_source)
-               return -EINVAL;
-
-       oper_cfg.hw_ops.select_ccdc_source(src_sel);
-       return 0;
-}
-EXPORT_SYMBOL(vpss_select_ccdc_source);
-
-static int dm644x_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
-{
-       u32 mask = 1, val;
-
-       if (wbl_sel < VPSS_PCR_AEW_WBL_0 ||
-           wbl_sel > VPSS_PCR_CCDC_WBL_O)
-               return -EINVAL;
-
-       /* writing a 0 clear the overflow */
-       mask = ~(mask << wbl_sel);
-       val = bl_regr(DM644X_SBL_PCR_VPSS) & mask;
-       bl_regw(val, DM644X_SBL_PCR_VPSS);
-       return 0;
-}
-
-void vpss_set_sync_pol(struct vpss_sync_pol sync)
-{
-       if (!oper_cfg.hw_ops.set_sync_pol)
-               return;
-
-       oper_cfg.hw_ops.set_sync_pol(sync);
-}
-EXPORT_SYMBOL(vpss_set_sync_pol);
-
-int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
-{
-       if (!oper_cfg.hw_ops.clear_wbl_overflow)
-               return -EINVAL;
-
-       return oper_cfg.hw_ops.clear_wbl_overflow(wbl_sel);
-}
-EXPORT_SYMBOL(vpss_clear_wbl_overflow);
-
-/*
- *  dm355_enable_clock - Enable VPSS Clock
- *  @clock_sel: Clock to be enabled/disabled
- *  @en: enable/disable flag
- *
- *  This is called to enable or disable a vpss clock
- */
-static int dm355_enable_clock(enum vpss_clock_sel clock_sel, int en)
-{
-       unsigned long flags;
-       u32 utemp, mask = 0x1, shift = 0;
-
-       switch (clock_sel) {
-       case VPSS_VPBE_CLOCK:
-               /* nothing since lsb */
-               break;
-       case VPSS_VENC_CLOCK_SEL:
-               shift = 2;
-               break;
-       case VPSS_CFALD_CLOCK:
-               shift = 3;
-               break;
-       case VPSS_H3A_CLOCK:
-               shift = 4;
-               break;
-       case VPSS_IPIPE_CLOCK:
-               shift = 5;
-               break;
-       case VPSS_CCDC_CLOCK:
-               shift = 6;
-               break;
-       default:
-               printk(KERN_ERR "dm355_enable_clock: Invalid selector: %d\n",
-                      clock_sel);
-               return -EINVAL;
-       }
-
-       spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
-       utemp = vpss_regr(DM355_VPSSCLK_CLKCTRL);
-       if (!en)
-               utemp &= ~(mask << shift);
-       else
-               utemp |= (mask << shift);
-
-       vpss_regw(utemp, DM355_VPSSCLK_CLKCTRL);
-       spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
-       return 0;
-}
-
-static int dm365_enable_clock(enum vpss_clock_sel clock_sel, int en)
-{
-       unsigned long flags;
-       u32 utemp, mask = 0x1, shift = 0, offset = DM365_ISP5_PCCR;
-       u32 (*read)(u32 offset) = isp5_read;
-       void(*write)(u32 val, u32 offset) = isp5_write;
-
-       switch (clock_sel) {
-       case VPSS_BL_CLOCK:
-               break;
-       case VPSS_CCDC_CLOCK:
-               shift = 1;
-               break;
-       case VPSS_H3A_CLOCK:
-               shift = 2;
-               break;
-       case VPSS_RSZ_CLOCK:
-               shift = 3;
-               break;
-       case VPSS_IPIPE_CLOCK:
-               shift = 4;
-               break;
-       case VPSS_IPIPEIF_CLOCK:
-               shift = 5;
-               break;
-       case VPSS_PCLK_INTERNAL:
-               shift = 6;
-               break;
-       case VPSS_PSYNC_CLOCK_SEL:
-               shift = 7;
-               break;
-       case VPSS_VPBE_CLOCK:
-               read = vpss_regr;
-               write = vpss_regw;
-               offset = DM365_VPBE_CLK_CTRL;
-               break;
-       case VPSS_VENC_CLOCK_SEL:
-               shift = 2;
-               read = vpss_regr;
-               write = vpss_regw;
-               offset = DM365_VPBE_CLK_CTRL;
-               break;
-       case VPSS_LDC_CLOCK:
-               shift = 3;
-               read = vpss_regr;
-               write = vpss_regw;
-               offset = DM365_VPBE_CLK_CTRL;
-               break;
-       case VPSS_FDIF_CLOCK:
-               shift = 4;
-               read = vpss_regr;
-               write = vpss_regw;
-               offset = DM365_VPBE_CLK_CTRL;
-               break;
-       case VPSS_OSD_CLOCK_SEL:
-               shift = 6;
-               read = vpss_regr;
-               write = vpss_regw;
-               offset = DM365_VPBE_CLK_CTRL;
-               break;
-       case VPSS_LDC_CLOCK_SEL:
-               shift = 7;
-               read = vpss_regr;
-               write = vpss_regw;
-               offset = DM365_VPBE_CLK_CTRL;
-               break;
-       default:
-               printk(KERN_ERR "dm365_enable_clock: Invalid selector: %d\n",
-                      clock_sel);
-               return -1;
-       }
-
-       spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
-       utemp = read(offset);
-       if (!en) {
-               mask = ~mask;
-               utemp &= (mask << shift);
-       } else
-               utemp |= (mask << shift);
-
-       write(utemp, offset);
-       spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
-
-       return 0;
-}
-
-int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en)
-{
-       if (!oper_cfg.hw_ops.enable_clock)
-               return -EINVAL;
-
-       return oper_cfg.hw_ops.enable_clock(clock_sel, en);
-}
-EXPORT_SYMBOL(vpss_enable_clock);
-
-void dm365_vpss_set_sync_pol(struct vpss_sync_pol sync)
-{
-       int val = 0;
-       val = isp5_read(DM365_ISP5_CCDCMUX);
-
-       val |= (sync.ccdpg_hdpol << DM365_CCDC_PG_HD_POL_SHIFT);
-       val |= (sync.ccdpg_vdpol << DM365_CCDC_PG_VD_POL_SHIFT);
-
-       isp5_write(val, DM365_ISP5_CCDCMUX);
-}
-EXPORT_SYMBOL(dm365_vpss_set_sync_pol);
-
-void vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size)
-{
-       if (!oper_cfg.hw_ops.set_pg_frame_size)
-               return;
-
-       oper_cfg.hw_ops.set_pg_frame_size(frame_size);
-}
-EXPORT_SYMBOL(vpss_set_pg_frame_size);
-
-void dm365_vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size)
-{
-       int current_reg = ((frame_size.hlpfr >> 1) - 1) << 16;
-
-       current_reg |= (frame_size.pplen - 1);
-       isp5_write(current_reg, DM365_ISP5_PG_FRAME_SIZE);
-}
-EXPORT_SYMBOL(dm365_vpss_set_pg_frame_size);
-
-static int vpss_probe(struct platform_device *pdev)
-{
-       char *platform_name;
-
-       if (!pdev->dev.platform_data) {
-               dev_err(&pdev->dev, "no platform data\n");
-               return -ENOENT;
-       }
-
-       platform_name = pdev->dev.platform_data;
-       if (!strcmp(platform_name, "dm355_vpss"))
-               oper_cfg.platform = DM355;
-       else if (!strcmp(platform_name, "dm365_vpss"))
-               oper_cfg.platform = DM365;
-       else if (!strcmp(platform_name, "dm644x_vpss"))
-               oper_cfg.platform = DM644X;
-       else {
-               dev_err(&pdev->dev, "vpss driver not supported on this platform\n");
-               return -ENODEV;
-       }
-
-       dev_info(&pdev->dev, "%s vpss probed\n", platform_name);
-       oper_cfg.vpss_regs_base0 = devm_platform_ioremap_resource(pdev, 0);
-       if (IS_ERR(oper_cfg.vpss_regs_base0))
-               return PTR_ERR(oper_cfg.vpss_regs_base0);
-
-       if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) {
-               oper_cfg.vpss_regs_base1 = devm_platform_ioremap_resource(pdev, 1);
-               if (IS_ERR(oper_cfg.vpss_regs_base1))
-                       return PTR_ERR(oper_cfg.vpss_regs_base1);
-       }
-
-       if (oper_cfg.platform == DM355) {
-               oper_cfg.hw_ops.enable_clock = dm355_enable_clock;
-               oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source;
-               /* Setup vpss interrupts */
-               bl_regw(DM355_VPSSBL_INTSEL_DEFAULT, DM355_VPSSBL_INTSEL);
-               bl_regw(DM355_VPSSBL_EVTSEL_DEFAULT, DM355_VPSSBL_EVTSEL);
-       } else if (oper_cfg.platform == DM365) {
-               oper_cfg.hw_ops.enable_clock = dm365_enable_clock;
-               oper_cfg.hw_ops.select_ccdc_source = dm365_select_ccdc_source;
-               /* Setup vpss interrupts */
-               isp5_write((isp5_read(DM365_ISP5_PCCR) |
-                                     DM365_ISP5_PCCR_BL_CLK_ENABLE |
-                                     DM365_ISP5_PCCR_ISIF_CLK_ENABLE |
-                                     DM365_ISP5_PCCR_H3A_CLK_ENABLE |
-                                     DM365_ISP5_PCCR_RSZ_CLK_ENABLE |
-                                     DM365_ISP5_PCCR_IPIPE_CLK_ENABLE |
-                                     DM365_ISP5_PCCR_IPIPEIF_CLK_ENABLE |
-                                     DM365_ISP5_PCCR_RSV), DM365_ISP5_PCCR);
-               isp5_write((isp5_read(DM365_ISP5_BCR) |
-                           DM365_ISP5_BCR_ISIF_OUT_ENABLE), DM365_ISP5_BCR);
-               isp5_write(DM365_ISP5_INTSEL1_DEFAULT, DM365_ISP5_INTSEL1);
-               isp5_write(DM365_ISP5_INTSEL2_DEFAULT, DM365_ISP5_INTSEL2);
-               isp5_write(DM365_ISP5_INTSEL3_DEFAULT, DM365_ISP5_INTSEL3);
-       } else
-               oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow;
-
-       pm_runtime_enable(&pdev->dev);
-
-       pm_runtime_get(&pdev->dev);
-
-       spin_lock_init(&oper_cfg.vpss_lock);
-       dev_info(&pdev->dev, "%s vpss probe success\n", platform_name);
-
-       return 0;
-}
-
-static int vpss_remove(struct platform_device *pdev)
-{
-       pm_runtime_disable(&pdev->dev);
-       return 0;
-}
-
-static int vpss_suspend(struct device *dev)
-{
-       pm_runtime_put(dev);
-       return 0;
-}
-
-static int vpss_resume(struct device *dev)
-{
-       pm_runtime_get(dev);
-       return 0;
-}
-
-static const struct dev_pm_ops vpss_pm_ops = {
-       .suspend = vpss_suspend,
-       .resume = vpss_resume,
-};
-
-static struct platform_driver vpss_driver = {
-       .driver = {
-               .name   = "vpss",
-               .pm = &vpss_pm_ops,
-       },
-       .remove = vpss_remove,
-       .probe = vpss_probe,
-};
-
-static void vpss_exit(void)
-{
-       platform_driver_unregister(&vpss_driver);
-       iounmap(oper_cfg.vpss_regs_base2);
-       release_mem_region(VPSS_CLK_CTRL, 4);
-}
-
-static int __init vpss_init(void)
-{
-       int ret;
-
-       if (!request_mem_region(VPSS_CLK_CTRL, 4, "vpss_clock_control"))
-               return -EBUSY;
-
-       oper_cfg.vpss_regs_base2 = ioremap(VPSS_CLK_CTRL, 4);
-       if (unlikely(!oper_cfg.vpss_regs_base2)) {
-               ret = -ENOMEM;
-               goto err_ioremap;
-       }
-
-       writel(VPSS_CLK_CTRL_VENCCLKEN |
-              VPSS_CLK_CTRL_DACCLKEN, oper_cfg.vpss_regs_base2);
-
-       ret = platform_driver_register(&vpss_driver);
-       if (ret)
-               goto err_pd_register;
-
-       return 0;
-
-err_pd_register:
-       iounmap(oper_cfg.vpss_regs_base2);
-err_ioremap:
-       release_mem_region(VPSS_CLK_CTRL, 4);
-       return ret;
-}
-subsys_initcall(vpss_init);
-module_exit(vpss_exit);
diff --git a/drivers/media/platform/ti/davinci/Kconfig b/drivers/media/platform/ti/davinci/Kconfig
new file mode 100644 (file)
index 0000000..7e5f92b
--- /dev/null
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config VIDEO_DAVINCI_VPIF_DISPLAY
+       tristate "TI DaVinci VPIF V4L2-Display driver"
+       depends on V4L_PLATFORM_DRIVERS
+       depends on VIDEO_V4L2
+       depends on ARCH_DAVINCI || COMPILE_TEST
+       depends on I2C
+       select VIDEOBUF2_DMA_CONTIG
+       select VIDEO_ADV7343 if MEDIA_SUBDRV_AUTOSELECT
+       select VIDEO_THS7303 if MEDIA_SUBDRV_AUTOSELECT
+       help
+         Enables Davinci VPIF module used for display devices.
+         This module is used for display on TI DM6467/DA850/OMAPL138
+         SoCs.
+
+         To compile this driver as a module, choose M here. There will
+         be two modules called vpif.ko and vpif_display.ko
+
+config VIDEO_DAVINCI_VPIF_CAPTURE
+       tristate "TI DaVinci VPIF video capture driver"
+       depends on V4L_PLATFORM_DRIVERS
+       depends on VIDEO_V4L2
+       depends on ARCH_DAVINCI || COMPILE_TEST
+       depends on I2C
+       select VIDEOBUF2_DMA_CONTIG
+       select V4L2_FWNODE
+       help
+         Enables Davinci VPIF module used for capture devices.
+         This module is used for capture on TI DM6467/DA850/OMAPL138
+         SoCs.
+
+         To compile this driver as a module, choose M here. There will
+         be two modules called vpif.ko and vpif_capture.ko
+
+config VIDEO_DM6446_CCDC
+       tristate "TI DM6446 CCDC video capture driver"
+       depends on V4L_PLATFORM_DRIVERS
+       depends on VIDEO_V4L2
+       depends on ARCH_DAVINCI || COMPILE_TEST
+       depends on I2C
+       select VIDEOBUF_DMA_CONTIG
+       help
+          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. There will
+          be three modules called vpfe_capture.ko, vpss.ko and dm644x_ccdc.ko
+
+config VIDEO_DM355_CCDC
+       tristate "TI DM355 CCDC video capture driver"
+       depends on V4L_PLATFORM_DRIVERS
+       depends on VIDEO_V4L2
+       depends on ARCH_DAVINCI || COMPILE_TEST
+       depends on I2C
+       select VIDEOBUF_DMA_CONTIG
+       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. There will
+          be three modules called vpfe_capture.ko, vpss.ko and dm355_ccdc.ko
+
+config VIDEO_DM365_ISIF
+       tristate "TI DM365 ISIF video capture driver"
+       depends on V4L_PLATFORM_DRIVERS
+       depends on VIDEO_V4L2
+       depends on ARCH_DAVINCI || COMPILE_TEST
+       depends on I2C
+       select VIDEOBUF_DMA_CONTIG
+       help
+          Enables ISIF hw module. This is the hardware module for
+          configuring ISIF in VPFE to capture Raw Bayer RGB data from
+          a image sensor or YUV data from a YUV source.
+
+          To compile this driver as a module, choose M here. There will
+          be three modules called vpfe_capture.ko, vpss.ko and isif.ko
+
+config VIDEO_DAVINCI_VPBE_DISPLAY
+       tristate "TI DaVinci VPBE V4L2-Display driver"
+       depends on V4L_PLATFORM_DRIVERS
+       depends on VIDEO_V4L2
+       depends on ARCH_DAVINCI || COMPILE_TEST
+       depends on I2C
+       select VIDEOBUF2_DMA_CONTIG
+       help
+           Enables Davinci VPBE module used for display devices.
+           This module is used for display on TI DM644x/DM365/DM355
+           based display devices.
+
+           To compile this driver as a module, choose M here. There will
+           be five modules created called vpss.ko, vpbe.ko, vpbe_osd.ko,
+           vpbe_venc.ko and vpbe_display.ko
diff --git a/drivers/media/platform/ti/davinci/Makefile b/drivers/media/platform/ti/davinci/Makefile
new file mode 100644 (file)
index 0000000..05c45bf
--- /dev/null
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the davinci video device drivers.
+#
+
+#VPIF Display driver
+obj-$(CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY) += vpif.o vpif_display.o
+#VPIF Capture driver
+obj-$(CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE) += vpif.o vpif_capture.o
+
+# Capture: DM6446 and DM355
+obj-$(CONFIG_VIDEO_DM6446_CCDC) += vpfe_capture.o vpss.o dm644x_ccdc.o
+obj-$(CONFIG_VIDEO_DM355_CCDC) += vpfe_capture.o vpss.o dm355_ccdc.o
+obj-$(CONFIG_VIDEO_DM365_ISIF) += vpfe_capture.o vpss.o isif.o
+obj-$(CONFIG_VIDEO_DAVINCI_VPBE_DISPLAY) += vpss.o vpbe.o vpbe_osd.o \
+       vpbe_venc.o vpbe_display.o
diff --git a/drivers/media/platform/ti/davinci/ccdc_hw_device.h b/drivers/media/platform/ti/davinci/ccdc_hw_device.h
new file mode 100644 (file)
index 0000000..a545052
--- /dev/null
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2008-2009 Texas Instruments Inc
+ *
+ * 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_types.h>
+
+/*
+ * ccdc hw operations
+ */
+struct ccdc_hw_ops {
+       /* Pointer to initialize function to initialize ccdc device */
+       int (*open) (struct device *dev);
+       /* Pointer to deinitialize function */
+       int (*close) (struct device *dev);
+       /* set ccdc base address */
+       void (*set_ccdc_base)(void *base, int size);
+       /* Pointer to function to enable or disable ccdc */
+       void (*enable) (int en);
+       /* reset sbl. only for 6446 */
+       void (*reset) (void);
+       /* enable output to sdram */
+       void (*enable_out_to_sdram) (int en);
+       /* Pointer to function to set hw parameters */
+       int (*set_hw_if_params) (struct vpfe_hw_if_param *param);
+       /* get interface parameters */
+       int (*get_hw_if_params) (struct vpfe_hw_if_param *param);
+       /* Pointer to function to configure ccdc */
+       int (*configure) (void);
+
+       /* Pointer to function to set buffer type */
+       int (*set_buftype) (enum ccdc_buftype buf_type);
+       /* Pointer to function to get buffer type */
+       enum ccdc_buftype (*get_buftype) (void);
+       /* Pointer to function to set frame format */
+       int (*set_frame_format) (enum ccdc_frmfmt frm_fmt);
+       /* Pointer to function to get frame format */
+       enum ccdc_frmfmt (*get_frame_format) (void);
+       /* enumerate hw pix formats */
+       int (*enum_pix)(u32 *hw_pix, int i);
+       /* Pointer to function to set buffer type */
+       u32 (*get_pixel_format) (void);
+       /* Pointer to function to get pixel format. */
+       int (*set_pixel_format) (u32 pixfmt);
+       /* Pointer to function to set image window */
+       int (*set_image_window) (struct v4l2_rect *win);
+       /* Pointer to function to set image window */
+       void (*get_image_window) (struct v4l2_rect *win);
+       /* Pointer to function to get line length */
+       unsigned int (*get_line_length) (void);
+
+       /* Pointer to function to set frame buffer address */
+       void (*setfbaddr) (unsigned long addr);
+       /* Pointer to function to get field id */
+       int (*getfid) (void);
+};
+
+struct ccdc_hw_device {
+       /* ccdc device name */
+       char name[32];
+       /* module owner */
+       struct module *owner;
+       /* hw ops */
+       struct ccdc_hw_ops hw_ops;
+};
+
+/* Used by CCDC module to register & unregister with vpfe capture driver */
+int vpfe_register_ccdc_device(const struct ccdc_hw_device *dev);
+void vpfe_unregister_ccdc_device(const struct ccdc_hw_device *dev);
+
+#endif
+#endif
diff --git a/drivers/media/platform/ti/davinci/dm355_ccdc.c b/drivers/media/platform/ti/davinci/dm355_ccdc.c
new file mode 100644 (file)
index 0000000..e06d113
--- /dev/null
@@ -0,0 +1,935 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2005-2009 Texas Instruments Inc
+ *
+ * CCDC hardware module for DM355
+ * ------------------------------
+ *
+ * This module is for configuring DM355 CCD controller of VPFE to capture
+ * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
+ * such as Defect Pixel Correction, Color Space Conversion etc to
+ * pre-process the Bayer RGB data, before writing it to SDRAM.
+ *
+ * TODO: 1) Raw bayer parameter settings and bayer capture
+ *      2) Split module parameter structure to module specific ioctl structs
+ *      3) add support for lense shading correction
+ *      4) investigate if enum used for user space type definition
+ *         to be replaced by #defines or integer
+ */
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/videodev2.h>
+#include <linux/err.h>
+#include <linux/module.h>
+
+#include <media/davinci/dm355_ccdc.h>
+#include <media/davinci/vpss.h>
+
+#include "dm355_ccdc_regs.h"
+#include "ccdc_hw_device.h"
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CCDC Driver for DM355");
+MODULE_AUTHOR("Texas Instruments");
+
+static struct ccdc_oper_config {
+       struct device *dev;
+       /* CCDC interface type */
+       enum vpfe_hw_if_type if_type;
+       /* Raw Bayer configuration */
+       struct ccdc_params_raw bayer;
+       /* YCbCr configuration */
+       struct ccdc_params_ycbcr ycbcr;
+       /* ccdc base address */
+       void __iomem *base_addr;
+} ccdc_cfg = {
+       /* Raw configurations */
+       .bayer = {
+               .pix_fmt = CCDC_PIXFMT_RAW,
+               .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
+               .win = CCDC_WIN_VGA,
+               .fid_pol = VPFE_PINPOL_POSITIVE,
+               .vd_pol = VPFE_PINPOL_POSITIVE,
+               .hd_pol = VPFE_PINPOL_POSITIVE,
+               .gain = {
+                       .r_ye = 256,
+                       .gb_g = 256,
+                       .gr_cy = 256,
+                       .b_mg = 256
+               },
+               .config_params = {
+                       .datasft = 2,
+                       .mfilt1 = CCDC_NO_MEDIAN_FILTER1,
+                       .mfilt2 = CCDC_NO_MEDIAN_FILTER2,
+                       .alaw = {
+                               .gamma_wd = 2,
+                       },
+                       .blk_clamp = {
+                               .sample_pixel = 1,
+                               .dc_sub = 25
+                       },
+                       .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
+                       },
+               },
+       },
+       /* YCbCr configuration */
+       .ycbcr = {
+               .win = CCDC_WIN_PAL,
+               .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
+               .frm_fmt = CCDC_FRMFMT_INTERLACED,
+               .fid_pol = VPFE_PINPOL_POSITIVE,
+               .vd_pol = VPFE_PINPOL_POSITIVE,
+               .hd_pol = VPFE_PINPOL_POSITIVE,
+               .bt656_enable = 1,
+               .pix_order = CCDC_PIXORDER_CBYCRY,
+               .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
+       },
+};
+
+
+/* Raw Bayer formats */
+static u32 ccdc_raw_bayer_pix_formats[] =
+               {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
+
+/* Raw YUV formats */
+static u32 ccdc_raw_yuv_pix_formats[] =
+               {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
+
+/* register access routines */
+static inline u32 regr(u32 offset)
+{
+       return __raw_readl(ccdc_cfg.base_addr + offset);
+}
+
+static inline void regw(u32 val, u32 offset)
+{
+       __raw_writel(val, ccdc_cfg.base_addr + offset);
+}
+
+static void ccdc_enable(int en)
+{
+       unsigned int temp;
+       temp = regr(SYNCEN);
+       temp &= (~CCDC_SYNCEN_VDHDEN_MASK);
+       temp |= (en & CCDC_SYNCEN_VDHDEN_MASK);
+       regw(temp, SYNCEN);
+}
+
+static void ccdc_enable_output_to_sdram(int en)
+{
+       unsigned int temp;
+       temp = regr(SYNCEN);
+       temp &= (~(CCDC_SYNCEN_WEN_MASK));
+       temp |= ((en << CCDC_SYNCEN_WEN_SHIFT) & CCDC_SYNCEN_WEN_MASK);
+       regw(temp, SYNCEN);
+}
+
+static void ccdc_config_gain_offset(void)
+{
+       /* configure gain */
+       regw(ccdc_cfg.bayer.gain.r_ye, RYEGAIN);
+       regw(ccdc_cfg.bayer.gain.gr_cy, GRCYGAIN);
+       regw(ccdc_cfg.bayer.gain.gb_g, GBGGAIN);
+       regw(ccdc_cfg.bayer.gain.b_mg, BMGGAIN);
+       /* configure offset */
+       regw(ccdc_cfg.bayer.ccdc_offset, OFFSET);
+}
+
+/*
+ * ccdc_restore_defaults()
+ * This function restore power on defaults in the ccdc registers
+ */
+static int ccdc_restore_defaults(void)
+{
+       int i;
+
+       dev_dbg(ccdc_cfg.dev, "\nstarting ccdc_restore_defaults...");
+       /* set all registers to zero */
+       for (i = 0; i <= CCDC_REG_LAST; i += 4)
+               regw(0, i);
+
+       /* now override the values with power on defaults in registers */
+       regw(MODESET_DEFAULT, MODESET);
+       /* no culling support */
+       regw(CULH_DEFAULT, CULH);
+       regw(CULV_DEFAULT, CULV);
+       /* Set default Gain and Offset */
+       ccdc_cfg.bayer.gain.r_ye = GAIN_DEFAULT;
+       ccdc_cfg.bayer.gain.gb_g = GAIN_DEFAULT;
+       ccdc_cfg.bayer.gain.gr_cy = GAIN_DEFAULT;
+       ccdc_cfg.bayer.gain.b_mg = GAIN_DEFAULT;
+       ccdc_config_gain_offset();
+       regw(OUTCLIP_DEFAULT, OUTCLIP);
+       regw(LSCCFG2_DEFAULT, LSCCFG2);
+       /* select ccdc input */
+       if (vpss_select_ccdc_source(VPSS_CCDCIN)) {
+               dev_dbg(ccdc_cfg.dev, "\ncouldn't select ccdc input source");
+               return -EFAULT;
+       }
+       /* select ccdc clock */
+       if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) {
+               dev_dbg(ccdc_cfg.dev, "\ncouldn't enable ccdc clock");
+               return -EFAULT;
+       }
+       dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_restore_defaults...");
+       return 0;
+}
+
+static int ccdc_open(struct device *device)
+{
+       return ccdc_restore_defaults();
+}
+
+static int ccdc_close(struct device *device)
+{
+       /* disable clock */
+       vpss_enable_clock(VPSS_CCDC_CLOCK, 0);
+       /* do nothing for now */
+       return 0;
+}
+/*
+ * ccdc_setwin()
+ * This function will configure the window size to
+ * be capture in CCDC reg.
+ */
+static void ccdc_setwin(struct v4l2_rect *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(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
+
+       /*
+        * ppc - per pixel count. indicates how many pixels per cell
+        * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
+        * raw capture this is 1
+        */
+       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, SPH);
+       regw(horz_nr_pixels, NPH);
+       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 and VDINT1 */
+               regw(vert_start, VDINT0);
+       } else {
+               /* Since first line doesn't have any data */
+               vert_start += 1;
+               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 & CCDC_START_VER_ONE_MASK, SLV0);
+       regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1);
+       regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV);
+       dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
+}
+
+/* This function will configure CCDC for YCbCr video capture */
+static void ccdc_config_ycbcr(void)
+{
+       struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
+       u32 temp;
+
+       /* first set the CCDC power on defaults values in all registers */
+       dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
+       ccdc_restore_defaults();
+
+       /* configure pixel format & video frame format */
+       temp = (((params->pix_fmt & CCDC_INPUT_MODE_MASK) <<
+               CCDC_INPUT_MODE_SHIFT) |
+               ((params->frm_fmt & CCDC_FRM_FMT_MASK) <<
+               CCDC_FRM_FMT_SHIFT));
+
+       /* setup BT.656 sync mode */
+       if (params->bt656_enable) {
+               regw(CCDC_REC656IF_BT656_EN, REC656IF);
+               /*
+                * configure the FID, VD, HD pin polarity fld,hd pol positive,
+                * vd negative, 8-bit pack mode
+                */
+               temp |= CCDC_VD_POL_NEGATIVE;
+       } else {                /* y/c external sync mode */
+               temp |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
+                       CCDC_FID_POL_SHIFT) |
+                       ((params->hd_pol & CCDC_HD_POL_MASK) <<
+                       CCDC_HD_POL_SHIFT) |
+                       ((params->vd_pol & CCDC_VD_POL_MASK) <<
+                       CCDC_VD_POL_SHIFT));
+       }
+
+       /* pack the data to 8-bit */
+       temp |= CCDC_DATA_PACK_ENABLE;
+
+       regw(temp, MODESET);
+
+       /* configure video window */
+       ccdc_setwin(&params->win, params->frm_fmt, 2);
+
+       /* configure the order of y cb cr in SD-RAM */
+       temp = (params->pix_order << CCDC_Y8POS_SHIFT);
+       temp |= CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC;
+       regw(temp, 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) >> 5), HSIZE);
+
+       /* configure the memory line offset */
+       if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) {
+               /* two fields are interleaved in memory */
+               regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST);
+       }
+
+       dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
+}
+
+/*
+ * ccdc_config_black_clamp()
+ * configure parameters for Optical Black Clamp
+ */
+static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
+{
+       u32 val;
+
+       if (!bclamp->b_clamp_enable) {
+               /* configure DCSub */
+               regw(bclamp->dc_sub & CCDC_BLK_DC_SUB_MASK, DCSUB);
+               regw(0x0000, CLAMP);
+               return;
+       }
+       /* Enable the Black clamping, set sample lines and pixels */
+       val = (bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) |
+             ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
+               CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE;
+       regw(val, CLAMP);
+
+       /* If Black clamping is enable then make dcsub 0 */
+       val = (bclamp->sample_ln & CCDC_NUM_LINE_CALC_MASK)
+                       << CCDC_NUM_LINE_CALC_SHIFT;
+       regw(val, DCSUB);
+}
+
+/*
+ * ccdc_config_black_compense()
+ * configure parameters for Black Compensation
+ */
+static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
+{
+       u32 val;
+
+       val = (bcomp->b & CCDC_BLK_COMP_MASK) |
+               ((bcomp->gb & CCDC_BLK_COMP_MASK) <<
+               CCDC_BLK_COMP_GB_COMP_SHIFT);
+       regw(val, BLKCMP1);
+
+       val = ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
+               CCDC_BLK_COMP_GR_COMP_SHIFT) |
+               ((bcomp->r & CCDC_BLK_COMP_MASK) <<
+               CCDC_BLK_COMP_R_COMP_SHIFT);
+       regw(val, BLKCMP0);
+}
+
+/*
+ * ccdc_write_dfc_entry()
+ * write an entry in the dfc table.
+ */
+static int ccdc_write_dfc_entry(int index, struct ccdc_vertical_dft *dfc)
+{
+/* TODO This is to be re-visited and adjusted */
+#define DFC_WRITE_WAIT_COUNT   1000
+       u32 val, count = DFC_WRITE_WAIT_COUNT;
+
+       regw(dfc->dft_corr_vert[index], DFCMEM0);
+       regw(dfc->dft_corr_horz[index], DFCMEM1);
+       regw(dfc->dft_corr_sub1[index], DFCMEM2);
+       regw(dfc->dft_corr_sub2[index], DFCMEM3);
+       regw(dfc->dft_corr_sub3[index], DFCMEM4);
+       /* set WR bit to write */
+       val = regr(DFCMEMCTL) | CCDC_DFCMEMCTL_DFCMWR_MASK;
+       regw(val, DFCMEMCTL);
+
+       /*
+        * Assume, it is very short. If we get an error, we need to
+        * adjust this value
+        */
+       while (regr(DFCMEMCTL) & CCDC_DFCMEMCTL_DFCMWR_MASK)
+               count--;
+       /*
+        * TODO We expect the count to be non-zero to be successful. Adjust
+        * the count if write requires more time
+        */
+
+       if (count) {
+               dev_err(ccdc_cfg.dev, "defect table write timeout !!!\n");
+               return -1;
+       }
+       return 0;
+}
+
+/*
+ * ccdc_config_vdfc()
+ * configure parameters for Vertical Defect Correction
+ */
+static int ccdc_config_vdfc(struct ccdc_vertical_dft *dfc)
+{
+       u32 val;
+       int i;
+
+       /* Configure General Defect Correction. The table used is from IPIPE */
+       val = dfc->gen_dft_en & CCDC_DFCCTL_GDFCEN_MASK;
+
+       /* Configure Vertical Defect Correction if needed */
+       if (!dfc->ver_dft_en) {
+               /* Enable only General Defect Correction */
+               regw(val, DFCCTL);
+               return 0;
+       }
+
+       if (dfc->table_size > CCDC_DFT_TABLE_SIZE)
+               return -EINVAL;
+
+       val |= CCDC_DFCCTL_VDFC_DISABLE;
+       val |= (dfc->dft_corr_ctl.vdfcsl & CCDC_DFCCTL_VDFCSL_MASK) <<
+               CCDC_DFCCTL_VDFCSL_SHIFT;
+       val |= (dfc->dft_corr_ctl.vdfcuda & CCDC_DFCCTL_VDFCUDA_MASK) <<
+               CCDC_DFCCTL_VDFCUDA_SHIFT;
+       val |= (dfc->dft_corr_ctl.vdflsft & CCDC_DFCCTL_VDFLSFT_MASK) <<
+               CCDC_DFCCTL_VDFLSFT_SHIFT;
+       regw(val , DFCCTL);
+
+       /* clear address ptr to offset 0 */
+       val = CCDC_DFCMEMCTL_DFCMARST_MASK << CCDC_DFCMEMCTL_DFCMARST_SHIFT;
+
+       /* write defect table entries */
+       for (i = 0; i < dfc->table_size; i++) {
+               /* increment address for non zero index */
+               if (i != 0)
+                       val = CCDC_DFCMEMCTL_INC_ADDR;
+               regw(val, DFCMEMCTL);
+               if (ccdc_write_dfc_entry(i, dfc) < 0)
+                       return -EFAULT;
+       }
+
+       /* update saturation level and enable dfc */
+       regw(dfc->saturation_ctl & CCDC_VDC_DFCVSAT_MASK, DFCVSAT);
+       val = regr(DFCCTL) | (CCDC_DFCCTL_VDFCEN_MASK <<
+                       CCDC_DFCCTL_VDFCEN_SHIFT);
+       regw(val, DFCCTL);
+       return 0;
+}
+
+/*
+ * ccdc_config_csc()
+ * configure parameters for color space conversion
+ * Each register CSCM0-7 has two values in S8Q5 format.
+ */
+static void ccdc_config_csc(struct ccdc_csc *csc)
+{
+       u32 val1 = 0, val2;
+       int i;
+
+       if (!csc->enable)
+               return;
+
+       /* 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 < CCDC_CSC_COEFF_TABLE_SIZE; i++) {
+               if ((i % 2) == 0) {
+                       /* CSCM - LSB */
+                       val1 = (csc->coeff[i].integer &
+                               CCDC_CSC_COEF_INTEG_MASK)
+                               << CCDC_CSC_COEF_INTEG_SHIFT;
+                       /*
+                        * convert decimal part to binary. Use 2 decimal
+                        * precision, user values range from .00 - 0.99
+                        */
+                       val1 |= (((csc->coeff[i].decimal &
+                               CCDC_CSC_COEF_DECIMAL_MASK) *
+                               CCDC_CSC_DEC_MAX) / 100);
+               } else {
+
+                       /* CSCM - MSB */
+                       val2 = (csc->coeff[i].integer &
+                               CCDC_CSC_COEF_INTEG_MASK)
+                               << CCDC_CSC_COEF_INTEG_SHIFT;
+                       val2 |= (((csc->coeff[i].decimal &
+                                CCDC_CSC_COEF_DECIMAL_MASK) *
+                                CCDC_CSC_DEC_MAX) / 100);
+                       val2 <<= CCDC_CSCM_MSB_SHIFT;
+                       val2 |= val1;
+                       regw(val2, (CSCM0 + ((i - 1) << 1)));
+               }
+       }
+}
+
+/*
+ * ccdc_config_color_patterns()
+ * configure parameters for color patterns
+ */
+static void ccdc_config_color_patterns(struct ccdc_col_pat *pat0,
+                                      struct ccdc_col_pat *pat1)
+{
+       u32 val;
+
+       val = (pat0->olop | (pat0->olep << 2) | (pat0->elop << 4) |
+               (pat0->elep << 6) | (pat1->olop << 8) | (pat1->olep << 10) |
+               (pat1->elop << 12) | (pat1->elep << 14));
+       regw(val, COLPTN);
+}
+
+/* This function will configure CCDC for Raw mode image capture */
+static int ccdc_config_raw(void)
+{
+       struct ccdc_params_raw *params = &ccdc_cfg.bayer;
+       struct ccdc_config_params_raw *config_params =
+                                       &ccdc_cfg.bayer.config_params;
+       unsigned int val;
+
+       dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
+
+       /* restore power on defaults to register */
+       ccdc_restore_defaults();
+
+       /* CCDCFG register:
+        * set CCD Not to swap input since input is RAW data
+        * set FID detection function to Latch at V-Sync
+        * set WENLOG - ccdc valid area to AND
+        * set TRGSEL to WENBIT
+        * set EXTRG to DISABLE
+        * disable latching function on VSYNC - shadowed registers
+        */
+       regw(CCDC_YCINSWP_RAW | CCDC_CCDCFG_FIDMD_LATCH_VSYNC |
+            CCDC_CCDCFG_WENLOG_AND | CCDC_CCDCFG_TRGSEL_WEN |
+            CCDC_CCDCFG_EXTRG_DISABLE | CCDC_LATCH_ON_VSYNC_DISABLE, CCDCFG);
+
+       /*
+        * Set VDHD direction to input,  input type to raw input
+        * normal data polarity, do not use external WEN
+        */
+       val = (CCDC_VDHDOUT_INPUT | CCDC_RAW_IP_MODE | CCDC_DATAPOL_NORMAL |
+               CCDC_EXWEN_DISABLE);
+
+       /*
+        * Configure the vertical sync polarity (MODESET.VDPOL), horizontal
+        * sync polarity (MODESET.HDPOL), field id polarity (MODESET.FLDPOL),
+        * frame format(progressive or interlace), & pixel format (Input mode)
+        */
+       val |= (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
+               ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
+               ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
+               ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
+               ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT));
+
+       /* set pack for alaw compression */
+       if ((config_params->data_sz == CCDC_DATA_8BITS) ||
+            config_params->alaw.enable)
+               val |= CCDC_DATA_PACK_ENABLE;
+
+       /* Configure for LPF */
+       if (config_params->lpf_enable)
+               val |= (config_params->lpf_enable & CCDC_LPF_MASK) <<
+                       CCDC_LPF_SHIFT;
+
+       /* Configure the data shift */
+       val |= (config_params->datasft & CCDC_DATASFT_MASK) <<
+               CCDC_DATASFT_SHIFT;
+       regw(val , MODESET);
+       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to MODESET...\n", val);
+
+       /* Configure the Median Filter threshold */
+       regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT);
+
+       /* Configure GAMMAWD register. defaur 11-2, and Mosaic cfa pattern */
+       val = CCDC_GAMMA_BITS_11_2 << CCDC_GAMMAWD_INPUT_SHIFT |
+               CCDC_CFA_MOSAIC;
+
+       /* Enable and configure aLaw register if needed */
+       if (config_params->alaw.enable) {
+               val |= (CCDC_ALAW_ENABLE |
+                       ((config_params->alaw.gamma_wd &
+                       CCDC_ALAW_GAMMA_WD_MASK) <<
+                       CCDC_GAMMAWD_INPUT_SHIFT));
+       }
+
+       /* Configure Median filter1 & filter2 */
+       val |= ((config_params->mfilt1 << CCDC_MFILT1_SHIFT) |
+               (config_params->mfilt2 << CCDC_MFILT2_SHIFT));
+
+       regw(val, GAMMAWD);
+       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to GAMMAWD...\n", val);
+
+       /* configure video window */
+       ccdc_setwin(&params->win, params->frm_fmt, 1);
+
+       /* Optical Clamp Averaging */
+       ccdc_config_black_clamp(&config_params->blk_clamp);
+
+       /* Black level compensation */
+       ccdc_config_black_compense(&config_params->blk_comp);
+
+       /* Vertical Defect Correction if needed */
+       if (ccdc_config_vdfc(&config_params->vertical_dft) < 0)
+               return -EFAULT;
+
+       /* color space conversion */
+       ccdc_config_csc(&config_params->csc);
+
+       /* color pattern */
+       ccdc_config_color_patterns(&config_params->col_pat_field0,
+                                  &config_params->col_pat_field1);
+
+       /* Configure the Gain  & offset control */
+       ccdc_config_gain_offset();
+
+       dev_dbg(ccdc_cfg.dev, "\nWriting %x to COLPTN...\n", val);
+
+       /* Configure DATAOFST  register */
+       val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) <<
+               CCDC_DATAOFST_H_SHIFT;
+       val |= (config_params->data_offset.vert_offset & CCDC_DATAOFST_MASK) <<
+               CCDC_DATAOFST_V_SHIFT;
+       regw(val, DATAOFST);
+
+       /* configuring HSIZE register */
+       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 ((config_params->data_sz == CCDC_DATA_8BITS) ||
+            config_params->alaw.enable) {
+               val |= (((params->win.width) + 31) >> 5) &
+                       CCDC_HSIZE_VAL_MASK;
+
+               /* adjust to multiple of 32 */
+               dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
+                      (((params->win.width) + 31) >> 5) &
+                       CCDC_HSIZE_VAL_MASK);
+       } else {
+               /* else one pixel will take 2 byte */
+               val |= (((params->win.width * 2) + 31) >> 5) &
+                       CCDC_HSIZE_VAL_MASK;
+
+               dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
+                      (((params->win.width * 2) + 31) >> 5) &
+                       CCDC_HSIZE_VAL_MASK);
+       }
+       regw(val, HSIZE);
+
+       /* Configure SDOFST register */
+       if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
+               if (params->image_invert_enable) {
+                       /* For interlace inverse mode */
+                       regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST);
+                       dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
+                               CCDC_SDOFST_INTERLACE_INVERSE);
+               } else {
+                       /* For interlace non inverse mode */
+                       regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST);
+                       dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
+                               CCDC_SDOFST_INTERLACE_NORMAL);
+               }
+       } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
+               if (params->image_invert_enable) {
+                       /* For progessive inverse mode */
+                       regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST);
+                       dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
+                               CCDC_SDOFST_PROGRESSIVE_INVERSE);
+               } else {
+                       /* For progessive non inverse mode */
+                       regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST);
+                       dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
+                               CCDC_SDOFST_PROGRESSIVE_NORMAL);
+               }
+       }
+       dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
+       return 0;
+}
+
+static int ccdc_configure(void)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               return ccdc_config_raw();
+       else
+               ccdc_config_ycbcr();
+       return 0;
+}
+
+static int ccdc_set_buftype(enum ccdc_buftype buf_type)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               ccdc_cfg.bayer.buf_type = buf_type;
+       else
+               ccdc_cfg.ycbcr.buf_type = buf_type;
+       return 0;
+}
+static enum ccdc_buftype ccdc_get_buftype(void)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               return ccdc_cfg.bayer.buf_type;
+       return ccdc_cfg.ycbcr.buf_type;
+}
+
+static int ccdc_enum_pix(u32 *pix, int i)
+{
+       int ret = -EINVAL;
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
+               if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
+                       *pix = ccdc_raw_bayer_pix_formats[i];
+                       ret = 0;
+               }
+       } else {
+               if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
+                       *pix = ccdc_raw_yuv_pix_formats[i];
+                       ret = 0;
+               }
+       }
+       return ret;
+}
+
+static int ccdc_set_pixel_format(u32 pixfmt)
+{
+       struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
+
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
+               ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
+               if (pixfmt == V4L2_PIX_FMT_SBGGR8)
+                       alaw->enable = 1;
+               else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
+                       return -EINVAL;
+       } else {
+               if (pixfmt == V4L2_PIX_FMT_YUYV)
+                       ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
+               else if (pixfmt == V4L2_PIX_FMT_UYVY)
+                       ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
+               else
+                       return -EINVAL;
+       }
+       return 0;
+}
+static u32 ccdc_get_pixel_format(void)
+{
+       struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
+       u32 pixfmt;
+
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               if (alaw->enable)
+                       pixfmt = V4L2_PIX_FMT_SBGGR8;
+               else
+                       pixfmt = V4L2_PIX_FMT_SBGGR16;
+       else {
+               if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
+                       pixfmt = V4L2_PIX_FMT_YUYV;
+               else
+                       pixfmt = V4L2_PIX_FMT_UYVY;
+       }
+       return pixfmt;
+}
+static int ccdc_set_image_window(struct v4l2_rect *win)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               ccdc_cfg.bayer.win = *win;
+       else
+               ccdc_cfg.ycbcr.win = *win;
+       return 0;
+}
+
+static void ccdc_get_image_window(struct v4l2_rect *win)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               *win = ccdc_cfg.bayer.win;
+       else
+               *win = ccdc_cfg.ycbcr.win;
+}
+
+static unsigned int ccdc_get_line_length(void)
+{
+       struct ccdc_config_params_raw *config_params =
+                               &ccdc_cfg.bayer.config_params;
+       unsigned int len;
+
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
+               if ((config_params->alaw.enable) ||
+                   (config_params->data_sz == CCDC_DATA_8BITS))
+                       len = ccdc_cfg.bayer.win.width;
+               else
+                       len = ccdc_cfg.bayer.win.width * 2;
+       } else
+               len = ccdc_cfg.ycbcr.win.width * 2;
+       return ALIGN(len, 32);
+}
+
+static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               ccdc_cfg.bayer.frm_fmt = frm_fmt;
+       else
+               ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
+       return 0;
+}
+
+static enum ccdc_frmfmt ccdc_get_frame_format(void)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               return ccdc_cfg.bayer.frm_fmt;
+       else
+               return ccdc_cfg.ycbcr.frm_fmt;
+}
+
+static int ccdc_getfid(void)
+{
+       return  (regr(MODESET) >> 15) & 1;
+}
+
+/* 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_params(struct vpfe_hw_if_param *params)
+{
+       ccdc_cfg.if_type = params->if_type;
+
+       switch (params->if_type) {
+       case VPFE_BT656:
+       case VPFE_YCBCR_SYNC_16:
+       case VPFE_YCBCR_SYNC_8:
+               ccdc_cfg.ycbcr.vd_pol = params->vdpol;
+               ccdc_cfg.ycbcr.hd_pol = params->hdpol;
+               break;
+       default:
+               /* TODO add support for raw bayer here */
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static const struct ccdc_hw_device ccdc_hw_dev = {
+       .name = "DM355 CCDC",
+       .owner = THIS_MODULE,
+       .hw_ops = {
+               .open = ccdc_open,
+               .close = ccdc_close,
+               .enable = ccdc_enable,
+               .enable_out_to_sdram = ccdc_enable_output_to_sdram,
+               .set_hw_if_params = ccdc_set_hw_if_params,
+               .configure = ccdc_configure,
+               .set_buftype = ccdc_set_buftype,
+               .get_buftype = ccdc_get_buftype,
+               .enum_pix = ccdc_enum_pix,
+               .set_pixel_format = ccdc_set_pixel_format,
+               .get_pixel_format = 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,
+       },
+};
+
+static int dm355_ccdc_probe(struct platform_device *pdev)
+{
+       void (*setup_pinmux)(void);
+       struct resource *res;
+       int status = 0;
+
+       /*
+        * first try to register with vpfe. If not correct platform, then we
+        * don't have to iomap
+        */
+       status = vpfe_register_ccdc_device(&ccdc_hw_dev);
+       if (status < 0)
+               return status;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               status = -ENODEV;
+               goto fail_nores;
+       }
+
+       res = request_mem_region(res->start, resource_size(res), res->name);
+       if (!res) {
+               status = -EBUSY;
+               goto fail_nores;
+       }
+
+       ccdc_cfg.base_addr = ioremap(res->start, resource_size(res));
+       if (!ccdc_cfg.base_addr) {
+               status = -ENOMEM;
+               goto fail_nomem;
+       }
+
+       /* Platform data holds setup_pinmux function ptr */
+       if (NULL == pdev->dev.platform_data) {
+               status = -ENODEV;
+               goto fail_nomap;
+       }
+       setup_pinmux = pdev->dev.platform_data;
+       /*
+        * setup Mux configuration for ccdc which may be different for
+        * different SoCs using this CCDC
+        */
+       setup_pinmux();
+       ccdc_cfg.dev = &pdev->dev;
+       printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
+       return 0;
+fail_nomap:
+       iounmap(ccdc_cfg.base_addr);
+fail_nomem:
+       release_mem_region(res->start, resource_size(res));
+fail_nores:
+       vpfe_unregister_ccdc_device(&ccdc_hw_dev);
+       return status;
+}
+
+static int dm355_ccdc_remove(struct platform_device *pdev)
+{
+       struct resource *res;
+
+       iounmap(ccdc_cfg.base_addr);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res)
+               release_mem_region(res->start, resource_size(res));
+       vpfe_unregister_ccdc_device(&ccdc_hw_dev);
+       return 0;
+}
+
+static struct platform_driver dm355_ccdc_driver = {
+       .driver = {
+               .name   = "dm355_ccdc",
+       },
+       .remove = dm355_ccdc_remove,
+       .probe = dm355_ccdc_probe,
+};
+
+module_platform_driver(dm355_ccdc_driver);
diff --git a/drivers/media/platform/ti/davinci/dm355_ccdc_regs.h b/drivers/media/platform/ti/davinci/dm355_ccdc_regs.h
new file mode 100644 (file)
index 0000000..eb381f0
--- /dev/null
@@ -0,0 +1,297 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2005-2009 Texas Instruments Inc
+ */
+#ifndef _DM355_CCDC_REGS_H
+#define _DM355_CCDC_REGS_H
+
+/**************************************************************************\
+* 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 CCDC_REG_LAST                  DATAOFST
+/**************************************************************
+*      Define for various register bit mask and shifts for CCDC
+*
+**************************************************************/
+#define CCDC_RAW_IP_MODE                       0
+#define CCDC_VDHDOUT_INPUT                     0
+#define CCDC_YCINSWP_RAW                       (0 << 4)
+#define CCDC_EXWEN_DISABLE                     0
+#define CCDC_DATAPOL_NORMAL                    0
+#define CCDC_CCDCFG_FIDMD_LATCH_VSYNC          0
+#define CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC       (1 << 6)
+#define CCDC_CCDCFG_WENLOG_AND                 0
+#define CCDC_CCDCFG_TRGSEL_WEN                 0
+#define CCDC_CCDCFG_EXTRG_DISABLE              0
+#define CCDC_CFA_MOSAIC                                0
+#define CCDC_Y8POS_SHIFT                       11
+
+#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                  1
+#define CCDC_GAMMAWD_CFA_SHIFT                 5
+#define CCDC_GAMMAWD_INPUT_SHIFT               2
+#define CCDC_FID_POL_MASK                      1
+#define CCDC_FID_POL_SHIFT                     4
+#define CCDC_HD_POL_MASK                       1
+#define CCDC_HD_POL_SHIFT                      3
+#define CCDC_VD_POL_MASK                       1
+#define CCDC_VD_POL_SHIFT                      2
+#define CCDC_VD_POL_NEGATIVE                   (1 << 2)
+#define CCDC_FRM_FMT_MASK                      1
+#define CCDC_FRM_FMT_SHIFT                     7
+#define CCDC_DATA_SZ_MASK                      7
+#define CCDC_DATA_SZ_SHIFT                     8
+#define CCDC_VDHDOUT_MASK                      1
+#define CCDC_VDHDOUT_SHIFT                     0
+#define CCDC_EXWEN_MASK                                1
+#define CCDC_EXWEN_SHIFT                       5
+#define CCDC_INPUT_MODE_MASK                   3
+#define CCDC_INPUT_MODE_SHIFT                  12
+#define CCDC_PIX_FMT_MASK                      3
+#define CCDC_PIX_FMT_SHIFT                     12
+#define CCDC_DATAPOL_MASK                      1
+#define CCDC_DATAPOL_SHIFT                     6
+#define CCDC_WEN_ENABLE                                (1 << 1)
+#define CCDC_VDHDEN_ENABLE                     (1 << 16)
+#define CCDC_LPF_ENABLE                                (1 << 14)
+#define CCDC_ALAW_ENABLE                       1
+#define CCDC_ALAW_GAMMA_WD_MASK                        7
+#define CCDC_REC656IF_BT656_EN                 3
+
+#define CCDC_FMTCFG_FMTMODE_MASK               3
+#define CCDC_FMTCFG_FMTMODE_SHIFT              1
+#define CCDC_FMTCFG_LNUM_MASK                  3
+#define CCDC_FMTCFG_LNUM_SHIFT                 4
+#define CCDC_FMTCFG_ADDRINC_MASK               7
+#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                   1
+#define CCDC_HSIZE_VAL_MASK                    0xFFF
+#define CCDC_SDOFST_FIELD_INTERLEAVED          0x249
+#define CCDC_SDOFST_INTERLACE_INVERSE          0x4B6D
+#define CCDC_SDOFST_INTERLACE_NORMAL           0x0B6D
+#define CCDC_SDOFST_PROGRESSIVE_INVERSE                0x4000
+#define CCDC_SDOFST_PROGRESSIVE_NORMAL         0
+#define CCDC_START_PX_HOR_MASK                 0x7FFF
+#define CCDC_NUM_PX_HOR_MASK                   0x7FFF
+#define CCDC_START_VER_ONE_MASK                        0x7FFF
+#define CCDC_START_VER_TWO_MASK                        0x7FFF
+#define CCDC_NUM_LINES_VER                     0x7FFF
+
+#define CCDC_BLK_CLAMP_ENABLE                  (1 << 15)
+#define CCDC_BLK_SGAIN_MASK                    0x1F
+#define CCDC_BLK_ST_PXL_MASK                   0x1FFF
+#define CCDC_BLK_SAMPLE_LN_MASK                        3
+#define CCDC_BLK_SAMPLE_LN_SHIFT               13
+
+#define CCDC_NUM_LINE_CALC_MASK                        3
+#define CCDC_NUM_LINE_CALC_SHIFT               14
+
+#define CCDC_BLK_DC_SUB_MASK                   0x3FFF
+#define CCDC_BLK_COMP_MASK                     0xFF
+#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            (1 << 15)
+#define CCDC_LATCH_ON_VSYNC_ENABLE             (0 << 15)
+#define CCDC_FPC_ENABLE                                (1 << 15)
+#define CCDC_FPC_FPC_NUM_MASK                  0x7FFF
+#define CCDC_DATA_PACK_ENABLE                  (1 << 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               0xF
+
+#define CCDC_CSC_COEF_INTEG_MASK               7
+#define CCDC_CSC_COEF_DECIMAL_MASK             0x1f
+#define CCDC_CSC_COEF_INTEG_SHIFT              5
+#define CCDC_CSCM_MSB_SHIFT                    8
+#define CCDC_CSC_ENABLE                                1
+#define CCDC_CSC_DEC_MAX                       32
+
+#define CCDC_MFILT1_SHIFT                      10
+#define CCDC_MFILT2_SHIFT                      8
+#define CCDC_MED_FILT_THRESH                   0x3FFF
+#define CCDC_LPF_MASK                          1
+#define CCDC_LPF_SHIFT                         14
+#define CCDC_OFFSET_MASK                       0x3FF
+#define CCDC_DATASFT_MASK                      7
+#define CCDC_DATASFT_SHIFT                     8
+
+#define CCDC_DF_ENABLE                         1
+
+#define CCDC_FMTPLEN_P0_MASK                   0xF
+#define CCDC_FMTPLEN_P1_MASK                   0xF
+#define CCDC_FMTPLEN_P2_MASK                   7
+#define CCDC_FMTPLEN_P3_MASK                   7
+#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                       0x1FFF
+#define CCDC_FMTLNH_MASK                       0x1FFF
+#define CCDC_FMTSLV_MASK                       0x1FFF
+#define CCDC_FMTLNV_MASK                       0x7FFF
+#define CCDC_FMTRLEN_MASK                      0x1FFF
+#define CCDC_FMTHCNT_MASK                      0x1FFF
+
+#define CCDC_ADP_INIT_MASK                     0x1FFF
+#define CCDC_ADP_LINE_SHIFT                    13
+#define CCDC_ADP_LINE_MASK                     3
+#define CCDC_FMTPGN_APTR_MASK                  7
+
+#define CCDC_DFCCTL_GDFCEN_MASK                        1
+#define CCDC_DFCCTL_VDFCEN_MASK                        1
+#define CCDC_DFCCTL_VDFC_DISABLE               (0 << 4)
+#define CCDC_DFCCTL_VDFCEN_SHIFT               4
+#define CCDC_DFCCTL_VDFCSL_MASK                        3
+#define CCDC_DFCCTL_VDFCSL_SHIFT               5
+#define CCDC_DFCCTL_VDFCUDA_MASK               1
+#define CCDC_DFCCTL_VDFCUDA_SHIFT              7
+#define CCDC_DFCCTL_VDFLSFT_MASK               3
+#define CCDC_DFCCTL_VDFLSFT_SHIFT              8
+#define CCDC_DFCMEMCTL_DFCMARST_MASK           1
+#define CCDC_DFCMEMCTL_DFCMARST_SHIFT          2
+#define CCDC_DFCMEMCTL_DFCMWR_MASK             1
+#define CCDC_DFCMEMCTL_DFCMWR_SHIFT            0
+#define CCDC_DFCMEMCTL_INC_ADDR                        (0 << 2)
+
+#define CCDC_LSCCFG_GFTSF_MASK                 7
+#define CCDC_LSCCFG_GFTSF_SHIFT                        1
+#define CCDC_LSCCFG_GFTINV_MASK                        0xf
+#define CCDC_LSCCFG_GFTINV_SHIFT               4
+#define CCDC_LSC_GFTABLE_SEL_MASK              3
+#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                   3
+#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                      3
+#define CCDC_LSC_FRAC_MASK                     0x3FFF
+#define CCDC_LSC_CENTRE_MASK                   0x3FFF
+#define CCDC_LSC_COEF_MASK                     0xff
+#define CCDC_LSC_COEFL_SHIFT                   0
+#define CCDC_LSC_COEFU_SHIFT                   8
+#define CCDC_GAIN_MASK                         0x7FF
+#define CCDC_SYNCEN_VDHDEN_MASK                        (1 << 0)
+#define CCDC_SYNCEN_WEN_MASK                   (1 << 1)
+#define CCDC_SYNCEN_WEN_SHIFT                  1
+
+/* Power on Defaults in hardware */
+#define MODESET_DEFAULT                                0x200
+#define CULH_DEFAULT                           0xFFFF
+#define CULV_DEFAULT                           0xFF
+#define GAIN_DEFAULT                           256
+#define OUTCLIP_DEFAULT                                0x3FFF
+#define LSCCFG2_DEFAULT                                0xE
+
+#endif
diff --git a/drivers/media/platform/ti/davinci/dm644x_ccdc.c b/drivers/media/platform/ti/davinci/dm644x_ccdc.c
new file mode 100644 (file)
index 0000000..c6378c4
--- /dev/null
@@ -0,0 +1,880 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2006-2009 Texas Instruments Inc
+ *
+ * CCDC hardware module for DM6446
+ * ------------------------------
+ *
+ * This module is for configuring CCD controller of DM6446 VPFE to capture
+ * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
+ * such as Defect Pixel Correction, Color Space Conversion etc to
+ * pre-process the Raw Bayer RGB data, before writing it to SDRAM.
+ * This file is named DM644x so that other variants such DM6443
+ * may be supported using the same module.
+ *
+ * TODO: Test Raw bayer parameter settings and bayer capture
+ *      Split module parameter structure to module specific ioctl structs
+ *      investigate if enum used for user space type definition
+ *      to be replaced by #defines or integer
+ */
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/videodev2.h>
+#include <linux/gfp.h>
+#include <linux/err.h>
+#include <linux/module.h>
+
+#include <media/davinci/dm644x_ccdc.h>
+#include <media/davinci/vpss.h>
+
+#include "dm644x_ccdc_regs.h"
+#include "ccdc_hw_device.h"
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CCDC Driver for DM6446");
+MODULE_AUTHOR("Texas Instruments");
+
+static struct ccdc_oper_config {
+       struct device *dev;
+       /* CCDC interface type */
+       enum vpfe_hw_if_type if_type;
+       /* Raw Bayer configuration */
+       struct ccdc_params_raw bayer;
+       /* YCbCr configuration */
+       struct ccdc_params_ycbcr ycbcr;
+       /* ccdc base address */
+       void __iomem *base_addr;
+} ccdc_cfg = {
+       /* Raw configurations */
+       .bayer = {
+               .pix_fmt = CCDC_PIXFMT_RAW,
+               .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
+               .win = CCDC_WIN_VGA,
+               .fid_pol = VPFE_PINPOL_POSITIVE,
+               .vd_pol = VPFE_PINPOL_POSITIVE,
+               .hd_pol = VPFE_PINPOL_POSITIVE,
+               .config_params = {
+                       .data_sz = CCDC_DATA_10BITS,
+               },
+       },
+       .ycbcr = {
+               .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
+               .frm_fmt = CCDC_FRMFMT_INTERLACED,
+               .win = CCDC_WIN_PAL,
+               .fid_pol = VPFE_PINPOL_POSITIVE,
+               .vd_pol = VPFE_PINPOL_POSITIVE,
+               .hd_pol = VPFE_PINPOL_POSITIVE,
+               .bt656_enable = 1,
+               .pix_order = CCDC_PIXORDER_CBYCRY,
+               .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
+       },
+};
+
+#define CCDC_MAX_RAW_YUV_FORMATS       2
+
+/* Raw Bayer formats */
+static u32 ccdc_raw_bayer_pix_formats[] =
+       {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
+
+/* Raw YUV formats */
+static u32 ccdc_raw_yuv_pix_formats[] =
+       {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
+
+/* CCDC Save/Restore context */
+static u32 ccdc_ctx[CCDC_REG_END / sizeof(u32)];
+
+/* register access routines */
+static inline u32 regr(u32 offset)
+{
+       return __raw_readl(ccdc_cfg.base_addr + offset);
+}
+
+static inline void regw(u32 val, u32 offset)
+{
+       __raw_writel(val, ccdc_cfg.base_addr + offset);
+}
+
+static void ccdc_enable(int flag)
+{
+       regw(flag, CCDC_PCR);
+}
+
+static void ccdc_enable_vport(int flag)
+{
+       if (flag)
+               /* enable video port */
+               regw(CCDC_ENABLE_VIDEO_PORT, CCDC_FMTCFG);
+       else
+               regw(CCDC_DISABLE_VIDEO_PORT, CCDC_FMTCFG);
+}
+
+/*
+ * ccdc_setwin()
+ * This function will configure the window size
+ * to be capture in CCDC reg
+ */
+static void ccdc_setwin(struct v4l2_rect *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(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
+       /*
+        * ppc - per pixel count. indicates how many pixels per cell
+        * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
+        * raw capture this is 1
+        */
+       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,
+            CCDC_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, CCDC_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, CCDC_VDINT);
+
+       }
+       regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start,
+            CCDC_VERT_START);
+       regw(vert_nr_lines, CCDC_VERT_LINES);
+       dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
+}
+
+static void ccdc_readregs(void)
+{
+       unsigned int val = 0;
+
+       val = regr(CCDC_ALAW);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to ALAW...\n", val);
+       val = regr(CCDC_CLAMP);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to CLAMP...\n", val);
+       val = regr(CCDC_DCSUB);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to DCSUB...\n", val);
+       val = regr(CCDC_BLKCMP);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to BLKCMP...\n", val);
+       val = regr(CCDC_FPC_ADDR);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC_ADDR...\n", val);
+       val = regr(CCDC_FPC);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC...\n", val);
+       val = regr(CCDC_FMTCFG);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMTCFG...\n", val);
+       val = regr(CCDC_COLPTN);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to COLPTN...\n", val);
+       val = regr(CCDC_FMT_HORZ);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_HORZ...\n", val);
+       val = regr(CCDC_FMT_VERT);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_VERT...\n", val);
+       val = regr(CCDC_HSIZE_OFF);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HSIZE_OFF...\n", val);
+       val = regr(CCDC_SDOFST);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SDOFST...\n", val);
+       val = regr(CCDC_VP_OUT);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VP_OUT...\n", val);
+       val = regr(CCDC_SYN_MODE);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SYN_MODE...\n", val);
+       val = regr(CCDC_HORZ_INFO);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HORZ_INFO...\n", val);
+       val = regr(CCDC_VERT_START);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_START...\n", val);
+       val = regr(CCDC_VERT_LINES);
+       dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_LINES...\n", val);
+}
+
+static int ccdc_close(struct device *dev)
+{
+       return 0;
+}
+
+/*
+ * ccdc_restore_defaults()
+ * This function will write defaults to all CCDC registers
+ */
+static void ccdc_restore_defaults(void)
+{
+       int i;
+
+       /* disable CCDC */
+       ccdc_enable(0);
+       /* set all registers to default value */
+       for (i = 4; i <= 0x94; i += 4)
+               regw(0,  i);
+       regw(CCDC_NO_CULLING, CCDC_CULLING);
+       regw(CCDC_GAMMA_BITS_11_2, CCDC_ALAW);
+}
+
+static int ccdc_open(struct device *device)
+{
+       ccdc_restore_defaults();
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               ccdc_enable_vport(1);
+       return 0;
+}
+
+static void ccdc_sbl_reset(void)
+{
+       vpss_clear_wbl_overflow(VPSS_PCR_CCDC_WBL_O);
+}
+
+/*
+ * ccdc_config_ycbcr()
+ * This function will configure CCDC for YCbCr video capture
+ */
+static void ccdc_config_ycbcr(void)
+{
+       struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
+       u32 syn_mode;
+
+       dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
+       /*
+        * first restore the CCDC registers to default values
+        * This is important since we assume default values to be set in
+        * a lot of registers that we didn't touch
+        */
+       ccdc_restore_defaults();
+
+       /*
+        * configure pixel format, frame format, configure video frame
+        * format, enable output to SDRAM, enable internal timing generator
+        * and 8bit pack mode
+        */
+       syn_mode = (((params->pix_fmt & CCDC_SYN_MODE_INPMOD_MASK) <<
+                   CCDC_SYN_MODE_INPMOD_SHIFT) |
+                   ((params->frm_fmt & CCDC_SYN_FLDMODE_MASK) <<
+                   CCDC_SYN_FLDMODE_SHIFT) | CCDC_VDHDEN_ENABLE |
+                   CCDC_WEN_ENABLE | CCDC_DATA_PACK_ENABLE);
+
+       /* setup BT.656 sync mode */
+       if (params->bt656_enable) {
+               regw(CCDC_REC656IF_BT656_EN, CCDC_REC656IF);
+
+               /*
+                * configure the FID, VD, HD pin polarity,
+                * fld,hd pol positive, vd negative, 8-bit data
+                */
+               syn_mode |= CCDC_SYN_MODE_VD_POL_NEGATIVE;
+               if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
+                       syn_mode |= CCDC_SYN_MODE_10BITS;
+               else
+                       syn_mode |= CCDC_SYN_MODE_8BITS;
+       } else {
+               /* y/c external sync mode */
+               syn_mode |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
+                            CCDC_FID_POL_SHIFT) |
+                            ((params->hd_pol & CCDC_HD_POL_MASK) <<
+                            CCDC_HD_POL_SHIFT) |
+                            ((params->vd_pol & CCDC_VD_POL_MASK) <<
+                            CCDC_VD_POL_SHIFT));
+       }
+       regw(syn_mode, CCDC_SYN_MODE);
+
+       /* configure video window */
+       ccdc_setwin(&params->win, params->frm_fmt, 2);
+
+       /*
+        * configure the order of y cb cr in SDRAM, and disable latch
+        * internal register on vsync
+        */
+       if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
+               regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
+                       CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_BW656_10BIT,
+                       CCDC_CCDCFG);
+       else
+               regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
+                       CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
+
+       /*
+        * configure the horizontal line offset. This should be a
+        * on 32 byte boundary. So clear LSB 5 bits
+        */
+       regw(((params->win.width * 2  + 31) & ~0x1f), CCDC_HSIZE_OFF);
+
+       /* configure the memory line offset */
+       if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
+               /* two fields are interleaved in memory */
+               regw(CCDC_SDOFST_FIELD_INTERLEAVED, CCDC_SDOFST);
+
+       ccdc_sbl_reset();
+       dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
+}
+
+static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
+{
+       u32 val;
+
+       if (!bclamp->enable) {
+               /* configure DCSub */
+               val = (bclamp->dc_sub) & CCDC_BLK_DC_SUB_MASK;
+               regw(val, CCDC_DCSUB);
+               dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to DCSUB...\n", val);
+               regw(CCDC_CLAMP_DEFAULT_VAL, CCDC_CLAMP);
+               dev_dbg(ccdc_cfg.dev, "\nWriting 0x0000 to CLAMP...\n");
+               return;
+       }
+       /*
+        * Configure gain,  Start pixel, No of line to be avg,
+        * No of pixel/line to be avg, & Enable the Black clamping
+        */
+       val = ((bclamp->sgain & CCDC_BLK_SGAIN_MASK) |
+              ((bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) <<
+               CCDC_BLK_ST_PXL_SHIFT) |
+              ((bclamp->sample_ln & CCDC_BLK_SAMPLE_LINE_MASK) <<
+               CCDC_BLK_SAMPLE_LINE_SHIFT) |
+              ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
+               CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE);
+       regw(val, CCDC_CLAMP);
+       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to CLAMP...\n", val);
+       /* If Black clamping is enable then make dcsub 0 */
+       regw(CCDC_DCSUB_DEFAULT_VAL, CCDC_DCSUB);
+       dev_dbg(ccdc_cfg.dev, "\nWriting 0x00000000 to DCSUB...\n");
+}
+
+static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
+{
+       u32 val;
+
+       val = ((bcomp->b & CCDC_BLK_COMP_MASK) |
+             ((bcomp->gb & CCDC_BLK_COMP_MASK) <<
+              CCDC_BLK_COMP_GB_COMP_SHIFT) |
+             ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
+              CCDC_BLK_COMP_GR_COMP_SHIFT) |
+             ((bcomp->r & CCDC_BLK_COMP_MASK) <<
+              CCDC_BLK_COMP_R_COMP_SHIFT));
+       regw(val, CCDC_BLKCMP);
+}
+
+/*
+ * ccdc_config_raw()
+ * This function will configure CCDC for Raw capture mode
+ */
+static void ccdc_config_raw(void)
+{
+       struct ccdc_params_raw *params = &ccdc_cfg.bayer;
+       struct ccdc_config_params_raw *config_params =
+                               &ccdc_cfg.bayer.config_params;
+       unsigned int syn_mode = 0;
+       unsigned int val;
+
+       dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
+
+       /*      Reset CCDC */
+       ccdc_restore_defaults();
+
+       /* Disable latching function registers on VSYNC  */
+       regw(CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
+
+       /*
+        * Configure the vertical sync polarity(SYN_MODE.VDPOL),
+        * horizontal sync polarity (SYN_MODE.HDPOL), frame id polarity
+        * (SYN_MODE.FLDPOL), frame format(progressive or interlace),
+        * data size(SYNMODE.DATSIZ), &pixel format (Input mode), output
+        * SDRAM, enable internal timing generator
+        */
+       syn_mode =
+               (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
+               ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
+               ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
+               ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
+               ((config_params->data_sz & CCDC_DATA_SZ_MASK) <<
+               CCDC_DATA_SZ_SHIFT) |
+               ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT) |
+               CCDC_WEN_ENABLE | CCDC_VDHDEN_ENABLE);
+
+       /* Enable and configure aLaw register if needed */
+       if (config_params->alaw.enable) {
+               val = ((config_params->alaw.gamma_wd &
+                     CCDC_ALAW_GAMMA_WD_MASK) | CCDC_ALAW_ENABLE);
+               regw(val, CCDC_ALAW);
+               dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to ALAW...\n", val);
+       }
+
+       /* Configure video window */
+       ccdc_setwin(&params->win, params->frm_fmt, CCDC_PPC_RAW);
+
+       /* Configure Black Clamp */
+       ccdc_config_black_clamp(&config_params->blk_clamp);
+
+       /* Configure Black level compensation */
+       ccdc_config_black_compense(&config_params->blk_comp);
+
+       /* If data size is 8 bit then pack the data */
+       if ((config_params->data_sz == CCDC_DATA_8BITS) ||
+            config_params->alaw.enable)
+               syn_mode |= CCDC_DATA_PACK_ENABLE;
+
+       /* disable video port */
+       val = CCDC_DISABLE_VIDEO_PORT;
+
+       if (config_params->data_sz == CCDC_DATA_8BITS)
+               val |= (CCDC_DATA_10BITS & CCDC_FMTCFG_VPIN_MASK)
+                   << CCDC_FMTCFG_VPIN_SHIFT;
+       else
+               val |= (config_params->data_sz & CCDC_FMTCFG_VPIN_MASK)
+                   << CCDC_FMTCFG_VPIN_SHIFT;
+       /* Write value in FMTCFG */
+       regw(val, CCDC_FMTCFG);
+
+       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMTCFG...\n", val);
+       /* Configure the color pattern according to mt9t001 sensor */
+       regw(CCDC_COLPTN_VAL, CCDC_COLPTN);
+
+       dev_dbg(ccdc_cfg.dev, "\nWriting 0xBB11BB11 to COLPTN...\n");
+       /*
+        * Configure Data formatter(Video port) pixel selection
+        * (FMT_HORZ, FMT_VERT)
+        */
+       val = ((params->win.left & CCDC_FMT_HORZ_FMTSPH_MASK) <<
+             CCDC_FMT_HORZ_FMTSPH_SHIFT) |
+             (params->win.width & CCDC_FMT_HORZ_FMTLNH_MASK);
+       regw(val, CCDC_FMT_HORZ);
+
+       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_HORZ...\n", val);
+       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(ccdc_cfg.dev, "\nparams->win.height  0x%x ...\n",
+              params->win.height);
+       regw(val, CCDC_FMT_VERT);
+
+       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_VERT...\n", val);
+
+       dev_dbg(ccdc_cfg.dev, "\nbelow regw(val, FMT_VERT)...");
+
+       /*
+        * Configure Horizontal offset register. If pack 8 is enabled then
+        * 1 pixel will take 1 byte
+        */
+       if ((config_params->data_sz == CCDC_DATA_8BITS) ||
+           config_params->alaw.enable)
+               regw((params->win.width + CCDC_32BYTE_ALIGN_VAL) &
+                   CCDC_HSIZE_OFF_MASK, CCDC_HSIZE_OFF);
+       else
+               /* else one pixel will take 2 byte */
+               regw(((params->win.width * CCDC_TWO_BYTES_PER_PIXEL) +
+                   CCDC_32BYTE_ALIGN_VAL) & CCDC_HSIZE_OFF_MASK,
+                   CCDC_HSIZE_OFF);
+
+       /* Set value for SDOFST */
+       if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
+               if (params->image_invert_enable) {
+                       /* For intelace inverse mode */
+                       regw(CCDC_INTERLACED_IMAGE_INVERT, CCDC_SDOFST);
+                       dev_dbg(ccdc_cfg.dev, "\nWriting 0x4B6D to SDOFST..\n");
+               }
+
+               else {
+                       /* For intelace non inverse mode */
+                       regw(CCDC_INTERLACED_NO_IMAGE_INVERT, CCDC_SDOFST);
+                       dev_dbg(ccdc_cfg.dev, "\nWriting 0x0249 to SDOFST..\n");
+               }
+       } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
+               regw(CCDC_PROGRESSIVE_NO_IMAGE_INVERT, CCDC_SDOFST);
+               dev_dbg(ccdc_cfg.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, CCDC_VP_OUT);
+
+       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to VP_OUT...\n", val);
+       regw(syn_mode, CCDC_SYN_MODE);
+       dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode);
+
+       ccdc_sbl_reset();
+       dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
+       ccdc_readregs();
+}
+
+static int ccdc_configure(void)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               ccdc_config_raw();
+       else
+               ccdc_config_ycbcr();
+       return 0;
+}
+
+static int ccdc_set_buftype(enum ccdc_buftype buf_type)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               ccdc_cfg.bayer.buf_type = buf_type;
+       else
+               ccdc_cfg.ycbcr.buf_type = buf_type;
+       return 0;
+}
+
+static enum ccdc_buftype ccdc_get_buftype(void)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               return ccdc_cfg.bayer.buf_type;
+       return ccdc_cfg.ycbcr.buf_type;
+}
+
+static int ccdc_enum_pix(u32 *pix, int i)
+{
+       int ret = -EINVAL;
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
+               if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
+                       *pix = ccdc_raw_bayer_pix_formats[i];
+                       ret = 0;
+               }
+       } else {
+               if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
+                       *pix = ccdc_raw_yuv_pix_formats[i];
+                       ret = 0;
+               }
+       }
+       return ret;
+}
+
+static int ccdc_set_pixel_format(u32 pixfmt)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
+               ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
+               if (pixfmt == V4L2_PIX_FMT_SBGGR8)
+                       ccdc_cfg.bayer.config_params.alaw.enable = 1;
+               else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
+                       return -EINVAL;
+       } else {
+               if (pixfmt == V4L2_PIX_FMT_YUYV)
+                       ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
+               else if (pixfmt == V4L2_PIX_FMT_UYVY)
+                       ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
+               else
+                       return -EINVAL;
+       }
+       return 0;
+}
+
+static u32 ccdc_get_pixel_format(void)
+{
+       struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
+       u32 pixfmt;
+
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               if (alaw->enable)
+                       pixfmt = V4L2_PIX_FMT_SBGGR8;
+               else
+                       pixfmt = V4L2_PIX_FMT_SBGGR16;
+       else {
+               if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
+                       pixfmt = V4L2_PIX_FMT_YUYV;
+               else
+                       pixfmt = V4L2_PIX_FMT_UYVY;
+       }
+       return pixfmt;
+}
+
+static int ccdc_set_image_window(struct v4l2_rect *win)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               ccdc_cfg.bayer.win = *win;
+       else
+               ccdc_cfg.ycbcr.win = *win;
+       return 0;
+}
+
+static void ccdc_get_image_window(struct v4l2_rect *win)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               *win = ccdc_cfg.bayer.win;
+       else
+               *win = ccdc_cfg.ycbcr.win;
+}
+
+static unsigned int ccdc_get_line_length(void)
+{
+       struct ccdc_config_params_raw *config_params =
+                               &ccdc_cfg.bayer.config_params;
+       unsigned int len;
+
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
+               if ((config_params->alaw.enable) ||
+                   (config_params->data_sz == CCDC_DATA_8BITS))
+                       len = ccdc_cfg.bayer.win.width;
+               else
+                       len = ccdc_cfg.bayer.win.width * 2;
+       } else
+               len = ccdc_cfg.ycbcr.win.width * 2;
+       return ALIGN(len, 32);
+}
+
+static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               ccdc_cfg.bayer.frm_fmt = frm_fmt;
+       else
+               ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
+       return 0;
+}
+
+static enum ccdc_frmfmt ccdc_get_frame_format(void)
+{
+       if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
+               return ccdc_cfg.bayer.frm_fmt;
+       else
+               return ccdc_cfg.ycbcr.frm_fmt;
+}
+
+static int ccdc_getfid(void)
+{
+       return (regr(CCDC_SYN_MODE) >> 15) & 1;
+}
+
+/* misc operations */
+static inline void ccdc_setfbaddr(unsigned long addr)
+{
+       regw(addr & 0xffffffe0, CCDC_SDR_ADDR);
+}
+
+static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
+{
+       ccdc_cfg.if_type = params->if_type;
+
+       switch (params->if_type) {
+       case VPFE_BT656:
+       case VPFE_YCBCR_SYNC_16:
+       case VPFE_YCBCR_SYNC_8:
+       case VPFE_BT656_10BIT:
+               ccdc_cfg.ycbcr.vd_pol = params->vdpol;
+               ccdc_cfg.ycbcr.hd_pol = params->hdpol;
+               break;
+       default:
+               /* TODO add support for raw bayer here */
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static void ccdc_save_context(void)
+{
+       ccdc_ctx[CCDC_PCR >> 2] = regr(CCDC_PCR);
+       ccdc_ctx[CCDC_SYN_MODE >> 2] = regr(CCDC_SYN_MODE);
+       ccdc_ctx[CCDC_HD_VD_WID >> 2] = regr(CCDC_HD_VD_WID);
+       ccdc_ctx[CCDC_PIX_LINES >> 2] = regr(CCDC_PIX_LINES);
+       ccdc_ctx[CCDC_HORZ_INFO >> 2] = regr(CCDC_HORZ_INFO);
+       ccdc_ctx[CCDC_VERT_START >> 2] = regr(CCDC_VERT_START);
+       ccdc_ctx[CCDC_VERT_LINES >> 2] = regr(CCDC_VERT_LINES);
+       ccdc_ctx[CCDC_CULLING >> 2] = regr(CCDC_CULLING);
+       ccdc_ctx[CCDC_HSIZE_OFF >> 2] = regr(CCDC_HSIZE_OFF);
+       ccdc_ctx[CCDC_SDOFST >> 2] = regr(CCDC_SDOFST);
+       ccdc_ctx[CCDC_SDR_ADDR >> 2] = regr(CCDC_SDR_ADDR);
+       ccdc_ctx[CCDC_CLAMP >> 2] = regr(CCDC_CLAMP);
+       ccdc_ctx[CCDC_DCSUB >> 2] = regr(CCDC_DCSUB);
+       ccdc_ctx[CCDC_COLPTN >> 2] = regr(CCDC_COLPTN);
+       ccdc_ctx[CCDC_BLKCMP >> 2] = regr(CCDC_BLKCMP);
+       ccdc_ctx[CCDC_FPC >> 2] = regr(CCDC_FPC);
+       ccdc_ctx[CCDC_FPC_ADDR >> 2] = regr(CCDC_FPC_ADDR);
+       ccdc_ctx[CCDC_VDINT >> 2] = regr(CCDC_VDINT);
+       ccdc_ctx[CCDC_ALAW >> 2] = regr(CCDC_ALAW);
+       ccdc_ctx[CCDC_REC656IF >> 2] = regr(CCDC_REC656IF);
+       ccdc_ctx[CCDC_CCDCFG >> 2] = regr(CCDC_CCDCFG);
+       ccdc_ctx[CCDC_FMTCFG >> 2] = regr(CCDC_FMTCFG);
+       ccdc_ctx[CCDC_FMT_HORZ >> 2] = regr(CCDC_FMT_HORZ);
+       ccdc_ctx[CCDC_FMT_VERT >> 2] = regr(CCDC_FMT_VERT);
+       ccdc_ctx[CCDC_FMT_ADDR0 >> 2] = regr(CCDC_FMT_ADDR0);
+       ccdc_ctx[CCDC_FMT_ADDR1 >> 2] = regr(CCDC_FMT_ADDR1);
+       ccdc_ctx[CCDC_FMT_ADDR2 >> 2] = regr(CCDC_FMT_ADDR2);
+       ccdc_ctx[CCDC_FMT_ADDR3 >> 2] = regr(CCDC_FMT_ADDR3);
+       ccdc_ctx[CCDC_FMT_ADDR4 >> 2] = regr(CCDC_FMT_ADDR4);
+       ccdc_ctx[CCDC_FMT_ADDR5 >> 2] = regr(CCDC_FMT_ADDR5);
+       ccdc_ctx[CCDC_FMT_ADDR6 >> 2] = regr(CCDC_FMT_ADDR6);
+       ccdc_ctx[CCDC_FMT_ADDR7 >> 2] = regr(CCDC_FMT_ADDR7);
+       ccdc_ctx[CCDC_PRGEVEN_0 >> 2] = regr(CCDC_PRGEVEN_0);
+       ccdc_ctx[CCDC_PRGEVEN_1 >> 2] = regr(CCDC_PRGEVEN_1);
+       ccdc_ctx[CCDC_PRGODD_0 >> 2] = regr(CCDC_PRGODD_0);
+       ccdc_ctx[CCDC_PRGODD_1 >> 2] = regr(CCDC_PRGODD_1);
+       ccdc_ctx[CCDC_VP_OUT >> 2] = regr(CCDC_VP_OUT);
+}
+
+static void ccdc_restore_context(void)
+{
+       regw(ccdc_ctx[CCDC_SYN_MODE >> 2], CCDC_SYN_MODE);
+       regw(ccdc_ctx[CCDC_HD_VD_WID >> 2], CCDC_HD_VD_WID);
+       regw(ccdc_ctx[CCDC_PIX_LINES >> 2], CCDC_PIX_LINES);
+       regw(ccdc_ctx[CCDC_HORZ_INFO >> 2], CCDC_HORZ_INFO);
+       regw(ccdc_ctx[CCDC_VERT_START >> 2], CCDC_VERT_START);
+       regw(ccdc_ctx[CCDC_VERT_LINES >> 2], CCDC_VERT_LINES);
+       regw(ccdc_ctx[CCDC_CULLING >> 2], CCDC_CULLING);
+       regw(ccdc_ctx[CCDC_HSIZE_OFF >> 2], CCDC_HSIZE_OFF);
+       regw(ccdc_ctx[CCDC_SDOFST >> 2], CCDC_SDOFST);
+       regw(ccdc_ctx[CCDC_SDR_ADDR >> 2], CCDC_SDR_ADDR);
+       regw(ccdc_ctx[CCDC_CLAMP >> 2], CCDC_CLAMP);
+       regw(ccdc_ctx[CCDC_DCSUB >> 2], CCDC_DCSUB);
+       regw(ccdc_ctx[CCDC_COLPTN >> 2], CCDC_COLPTN);
+       regw(ccdc_ctx[CCDC_BLKCMP >> 2], CCDC_BLKCMP);
+       regw(ccdc_ctx[CCDC_FPC >> 2], CCDC_FPC);
+       regw(ccdc_ctx[CCDC_FPC_ADDR >> 2], CCDC_FPC_ADDR);
+       regw(ccdc_ctx[CCDC_VDINT >> 2], CCDC_VDINT);
+       regw(ccdc_ctx[CCDC_ALAW >> 2], CCDC_ALAW);
+       regw(ccdc_ctx[CCDC_REC656IF >> 2], CCDC_REC656IF);
+       regw(ccdc_ctx[CCDC_CCDCFG >> 2], CCDC_CCDCFG);
+       regw(ccdc_ctx[CCDC_FMTCFG >> 2], CCDC_FMTCFG);
+       regw(ccdc_ctx[CCDC_FMT_HORZ >> 2], CCDC_FMT_HORZ);
+       regw(ccdc_ctx[CCDC_FMT_VERT >> 2], CCDC_FMT_VERT);
+       regw(ccdc_ctx[CCDC_FMT_ADDR0 >> 2], CCDC_FMT_ADDR0);
+       regw(ccdc_ctx[CCDC_FMT_ADDR1 >> 2], CCDC_FMT_ADDR1);
+       regw(ccdc_ctx[CCDC_FMT_ADDR2 >> 2], CCDC_FMT_ADDR2);
+       regw(ccdc_ctx[CCDC_FMT_ADDR3 >> 2], CCDC_FMT_ADDR3);
+       regw(ccdc_ctx[CCDC_FMT_ADDR4 >> 2], CCDC_FMT_ADDR4);
+       regw(ccdc_ctx[CCDC_FMT_ADDR5 >> 2], CCDC_FMT_ADDR5);
+       regw(ccdc_ctx[CCDC_FMT_ADDR6 >> 2], CCDC_FMT_ADDR6);
+       regw(ccdc_ctx[CCDC_FMT_ADDR7 >> 2], CCDC_FMT_ADDR7);
+       regw(ccdc_ctx[CCDC_PRGEVEN_0 >> 2], CCDC_PRGEVEN_0);
+       regw(ccdc_ctx[CCDC_PRGEVEN_1 >> 2], CCDC_PRGEVEN_1);
+       regw(ccdc_ctx[CCDC_PRGODD_0 >> 2], CCDC_PRGODD_0);
+       regw(ccdc_ctx[CCDC_PRGODD_1 >> 2], CCDC_PRGODD_1);
+       regw(ccdc_ctx[CCDC_VP_OUT >> 2], CCDC_VP_OUT);
+       regw(ccdc_ctx[CCDC_PCR >> 2], CCDC_PCR);
+}
+static const struct ccdc_hw_device ccdc_hw_dev = {
+       .name = "DM6446 CCDC",
+       .owner = THIS_MODULE,
+       .hw_ops = {
+               .open = ccdc_open,
+               .close = ccdc_close,
+               .reset = ccdc_sbl_reset,
+               .enable = ccdc_enable,
+               .set_hw_if_params = ccdc_set_hw_if_params,
+               .configure = ccdc_configure,
+               .set_buftype = ccdc_set_buftype,
+               .get_buftype = ccdc_get_buftype,
+               .enum_pix = ccdc_enum_pix,
+               .set_pixel_format = ccdc_set_pixel_format,
+               .get_pixel_format = 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,
+       },
+};
+
+static int dm644x_ccdc_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       int status = 0;
+
+       /*
+        * first try to register with vpfe. If not correct platform, then we
+        * don't have to iomap
+        */
+       status = vpfe_register_ccdc_device(&ccdc_hw_dev);
+       if (status < 0)
+               return status;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               status = -ENODEV;
+               goto fail_nores;
+       }
+
+       res = request_mem_region(res->start, resource_size(res), res->name);
+       if (!res) {
+               status = -EBUSY;
+               goto fail_nores;
+       }
+
+       ccdc_cfg.base_addr = ioremap(res->start, resource_size(res));
+       if (!ccdc_cfg.base_addr) {
+               status = -ENOMEM;
+               goto fail_nomem;
+       }
+
+       ccdc_cfg.dev = &pdev->dev;
+       printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
+       return 0;
+fail_nomem:
+       release_mem_region(res->start, resource_size(res));
+fail_nores:
+       vpfe_unregister_ccdc_device(&ccdc_hw_dev);
+       return status;
+}
+
+static int dm644x_ccdc_remove(struct platform_device *pdev)
+{
+       struct resource *res;
+
+       iounmap(ccdc_cfg.base_addr);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res)
+               release_mem_region(res->start, resource_size(res));
+       vpfe_unregister_ccdc_device(&ccdc_hw_dev);
+       return 0;
+}
+
+static int dm644x_ccdc_suspend(struct device *dev)
+{
+       /* Save CCDC context */
+       ccdc_save_context();
+       /* Disable CCDC */
+       ccdc_enable(0);
+
+       return 0;
+}
+
+static int dm644x_ccdc_resume(struct device *dev)
+{
+       /* Restore CCDC context */
+       ccdc_restore_context();
+
+       return 0;
+}
+
+static const struct dev_pm_ops dm644x_ccdc_pm_ops = {
+       .suspend = dm644x_ccdc_suspend,
+       .resume = dm644x_ccdc_resume,
+};
+
+static struct platform_driver dm644x_ccdc_driver = {
+       .driver = {
+               .name   = "dm644x_ccdc",
+               .pm = &dm644x_ccdc_pm_ops,
+       },
+       .remove = dm644x_ccdc_remove,
+       .probe = dm644x_ccdc_probe,
+};
+
+module_platform_driver(dm644x_ccdc_driver);
diff --git a/drivers/media/platform/ti/davinci/dm644x_ccdc_regs.h b/drivers/media/platform/ti/davinci/dm644x_ccdc_regs.h
new file mode 100644 (file)
index 0000000..c4894f6
--- /dev/null
@@ -0,0 +1,140 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2006-2009 Texas Instruments Inc
+ */
+#ifndef _DM644X_CCDC_REGS_H
+#define _DM644X_CCDC_REGS_H
+
+/**************************************************************************\
+* Register OFFSET Definitions
+\**************************************************************************/
+#define CCDC_PID                               0x0
+#define CCDC_PCR                               0x4
+#define CCDC_SYN_MODE                          0x8
+#define CCDC_HD_VD_WID                         0xc
+#define CCDC_PIX_LINES                         0x10
+#define CCDC_HORZ_INFO                         0x14
+#define CCDC_VERT_START                                0x18
+#define CCDC_VERT_LINES                                0x1c
+#define CCDC_CULLING                           0x20
+#define CCDC_HSIZE_OFF                         0x24
+#define CCDC_SDOFST                            0x28
+#define CCDC_SDR_ADDR                          0x2c
+#define CCDC_CLAMP                             0x30
+#define CCDC_DCSUB                             0x34
+#define CCDC_COLPTN                            0x38
+#define CCDC_BLKCMP                            0x3c
+#define CCDC_FPC                               0x40
+#define CCDC_FPC_ADDR                          0x44
+#define CCDC_VDINT                             0x48
+#define CCDC_ALAW                              0x4c
+#define CCDC_REC656IF                          0x50
+#define CCDC_CCDCFG                            0x54
+#define CCDC_FMTCFG                            0x58
+#define CCDC_FMT_HORZ                          0x5c
+#define CCDC_FMT_VERT                          0x60
+#define CCDC_FMT_ADDR0                         0x64
+#define CCDC_FMT_ADDR1                         0x68
+#define CCDC_FMT_ADDR2                         0x6c
+#define CCDC_FMT_ADDR3                         0x70
+#define CCDC_FMT_ADDR4                         0x74
+#define CCDC_FMT_ADDR5                         0x78
+#define CCDC_FMT_ADDR6                         0x7c
+#define CCDC_FMT_ADDR7                         0x80
+#define CCDC_PRGEVEN_0                         0x84
+#define CCDC_PRGEVEN_1                         0x88
+#define CCDC_PRGODD_0                          0x8c
+#define CCDC_PRGODD_1                          0x90
+#define CCDC_VP_OUT                            0x94
+#define CCDC_REG_END                           0x98
+
+/***************************************************************
+*      Define for various register bit mask and shifts for CCDC
+****************************************************************/
+#define CCDC_FID_POL_MASK                      1
+#define CCDC_FID_POL_SHIFT                     4
+#define CCDC_HD_POL_MASK                       1
+#define CCDC_HD_POL_SHIFT                      3
+#define CCDC_VD_POL_MASK                       1
+#define CCDC_VD_POL_SHIFT                      2
+#define CCDC_HSIZE_OFF_MASK                    0xffffffe0
+#define CCDC_32BYTE_ALIGN_VAL                  31
+#define CCDC_FRM_FMT_MASK                      0x1
+#define CCDC_FRM_FMT_SHIFT                     7
+#define CCDC_DATA_SZ_MASK                      7
+#define CCDC_DATA_SZ_SHIFT                     8
+#define CCDC_PIX_FMT_MASK                      3
+#define CCDC_PIX_FMT_SHIFT                     12
+#define CCDC_VP2SDR_DISABLE                    0xFFFBFFFF
+#define CCDC_WEN_ENABLE                                BIT(17)
+#define CCDC_SDR2RSZ_DISABLE                   0xFFF7FFFF
+#define CCDC_VDHDEN_ENABLE                     BIT(16)
+#define CCDC_LPF_ENABLE                                BIT(14)
+#define CCDC_ALAW_ENABLE                       BIT(3)
+#define CCDC_ALAW_GAMMA_WD_MASK                        7
+#define CCDC_BLK_CLAMP_ENABLE                  BIT(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                        7
+#define CCDC_BLK_SAMPLE_LN_SHIFT               28
+#define CCDC_BLK_SAMPLE_LINE_MASK              7
+#define CCDC_BLK_SAMPLE_LINE_SHIFT             25
+#define CCDC_BLK_DC_SUB_MASK                   0x03FFF
+#define CCDC_BLK_COMP_MASK                     0xFF
+#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            BIT(15)
+#define CCDC_FPC_ENABLE                                BIT(15)
+#define CCDC_FPC_DISABLE                       0
+#define CCDC_FPC_FPC_NUM_MASK                  0x7FFF
+#define CCDC_DATA_PACK_ENABLE                  BIT(11)
+#define CCDC_FMTCFG_VPIN_MASK                  7
+#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               0xF
+#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
+#define CCDC_PPC_RAW                           1
+#define CCDC_DCSUB_DEFAULT_VAL                 0
+#define CCDC_CLAMP_DEFAULT_VAL                 0
+#define CCDC_ENABLE_VIDEO_PORT                 0x8000
+#define CCDC_DISABLE_VIDEO_PORT                        0
+#define CCDC_COLPTN_VAL                                0xBB11BB11
+#define CCDC_TWO_BYTES_PER_PIXEL               2
+#define CCDC_INTERLACED_IMAGE_INVERT           0x4B6D
+#define CCDC_INTERLACED_NO_IMAGE_INVERT                0x0249
+#define CCDC_PROGRESSIVE_IMAGE_INVERT          0x4000
+#define CCDC_PROGRESSIVE_NO_IMAGE_INVERT       0
+#define CCDC_INTERLACED_HEIGHT_SHIFT           1
+#define CCDC_SYN_MODE_INPMOD_SHIFT             12
+#define CCDC_SYN_MODE_INPMOD_MASK              3
+#define CCDC_SYN_MODE_8BITS                    (7 << 8)
+#define CCDC_SYN_MODE_10BITS                   (6 << 8)
+#define CCDC_SYN_MODE_11BITS                   (5 << 8)
+#define CCDC_SYN_MODE_12BITS                   (4 << 8)
+#define CCDC_SYN_MODE_13BITS                   (3 << 8)
+#define CCDC_SYN_MODE_14BITS                   (2 << 8)
+#define CCDC_SYN_MODE_15BITS                   (1 << 8)
+#define CCDC_SYN_MODE_16BITS                   (0 << 8)
+#define CCDC_SYN_FLDMODE_MASK                  1
+#define CCDC_SYN_FLDMODE_SHIFT                 7
+#define CCDC_REC656IF_BT656_EN                 3
+#define CCDC_SYN_MODE_VD_POL_NEGATIVE          BIT(2)
+#define CCDC_CCDCFG_Y8POS_SHIFT                        11
+#define CCDC_CCDCFG_BW656_10BIT                        BIT(5)
+#define CCDC_SDOFST_FIELD_INTERLEAVED          0x249
+#define CCDC_NO_CULLING                                0xffff00ff
+#endif
diff --git a/drivers/media/platform/ti/davinci/isif.c b/drivers/media/platform/ti/davinci/isif.c
new file mode 100644 (file)
index 0000000..c53cecd
--- /dev/null
@@ -0,0 +1,1128 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2008-2009 Texas Instruments Inc
+ *
+ * Image Sensor Interface (ISIF) driver
+ *
+ * This driver is for configuring the ISIF IP available on DM365 or any other
+ * TI SoCs. This is used for capturing yuv or bayer video or image data
+ * from a decoder or sensor. This IP is similar to the CCDC IP on DM355
+ * and DM6446, but with enhanced or additional ip blocks. The driver
+ * configures the ISIF upon commands from the vpfe bridge driver through
+ * ccdc_hw_device interface.
+ *
+ * TODO: 1) Raw bayer parameter settings and bayer capture
+ *      2) Add support for control ioctl
+ */
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/videodev2.h>
+#include <linux/err.h>
+#include <linux/module.h>
+
+#include <media/davinci/isif.h>
+#include <media/davinci/vpss.h>
+
+#include "isif_regs.h"
+#include "ccdc_hw_device.h"
+
+/* Defaults for module configuration parameters */
+static const struct isif_config_params_raw isif_config_defaults = {
+       .linearize = {
+               .en = 0,
+               .corr_shft = ISIF_NO_SHIFT,
+               .scale_fact = {1, 0},
+       },
+       .df_csc = {
+               .df_or_csc = 0,
+               .csc = {
+                       .en = 0,
+               },
+       },
+       .dfc = {
+               .en = 0,
+       },
+       .bclamp = {
+               .en = 0,
+       },
+       .gain_offset = {
+               .gain = {
+                       .r_ye = {1, 0},
+                       .gr_cy = {1, 0},
+                       .gb_g = {1, 0},
+                       .b_mg = {1, 0},
+               },
+       },
+       .culling = {
+               .hcpat_odd = 0xff,
+               .hcpat_even = 0xff,
+               .vcpat = 0xff,
+       },
+       .compress = {
+               .alg = ISIF_ALAW,
+       },
+};
+
+/* ISIF operation configuration */
+static struct isif_oper_config {
+       struct device *dev;
+       enum vpfe_hw_if_type if_type;
+       struct isif_ycbcr_config ycbcr;
+       struct isif_params_raw bayer;
+       enum isif_data_pack data_pack;
+       /* ISIF base address */
+       void __iomem *base_addr;
+       /* ISIF Linear Table 0 */
+       void __iomem *linear_tbl0_addr;
+       /* ISIF Linear Table 1 */
+       void __iomem *linear_tbl1_addr;
+} isif_cfg = {
+       .ycbcr = {
+               .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
+               .frm_fmt = CCDC_FRMFMT_INTERLACED,
+               .win = ISIF_WIN_NTSC,
+               .fid_pol = VPFE_PINPOL_POSITIVE,
+               .vd_pol = VPFE_PINPOL_POSITIVE,
+               .hd_pol = VPFE_PINPOL_POSITIVE,
+               .pix_order = CCDC_PIXORDER_CBYCRY,
+               .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED,
+       },
+       .bayer = {
+               .pix_fmt = CCDC_PIXFMT_RAW,
+               .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
+               .win = ISIF_WIN_VGA,
+               .fid_pol = VPFE_PINPOL_POSITIVE,
+               .vd_pol = VPFE_PINPOL_POSITIVE,
+               .hd_pol = VPFE_PINPOL_POSITIVE,
+               .gain = {
+                       .r_ye = {1, 0},
+                       .gr_cy = {1, 0},
+                       .gb_g = {1, 0},
+                       .b_mg = {1, 0},
+               },
+               .cfa_pat = ISIF_CFA_PAT_MOSAIC,
+               .data_msb = ISIF_BIT_MSB_11,
+               .config_params = {
+                       .data_shift = ISIF_NO_SHIFT,
+                       .col_pat_field0 = {
+                               .olop = ISIF_GREEN_BLUE,
+                               .olep = ISIF_BLUE,
+                               .elop = ISIF_RED,
+                               .elep = ISIF_GREEN_RED,
+                       },
+                       .col_pat_field1 = {
+                               .olop = ISIF_GREEN_BLUE,
+                               .olep = ISIF_BLUE,
+                               .elop = ISIF_RED,
+                               .elep = ISIF_GREEN_RED,
+                       },
+                       .test_pat_gen = 0,
+               },
+       },
+       .data_pack = ISIF_DATA_PACK8,
+};
+
+/* Raw Bayer formats */
+static const u32 isif_raw_bayer_pix_formats[] = {
+       V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
+
+/* Raw YUV formats */
+static const u32 isif_raw_yuv_pix_formats[] = {
+       V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
+
+/* register access routines */
+static inline u32 regr(u32 offset)
+{
+       return __raw_readl(isif_cfg.base_addr + offset);
+}
+
+static inline void regw(u32 val, u32 offset)
+{
+       __raw_writel(val, isif_cfg.base_addr + offset);
+}
+
+/* reg_modify() - read, modify and write register */
+static inline u32 reg_modify(u32 mask, u32 val, u32 offset)
+{
+       u32 new_val = (regr(offset) & ~mask) | (val & mask);
+
+       regw(new_val, offset);
+       return new_val;
+}
+
+static inline void regw_lin_tbl(u32 val, u32 offset, int i)
+{
+       if (!i)
+               __raw_writel(val, isif_cfg.linear_tbl0_addr + offset);
+       else
+               __raw_writel(val, isif_cfg.linear_tbl1_addr + offset);
+}
+
+static void isif_disable_all_modules(void)
+{
+       /* disable BC */
+       regw(0, CLAMPCFG);
+       /* disable vdfc */
+       regw(0, DFCCTL);
+       /* disable CSC */
+       regw(0, CSCCTL);
+       /* disable linearization */
+       regw(0, LINCFG0);
+       /* disable other modules here as they are supported */
+}
+
+static void isif_enable(int en)
+{
+       if (!en) {
+               /* Before disable isif, disable all ISIF modules */
+               isif_disable_all_modules();
+               /*
+                * wait for next VD. Assume lowest scan rate is 12 Hz. So
+                * 100 msec delay is good enough
+                */
+               msleep(100);
+       }
+       reg_modify(ISIF_SYNCEN_VDHDEN_MASK, en, SYNCEN);
+}
+
+static void isif_enable_output_to_sdram(int en)
+{
+       reg_modify(ISIF_SYNCEN_WEN_MASK, en << ISIF_SYNCEN_WEN_SHIFT, SYNCEN);
+}
+
+static void isif_config_culling(struct isif_cul *cul)
+{
+       u32 val;
+
+       /* Horizontal pattern */
+       val = (cul->hcpat_even << CULL_PAT_EVEN_LINE_SHIFT) | cul->hcpat_odd;
+       regw(val, CULH);
+
+       /* vertical pattern */
+       regw(cul->vcpat, CULV);
+
+       /* LPF */
+       reg_modify(ISIF_LPF_MASK << ISIF_LPF_SHIFT,
+                 cul->en_lpf << ISIF_LPF_SHIFT, MODESET);
+}
+
+static void isif_config_gain_offset(void)
+{
+       struct isif_gain_offsets_adj *gain_off_p =
+               &isif_cfg.bayer.config_params.gain_offset;
+       u32 val;
+
+       val = (!!gain_off_p->gain_sdram_en << GAIN_SDRAM_EN_SHIFT) |
+             (!!gain_off_p->gain_ipipe_en << GAIN_IPIPE_EN_SHIFT) |
+             (!!gain_off_p->gain_h3a_en << GAIN_H3A_EN_SHIFT) |
+             (!!gain_off_p->offset_sdram_en << OFST_SDRAM_EN_SHIFT) |
+             (!!gain_off_p->offset_ipipe_en << OFST_IPIPE_EN_SHIFT) |
+             (!!gain_off_p->offset_h3a_en << OFST_H3A_EN_SHIFT);
+
+       reg_modify(GAIN_OFFSET_EN_MASK, val, CGAMMAWD);
+
+       val = (gain_off_p->gain.r_ye.integer << GAIN_INTEGER_SHIFT) |
+              gain_off_p->gain.r_ye.decimal;
+       regw(val, CRGAIN);
+
+       val = (gain_off_p->gain.gr_cy.integer << GAIN_INTEGER_SHIFT) |
+              gain_off_p->gain.gr_cy.decimal;
+       regw(val, CGRGAIN);
+
+       val = (gain_off_p->gain.gb_g.integer << GAIN_INTEGER_SHIFT) |
+              gain_off_p->gain.gb_g.decimal;
+       regw(val, CGBGAIN);
+
+       val = (gain_off_p->gain.b_mg.integer << GAIN_INTEGER_SHIFT) |
+              gain_off_p->gain.b_mg.decimal;
+       regw(val, CBGAIN);
+
+       regw(gain_off_p->offset, COFSTA);
+}
+
+static void isif_restore_defaults(void)
+{
+       enum vpss_ccdc_source_sel source = VPSS_CCDCIN;
+
+       dev_dbg(isif_cfg.dev, "\nstarting isif_restore_defaults...");
+       isif_cfg.bayer.config_params = isif_config_defaults;
+       /* Enable clock to ISIF, IPIPEIF and BL */
+       vpss_enable_clock(VPSS_CCDC_CLOCK, 1);
+       vpss_enable_clock(VPSS_IPIPEIF_CLOCK, 1);
+       vpss_enable_clock(VPSS_BL_CLOCK, 1);
+       /* Set default offset and gain */
+       isif_config_gain_offset();
+       vpss_select_ccdc_source(source);
+       dev_dbg(isif_cfg.dev, "\nEnd of isif_restore_defaults...");
+}
+
+static int isif_open(struct device *device)
+{
+       isif_restore_defaults();
+       return 0;
+}
+
+/* This function will configure the window size to be capture in ISIF reg */
+static void isif_setwin(struct v4l2_rect *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(isif_cfg.dev, "\nStarting isif_setwin...");
+       /*
+        * ppc - per pixel count. indicates how many pixels per cell
+        * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
+        * raw capture this is 1
+        */
+       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, LNH);
+       vert_start = image_win->top;
+
+       if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
+               vert_nr_lines = (image_win->height >> 1) - 1;
+               vert_start >>= 1;
+               /* To account for VD since line 0 doesn't have any data */
+               vert_start += 1;
+       } else {
+               /* To account for VD since line 0 doesn't have any data */
+               vert_start += 1;
+               vert_nr_lines = image_win->height - 1;
+               /* configure VDINT0 and VDINT1 */
+               mid_img = vert_start + (image_win->height / 2);
+               regw(mid_img, VDINT1);
+       }
+
+       regw(0, VDINT0);
+       regw(vert_start & START_VER_ONE_MASK, SLV0);
+       regw(vert_start & START_VER_TWO_MASK, SLV1);
+       regw(vert_nr_lines & NUM_LINES_VER, LNV);
+}
+
+static void isif_config_bclamp(struct isif_black_clamp *bc)
+{
+       u32 val;
+
+       /*
+        * DC Offset is always added to image data irrespective of bc enable
+        * status
+        */
+       regw(bc->dc_offset, CLDCOFST);
+
+       if (bc->en) {
+               val = bc->bc_mode_color << ISIF_BC_MODE_COLOR_SHIFT;
+
+               /* Enable BC and horizontal clamp calculation parameters */
+               val = val | 1 | (bc->horz.mode << ISIF_HORZ_BC_MODE_SHIFT);
+
+               regw(val, CLAMPCFG);
+
+               if (bc->horz.mode != ISIF_HORZ_BC_DISABLE) {
+                       /*
+                        * Window count for calculation
+                        * Base window selection
+                        * pixel limit
+                        * Horizontal size of window
+                        * vertical size of the window
+                        * Horizontal start position of the window
+                        * Vertical start position of the window
+                        */
+                       val = bc->horz.win_count_calc |
+                             ((!!bc->horz.base_win_sel_calc) <<
+                               ISIF_HORZ_BC_WIN_SEL_SHIFT) |
+                             ((!!bc->horz.clamp_pix_limit) <<
+                               ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
+                             (bc->horz.win_h_sz_calc <<
+                               ISIF_HORZ_BC_WIN_H_SIZE_SHIFT) |
+                             (bc->horz.win_v_sz_calc <<
+                               ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);
+                       regw(val, CLHWIN0);
+
+                       regw(bc->horz.win_start_h_calc, CLHWIN1);
+                       regw(bc->horz.win_start_v_calc, CLHWIN2);
+               }
+
+               /* vertical clamp calculation parameters */
+
+               /* Reset clamp value sel for previous line */
+               val |=
+               (bc->vert.reset_val_sel << ISIF_VERT_BC_RST_VAL_SEL_SHIFT) |
+               (bc->vert.line_ave_coef << ISIF_VERT_BC_LINE_AVE_COEF_SHIFT);
+               regw(val, CLVWIN0);
+
+               /* Optical Black horizontal start position */
+               regw(bc->vert.ob_start_h, CLVWIN1);
+               /* Optical Black vertical start position */
+               regw(bc->vert.ob_start_v, CLVWIN2);
+               /* Optical Black vertical size for calculation */
+               regw(bc->vert.ob_v_sz_calc, CLVWIN3);
+               /* Vertical start position for BC subtraction */
+               regw(bc->vert_start_sub, CLSV);
+       }
+}
+
+static void isif_config_linearization(struct isif_linearize *linearize)
+{
+       u32 val, i;
+
+       if (!linearize->en) {
+               regw(0, LINCFG0);
+               return;
+       }
+
+       /* shift value for correction & enable linearization (set lsb) */
+       val = (linearize->corr_shft << ISIF_LIN_CORRSFT_SHIFT) | 1;
+       regw(val, LINCFG0);
+
+       /* Scale factor */
+       val = ((!!linearize->scale_fact.integer) <<
+              ISIF_LIN_SCALE_FACT_INTEG_SHIFT) |
+              linearize->scale_fact.decimal;
+       regw(val, LINCFG1);
+
+       for (i = 0; i < ISIF_LINEAR_TAB_SIZE; i++) {
+               if (i % 2)
+                       regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 1);
+               else
+                       regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 0);
+       }
+}
+
+static int isif_config_dfc(struct isif_dfc *vdfc)
+{
+       /* initialize retries to loop for max ~ 250 usec */
+       u32 val, count, retries = loops_per_jiffy / (4000/HZ);
+       int i;
+
+       if (!vdfc->en)
+               return 0;
+
+       /* Correction mode */
+       val = (vdfc->corr_mode << ISIF_VDFC_CORR_MOD_SHIFT);
+
+       /* Correct whole line or partial */
+       if (vdfc->corr_whole_line)
+               val |= 1 << ISIF_VDFC_CORR_WHOLE_LN_SHIFT;
+
+       /* level shift value */
+       val |= vdfc->def_level_shift << ISIF_VDFC_LEVEL_SHFT_SHIFT;
+
+       regw(val, DFCCTL);
+
+       /* Defect saturation level */
+       regw(vdfc->def_sat_level, VDFSATLV);
+
+       regw(vdfc->table[0].pos_vert, DFCMEM0);
+       regw(vdfc->table[0].pos_horz, DFCMEM1);
+       if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
+           vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
+               regw(vdfc->table[0].level_at_pos, DFCMEM2);
+               regw(vdfc->table[0].level_up_pixels, DFCMEM3);
+               regw(vdfc->table[0].level_low_pixels, DFCMEM4);
+       }
+
+       /* set DFCMARST and set DFCMWR */
+       val = regr(DFCMEMCTL) | (1 << ISIF_DFCMEMCTL_DFCMARST_SHIFT) | 1;
+       regw(val, DFCMEMCTL);
+
+       count = retries;
+       while (count && (regr(DFCMEMCTL) & 0x1))
+               count--;
+
+       if (!count) {
+               dev_dbg(isif_cfg.dev, "defect table write timeout !!!\n");
+               return -1;
+       }
+
+       for (i = 1; i < vdfc->num_vdefects; i++) {
+               regw(vdfc->table[i].pos_vert, DFCMEM0);
+               regw(vdfc->table[i].pos_horz, DFCMEM1);
+               if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
+                   vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
+                       regw(vdfc->table[i].level_at_pos, DFCMEM2);
+                       regw(vdfc->table[i].level_up_pixels, DFCMEM3);
+                       regw(vdfc->table[i].level_low_pixels, DFCMEM4);
+               }
+               val = regr(DFCMEMCTL);
+               /* clear DFCMARST and set DFCMWR */
+               val &= ~BIT(ISIF_DFCMEMCTL_DFCMARST_SHIFT);
+               val |= 1;
+               regw(val, DFCMEMCTL);
+
+               count = retries;
+               while (count && (regr(DFCMEMCTL) & 0x1))
+                       count--;
+
+               if (!count) {
+                       dev_err(isif_cfg.dev,
+                               "defect table write timeout !!!\n");
+                       return -1;
+               }
+       }
+       if (vdfc->num_vdefects < ISIF_VDFC_TABLE_SIZE) {
+               /* Extra cycle needed */
+               regw(0, DFCMEM0);
+               regw(0x1FFF, DFCMEM1);
+               regw(1, DFCMEMCTL);
+       }
+
+       /* enable VDFC */
+       reg_modify((1 << ISIF_VDFC_EN_SHIFT), (1 << ISIF_VDFC_EN_SHIFT),
+                  DFCCTL);
+       return 0;
+}
+
+static void isif_config_csc(struct isif_df_csc *df_csc)
+{
+       u32 val1 = 0, val2 = 0, i;
+
+       if (!df_csc->csc.en) {
+               regw(0, CSCCTL);
+               return;
+       }
+       for (i = 0; i < ISIF_CSC_NUM_COEFF; i++) {
+               if ((i % 2) == 0) {
+                       /* CSCM - LSB */
+                       val1 = (df_csc->csc.coeff[i].integer <<
+                               ISIF_CSC_COEF_INTEG_SHIFT) |
+                               df_csc->csc.coeff[i].decimal;
+               } else {
+
+                       /* CSCM - MSB */
+                       val2 = (df_csc->csc.coeff[i].integer <<
+                               ISIF_CSC_COEF_INTEG_SHIFT) |
+                               df_csc->csc.coeff[i].decimal;
+                       val2 <<= ISIF_CSCM_MSB_SHIFT;
+                       val2 |= val1;
+                       regw(val2, (CSCM0 + ((i - 1) << 1)));
+               }
+       }
+
+       /* program the active area */
+       regw(df_csc->start_pix, FMTSPH);
+       /*
+        * one extra pixel as required for CSC. Actually number of
+        * pixel - 1 should be configured in this register. So we
+        * need to subtract 1 before writing to FMTSPH, but we will
+        * not do this since csc requires one extra pixel
+        */
+       regw(df_csc->num_pixels, FMTLNH);
+       regw(df_csc->start_line, FMTSLV);
+       /*
+        * one extra line as required for CSC. See reason documented for
+        * num_pixels
+        */
+       regw(df_csc->num_lines, FMTLNV);
+
+       /* Enable CSC */
+       regw(1, CSCCTL);
+}
+
+static int isif_config_raw(void)
+{
+       struct isif_params_raw *params = &isif_cfg.bayer;
+       struct isif_config_params_raw *module_params =
+               &isif_cfg.bayer.config_params;
+       struct vpss_pg_frame_size frame_size;
+       struct vpss_sync_pol sync;
+       u32 val;
+
+       dev_dbg(isif_cfg.dev, "\nStarting isif_config_raw..\n");
+
+       /*
+        * Configure CCDCFG register:-
+        * Set CCD Not to swap input since input is RAW data
+        * Set FID detection function to Latch at V-Sync
+        * Set WENLOG - isif valid area
+        * Set TRGSEL
+        * Set EXTRG
+        * Packed to 8 or 16 bits
+        */
+
+       val = ISIF_YCINSWP_RAW | ISIF_CCDCFG_FIDMD_LATCH_VSYNC |
+               ISIF_CCDCFG_WENLOG_AND | ISIF_CCDCFG_TRGSEL_WEN |
+               ISIF_CCDCFG_EXTRG_DISABLE | isif_cfg.data_pack;
+
+       dev_dbg(isif_cfg.dev, "Writing 0x%x to ...CCDCFG \n", val);
+       regw(val, CCDCFG);
+
+       /*
+        * Configure the vertical sync polarity(MODESET.VDPOL)
+        * Configure the horizontal sync polarity (MODESET.HDPOL)
+        * Configure frame id polarity (MODESET.FLDPOL)
+        * Configure data polarity
+        * Configure External WEN Selection
+        * Configure frame format(progressive or interlace)
+        * Configure pixel format (Input mode)
+        * Configure the data shift
+        */
+
+       val = ISIF_VDHDOUT_INPUT | (params->vd_pol << ISIF_VD_POL_SHIFT) |
+               (params->hd_pol << ISIF_HD_POL_SHIFT) |
+               (params->fid_pol << ISIF_FID_POL_SHIFT) |
+               (ISIF_DATAPOL_NORMAL << ISIF_DATAPOL_SHIFT) |
+               (ISIF_EXWEN_DISABLE << ISIF_EXWEN_SHIFT) |
+               (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
+               (params->pix_fmt << ISIF_INPUT_SHIFT) |
+               (params->config_params.data_shift << ISIF_DATASFT_SHIFT);
+
+       regw(val, MODESET);
+       dev_dbg(isif_cfg.dev, "Writing 0x%x to MODESET...\n", val);
+
+       /*
+        * Configure GAMMAWD register
+        * CFA pattern setting
+        */
+       val = params->cfa_pat << ISIF_GAMMAWD_CFA_SHIFT;
+
+       /* Gamma msb */
+       if (module_params->compress.alg == ISIF_ALAW)
+               val |= ISIF_ALAW_ENABLE;
+
+       val |= (params->data_msb << ISIF_ALAW_GAMMA_WD_SHIFT);
+       regw(val, CGAMMAWD);
+
+       /* Configure DPCM compression settings */
+       if (module_params->compress.alg == ISIF_DPCM) {
+               val =  BIT(ISIF_DPCM_EN_SHIFT) |
+                      (module_params->compress.pred <<
+                      ISIF_DPCM_PREDICTOR_SHIFT);
+       }
+
+       regw(val, MISC);
+
+       /* Configure Gain & Offset */
+       isif_config_gain_offset();
+
+       /* Configure Color pattern */
+       val = (params->config_params.col_pat_field0.olop) |
+             (params->config_params.col_pat_field0.olep << 2) |
+             (params->config_params.col_pat_field0.elop << 4) |
+             (params->config_params.col_pat_field0.elep << 6) |
+             (params->config_params.col_pat_field1.olop << 8) |
+             (params->config_params.col_pat_field1.olep << 10) |
+             (params->config_params.col_pat_field1.elop << 12) |
+             (params->config_params.col_pat_field1.elep << 14);
+       regw(val, CCOLP);
+       dev_dbg(isif_cfg.dev, "Writing %x to CCOLP ...\n", val);
+
+       /* Configure HSIZE register  */
+       val = (!!params->horz_flip_en) << ISIF_HSIZE_FLIP_SHIFT;
+
+       /* calculate line offset in 32 bytes based on pack value */
+       if (isif_cfg.data_pack == ISIF_PACK_8BIT)
+               val |= ((params->win.width + 31) >> 5);
+       else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
+               val |= (((params->win.width +
+                      (params->win.width >> 2)) + 31) >> 5);
+       else
+               val |= (((params->win.width * 2) + 31) >> 5);
+       regw(val, HSIZE);
+
+       /* Configure SDOFST register  */
+       if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
+               if (params->image_invert_en) {
+                       /* For interlace inverse mode */
+                       regw(0x4B6D, SDOFST);
+                       dev_dbg(isif_cfg.dev, "Writing 0x4B6D to SDOFST...\n");
+               } else {
+                       /* For interlace non inverse mode */
+                       regw(0x0B6D, SDOFST);
+                       dev_dbg(isif_cfg.dev, "Writing 0x0B6D to SDOFST...\n");
+               }
+       } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
+               if (params->image_invert_en) {
+                       /* For progressive inverse mode */
+                       regw(0x4000, SDOFST);
+                       dev_dbg(isif_cfg.dev, "Writing 0x4000 to SDOFST...\n");
+               } else {
+                       /* For progressive non inverse mode */
+                       regw(0x0000, SDOFST);
+                       dev_dbg(isif_cfg.dev, "Writing 0x0000 to SDOFST...\n");
+               }
+       }
+
+       /* Configure video window */
+       isif_setwin(&params->win, params->frm_fmt, 1);
+
+       /* Configure Black Clamp */
+       isif_config_bclamp(&module_params->bclamp);
+
+       /* Configure Vertical Defection Pixel Correction */
+       if (isif_config_dfc(&module_params->dfc) < 0)
+               return -EFAULT;
+
+       if (!module_params->df_csc.df_or_csc)
+               /* Configure Color Space Conversion */
+               isif_config_csc(&module_params->df_csc);
+
+       isif_config_linearization(&module_params->linearize);
+
+       /* Configure Culling */
+       isif_config_culling(&module_params->culling);
+
+       /* Configure horizontal and vertical offsets(DFC,LSC,Gain) */
+       regw(module_params->horz_offset, DATAHOFST);
+       regw(module_params->vert_offset, DATAVOFST);
+
+       /* Setup test pattern if enabled */
+       if (params->config_params.test_pat_gen) {
+               /* Use the HD/VD pol settings from user */
+               sync.ccdpg_hdpol = params->hd_pol;
+               sync.ccdpg_vdpol = params->vd_pol;
+               dm365_vpss_set_sync_pol(sync);
+               frame_size.hlpfr = isif_cfg.bayer.win.width;
+               frame_size.pplen = isif_cfg.bayer.win.height;
+               dm365_vpss_set_pg_frame_size(frame_size);
+               vpss_select_ccdc_source(VPSS_PGLPBK);
+       }
+
+       dev_dbg(isif_cfg.dev, "\nEnd of isif_config_ycbcr...\n");
+       return 0;
+}
+
+static int isif_set_buftype(enum ccdc_buftype buf_type)
+{
+       if (isif_cfg.if_type == VPFE_RAW_BAYER)
+               isif_cfg.bayer.buf_type = buf_type;
+       else
+               isif_cfg.ycbcr.buf_type = buf_type;
+
+       return 0;
+
+}
+static enum ccdc_buftype isif_get_buftype(void)
+{
+       if (isif_cfg.if_type == VPFE_RAW_BAYER)
+               return isif_cfg.bayer.buf_type;
+
+       return isif_cfg.ycbcr.buf_type;
+}
+
+static int isif_enum_pix(u32 *pix, int i)
+{
+       int ret = -EINVAL;
+
+       if (isif_cfg.if_type == VPFE_RAW_BAYER) {
+               if (i < ARRAY_SIZE(isif_raw_bayer_pix_formats)) {
+                       *pix = isif_raw_bayer_pix_formats[i];
+                       ret = 0;
+               }
+       } else {
+               if (i < ARRAY_SIZE(isif_raw_yuv_pix_formats)) {
+                       *pix = isif_raw_yuv_pix_formats[i];
+                       ret = 0;
+               }
+       }
+
+       return ret;
+}
+
+static int isif_set_pixel_format(unsigned int pixfmt)
+{
+       if (isif_cfg.if_type == VPFE_RAW_BAYER) {
+               if (pixfmt == V4L2_PIX_FMT_SBGGR8) {
+                       if ((isif_cfg.bayer.config_params.compress.alg !=
+                            ISIF_ALAW) &&
+                           (isif_cfg.bayer.config_params.compress.alg !=
+                            ISIF_DPCM)) {
+                               dev_dbg(isif_cfg.dev,
+                                       "Either configure A-Law or DPCM\n");
+                               return -EINVAL;
+                       }
+                       isif_cfg.data_pack = ISIF_PACK_8BIT;
+               } else if (pixfmt == V4L2_PIX_FMT_SBGGR16) {
+                       isif_cfg.bayer.config_params.compress.alg =
+                                       ISIF_NO_COMPRESSION;
+                       isif_cfg.data_pack = ISIF_PACK_16BIT;
+               } else
+                       return -EINVAL;
+               isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
+       } else {
+               if (pixfmt == V4L2_PIX_FMT_YUYV)
+                       isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
+               else if (pixfmt == V4L2_PIX_FMT_UYVY)
+                       isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
+               else
+                       return -EINVAL;
+               isif_cfg.data_pack = ISIF_PACK_8BIT;
+       }
+       return 0;
+}
+
+static u32 isif_get_pixel_format(void)
+{
+       u32 pixfmt;
+
+       if (isif_cfg.if_type == VPFE_RAW_BAYER)
+               if (isif_cfg.bayer.config_params.compress.alg == ISIF_ALAW ||
+                   isif_cfg.bayer.config_params.compress.alg == ISIF_DPCM)
+                       pixfmt = V4L2_PIX_FMT_SBGGR8;
+               else
+                       pixfmt = V4L2_PIX_FMT_SBGGR16;
+       else {
+               if (isif_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
+                       pixfmt = V4L2_PIX_FMT_YUYV;
+               else
+                       pixfmt = V4L2_PIX_FMT_UYVY;
+       }
+       return pixfmt;
+}
+
+static int isif_set_image_window(struct v4l2_rect *win)
+{
+       if (isif_cfg.if_type == VPFE_RAW_BAYER) {
+               isif_cfg.bayer.win.top = win->top;
+               isif_cfg.bayer.win.left = win->left;
+               isif_cfg.bayer.win.width = win->width;
+               isif_cfg.bayer.win.height = win->height;
+       } else {
+               isif_cfg.ycbcr.win.top = win->top;
+               isif_cfg.ycbcr.win.left = win->left;
+               isif_cfg.ycbcr.win.width = win->width;
+               isif_cfg.ycbcr.win.height = win->height;
+       }
+       return 0;
+}
+
+static void isif_get_image_window(struct v4l2_rect *win)
+{
+       if (isif_cfg.if_type == VPFE_RAW_BAYER)
+               *win = isif_cfg.bayer.win;
+       else
+               *win = isif_cfg.ycbcr.win;
+}
+
+static unsigned int isif_get_line_length(void)
+{
+       unsigned int len;
+
+       if (isif_cfg.if_type == VPFE_RAW_BAYER) {
+               if (isif_cfg.data_pack == ISIF_PACK_8BIT)
+                       len = ((isif_cfg.bayer.win.width));
+               else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
+                       len = (((isif_cfg.bayer.win.width * 2) +
+                                (isif_cfg.bayer.win.width >> 2)));
+               else
+                       len = (((isif_cfg.bayer.win.width * 2)));
+       } else
+               len = (((isif_cfg.ycbcr.win.width * 2)));
+       return ALIGN(len, 32);
+}
+
+static int isif_set_frame_format(enum ccdc_frmfmt frm_fmt)
+{
+       if (isif_cfg.if_type == VPFE_RAW_BAYER)
+               isif_cfg.bayer.frm_fmt = frm_fmt;
+       else
+               isif_cfg.ycbcr.frm_fmt = frm_fmt;
+       return 0;
+}
+static enum ccdc_frmfmt isif_get_frame_format(void)
+{
+       if (isif_cfg.if_type == VPFE_RAW_BAYER)
+               return isif_cfg.bayer.frm_fmt;
+       return isif_cfg.ycbcr.frm_fmt;
+}
+
+static int isif_getfid(void)
+{
+       return (regr(MODESET) >> 15) & 0x1;
+}
+
+/* misc operations */
+static void isif_setfbaddr(unsigned long addr)
+{
+       regw((addr >> 21) & 0x07ff, CADU);
+       regw((addr >> 5) & 0x0ffff, CADL);
+}
+
+static int isif_set_hw_if_params(struct vpfe_hw_if_param *params)
+{
+       isif_cfg.if_type = params->if_type;
+
+       switch (params->if_type) {
+       case VPFE_BT656:
+       case VPFE_BT656_10BIT:
+       case VPFE_YCBCR_SYNC_8:
+               isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
+               isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
+               break;
+       case VPFE_BT1120:
+       case VPFE_YCBCR_SYNC_16:
+               isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_16BIT;
+               isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
+               break;
+       case VPFE_RAW_BAYER:
+               isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
+               break;
+       default:
+               dev_dbg(isif_cfg.dev, "Invalid interface type\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/* This function will configure ISIF for YCbCr parameters. */
+static int isif_config_ycbcr(void)
+{
+       struct isif_ycbcr_config *params = &isif_cfg.ycbcr;
+       u32 modeset = 0, ccdcfg = 0;
+
+       dev_dbg(isif_cfg.dev, "\nStarting isif_config_ycbcr...");
+
+       /* configure pixel format or input mode */
+       modeset = modeset | (params->pix_fmt << ISIF_INPUT_SHIFT) |
+                 (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
+                 (params->fid_pol << ISIF_FID_POL_SHIFT) |
+                 (params->hd_pol << ISIF_HD_POL_SHIFT) |
+                 (params->vd_pol << ISIF_VD_POL_SHIFT);
+
+       /* pack the data to 8-bit ISIFCFG */
+       switch (isif_cfg.if_type) {
+       case VPFE_BT656:
+               if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
+                       dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
+                       return -EINVAL;
+               }
+               modeset |= (VPFE_PINPOL_NEGATIVE << ISIF_VD_POL_SHIFT);
+               regw(3, REC656IF);
+               ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR;
+               break;
+       case VPFE_BT656_10BIT:
+               if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
+                       dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
+                       return -EINVAL;
+               }
+               /* setup BT.656, embedded sync  */
+               regw(3, REC656IF);
+               /* enable 10 bit mode in ccdcfg */
+               ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR |
+                       ISIF_BW656_ENABLE;
+               break;
+       case VPFE_BT1120:
+               if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
+                       dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
+                       return -EINVAL;
+               }
+               regw(3, REC656IF);
+               break;
+
+       case VPFE_YCBCR_SYNC_8:
+               ccdcfg |= ISIF_DATA_PACK8;
+               ccdcfg |= ISIF_YCINSWP_YCBCR;
+               if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
+                       dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
+                       return -EINVAL;
+               }
+               break;
+       case VPFE_YCBCR_SYNC_16:
+               if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
+                       dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
+                       return -EINVAL;
+               }
+               break;
+       default:
+               /* should never come here */
+               dev_dbg(isif_cfg.dev, "Invalid interface type\n");
+               return -EINVAL;
+       }
+
+       regw(modeset, MODESET);
+
+       /* Set up pix order */
+       ccdcfg |= params->pix_order << ISIF_PIX_ORDER_SHIFT;
+
+       regw(ccdcfg, CCDCFG);
+
+       /* configure video window */
+       if ((isif_cfg.if_type == VPFE_BT1120) ||
+           (isif_cfg.if_type == VPFE_YCBCR_SYNC_16))
+               isif_setwin(&params->win, params->frm_fmt, 1);
+       else
+               isif_setwin(&params->win, params->frm_fmt, 2);
+
+       /*
+        * 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->frm_fmt == CCDC_FRMFMT_INTERLACED) &&
+           (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED))
+               /* two fields are interleaved in memory */
+               regw(0x00000249, SDOFST);
+
+       return 0;
+}
+
+static int isif_configure(void)
+{
+       if (isif_cfg.if_type == VPFE_RAW_BAYER)
+               return isif_config_raw();
+       return isif_config_ycbcr();
+}
+
+static int isif_close(struct device *device)
+{
+       /* copy defaults to module params */
+       isif_cfg.bayer.config_params = isif_config_defaults;
+       return 0;
+}
+
+static const struct ccdc_hw_device isif_hw_dev = {
+       .name = "ISIF",
+       .owner = THIS_MODULE,
+       .hw_ops = {
+               .open = isif_open,
+               .close = isif_close,
+               .enable = isif_enable,
+               .enable_out_to_sdram = isif_enable_output_to_sdram,
+               .set_hw_if_params = isif_set_hw_if_params,
+               .configure = isif_configure,
+               .set_buftype = isif_set_buftype,
+               .get_buftype = isif_get_buftype,
+               .enum_pix = isif_enum_pix,
+               .set_pixel_format = isif_set_pixel_format,
+               .get_pixel_format = isif_get_pixel_format,
+               .set_frame_format = isif_set_frame_format,
+               .get_frame_format = isif_get_frame_format,
+               .set_image_window = isif_set_image_window,
+               .get_image_window = isif_get_image_window,
+               .get_line_length = isif_get_line_length,
+               .setfbaddr = isif_setfbaddr,
+               .getfid = isif_getfid,
+       },
+};
+
+static int isif_probe(struct platform_device *pdev)
+{
+       void (*setup_pinmux)(void);
+       struct resource *res;
+       void __iomem *addr;
+       int status = 0, i;
+
+       /* Platform data holds setup_pinmux function ptr */
+       if (!pdev->dev.platform_data)
+               return -ENODEV;
+
+       /*
+        * first try to register with vpfe. If not correct platform, then we
+        * don't have to iomap
+        */
+       status = vpfe_register_ccdc_device(&isif_hw_dev);
+       if (status < 0)
+               return status;
+
+       setup_pinmux = pdev->dev.platform_data;
+       /*
+        * setup Mux configuration for ccdc which may be different for
+        * different SoCs using this CCDC
+        */
+       setup_pinmux();
+
+       i = 0;
+       /* Get the ISIF base address, linearization table0 and table1 addr. */
+       while (i < 3) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+               if (!res) {
+                       status = -ENODEV;
+                       goto fail_nobase_res;
+               }
+               res = request_mem_region(res->start, resource_size(res),
+                                        res->name);
+               if (!res) {
+                       status = -EBUSY;
+                       goto fail_nobase_res;
+               }
+               addr = ioremap(res->start, resource_size(res));
+               if (!addr) {
+                       status = -ENOMEM;
+                       goto fail_base_iomap;
+               }
+               switch (i) {
+               case 0:
+                       /* ISIF base address */
+                       isif_cfg.base_addr = addr;
+                       break;
+               case 1:
+                       /* ISIF linear tbl0 address */
+                       isif_cfg.linear_tbl0_addr = addr;
+                       break;
+               default:
+                       /* ISIF linear tbl0 address */
+                       isif_cfg.linear_tbl1_addr = addr;
+                       break;
+               }
+               i++;
+       }
+       isif_cfg.dev = &pdev->dev;
+
+       printk(KERN_NOTICE "%s is registered with vpfe.\n",
+               isif_hw_dev.name);
+       return 0;
+fail_base_iomap:
+       release_mem_region(res->start, resource_size(res));
+       i--;
+fail_nobase_res:
+       if (isif_cfg.base_addr) {
+               iounmap(isif_cfg.base_addr);
+               isif_cfg.base_addr = NULL;
+       }
+       if (isif_cfg.linear_tbl0_addr) {
+               iounmap(isif_cfg.linear_tbl0_addr);
+               isif_cfg.linear_tbl0_addr = NULL;
+       }
+
+       while (i >= 0) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+               if (res)
+                       release_mem_region(res->start, resource_size(res));
+               i--;
+       }
+       vpfe_unregister_ccdc_device(&isif_hw_dev);
+       return status;
+}
+
+static int isif_remove(struct platform_device *pdev)
+{
+       struct resource *res;
+       int i = 0;
+
+       iounmap(isif_cfg.base_addr);
+       isif_cfg.base_addr = NULL;
+       iounmap(isif_cfg.linear_tbl0_addr);
+       isif_cfg.linear_tbl0_addr = NULL;
+       iounmap(isif_cfg.linear_tbl1_addr);
+       isif_cfg.linear_tbl1_addr = NULL;
+       while (i < 3) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+               if (res)
+                       release_mem_region(res->start, resource_size(res));
+               i++;
+       }
+       vpfe_unregister_ccdc_device(&isif_hw_dev);
+       return 0;
+}
+
+static struct platform_driver isif_driver = {
+       .driver = {
+               .name   = "isif",
+       },
+       .remove = isif_remove,
+       .probe = isif_probe,
+};
+
+module_platform_driver(isif_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/ti/davinci/isif_regs.h b/drivers/media/platform/ti/davinci/isif_regs.h
new file mode 100644 (file)
index 0000000..d68d388
--- /dev/null
@@ -0,0 +1,256 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2008-2009 Texas Instruments Inc
+ */
+#ifndef _ISIF_REGS_H
+#define _ISIF_REGS_H
+
+/* ISIF registers relative offsets */
+#define SYNCEN                                 0x00
+#define MODESET                                        0x04
+#define HDW                                    0x08
+#define VDW                                    0x0c
+#define PPLN                                   0x10
+#define LPFR                                   0x14
+#define SPH                                    0x18
+#define LNH                                    0x1c
+#define SLV0                                   0x20
+#define SLV1                                   0x24
+#define LNV                                    0x28
+#define CULH                                   0x2c
+#define CULV                                   0x30
+#define HSIZE                                  0x34
+#define SDOFST                                 0x38
+#define CADU                                   0x3c
+#define CADL                                   0x40
+#define LINCFG0                                        0x44
+#define LINCFG1                                        0x48
+#define CCOLP                                  0x4c
+#define CRGAIN                                 0x50
+#define CGRGAIN                                        0x54
+#define CGBGAIN                                        0x58
+#define CBGAIN                                 0x5c
+#define COFSTA                                 0x60
+#define FLSHCFG0                               0x64
+#define FLSHCFG1                               0x68
+#define FLSHCFG2                               0x6c
+#define VDINT0                                 0x70
+#define VDINT1                                 0x74
+#define VDINT2                                 0x78
+#define MISC                                   0x7c
+#define CGAMMAWD                               0x80
+#define REC656IF                               0x84
+#define CCDCFG                                 0x88
+/*****************************************************
+* Defect Correction registers
+*****************************************************/
+#define DFCCTL                                 0x8c
+#define VDFSATLV                               0x90
+#define DFCMEMCTL                              0x94
+#define DFCMEM0                                        0x98
+#define DFCMEM1                                        0x9c
+#define DFCMEM2                                        0xa0
+#define DFCMEM3                                        0xa4
+#define DFCMEM4                                        0xa8
+/****************************************************
+* Black Clamp registers
+****************************************************/
+#define CLAMPCFG                               0xac
+#define CLDCOFST                               0xb0
+#define CLSV                                   0xb4
+#define CLHWIN0                                        0xb8
+#define CLHWIN1                                        0xbc
+#define CLHWIN2                                        0xc0
+#define CLVRV                                  0xc4
+#define CLVWIN0                                        0xc8
+#define CLVWIN1                                        0xcc
+#define CLVWIN2                                        0xd0
+#define CLVWIN3                                        0xd4
+/****************************************************
+* Lense Shading Correction
+****************************************************/
+#define DATAHOFST                              0xd8
+#define DATAVOFST                              0xdc
+#define LSCHVAL                                        0xe0
+#define LSCVVAL                                        0xe4
+#define TWODLSCCFG                             0xe8
+#define TWODLSCOFST                            0xec
+#define TWODLSCINI                             0xf0
+#define TWODLSCGRBU                            0xf4
+#define TWODLSCGRBL                            0xf8
+#define TWODLSCGROF                            0xfc
+#define TWODLSCORBU                            0x100
+#define TWODLSCORBL                            0x104
+#define TWODLSCOROF                            0x108
+#define TWODLSCIRQEN                           0x10c
+#define TWODLSCIRQST                           0x110
+/****************************************************
+* Data formatter
+****************************************************/
+#define FMTCFG                                 0x114
+#define FMTPLEN                                        0x118
+#define FMTSPH                                 0x11c
+#define FMTLNH                                 0x120
+#define FMTSLV                                 0x124
+#define FMTLNV                                 0x128
+#define FMTRLEN                                        0x12c
+#define FMTHCNT                                        0x130
+#define FMTAPTR_BASE                           0x134
+/* Below macro for addresses FMTAPTR0 - FMTAPTR15 */
+#define FMTAPTR(i)                     (FMTAPTR_BASE + (i * 4))
+#define FMTPGMVF0                              0x174
+#define FMTPGMVF1                              0x178
+#define FMTPGMAPU0                             0x17c
+#define FMTPGMAPU1                             0x180
+#define FMTPGMAPS0                             0x184
+#define FMTPGMAPS1                             0x188
+#define FMTPGMAPS2                             0x18c
+#define FMTPGMAPS3                             0x190
+#define FMTPGMAPS4                             0x194
+#define FMTPGMAPS5                             0x198
+#define FMTPGMAPS6                             0x19c
+#define FMTPGMAPS7                             0x1a0
+/************************************************
+* Color Space Converter
+************************************************/
+#define CSCCTL                                 0x1a4
+#define CSCM0                                  0x1a8
+#define CSCM1                                  0x1ac
+#define CSCM2                                  0x1b0
+#define CSCM3                                  0x1b4
+#define CSCM4                                  0x1b8
+#define CSCM5                                  0x1bc
+#define CSCM6                                  0x1c0
+#define CSCM7                                  0x1c4
+#define OBWIN0                                 0x1c8
+#define OBWIN1                                 0x1cc
+#define OBWIN2                                 0x1d0
+#define OBWIN3                                 0x1d4
+#define OBVAL0                                 0x1d8
+#define OBVAL1                                 0x1dc
+#define OBVAL2                                 0x1e0
+#define OBVAL3                                 0x1e4
+#define OBVAL4                                 0x1e8
+#define OBVAL5                                 0x1ec
+#define OBVAL6                                 0x1f0
+#define OBVAL7                                 0x1f4
+#define CLKCTL                                 0x1f8
+
+/* Masks & Shifts below */
+#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
+
+/* gain - offset masks */
+#define GAIN_INTEGER_SHIFT                     9
+#define OFFSET_MASK                            0xFFF
+#define GAIN_SDRAM_EN_SHIFT                    12
+#define GAIN_IPIPE_EN_SHIFT                    13
+#define GAIN_H3A_EN_SHIFT                      14
+#define OFST_SDRAM_EN_SHIFT                    8
+#define OFST_IPIPE_EN_SHIFT                    9
+#define OFST_H3A_EN_SHIFT                      10
+#define GAIN_OFFSET_EN_MASK                    0x7700
+
+/* Culling */
+#define CULL_PAT_EVEN_LINE_SHIFT               8
+
+/* CCDCFG register */
+#define ISIF_YCINSWP_RAW                       (0x00 << 4)
+#define ISIF_YCINSWP_YCBCR                     (0x01 << 4)
+#define ISIF_CCDCFG_FIDMD_LATCH_VSYNC          (0x00 << 6)
+#define ISIF_CCDCFG_WENLOG_AND                 (0x00 << 8)
+#define ISIF_CCDCFG_TRGSEL_WEN                 (0x00 << 9)
+#define ISIF_CCDCFG_EXTRG_DISABLE              (0x00 << 10)
+#define ISIF_LATCH_ON_VSYNC_DISABLE            (0x01 << 15)
+#define ISIF_LATCH_ON_VSYNC_ENABLE             (0x00 << 15)
+#define ISIF_DATA_PACK_MASK                    3
+#define ISIF_DATA_PACK16                       0
+#define ISIF_DATA_PACK12                       1
+#define ISIF_DATA_PACK8                                2
+#define ISIF_PIX_ORDER_SHIFT                   11
+#define ISIF_BW656_ENABLE                      (0x01 << 5)
+
+/* MODESET registers */
+#define ISIF_VDHDOUT_INPUT                     (0x00 << 0)
+#define ISIF_INPUT_SHIFT                       12
+#define ISIF_RAW_INPUT_MODE                    0
+#define ISIF_FID_POL_SHIFT                     4
+#define ISIF_HD_POL_SHIFT                      3
+#define ISIF_VD_POL_SHIFT                      2
+#define ISIF_DATAPOL_NORMAL                    0
+#define ISIF_DATAPOL_SHIFT                     6
+#define ISIF_EXWEN_DISABLE                     0
+#define ISIF_EXWEN_SHIFT                       5
+#define ISIF_FRM_FMT_SHIFT                     7
+#define ISIF_DATASFT_SHIFT                     8
+#define ISIF_LPF_SHIFT                         14
+#define ISIF_LPF_MASK                          1
+
+/* GAMMAWD registers */
+#define ISIF_ALAW_GAMMA_WD_MASK                        0xF
+#define ISIF_ALAW_GAMMA_WD_SHIFT               1
+#define ISIF_ALAW_ENABLE                       1
+#define ISIF_GAMMAWD_CFA_SHIFT                 5
+
+/* HSIZE registers */
+#define ISIF_HSIZE_FLIP_MASK                   1
+#define ISIF_HSIZE_FLIP_SHIFT                  12
+
+/* MISC registers */
+#define ISIF_DPCM_EN_SHIFT                     12
+#define ISIF_DPCM_PREDICTOR_SHIFT              13
+
+/* Black clamp related */
+#define ISIF_BC_MODE_COLOR_SHIFT               4
+#define ISIF_HORZ_BC_MODE_SHIFT                        1
+#define ISIF_HORZ_BC_WIN_SEL_SHIFT             5
+#define ISIF_HORZ_BC_PIX_LIMIT_SHIFT           6
+#define ISIF_HORZ_BC_WIN_H_SIZE_SHIFT          8
+#define ISIF_HORZ_BC_WIN_V_SIZE_SHIFT          12
+#define        ISIF_VERT_BC_RST_VAL_SEL_SHIFT          4
+#define ISIF_VERT_BC_LINE_AVE_COEF_SHIFT       8
+
+/* VDFC registers */
+#define ISIF_VDFC_EN_SHIFT                     4
+#define ISIF_VDFC_CORR_MOD_SHIFT               5
+#define ISIF_VDFC_CORR_WHOLE_LN_SHIFT          7
+#define ISIF_VDFC_LEVEL_SHFT_SHIFT             8
+#define ISIF_VDFC_POS_MASK                     0x1FFF
+#define ISIF_DFCMEMCTL_DFCMARST_SHIFT          2
+
+/* CSC registers */
+#define ISIF_CSC_COEF_INTEG_MASK               7
+#define ISIF_CSC_COEF_DECIMAL_MASK             0x1f
+#define ISIF_CSC_COEF_INTEG_SHIFT              5
+#define ISIF_CSCM_MSB_SHIFT                    8
+#define ISIF_DF_CSC_SPH_MASK                   0x1FFF
+#define ISIF_DF_CSC_LNH_MASK                   0x1FFF
+#define ISIF_DF_CSC_SLV_MASK                   0x1FFF
+#define ISIF_DF_CSC_LNV_MASK                   0x1FFF
+#define ISIF_DF_NUMLINES                       0x7FFF
+#define ISIF_DF_NUMPIX                         0x1FFF
+
+/* Offsets for LSC/DFC/Gain */
+#define ISIF_DATA_H_OFFSET_MASK                        0x1FFF
+#define ISIF_DATA_V_OFFSET_MASK                        0x1FFF
+
+/* Linearization */
+#define ISIF_LIN_CORRSFT_SHIFT                 4
+#define ISIF_LIN_SCALE_FACT_INTEG_SHIFT                10
+
+
+/* Pattern registers */
+#define ISIF_PG_EN                             (1 << 3)
+#define ISIF_SEL_PG_SRC                                (3 << 4)
+#define ISIF_PG_VD_POL_SHIFT                   0
+#define ISIF_PG_HD_POL_SHIFT                   1
+
+/*random other junk*/
+#define ISIF_SYNCEN_VDHDEN_MASK                        (1 << 0)
+#define ISIF_SYNCEN_WEN_MASK                   (1 << 1)
+#define ISIF_SYNCEN_WEN_SHIFT                  1
+
+#endif
diff --git a/drivers/media/platform/ti/davinci/vpbe.c b/drivers/media/platform/ti/davinci/vpbe.c
new file mode 100644 (file)
index 0000000..5f0aeb7
--- /dev/null
@@ -0,0 +1,840 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2010 Texas Instruments Inc
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <media/v4l2-device.h>
+#include <media/davinci/vpbe_types.h>
+#include <media/davinci/vpbe.h>
+#include <media/davinci/vpss.h>
+#include <media/davinci/vpbe_venc.h>
+
+#define VPBE_DEFAULT_OUTPUT    "Composite"
+#define VPBE_DEFAULT_MODE      "ntsc"
+
+static char *def_output = VPBE_DEFAULT_OUTPUT;
+static char *def_mode = VPBE_DEFAULT_MODE;
+static int debug;
+
+module_param(def_output, charp, S_IRUGO);
+module_param(def_mode, charp, S_IRUGO);
+module_param(debug, int, 0644);
+
+MODULE_PARM_DESC(def_output, "vpbe output name (default:Composite)");
+MODULE_PARM_DESC(def_mode, "vpbe output mode name (default:ntsc");
+MODULE_PARM_DESC(debug, "Debug level 0-1");
+
+MODULE_DESCRIPTION("TI DMXXX VPBE Display controller");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Texas Instruments");
+
+/**
+ * vpbe_current_encoder_info - Get config info for current encoder
+ * @vpbe_dev: vpbe device ptr
+ *
+ * Return ptr to current encoder config info
+ */
+static struct encoder_config_info*
+vpbe_current_encoder_info(struct vpbe_device *vpbe_dev)
+{
+       struct vpbe_config *cfg = vpbe_dev->cfg;
+       int index = vpbe_dev->current_sd_index;
+
+       return ((index == 0) ? &cfg->venc :
+                               &cfg->ext_encoders[index-1]);
+}
+
+/**
+ * vpbe_find_encoder_sd_index - Given a name find encoder sd index
+ *
+ * @cfg: ptr to vpbe cfg
+ * @index: index used by application
+ *
+ * Return sd index of the encoder
+ */
+static int vpbe_find_encoder_sd_index(struct vpbe_config *cfg,
+                            int index)
+{
+       char *encoder_name = cfg->outputs[index].subdev_name;
+       int i;
+
+       /* Venc is always first */
+       if (!strcmp(encoder_name, cfg->venc.module_name))
+               return 0;
+
+       for (i = 0; i < cfg->num_ext_encoders; i++) {
+               if (!strcmp(encoder_name,
+                    cfg->ext_encoders[i].module_name))
+                       return i+1;
+       }
+
+       return -EINVAL;
+}
+
+/**
+ * vpbe_enum_outputs - enumerate outputs
+ * @vpbe_dev: vpbe device ptr
+ * @output: ptr to v4l2_output structure
+ *
+ * Enumerates the outputs available at the vpbe display
+ * returns the status, -EINVAL if end of output list
+ */
+static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev,
+                            struct v4l2_output *output)
+{
+       struct vpbe_config *cfg = vpbe_dev->cfg;
+       unsigned int temp_index = output->index;
+
+       if (temp_index >= cfg->num_outputs)
+               return -EINVAL;
+
+       *output = cfg->outputs[temp_index].output;
+       output->index = temp_index;
+
+       return 0;
+}
+
+static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode,
+                             int output_index)
+{
+       struct vpbe_config *cfg = vpbe_dev->cfg;
+       struct vpbe_enc_mode_info var;
+       int curr_output = output_index;
+       int i;
+
+       if (!mode)
+               return -EINVAL;
+
+       for (i = 0; i < cfg->outputs[curr_output].num_modes; i++) {
+               var = cfg->outputs[curr_output].modes[i];
+               if (!strcmp(mode, var.name)) {
+                       vpbe_dev->current_timings = var;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int vpbe_get_current_mode_info(struct vpbe_device *vpbe_dev,
+                                     struct vpbe_enc_mode_info *mode_info)
+{
+       if (!mode_info)
+               return -EINVAL;
+
+       *mode_info = vpbe_dev->current_timings;
+
+       return 0;
+}
+
+/* Get std by std id */
+static int vpbe_get_std_info(struct vpbe_device *vpbe_dev,
+                            v4l2_std_id std_id)
+{
+       struct vpbe_config *cfg = vpbe_dev->cfg;
+       struct vpbe_enc_mode_info var;
+       int curr_output = vpbe_dev->current_out_index;
+       int i;
+
+       for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
+               var = cfg->outputs[curr_output].modes[i];
+               if ((var.timings_type & VPBE_ENC_STD) &&
+                 (var.std_id & std_id)) {
+                       vpbe_dev->current_timings = var;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int vpbe_get_std_info_by_name(struct vpbe_device *vpbe_dev,
+                               char *std_name)
+{
+       struct vpbe_config *cfg = vpbe_dev->cfg;
+       struct vpbe_enc_mode_info var;
+       int curr_output = vpbe_dev->current_out_index;
+       int i;
+
+       for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
+               var = cfg->outputs[curr_output].modes[i];
+               if (!strcmp(var.name, std_name)) {
+                       vpbe_dev->current_timings = var;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+/**
+ * vpbe_set_output - Set output
+ * @vpbe_dev: vpbe device ptr
+ * @index: index of output
+ *
+ * Set vpbe output to the output specified by the index
+ */
+static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index)
+{
+       struct encoder_config_info *curr_enc_info =
+                       vpbe_current_encoder_info(vpbe_dev);
+       struct vpbe_config *cfg = vpbe_dev->cfg;
+       struct venc_platform_data *venc_device = vpbe_dev->venc_device;
+       int enc_out_index;
+       int sd_index;
+       int ret;
+
+       if (index >= cfg->num_outputs)
+               return -EINVAL;
+
+       mutex_lock(&vpbe_dev->lock);
+
+       sd_index = vpbe_dev->current_sd_index;
+       enc_out_index = cfg->outputs[index].output.index;
+       /*
+        * Currently we switch the encoder based on output selected
+        * by the application. If media controller is implemented later
+        * there is will be an API added to setup_link between venc
+        * and external encoder. So in that case below comparison always
+        * match and encoder will not be switched. But if application
+        * chose not to use media controller, then this provides current
+        * way of switching encoder at the venc output.
+        */
+       if (strcmp(curr_enc_info->module_name,
+                  cfg->outputs[index].subdev_name)) {
+               /* Need to switch the encoder at the output */
+               sd_index = vpbe_find_encoder_sd_index(cfg, index);
+               if (sd_index < 0) {
+                       ret = -EINVAL;
+                       goto unlock;
+               }
+
+               ret = venc_device->setup_if_config(cfg->outputs[index].if_params);
+               if (ret)
+                       goto unlock;
+       }
+
+       /* Set output at the encoder */
+       ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
+                                      s_routing, 0, enc_out_index, 0);
+       if (ret)
+               goto unlock;
+
+       /*
+        * It is assumed that venc or external encoder will set a default
+        * mode in the sub device. For external encoder or LCD pannel output,
+        * we also need to set up the lcd port for the required mode. So setup
+        * the lcd port for the default mode that is configured in the board
+        * arch/arm/mach-davinci/board-dm355-evm.setup file for the external
+        * encoder.
+        */
+       ret = vpbe_get_mode_info(vpbe_dev,
+                                cfg->outputs[index].default_mode, index);
+       if (!ret) {
+               struct osd_state *osd_device = vpbe_dev->osd_device;
+
+               osd_device->ops.set_left_margin(osd_device,
+                       vpbe_dev->current_timings.left_margin);
+               osd_device->ops.set_top_margin(osd_device,
+               vpbe_dev->current_timings.upper_margin);
+               vpbe_dev->current_sd_index = sd_index;
+               vpbe_dev->current_out_index = index;
+       }
+unlock:
+       mutex_unlock(&vpbe_dev->lock);
+       return ret;
+}
+
+static int vpbe_set_default_output(struct vpbe_device *vpbe_dev)
+{
+       struct vpbe_config *cfg = vpbe_dev->cfg;
+       int i;
+
+       for (i = 0; i < cfg->num_outputs; i++) {
+               if (!strcmp(def_output,
+                           cfg->outputs[i].output.name)) {
+                       int ret = vpbe_set_output(vpbe_dev, i);
+
+                       if (!ret)
+                               vpbe_dev->current_out_index = i;
+                       return ret;
+               }
+       }
+       return 0;
+}
+
+/**
+ * vpbe_get_output - Get output
+ * @vpbe_dev: vpbe device ptr
+ *
+ * return current vpbe output to the the index
+ */
+static unsigned int vpbe_get_output(struct vpbe_device *vpbe_dev)
+{
+       return vpbe_dev->current_out_index;
+}
+
+/*
+ * vpbe_s_dv_timings - Set the given preset timings in the encoder
+ *
+ * Sets the timings if supported by the current encoder. Return the status.
+ * 0 - success & -EINVAL on error
+ */
+static int vpbe_s_dv_timings(struct vpbe_device *vpbe_dev,
+                   struct v4l2_dv_timings *dv_timings)
+{
+       struct vpbe_config *cfg = vpbe_dev->cfg;
+       int out_index = vpbe_dev->current_out_index;
+       struct vpbe_output *output = &cfg->outputs[out_index];
+       int sd_index = vpbe_dev->current_sd_index;
+       int ret, i;
+
+
+       if (!(cfg->outputs[out_index].output.capabilities &
+           V4L2_OUT_CAP_DV_TIMINGS))
+               return -ENODATA;
+
+       for (i = 0; i < output->num_modes; i++) {
+               if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS &&
+                   !memcmp(&output->modes[i].dv_timings,
+                               dv_timings, sizeof(*dv_timings)))
+                       break;
+       }
+       if (i >= output->num_modes)
+               return -EINVAL;
+       vpbe_dev->current_timings = output->modes[i];
+       mutex_lock(&vpbe_dev->lock);
+
+       ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
+                                       s_dv_timings, dv_timings);
+       if (!ret && vpbe_dev->amp) {
+               /* Call amplifier subdevice */
+               ret = v4l2_subdev_call(vpbe_dev->amp, video,
+                               s_dv_timings, dv_timings);
+       }
+       /* set the lcd controller output for the given mode */
+       if (!ret) {
+               struct osd_state *osd_device = vpbe_dev->osd_device;
+
+               osd_device->ops.set_left_margin(osd_device,
+               vpbe_dev->current_timings.left_margin);
+               osd_device->ops.set_top_margin(osd_device,
+               vpbe_dev->current_timings.upper_margin);
+       }
+       mutex_unlock(&vpbe_dev->lock);
+
+       return ret;
+}
+
+/*
+ * vpbe_g_dv_timings - Get the timings in the current encoder
+ *
+ * Get the timings in the current encoder. Return the status. 0 - success
+ * -EINVAL on error
+ */
+static int vpbe_g_dv_timings(struct vpbe_device *vpbe_dev,
+                    struct v4l2_dv_timings *dv_timings)
+{
+       struct vpbe_config *cfg = vpbe_dev->cfg;
+       int out_index = vpbe_dev->current_out_index;
+
+       if (!(cfg->outputs[out_index].output.capabilities &
+               V4L2_OUT_CAP_DV_TIMINGS))
+               return -ENODATA;
+
+       if (vpbe_dev->current_timings.timings_type &
+         VPBE_ENC_DV_TIMINGS) {
+               *dv_timings = vpbe_dev->current_timings.dv_timings;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+/*
+ * vpbe_enum_dv_timings - Enumerate the dv timings in the current encoder
+ *
+ * Get the timings in the current encoder. Return the status. 0 - success
+ * -EINVAL on error
+ */
+static int vpbe_enum_dv_timings(struct vpbe_device *vpbe_dev,
+                        struct v4l2_enum_dv_timings *timings)
+{
+       struct vpbe_config *cfg = vpbe_dev->cfg;
+       int out_index = vpbe_dev->current_out_index;
+       struct vpbe_output *output = &cfg->outputs[out_index];
+       int j = 0;
+       int i;
+
+       if (!(output->output.capabilities & V4L2_OUT_CAP_DV_TIMINGS))
+               return -ENODATA;
+
+       for (i = 0; i < output->num_modes; i++) {
+               if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS) {
+                       if (j == timings->index)
+                               break;
+                       j++;
+               }
+       }
+
+       if (i == output->num_modes)
+               return -EINVAL;
+       timings->timings = output->modes[i].dv_timings;
+       return 0;
+}
+
+/*
+ * vpbe_s_std - Set the given standard in the encoder
+ *
+ * Sets the standard if supported by the current encoder. Return the status.
+ * 0 - success & -EINVAL on error
+ */
+static int vpbe_s_std(struct vpbe_device *vpbe_dev, v4l2_std_id std_id)
+{
+       struct vpbe_config *cfg = vpbe_dev->cfg;
+       int out_index = vpbe_dev->current_out_index;
+       int sd_index = vpbe_dev->current_sd_index;
+       int ret;
+
+       if (!(cfg->outputs[out_index].output.capabilities &
+               V4L2_OUT_CAP_STD))
+               return -ENODATA;
+
+       ret = vpbe_get_std_info(vpbe_dev, std_id);
+       if (ret)
+               return ret;
+
+       mutex_lock(&vpbe_dev->lock);
+
+       ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
+                              s_std_output, std_id);
+       /* set the lcd controller output for the given mode */
+       if (!ret) {
+               struct osd_state *osd_device = vpbe_dev->osd_device;
+
+               osd_device->ops.set_left_margin(osd_device,
+               vpbe_dev->current_timings.left_margin);
+               osd_device->ops.set_top_margin(osd_device,
+               vpbe_dev->current_timings.upper_margin);
+       }
+       mutex_unlock(&vpbe_dev->lock);
+
+       return ret;
+}
+
+/*
+ * vpbe_g_std - Get the standard in the current encoder
+ *
+ * Get the standard in the current encoder. Return the status. 0 - success
+ * -EINVAL on error
+ */
+static int vpbe_g_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
+{
+       struct vpbe_enc_mode_info *cur_timings = &vpbe_dev->current_timings;
+       struct vpbe_config *cfg = vpbe_dev->cfg;
+       int out_index = vpbe_dev->current_out_index;
+
+       if (!(cfg->outputs[out_index].output.capabilities & V4L2_OUT_CAP_STD))
+               return -ENODATA;
+
+       if (cur_timings->timings_type & VPBE_ENC_STD) {
+               *std_id = cur_timings->std_id;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+/*
+ * vpbe_set_mode - Set mode in the current encoder using mode info
+ *
+ * Use the mode string to decide what timings to set in the encoder
+ * This is typically useful when fbset command is used to change the current
+ * timings by specifying a string to indicate the timings.
+ */
+static int vpbe_set_mode(struct vpbe_device *vpbe_dev,
+                        struct vpbe_enc_mode_info *mode_info)
+{
+       struct vpbe_enc_mode_info *preset_mode = NULL;
+       struct vpbe_config *cfg = vpbe_dev->cfg;
+       struct v4l2_dv_timings dv_timings;
+       struct osd_state *osd_device;
+       int out_index = vpbe_dev->current_out_index;
+       int i;
+
+       if (!mode_info || !mode_info->name)
+               return -EINVAL;
+
+       for (i = 0; i < cfg->outputs[out_index].num_modes; i++) {
+               if (!strcmp(mode_info->name,
+                    cfg->outputs[out_index].modes[i].name)) {
+                       preset_mode = &cfg->outputs[out_index].modes[i];
+                       /*
+                        * it may be one of the 3 timings type. Check and
+                        * invoke right API
+                        */
+                       if (preset_mode->timings_type & VPBE_ENC_STD)
+                               return vpbe_s_std(vpbe_dev,
+                                                preset_mode->std_id);
+                       if (preset_mode->timings_type &
+                                               VPBE_ENC_DV_TIMINGS) {
+                               dv_timings =
+                                       preset_mode->dv_timings;
+                               return vpbe_s_dv_timings(vpbe_dev, &dv_timings);
+                       }
+               }
+       }
+
+       /* Only custom timing should reach here */
+       if (!preset_mode)
+               return -EINVAL;
+
+       mutex_lock(&vpbe_dev->lock);
+
+       osd_device = vpbe_dev->osd_device;
+       vpbe_dev->current_timings = *preset_mode;
+       osd_device->ops.set_left_margin(osd_device,
+               vpbe_dev->current_timings.left_margin);
+       osd_device->ops.set_top_margin(osd_device,
+               vpbe_dev->current_timings.upper_margin);
+
+       mutex_unlock(&vpbe_dev->lock);
+       return 0;
+}
+
+static int vpbe_set_default_mode(struct vpbe_device *vpbe_dev)
+{
+       int ret;
+
+       ret = vpbe_get_std_info_by_name(vpbe_dev, def_mode);
+       if (ret)
+               return ret;
+
+       /* set the default mode in the encoder */
+       return vpbe_set_mode(vpbe_dev, &vpbe_dev->current_timings);
+}
+
+static int platform_device_get(struct device *dev, void *data)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct vpbe_device *vpbe_dev = data;
+
+       if (strstr(pdev->name, "vpbe-osd"))
+               vpbe_dev->osd_device = platform_get_drvdata(pdev);
+       if (strstr(pdev->name, "vpbe-venc"))
+               vpbe_dev->venc_device = dev_get_platdata(&pdev->dev);
+
+       return 0;
+}
+
+/**
+ * vpbe_initialize() - Initialize the vpbe display controller
+ * @dev: Master and slave device ptr
+ * @vpbe_dev: vpbe device ptr
+ *
+ * Master frame buffer device drivers calls this to initialize vpbe
+ * display controller. This will then registers v4l2 device and the sub
+ * devices and sets a current encoder sub device for display. v4l2 display
+ * device driver is the master and frame buffer display device driver is
+ * the slave. Frame buffer display driver checks the initialized during
+ * probe and exit if not initialized. Returns status.
+ */
+static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
+{
+       struct encoder_config_info *enc_info;
+       struct amp_config_info *amp_info;
+       struct v4l2_subdev **enc_subdev;
+       struct osd_state *osd_device;
+       struct i2c_adapter *i2c_adap;
+       int num_encoders;
+       int ret = 0;
+       int err;
+       int i;
+
+       /*
+        * v4l2 abd FBDev frame buffer devices will get the vpbe_dev pointer
+        * from the platform device by iteration of platform drivers and
+        * matching with device name
+        */
+       if (!vpbe_dev || !dev) {
+               printk(KERN_ERR "Null device pointers.\n");
+               return -ENODEV;
+       }
+
+       if (vpbe_dev->initialized)
+               return 0;
+
+       mutex_lock(&vpbe_dev->lock);
+
+       if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
+               /* We have dac clock available for platform */
+               vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac");
+               if (IS_ERR(vpbe_dev->dac_clk)) {
+                       ret =  PTR_ERR(vpbe_dev->dac_clk);
+                       goto fail_mutex_unlock;
+               }
+               if (clk_prepare_enable(vpbe_dev->dac_clk)) {
+                       ret =  -ENODEV;
+                       clk_put(vpbe_dev->dac_clk);
+                       goto fail_mutex_unlock;
+               }
+       }
+
+       /* first enable vpss clocks */
+       vpss_enable_clock(VPSS_VPBE_CLOCK, 1);
+
+       /* First register a v4l2 device */
+       ret = v4l2_device_register(dev, &vpbe_dev->v4l2_dev);
+       if (ret) {
+               v4l2_err(dev->driver,
+                       "Unable to register v4l2 device.\n");
+               goto fail_clk_put;
+       }
+       v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n");
+
+       err = bus_for_each_dev(&platform_bus_type, NULL, vpbe_dev,
+                              platform_device_get);
+       if (err < 0) {
+               ret = err;
+               goto fail_dev_unregister;
+       }
+
+       vpbe_dev->venc = venc_sub_dev_init(&vpbe_dev->v4l2_dev,
+                                          vpbe_dev->cfg->venc.module_name);
+       /* register venc sub device */
+       if (!vpbe_dev->venc) {
+               v4l2_err(&vpbe_dev->v4l2_dev,
+                       "vpbe unable to init venc sub device\n");
+               ret = -ENODEV;
+               goto fail_dev_unregister;
+       }
+       /* initialize osd device */
+       osd_device = vpbe_dev->osd_device;
+       if (osd_device->ops.initialize) {
+               err = osd_device->ops.initialize(osd_device);
+               if (err) {
+                       v4l2_err(&vpbe_dev->v4l2_dev,
+                                "unable to initialize the OSD device");
+                       ret = -ENOMEM;
+                       goto fail_dev_unregister;
+               }
+       }
+
+       /*
+        * Register any external encoders that are configured. At index 0 we
+        * store venc sd index.
+        */
+       num_encoders = vpbe_dev->cfg->num_ext_encoders + 1;
+       vpbe_dev->encoders = kmalloc_array(num_encoders,
+                                          sizeof(*vpbe_dev->encoders),
+                                          GFP_KERNEL);
+       if (!vpbe_dev->encoders) {
+               ret = -ENOMEM;
+               goto fail_dev_unregister;
+       }
+
+       i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id);
+       for (i = 0; i < (vpbe_dev->cfg->num_ext_encoders + 1); i++) {
+               if (i == 0) {
+                       /* venc is at index 0 */
+                       enc_subdev = &vpbe_dev->encoders[i];
+                       *enc_subdev = vpbe_dev->venc;
+                       continue;
+               }
+               enc_info = &vpbe_dev->cfg->ext_encoders[i];
+               if (enc_info->is_i2c) {
+                       enc_subdev = &vpbe_dev->encoders[i];
+                       *enc_subdev = v4l2_i2c_new_subdev_board(
+                                               &vpbe_dev->v4l2_dev, i2c_adap,
+                                               &enc_info->board_info, NULL);
+                       if (*enc_subdev)
+                               v4l2_info(&vpbe_dev->v4l2_dev,
+                                         "v4l2 sub device %s registered\n",
+                                         enc_info->module_name);
+                       else {
+                               v4l2_err(&vpbe_dev->v4l2_dev, "encoder %s failed to register",
+                                        enc_info->module_name);
+                               ret = -ENODEV;
+                               goto fail_kfree_encoders;
+                       }
+               } else
+                       v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders currently not supported");
+       }
+       /* Add amplifier subdevice for dm365 */
+       if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) &&
+          vpbe_dev->cfg->amp) {
+               amp_info = vpbe_dev->cfg->amp;
+               if (amp_info->is_i2c) {
+                       vpbe_dev->amp = v4l2_i2c_new_subdev_board(
+                       &vpbe_dev->v4l2_dev, i2c_adap,
+                       &amp_info->board_info, NULL);
+                       if (!vpbe_dev->amp) {
+                               v4l2_err(&vpbe_dev->v4l2_dev,
+                                        "amplifier %s failed to register",
+                                        amp_info->module_name);
+                               ret = -ENODEV;
+                               goto fail_kfree_encoders;
+                       }
+                       v4l2_info(&vpbe_dev->v4l2_dev,
+                                         "v4l2 sub device %s registered\n",
+                                         amp_info->module_name);
+               } else {
+                           vpbe_dev->amp = NULL;
+                           v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers currently not supported");
+               }
+       } else {
+           vpbe_dev->amp = NULL;
+       }
+
+       /* set the current encoder and output to that of venc by default */
+       vpbe_dev->current_sd_index = 0;
+       vpbe_dev->current_out_index = 0;
+
+       mutex_unlock(&vpbe_dev->lock);
+
+       printk(KERN_NOTICE "Setting default output to %s\n", def_output);
+       ret = vpbe_set_default_output(vpbe_dev);
+       if (ret) {
+               v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default output %s",
+                        def_output);
+               goto fail_kfree_amp;
+       }
+
+       printk(KERN_NOTICE "Setting default mode to %s\n", def_mode);
+       ret = vpbe_set_default_mode(vpbe_dev);
+       if (ret) {
+               v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default mode %s",
+                        def_mode);
+               goto fail_kfree_amp;
+       }
+       vpbe_dev->initialized = 1;
+       /* TBD handling of bootargs for default output and mode */
+       return 0;
+
+fail_kfree_amp:
+       mutex_lock(&vpbe_dev->lock);
+       kfree(vpbe_dev->amp);
+fail_kfree_encoders:
+       kfree(vpbe_dev->encoders);
+fail_dev_unregister:
+       v4l2_device_unregister(&vpbe_dev->v4l2_dev);
+fail_clk_put:
+       if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
+               clk_disable_unprepare(vpbe_dev->dac_clk);
+               clk_put(vpbe_dev->dac_clk);
+       }
+fail_mutex_unlock:
+       mutex_unlock(&vpbe_dev->lock);
+       return ret;
+}
+
+/**
+ * vpbe_deinitialize() - de-initialize the vpbe display controller
+ * @dev: Master and slave device ptr
+ * @vpbe_dev: vpbe device ptr
+ *
+ * vpbe_master and slave frame buffer devices calls this to de-initialize
+ * the display controller. It is called when master and slave device
+ * driver modules are removed and no longer requires the display controller.
+ */
+static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev)
+{
+       v4l2_device_unregister(&vpbe_dev->v4l2_dev);
+       if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
+               clk_disable_unprepare(vpbe_dev->dac_clk);
+               clk_put(vpbe_dev->dac_clk);
+       }
+
+       kfree(vpbe_dev->amp);
+       kfree(vpbe_dev->encoders);
+       vpbe_dev->initialized = 0;
+       /* disable vpss clocks */
+       vpss_enable_clock(VPSS_VPBE_CLOCK, 0);
+}
+
+static const struct vpbe_device_ops vpbe_dev_ops = {
+       .enum_outputs = vpbe_enum_outputs,
+       .set_output = vpbe_set_output,
+       .get_output = vpbe_get_output,
+       .s_dv_timings = vpbe_s_dv_timings,
+       .g_dv_timings = vpbe_g_dv_timings,
+       .enum_dv_timings = vpbe_enum_dv_timings,
+       .s_std = vpbe_s_std,
+       .g_std = vpbe_g_std,
+       .initialize = vpbe_initialize,
+       .deinitialize = vpbe_deinitialize,
+       .get_mode_info = vpbe_get_current_mode_info,
+       .set_mode = vpbe_set_mode,
+};
+
+static int vpbe_probe(struct platform_device *pdev)
+{
+       struct vpbe_device *vpbe_dev;
+       struct vpbe_config *cfg;
+
+       if (!pdev->dev.platform_data) {
+               v4l2_err(pdev->dev.driver, "No platform data\n");
+               return -ENODEV;
+       }
+       cfg = pdev->dev.platform_data;
+
+       if (!cfg->module_name[0] ||
+           !cfg->osd.module_name[0] ||
+           !cfg->venc.module_name[0]) {
+               v4l2_err(pdev->dev.driver, "vpbe display module names not defined\n");
+               return -EINVAL;
+       }
+
+       vpbe_dev = kzalloc(sizeof(*vpbe_dev), GFP_KERNEL);
+       if (!vpbe_dev)
+               return -ENOMEM;
+
+       vpbe_dev->cfg = cfg;
+       vpbe_dev->ops = vpbe_dev_ops;
+       vpbe_dev->pdev = &pdev->dev;
+
+       if (cfg->outputs->num_modes > 0)
+               vpbe_dev->current_timings = vpbe_dev->cfg->outputs[0].modes[0];
+       else {
+               kfree(vpbe_dev);
+               return -ENODEV;
+       }
+
+       /* set the driver data in platform device */
+       platform_set_drvdata(pdev, vpbe_dev);
+       mutex_init(&vpbe_dev->lock);
+
+       return 0;
+}
+
+static int vpbe_remove(struct platform_device *device)
+{
+       struct vpbe_device *vpbe_dev = platform_get_drvdata(device);
+
+       kfree(vpbe_dev);
+
+       return 0;
+}
+
+static struct platform_driver vpbe_driver = {
+       .driver = {
+               .name   = "vpbe_controller",
+       },
+       .probe = vpbe_probe,
+       .remove = vpbe_remove,
+};
+
+module_platform_driver(vpbe_driver);
diff --git a/drivers/media/platform/ti/davinci/vpbe_display.c b/drivers/media/platform/ti/davinci/vpbe_display.c
new file mode 100644 (file)
index 0000000..bf3c3e7
--- /dev/null
@@ -0,0 +1,1512 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/davinci/vpbe_display.h>
+#include <media/davinci/vpbe_types.h>
+#include <media/davinci/vpbe.h>
+#include <media/davinci/vpbe_venc.h>
+#include <media/davinci/vpbe_osd.h>
+#include "vpbe_venc_regs.h"
+
+#define VPBE_DISPLAY_DRIVER "vpbe-v4l2"
+
+static int debug;
+
+#define VPBE_DEFAULT_NUM_BUFS 3
+
+module_param(debug, int, 0644);
+
+static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
+                       struct vpbe_layer *layer);
+
+static int venc_is_second_field(struct vpbe_display *disp_dev)
+{
+       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
+       int ret, val;
+
+       ret = v4l2_subdev_call(vpbe_dev->venc,
+                              core,
+                              command,
+                              VENC_GET_FLD,
+                              &val);
+       if (ret < 0) {
+               v4l2_err(&vpbe_dev->v4l2_dev,
+                        "Error in getting Field ID 0\n");
+               return 1;
+       }
+       return val;
+}
+
+static void vpbe_isr_even_field(struct vpbe_display *disp_obj,
+                               struct vpbe_layer *layer)
+{
+       if (layer->cur_frm == layer->next_frm)
+               return;
+
+       layer->cur_frm->vb.vb2_buf.timestamp = ktime_get_ns();
+       vb2_buffer_done(&layer->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
+       /* Make cur_frm pointing to next_frm */
+       layer->cur_frm = layer->next_frm;
+}
+
+static void vpbe_isr_odd_field(struct vpbe_display *disp_obj,
+                               struct vpbe_layer *layer)
+{
+       struct osd_state *osd_device = disp_obj->osd_device;
+       unsigned long addr;
+
+       spin_lock(&disp_obj->dma_queue_lock);
+       if (list_empty(&layer->dma_queue) ||
+               (layer->cur_frm != layer->next_frm)) {
+               spin_unlock(&disp_obj->dma_queue_lock);
+               return;
+       }
+       /*
+        * one field is displayed configure
+        * the next frame if it is available
+        * otherwise hold on current frame
+        * Get next from the buffer queue
+        */
+       layer->next_frm = list_entry(layer->dma_queue.next,
+                         struct  vpbe_disp_buffer, list);
+       /* Remove that from the buffer queue */
+       list_del(&layer->next_frm->list);
+       spin_unlock(&disp_obj->dma_queue_lock);
+       /* Mark state of the frame to active */
+       layer->next_frm->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
+       addr = vb2_dma_contig_plane_dma_addr(&layer->next_frm->vb.vb2_buf, 0);
+       osd_device->ops.start_layer(osd_device,
+                       layer->layer_info.id,
+                       addr,
+                       disp_obj->cbcr_ofst);
+}
+
+/* interrupt service routine */
+static irqreturn_t venc_isr(int irq, void *arg)
+{
+       struct vpbe_display *disp_dev = (struct vpbe_display *)arg;
+       struct vpbe_layer *layer;
+       static unsigned last_event;
+       unsigned event = 0;
+       int fid;
+       int i;
+
+       if (!arg || !disp_dev->dev[0])
+               return IRQ_HANDLED;
+
+       if (venc_is_second_field(disp_dev))
+               event |= VENC_SECOND_FIELD;
+       else
+               event |= VENC_FIRST_FIELD;
+
+       if (event == (last_event & ~VENC_END_OF_FRAME)) {
+               /*
+               * If the display is non-interlaced, then we need to flag the
+               * end-of-frame event at every interrupt regardless of the
+               * value of the FIDST bit.  We can conclude that the display is
+               * non-interlaced if the value of the FIDST bit is unchanged
+               * from the previous interrupt.
+               */
+               event |= VENC_END_OF_FRAME;
+       } else if (event == VENC_SECOND_FIELD) {
+               /* end-of-frame for interlaced display */
+               event |= VENC_END_OF_FRAME;
+       }
+       last_event = event;
+
+       for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
+               layer = disp_dev->dev[i];
+
+               if (!vb2_start_streaming_called(&layer->buffer_queue))
+                       continue;
+
+               if (layer->layer_first_int) {
+                       layer->layer_first_int = 0;
+                       continue;
+               }
+               /* Check the field format */
+               if ((V4L2_FIELD_NONE == layer->pix_fmt.field) &&
+                       (event & VENC_END_OF_FRAME)) {
+                       /* Progressive mode */
+
+                       vpbe_isr_even_field(disp_dev, layer);
+                       vpbe_isr_odd_field(disp_dev, layer);
+               } else {
+               /* Interlaced mode */
+
+                       layer->field_id ^= 1;
+                       if (event & VENC_FIRST_FIELD)
+                               fid = 0;
+                       else
+                               fid = 1;
+
+                       /*
+                       * If field id does not match with store
+                       * field id
+                       */
+                       if (fid != layer->field_id) {
+                               /* Make them in sync */
+                               layer->field_id = fid;
+                               continue;
+                       }
+                       /*
+                       * device field id and local field id are
+                       * in sync. If this is even field
+                       */
+                       if (0 == fid)
+                               vpbe_isr_even_field(disp_dev, layer);
+                       else  /* odd field */
+                               vpbe_isr_odd_field(disp_dev, layer);
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * vpbe_buffer_prepare()
+ * This is the callback function called from vb2_qbuf() function
+ * the buffer is prepared and user space virtual address is converted into
+ * physical address
+ */
+static int vpbe_buffer_prepare(struct vb2_buffer *vb)
+{
+       struct vb2_queue *q = vb->vb2_queue;
+       struct vpbe_layer *layer = vb2_get_drv_priv(q);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+       unsigned long addr;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
+                               "vpbe_buffer_prepare\n");
+
+       vb2_set_plane_payload(vb, 0, layer->pix_fmt.sizeimage);
+       if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
+               return -EINVAL;
+
+       addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+       if (!IS_ALIGNED(addr, 8)) {
+               v4l2_err(&vpbe_dev->v4l2_dev,
+                        "buffer_prepare:offset is not aligned to 32 bytes\n");
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/*
+ * vpbe_buffer_setup()
+ * This function allocates memory for the buffers
+ */
+static int
+vpbe_buffer_queue_setup(struct vb2_queue *vq,
+                       unsigned int *nbuffers, unsigned int *nplanes,
+                       unsigned int sizes[], struct device *alloc_devs[])
+
+{
+       /* Get the file handle object and layer object */
+       struct vpbe_layer *layer = vb2_get_drv_priv(vq);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n");
+
+       /* Store number of buffers allocated in numbuffer member */
+       if (vq->num_buffers + *nbuffers < VPBE_DEFAULT_NUM_BUFS)
+               *nbuffers = VPBE_DEFAULT_NUM_BUFS - vq->num_buffers;
+
+       if (*nplanes)
+               return sizes[0] < layer->pix_fmt.sizeimage ? -EINVAL : 0;
+
+       *nplanes = 1;
+       sizes[0] = layer->pix_fmt.sizeimage;
+
+       return 0;
+}
+
+/*
+ * vpbe_buffer_queue()
+ * This function adds the buffer to DMA queue
+ */
+static void vpbe_buffer_queue(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       /* Get the file handle object and layer object */
+       struct vpbe_disp_buffer *buf = container_of(vbuf,
+                               struct vpbe_disp_buffer, vb);
+       struct vpbe_layer *layer = vb2_get_drv_priv(vb->vb2_queue);
+       struct vpbe_display *disp = layer->disp_dev;
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+       unsigned long flags;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
+                       "vpbe_buffer_queue\n");
+
+       /* add the buffer to the DMA queue */
+       spin_lock_irqsave(&disp->dma_queue_lock, flags);
+       list_add_tail(&buf->list, &layer->dma_queue);
+       spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
+}
+
+static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+       struct vpbe_layer *layer = vb2_get_drv_priv(vq);
+       struct osd_state *osd_device = layer->disp_dev->osd_device;
+       int ret;
+
+       osd_device->ops.disable_layer(osd_device, layer->layer_info.id);
+
+       /* Get the next frame from the buffer queue */
+       layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next,
+                               struct vpbe_disp_buffer, list);
+       /* Remove buffer from the buffer queue */
+       list_del(&layer->cur_frm->list);
+       /* Mark state of the current frame to active */
+       layer->cur_frm->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
+       /* Initialize field_id and started member */
+       layer->field_id = 0;
+
+       /* Set parameters in OSD and VENC */
+       ret = vpbe_set_osd_display_params(layer->disp_dev, layer);
+       if (ret < 0) {
+               struct vpbe_disp_buffer *buf, *tmp;
+
+               vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
+                               VB2_BUF_STATE_QUEUED);
+               list_for_each_entry_safe(buf, tmp, &layer->dma_queue, list) {
+                       list_del(&buf->list);
+                       vb2_buffer_done(&buf->vb.vb2_buf,
+                                       VB2_BUF_STATE_QUEUED);
+               }
+
+               return ret;
+       }
+
+       /*
+        * if request format is yuv420 semiplanar, need to
+        * enable both video windows
+        */
+       layer->layer_first_int = 1;
+
+       return ret;
+}
+
+static void vpbe_stop_streaming(struct vb2_queue *vq)
+{
+       struct vpbe_layer *layer = vb2_get_drv_priv(vq);
+       struct osd_state *osd_device = layer->disp_dev->osd_device;
+       struct vpbe_display *disp = layer->disp_dev;
+       unsigned long flags;
+
+       if (!vb2_is_streaming(vq))
+               return;
+
+       osd_device->ops.disable_layer(osd_device, layer->layer_info.id);
+
+       /* release all active buffers */
+       spin_lock_irqsave(&disp->dma_queue_lock, flags);
+       if (layer->cur_frm == layer->next_frm) {
+               vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
+                               VB2_BUF_STATE_ERROR);
+       } else {
+               if (layer->cur_frm)
+                       vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
+                                       VB2_BUF_STATE_ERROR);
+               if (layer->next_frm)
+                       vb2_buffer_done(&layer->next_frm->vb.vb2_buf,
+                                       VB2_BUF_STATE_ERROR);
+       }
+
+       while (!list_empty(&layer->dma_queue)) {
+               layer->next_frm = list_entry(layer->dma_queue.next,
+                                               struct vpbe_disp_buffer, list);
+               list_del(&layer->next_frm->list);
+               vb2_buffer_done(&layer->next_frm->vb.vb2_buf,
+                               VB2_BUF_STATE_ERROR);
+       }
+       spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
+}
+
+static const struct vb2_ops video_qops = {
+       .queue_setup = vpbe_buffer_queue_setup,
+       .wait_prepare = vb2_ops_wait_prepare,
+       .wait_finish = vb2_ops_wait_finish,
+       .buf_prepare = vpbe_buffer_prepare,
+       .start_streaming = vpbe_start_streaming,
+       .stop_streaming = vpbe_stop_streaming,
+       .buf_queue = vpbe_buffer_queue,
+};
+
+static
+struct vpbe_layer*
+_vpbe_display_get_other_win_layer(struct vpbe_display *disp_dev,
+                       struct vpbe_layer *layer)
+{
+       enum vpbe_display_device_id thiswin, otherwin;
+       thiswin = layer->device_id;
+
+       otherwin = (thiswin == VPBE_DISPLAY_DEVICE_0) ?
+       VPBE_DISPLAY_DEVICE_1 : VPBE_DISPLAY_DEVICE_0;
+       return disp_dev->dev[otherwin];
+}
+
+static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
+                       struct vpbe_layer *layer)
+{
+       struct osd_layer_config *cfg  = &layer->layer_info.config;
+       struct osd_state *osd_device = disp_dev->osd_device;
+       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
+       unsigned long addr;
+       int ret;
+
+       addr = vb2_dma_contig_plane_dma_addr(&layer->cur_frm->vb.vb2_buf, 0);
+       /* Set address in the display registers */
+       osd_device->ops.start_layer(osd_device,
+                                   layer->layer_info.id,
+                                   addr,
+                                   disp_dev->cbcr_ofst);
+
+       ret = osd_device->ops.enable_layer(osd_device,
+                               layer->layer_info.id, 0);
+       if (ret < 0) {
+               v4l2_err(&vpbe_dev->v4l2_dev,
+                       "Error in enabling osd window layer 0\n");
+               return -1;
+       }
+
+       /* Enable the window */
+       layer->layer_info.enable = 1;
+       if (cfg->pixfmt == PIXFMT_NV12) {
+               struct vpbe_layer *otherlayer =
+                       _vpbe_display_get_other_win_layer(disp_dev, layer);
+
+               ret = osd_device->ops.enable_layer(osd_device,
+                               otherlayer->layer_info.id, 1);
+               if (ret < 0) {
+                       v4l2_err(&vpbe_dev->v4l2_dev,
+                               "Error in enabling osd window layer 1\n");
+                       return -1;
+               }
+               otherlayer->layer_info.enable = 1;
+       }
+       return 0;
+}
+
+static void
+vpbe_disp_calculate_scale_factor(struct vpbe_display *disp_dev,
+                       struct vpbe_layer *layer,
+                       int expected_xsize, int expected_ysize)
+{
+       struct display_layer_info *layer_info = &layer->layer_info;
+       struct v4l2_pix_format *pixfmt = &layer->pix_fmt;
+       struct osd_layer_config *cfg  = &layer->layer_info.config;
+       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
+       int calculated_xsize;
+       int h_exp = 0;
+       int v_exp = 0;
+       int h_scale;
+       int v_scale;
+
+       v4l2_std_id standard_id = vpbe_dev->current_timings.std_id;
+
+       /*
+        * Application initially set the image format. Current display
+        * size is obtained from the vpbe display controller. expected_xsize
+        * and expected_ysize are set through S_SELECTION ioctl. Based on this,
+        * driver will calculate the scale factors for vertical and
+        * horizontal direction so that the image is displayed scaled
+        * and expanded. Application uses expansion to display the image
+        * in a square pixel. Otherwise it is displayed using displays
+        * pixel aspect ratio.It is expected that application chooses
+        * the crop coordinates for cropped or scaled display. if crop
+        * size is less than the image size, it is displayed cropped or
+        * it is displayed scaled and/or expanded.
+        *
+        * to begin with, set the crop window same as expected. Later we
+        * will override with scaled window size
+        */
+
+       cfg->xsize = pixfmt->width;
+       cfg->ysize = pixfmt->height;
+       layer_info->h_zoom = ZOOM_X1;   /* no horizontal zoom */
+       layer_info->v_zoom = ZOOM_X1;   /* no horizontal zoom */
+       layer_info->h_exp = H_EXP_OFF;  /* no horizontal zoom */
+       layer_info->v_exp = V_EXP_OFF;  /* no horizontal zoom */
+
+       if (pixfmt->width < expected_xsize) {
+               h_scale = vpbe_dev->current_timings.xres / pixfmt->width;
+               if (h_scale < 2)
+                       h_scale = 1;
+               else if (h_scale >= 4)
+                       h_scale = 4;
+               else
+                       h_scale = 2;
+               cfg->xsize *= h_scale;
+               if (cfg->xsize < expected_xsize) {
+                       if ((standard_id & V4L2_STD_525_60) ||
+                       (standard_id & V4L2_STD_625_50)) {
+                               calculated_xsize = (cfg->xsize *
+                                       VPBE_DISPLAY_H_EXP_RATIO_N) /
+                                       VPBE_DISPLAY_H_EXP_RATIO_D;
+                               if (calculated_xsize <= expected_xsize) {
+                                       h_exp = 1;
+                                       cfg->xsize = calculated_xsize;
+                               }
+                       }
+               }
+               if (h_scale == 2)
+                       layer_info->h_zoom = ZOOM_X2;
+               else if (h_scale == 4)
+                       layer_info->h_zoom = ZOOM_X4;
+               if (h_exp)
+                       layer_info->h_exp = H_EXP_9_OVER_8;
+       } else {
+               /* no scaling, only cropping. Set display area to crop area */
+               cfg->xsize = expected_xsize;
+       }
+
+       if (pixfmt->height < expected_ysize) {
+               v_scale = expected_ysize / pixfmt->height;
+               if (v_scale < 2)
+                       v_scale = 1;
+               else if (v_scale >= 4)
+                       v_scale = 4;
+               else
+                       v_scale = 2;
+               cfg->ysize *= v_scale;
+               if (cfg->ysize < expected_ysize) {
+                       if ((standard_id & V4L2_STD_625_50)) {
+                               calculated_xsize = (cfg->ysize *
+                                       VPBE_DISPLAY_V_EXP_RATIO_N) /
+                                       VPBE_DISPLAY_V_EXP_RATIO_D;
+                               if (calculated_xsize <= expected_ysize) {
+                                       v_exp = 1;
+                                       cfg->ysize = calculated_xsize;
+                               }
+                       }
+               }
+               if (v_scale == 2)
+                       layer_info->v_zoom = ZOOM_X2;
+               else if (v_scale == 4)
+                       layer_info->v_zoom = ZOOM_X4;
+               if (v_exp)
+                       layer_info->v_exp = V_EXP_6_OVER_5;
+       } else {
+               /* no scaling, only cropping. Set display area to crop area */
+               cfg->ysize = expected_ysize;
+       }
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
+               "crop display xsize = %d, ysize = %d\n",
+               cfg->xsize, cfg->ysize);
+}
+
+static void vpbe_disp_adj_position(struct vpbe_display *disp_dev,
+                       struct vpbe_layer *layer,
+                       int top, int left)
+{
+       struct osd_layer_config *cfg = &layer->layer_info.config;
+       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
+
+       cfg->xpos = min((unsigned int)left,
+                       vpbe_dev->current_timings.xres - cfg->xsize);
+       cfg->ypos = min((unsigned int)top,
+                       vpbe_dev->current_timings.yres - cfg->ysize);
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
+               "new xpos = %d, ypos = %d\n",
+               cfg->xpos, cfg->ypos);
+}
+
+static void vpbe_disp_check_window_params(struct vpbe_display *disp_dev,
+                       struct v4l2_rect *c)
+{
+       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
+
+       if ((c->width == 0) ||
+         ((c->width + c->left) > vpbe_dev->current_timings.xres))
+               c->width = vpbe_dev->current_timings.xres - c->left;
+
+       if ((c->height == 0) || ((c->height + c->top) >
+         vpbe_dev->current_timings.yres))
+               c->height = vpbe_dev->current_timings.yres - c->top;
+
+       /* window height must be even for interlaced display */
+       if (vpbe_dev->current_timings.interlaced)
+               c->height &= (~0x01);
+
+}
+
+/*
+ * vpbe_try_format()
+ * If user application provides width and height, and have bytesperline set
+ * to zero, driver calculates bytesperline and sizeimage based on hardware
+ * limits.
+ */
+static int vpbe_try_format(struct vpbe_display *disp_dev,
+                       struct v4l2_pix_format *pixfmt, int check)
+{
+       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
+       int min_height = 1;
+       int min_width = 32;
+       int max_height;
+       int max_width;
+       int bpp;
+
+       if ((pixfmt->pixelformat != V4L2_PIX_FMT_UYVY) &&
+           (pixfmt->pixelformat != V4L2_PIX_FMT_NV12))
+               /* choose default as V4L2_PIX_FMT_UYVY */
+               pixfmt->pixelformat = V4L2_PIX_FMT_UYVY;
+
+       /* Check the field format */
+       if ((pixfmt->field != V4L2_FIELD_INTERLACED) &&
+               (pixfmt->field != V4L2_FIELD_NONE)) {
+               if (vpbe_dev->current_timings.interlaced)
+                       pixfmt->field = V4L2_FIELD_INTERLACED;
+               else
+                       pixfmt->field = V4L2_FIELD_NONE;
+       }
+
+       if (pixfmt->field == V4L2_FIELD_INTERLACED)
+               min_height = 2;
+
+       if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
+               bpp = 1;
+       else
+               bpp = 2;
+
+       max_width = vpbe_dev->current_timings.xres;
+       max_height = vpbe_dev->current_timings.yres;
+
+       min_width /= bpp;
+
+       if (!pixfmt->width || (pixfmt->width < min_width) ||
+               (pixfmt->width > max_width)) {
+               pixfmt->width = vpbe_dev->current_timings.xres;
+       }
+
+       if (!pixfmt->height || (pixfmt->height  < min_height) ||
+               (pixfmt->height  > max_height)) {
+               pixfmt->height = vpbe_dev->current_timings.yres;
+       }
+
+       if (pixfmt->bytesperline < (pixfmt->width * bpp))
+               pixfmt->bytesperline = pixfmt->width * bpp;
+
+       /* Make the bytesperline 32 byte aligned */
+       pixfmt->bytesperline = ((pixfmt->width * bpp + 31) & ~31);
+
+       if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
+               pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height +
+                               (pixfmt->bytesperline * pixfmt->height >> 1);
+       else
+               pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
+
+       return 0;
+}
+
+static int vpbe_display_querycap(struct file *file, void  *priv,
+                              struct v4l2_capability *cap)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+
+       snprintf(cap->driver, sizeof(cap->driver), "%s",
+               dev_name(vpbe_dev->pdev));
+       snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+                dev_name(vpbe_dev->pdev));
+       strscpy(cap->card, vpbe_dev->cfg->module_name, sizeof(cap->card));
+
+       return 0;
+}
+
+static int vpbe_display_s_selection(struct file *file, void *priv,
+                            struct v4l2_selection *sel)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_display *disp_dev = layer->disp_dev;
+       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
+       struct osd_layer_config *cfg = &layer->layer_info.config;
+       struct osd_state *osd_device = disp_dev->osd_device;
+       struct v4l2_rect rect = sel->r;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
+               "VIDIOC_S_SELECTION, layer id = %d\n", layer->device_id);
+
+       if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
+           sel->target != V4L2_SEL_TGT_CROP)
+               return -EINVAL;
+
+       if (rect.top < 0)
+               rect.top = 0;
+       if (rect.left < 0)
+               rect.left = 0;
+
+       vpbe_disp_check_window_params(disp_dev, &rect);
+
+       osd_device->ops.get_layer_config(osd_device,
+                       layer->layer_info.id, cfg);
+
+       vpbe_disp_calculate_scale_factor(disp_dev, layer,
+                                       rect.width,
+                                       rect.height);
+       vpbe_disp_adj_position(disp_dev, layer, rect.top,
+                                       rect.left);
+       ret = osd_device->ops.set_layer_config(osd_device,
+                               layer->layer_info.id, cfg);
+       if (ret < 0) {
+               v4l2_err(&vpbe_dev->v4l2_dev,
+                       "Error in set layer config:\n");
+               return -EINVAL;
+       }
+
+       /* apply zooming and h or v expansion */
+       osd_device->ops.set_zoom(osd_device,
+                       layer->layer_info.id,
+                       layer->layer_info.h_zoom,
+                       layer->layer_info.v_zoom);
+       ret = osd_device->ops.set_vid_expansion(osd_device,
+                       layer->layer_info.h_exp,
+                       layer->layer_info.v_exp);
+       if (ret < 0) {
+               v4l2_err(&vpbe_dev->v4l2_dev,
+               "Error in set vid expansion:\n");
+               return -EINVAL;
+       }
+
+       if ((layer->layer_info.h_zoom != ZOOM_X1) ||
+               (layer->layer_info.v_zoom != ZOOM_X1) ||
+               (layer->layer_info.h_exp != H_EXP_OFF) ||
+               (layer->layer_info.v_exp != V_EXP_OFF))
+               /* Enable expansion filter */
+               osd_device->ops.set_interpolation_filter(osd_device, 1);
+       else
+               osd_device->ops.set_interpolation_filter(osd_device, 0);
+
+       sel->r = rect;
+       return 0;
+}
+
+static int vpbe_display_g_selection(struct file *file, void *priv,
+                                   struct v4l2_selection *sel)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct osd_layer_config *cfg = &layer->layer_info.config;
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+       struct osd_state *osd_device = layer->disp_dev->osd_device;
+       struct v4l2_rect *rect = &sel->r;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
+                       "VIDIOC_G_SELECTION, layer id = %d\n",
+                       layer->device_id);
+
+       if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+               return -EINVAL;
+
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP:
+               osd_device->ops.get_layer_config(osd_device,
+                                                layer->layer_info.id, cfg);
+               rect->top = cfg->ypos;
+               rect->left = cfg->xpos;
+               rect->width = cfg->xsize;
+               rect->height = cfg->ysize;
+               break;
+       case V4L2_SEL_TGT_CROP_DEFAULT:
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+               rect->left = 0;
+               rect->top = 0;
+               rect->width = vpbe_dev->current_timings.xres;
+               rect->height = vpbe_dev->current_timings.yres;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int vpbe_display_g_pixelaspect(struct file *file, void *priv,
+                                     int type, struct v4l2_fract *f)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_CROPCAP ioctl\n");
+
+       if (type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+               return -EINVAL;
+
+       *f = vpbe_dev->current_timings.aspect;
+       return 0;
+}
+
+static int vpbe_display_g_fmt(struct file *file, void *priv,
+                               struct v4l2_format *fmt)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
+                       "VIDIOC_G_FMT, layer id = %d\n",
+                       layer->device_id);
+
+       /* If buffer type is video output */
+       if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
+               v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
+               return -EINVAL;
+       }
+       /* Fill in the information about format */
+       fmt->fmt.pix = layer->pix_fmt;
+
+       return 0;
+}
+
+static int vpbe_display_enum_fmt(struct file *file, void  *priv,
+                                  struct v4l2_fmtdesc *fmt)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
+                               "VIDIOC_ENUM_FMT, layer id = %d\n",
+                               layer->device_id);
+       if (fmt->index > 1) {
+               v4l2_err(&vpbe_dev->v4l2_dev, "Invalid format index\n");
+               return -EINVAL;
+       }
+
+       /* Fill in the information about format */
+       if (fmt->index == 0)
+               fmt->pixelformat = V4L2_PIX_FMT_UYVY;
+       else
+               fmt->pixelformat = V4L2_PIX_FMT_NV12;
+
+       return 0;
+}
+
+static int vpbe_display_s_fmt(struct file *file, void *priv,
+                               struct v4l2_format *fmt)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_display *disp_dev = layer->disp_dev;
+       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
+       struct osd_layer_config *cfg  = &layer->layer_info.config;
+       struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+       struct osd_state *osd_device = disp_dev->osd_device;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
+                       "VIDIOC_S_FMT, layer id = %d\n",
+                       layer->device_id);
+
+       if (vb2_is_busy(&layer->buffer_queue))
+               return -EBUSY;
+
+       if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
+               v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "invalid type\n");
+               return -EINVAL;
+       }
+       /* Check for valid pixel format */
+       ret = vpbe_try_format(disp_dev, pixfmt, 1);
+       if (ret)
+               return ret;
+
+       /* YUV420 is requested, check availability of the
+       other video window */
+
+       layer->pix_fmt = *pixfmt;
+       if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12) {
+               struct vpbe_layer *otherlayer;
+
+               otherlayer = _vpbe_display_get_other_win_layer(disp_dev, layer);
+               /* if other layer is available, only
+                * claim it, do not configure it
+                */
+               ret = osd_device->ops.request_layer(osd_device,
+                                                   otherlayer->layer_info.id);
+               if (ret < 0) {
+                       v4l2_err(&vpbe_dev->v4l2_dev,
+                                "Display Manager failed to allocate layer\n");
+                       return -EBUSY;
+               }
+       }
+
+       /* Get osd layer config */
+       osd_device->ops.get_layer_config(osd_device,
+                       layer->layer_info.id, cfg);
+       /* Store the pixel format in the layer object */
+       cfg->xsize = pixfmt->width;
+       cfg->ysize = pixfmt->height;
+       cfg->line_length = pixfmt->bytesperline;
+       cfg->ypos = 0;
+       cfg->xpos = 0;
+       cfg->interlaced = vpbe_dev->current_timings.interlaced;
+
+       if (V4L2_PIX_FMT_UYVY == pixfmt->pixelformat)
+               cfg->pixfmt = PIXFMT_YCBCRI;
+
+       /* Change of the default pixel format for both video windows */
+       if (V4L2_PIX_FMT_NV12 == pixfmt->pixelformat) {
+               struct vpbe_layer *otherlayer;
+               cfg->pixfmt = PIXFMT_NV12;
+               otherlayer = _vpbe_display_get_other_win_layer(disp_dev,
+                                                               layer);
+               otherlayer->layer_info.config.pixfmt = PIXFMT_NV12;
+       }
+
+       /* Set the layer config in the osd window */
+       ret = osd_device->ops.set_layer_config(osd_device,
+                               layer->layer_info.id, cfg);
+       if (ret < 0) {
+               v4l2_err(&vpbe_dev->v4l2_dev,
+                               "Error in S_FMT params:\n");
+               return -EINVAL;
+       }
+
+       /* Readback and fill the local copy of current pix format */
+       osd_device->ops.get_layer_config(osd_device,
+                       layer->layer_info.id, cfg);
+
+       return 0;
+}
+
+static int vpbe_display_try_fmt(struct file *file, void *priv,
+                                 struct v4l2_format *fmt)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_display *disp_dev = layer->disp_dev;
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+       struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_TRY_FMT\n");
+
+       if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
+               v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
+               return -EINVAL;
+       }
+
+       /* Check for valid field format */
+       return  vpbe_try_format(disp_dev, pixfmt, 0);
+
+}
+
+/*
+ * vpbe_display_s_std - Set the given standard in the encoder
+ *
+ * Sets the standard if supported by the current encoder. Return the status.
+ * 0 - success & -EINVAL on error
+ */
+static int vpbe_display_s_std(struct file *file, void *priv,
+                               v4l2_std_id std_id)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_STD\n");
+
+       if (vb2_is_busy(&layer->buffer_queue))
+               return -EBUSY;
+
+       if (vpbe_dev->ops.s_std) {
+               ret = vpbe_dev->ops.s_std(vpbe_dev, std_id);
+               if (ret) {
+                       v4l2_err(&vpbe_dev->v4l2_dev,
+                       "Failed to set standard for sub devices\n");
+                       return -EINVAL;
+               }
+       } else {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * vpbe_display_g_std - Get the standard in the current encoder
+ *
+ * Get the standard in the current encoder. Return the status. 0 - success
+ * -EINVAL on error
+ */
+static int vpbe_display_g_std(struct file *file, void *priv,
+                               v4l2_std_id *std_id)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_STD\n");
+
+       /* Get the standard from the current encoder */
+       if (vpbe_dev->current_timings.timings_type & VPBE_ENC_STD) {
+               *std_id = vpbe_dev->current_timings.std_id;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+/*
+ * vpbe_display_enum_output - enumerate outputs
+ *
+ * Enumerates the outputs available at the vpbe display
+ * returns the status, -EINVAL if end of output list
+ */
+static int vpbe_display_enum_output(struct file *file, void *priv,
+                                   struct v4l2_output *output)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_OUTPUT\n");
+
+       /* Enumerate outputs */
+       if (!vpbe_dev->ops.enum_outputs)
+               return -EINVAL;
+
+       ret = vpbe_dev->ops.enum_outputs(vpbe_dev, output);
+       if (ret) {
+               v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
+                       "Failed to enumerate outputs\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * vpbe_display_s_output - Set output to
+ * the output specified by the index
+ */
+static int vpbe_display_s_output(struct file *file, void *priv,
+                               unsigned int i)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_OUTPUT\n");
+
+       if (vb2_is_busy(&layer->buffer_queue))
+               return -EBUSY;
+
+       if (!vpbe_dev->ops.set_output)
+               return -EINVAL;
+
+       ret = vpbe_dev->ops.set_output(vpbe_dev, i);
+       if (ret) {
+               v4l2_err(&vpbe_dev->v4l2_dev,
+                       "Failed to set output for sub devices\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * vpbe_display_g_output - Get output from subdevice
+ * for a given by the index
+ */
+static int vpbe_display_g_output(struct file *file, void *priv,
+                               unsigned int *i)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_OUTPUT\n");
+       /* Get the standard from the current encoder */
+       *i = vpbe_dev->current_out_index;
+
+       return 0;
+}
+
+/*
+ * vpbe_display_enum_dv_timings - Enumerate the dv timings
+ *
+ * enum the timings in the current encoder. Return the status. 0 - success
+ * -EINVAL on error
+ */
+static int
+vpbe_display_enum_dv_timings(struct file *file, void *priv,
+                       struct v4l2_enum_dv_timings *timings)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_TIMINGS\n");
+
+       /* Enumerate outputs */
+       if (!vpbe_dev->ops.enum_dv_timings)
+               return -EINVAL;
+
+       ret = vpbe_dev->ops.enum_dv_timings(vpbe_dev, timings);
+       if (ret) {
+               v4l2_err(&vpbe_dev->v4l2_dev,
+                       "Failed to enumerate dv timings info\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * vpbe_display_s_dv_timings - Set the dv timings
+ *
+ * Set the timings in the current encoder. Return the status. 0 - success
+ * -EINVAL on error
+ */
+static int
+vpbe_display_s_dv_timings(struct file *file, void *priv,
+                               struct v4l2_dv_timings *timings)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_TIMINGS\n");
+
+       if (vb2_is_busy(&layer->buffer_queue))
+               return -EBUSY;
+
+       /* Set the given standard in the encoder */
+       if (!vpbe_dev->ops.s_dv_timings)
+               return -EINVAL;
+
+       ret = vpbe_dev->ops.s_dv_timings(vpbe_dev, timings);
+       if (ret) {
+               v4l2_err(&vpbe_dev->v4l2_dev,
+                       "Failed to set the dv timings info\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * vpbe_display_g_dv_timings - Set the dv timings
+ *
+ * Get the timings in the current encoder. Return the status. 0 - success
+ * -EINVAL on error
+ */
+static int
+vpbe_display_g_dv_timings(struct file *file, void *priv,
+                               struct v4l2_dv_timings *dv_timings)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_DV_TIMINGS\n");
+
+       /* Get the given standard in the encoder */
+
+       if (vpbe_dev->current_timings.timings_type &
+                               VPBE_ENC_DV_TIMINGS) {
+               *dv_timings = vpbe_dev->current_timings.dv_timings;
+       } else {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * vpbe_display_open()
+ * It creates object of file handle structure and stores it in private_data
+ * member of filepointer
+ */
+static int vpbe_display_open(struct file *file)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct vpbe_display *disp_dev = layer->disp_dev;
+       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
+       struct osd_state *osd_device = disp_dev->osd_device;
+       int err;
+
+       /* creating context for file descriptor */
+       err = v4l2_fh_open(file);
+       if (err) {
+               v4l2_err(&vpbe_dev->v4l2_dev, "v4l2_fh_open failed\n");
+               return err;
+       }
+
+       /* leaving if layer is already initialized */
+       if (!v4l2_fh_is_singular_file(file))
+               return err;
+
+       if (!layer->usrs) {
+               if (mutex_lock_interruptible(&layer->opslock))
+                       return -ERESTARTSYS;
+               /* First claim the layer for this device */
+               err = osd_device->ops.request_layer(osd_device,
+                                               layer->layer_info.id);
+               mutex_unlock(&layer->opslock);
+               if (err < 0) {
+                       /* Couldn't get layer */
+                       v4l2_err(&vpbe_dev->v4l2_dev,
+                               "Display Manager failed to allocate layer\n");
+                       v4l2_fh_release(file);
+                       return -EINVAL;
+               }
+       }
+       /* Increment layer usrs counter */
+       layer->usrs++;
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
+                       "vpbe display device opened successfully\n");
+       return 0;
+}
+
+/*
+ * vpbe_display_release()
+ * This function deletes buffer queue, frees the buffers and the davinci
+ * display file * handle
+ */
+static int vpbe_display_release(struct file *file)
+{
+       struct vpbe_layer *layer = video_drvdata(file);
+       struct osd_layer_config *cfg  = &layer->layer_info.config;
+       struct vpbe_display *disp_dev = layer->disp_dev;
+       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
+       struct osd_state *osd_device = disp_dev->osd_device;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_release\n");
+
+       mutex_lock(&layer->opslock);
+
+       osd_device->ops.disable_layer(osd_device,
+                       layer->layer_info.id);
+       /* Decrement layer usrs counter */
+       layer->usrs--;
+       /* If this file handle has initialize encoder device, reset it */
+       if (!layer->usrs) {
+               if (cfg->pixfmt == PIXFMT_NV12) {
+                       struct vpbe_layer *otherlayer;
+                       otherlayer =
+                       _vpbe_display_get_other_win_layer(disp_dev, layer);
+                       osd_device->ops.disable_layer(osd_device,
+                                       otherlayer->layer_info.id);
+                       osd_device->ops.release_layer(osd_device,
+                                       otherlayer->layer_info.id);
+               }
+               osd_device->ops.disable_layer(osd_device,
+                               layer->layer_info.id);
+               osd_device->ops.release_layer(osd_device,
+                               layer->layer_info.id);
+       }
+
+       _vb2_fop_release(file, NULL);
+       mutex_unlock(&layer->opslock);
+
+       disp_dev->cbcr_ofst = 0;
+
+       return 0;
+}
+
+/* vpbe capture ioctl operations */
+static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
+       .vidioc_querycap         = vpbe_display_querycap,
+       .vidioc_g_fmt_vid_out    = vpbe_display_g_fmt,
+       .vidioc_enum_fmt_vid_out = vpbe_display_enum_fmt,
+       .vidioc_s_fmt_vid_out    = vpbe_display_s_fmt,
+       .vidioc_try_fmt_vid_out  = vpbe_display_try_fmt,
+
+       .vidioc_reqbufs          = vb2_ioctl_reqbufs,
+       .vidioc_create_bufs      = vb2_ioctl_create_bufs,
+       .vidioc_querybuf         = vb2_ioctl_querybuf,
+       .vidioc_qbuf             = vb2_ioctl_qbuf,
+       .vidioc_dqbuf            = vb2_ioctl_dqbuf,
+       .vidioc_streamon         = vb2_ioctl_streamon,
+       .vidioc_streamoff        = vb2_ioctl_streamoff,
+       .vidioc_expbuf           = vb2_ioctl_expbuf,
+
+       .vidioc_g_pixelaspect    = vpbe_display_g_pixelaspect,
+       .vidioc_g_selection      = vpbe_display_g_selection,
+       .vidioc_s_selection      = vpbe_display_s_selection,
+
+       .vidioc_s_std            = vpbe_display_s_std,
+       .vidioc_g_std            = vpbe_display_g_std,
+
+       .vidioc_enum_output      = vpbe_display_enum_output,
+       .vidioc_s_output         = vpbe_display_s_output,
+       .vidioc_g_output         = vpbe_display_g_output,
+
+       .vidioc_s_dv_timings     = vpbe_display_s_dv_timings,
+       .vidioc_g_dv_timings     = vpbe_display_g_dv_timings,
+       .vidioc_enum_dv_timings  = vpbe_display_enum_dv_timings,
+};
+
+static const struct v4l2_file_operations vpbe_fops = {
+       .owner = THIS_MODULE,
+       .open = vpbe_display_open,
+       .release = vpbe_display_release,
+       .unlocked_ioctl = video_ioctl2,
+       .mmap = vb2_fop_mmap,
+       .poll =  vb2_fop_poll,
+};
+
+static int vpbe_device_get(struct device *dev, void *data)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct vpbe_display *vpbe_disp  = data;
+
+       if (strcmp("vpbe_controller", pdev->name) == 0)
+               vpbe_disp->vpbe_dev = platform_get_drvdata(pdev);
+
+       if (strstr(pdev->name, "vpbe-osd"))
+               vpbe_disp->osd_device = platform_get_drvdata(pdev);
+
+       return 0;
+}
+
+static int init_vpbe_layer(int i, struct vpbe_display *disp_dev,
+                          struct platform_device *pdev)
+{
+       struct vpbe_layer *vpbe_display_layer = NULL;
+       struct video_device *vbd = NULL;
+
+       /* Allocate memory for four plane display objects */
+       disp_dev->dev[i] = kzalloc(sizeof(*disp_dev->dev[i]), GFP_KERNEL);
+       if (!disp_dev->dev[i])
+               return  -ENOMEM;
+
+       spin_lock_init(&disp_dev->dev[i]->irqlock);
+       mutex_init(&disp_dev->dev[i]->opslock);
+
+       /* Get the pointer to the layer object */
+       vpbe_display_layer = disp_dev->dev[i];
+       vbd = &vpbe_display_layer->video_dev;
+       /* Initialize field of video device */
+       vbd->release    = video_device_release_empty;
+       vbd->fops       = &vpbe_fops;
+       vbd->ioctl_ops  = &vpbe_ioctl_ops;
+       vbd->minor      = -1;
+       vbd->v4l2_dev   = &disp_dev->vpbe_dev->v4l2_dev;
+       vbd->lock       = &vpbe_display_layer->opslock;
+       vbd->vfl_dir    = VFL_DIR_TX;
+       vbd->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
+
+       if (disp_dev->vpbe_dev->current_timings.timings_type &
+                       VPBE_ENC_STD)
+               vbd->tvnorms = (V4L2_STD_525_60 | V4L2_STD_625_50);
+
+       snprintf(vbd->name, sizeof(vbd->name),
+                       "DaVinci_VPBE Display_DRIVER_V%d.%d.%d",
+                       (VPBE_DISPLAY_VERSION_CODE >> 16) & 0xff,
+                       (VPBE_DISPLAY_VERSION_CODE >> 8) & 0xff,
+                       (VPBE_DISPLAY_VERSION_CODE) & 0xff);
+
+       vpbe_display_layer->device_id = i;
+
+       vpbe_display_layer->layer_info.id =
+               ((i == VPBE_DISPLAY_DEVICE_0) ? WIN_VID0 : WIN_VID1);
+
+
+       return 0;
+}
+
+static int register_device(struct vpbe_layer *vpbe_display_layer,
+                          struct vpbe_display *disp_dev,
+                          struct platform_device *pdev)
+{
+       int err;
+
+       v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
+                 "Trying to register VPBE display device.\n");
+       v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
+                 "layer=%p,layer->video_dev=%p\n",
+                 vpbe_display_layer,
+                 &vpbe_display_layer->video_dev);
+
+       vpbe_display_layer->video_dev.queue = &vpbe_display_layer->buffer_queue;
+       err = video_register_device(&vpbe_display_layer->video_dev,
+                                   VFL_TYPE_VIDEO,
+                                   -1);
+       if (err)
+               return -ENODEV;
+
+       vpbe_display_layer->disp_dev = disp_dev;
+       /* set the driver data in platform device */
+       platform_set_drvdata(pdev, disp_dev);
+       video_set_drvdata(&vpbe_display_layer->video_dev,
+                         vpbe_display_layer);
+
+       return 0;
+}
+
+
+
+/*
+ * vpbe_display_probe()
+ * This function creates device entries by register itself to the V4L2 driver
+ * and initializes fields of each layer objects
+ */
+static int vpbe_display_probe(struct platform_device *pdev)
+{
+       struct vpbe_display *disp_dev;
+       struct v4l2_device *v4l2_dev;
+       struct resource *res = NULL;
+       struct vb2_queue *q;
+       int k;
+       int i;
+       int err;
+       int irq;
+
+       printk(KERN_DEBUG "vpbe_display_probe\n");
+       /* Allocate memory for vpbe_display */
+       disp_dev = devm_kzalloc(&pdev->dev, sizeof(*disp_dev), GFP_KERNEL);
+       if (!disp_dev)
+               return -ENOMEM;
+
+       spin_lock_init(&disp_dev->dma_queue_lock);
+       /*
+        * Scan all the platform devices to find the vpbe
+        * controller device and get the vpbe_dev object
+        */
+       err = bus_for_each_dev(&platform_bus_type, NULL, disp_dev,
+                       vpbe_device_get);
+       if (err < 0)
+               return err;
+
+       v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev;
+       /* Initialize the vpbe display controller */
+       if (disp_dev->vpbe_dev->ops.initialize) {
+               err = disp_dev->vpbe_dev->ops.initialize(&pdev->dev,
+                                                        disp_dev->vpbe_dev);
+               if (err) {
+                       v4l2_err(v4l2_dev, "Error initing vpbe\n");
+                       err = -ENOMEM;
+                       goto probe_out;
+               }
+       }
+
+       for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
+               if (init_vpbe_layer(i, disp_dev, pdev)) {
+                       err = -ENODEV;
+                       goto probe_out;
+               }
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!res) {
+               v4l2_err(v4l2_dev, "Unable to get VENC interrupt resource\n");
+               err = -ENODEV;
+               goto probe_out;
+       }
+
+       irq = res->start;
+       err = devm_request_irq(&pdev->dev, irq, venc_isr, 0,
+                              VPBE_DISPLAY_DRIVER, disp_dev);
+       if (err) {
+               v4l2_err(v4l2_dev, "VPBE IRQ request failed\n");
+               goto probe_out;
+       }
+
+       for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
+               /* initialize vb2 queue */
+               q = &disp_dev->dev[i]->buffer_queue;
+               memset(q, 0, sizeof(*q));
+               q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+               q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+               q->drv_priv = disp_dev->dev[i];
+               q->ops = &video_qops;
+               q->mem_ops = &vb2_dma_contig_memops;
+               q->buf_struct_size = sizeof(struct vpbe_disp_buffer);
+               q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+               q->min_buffers_needed = 1;
+               q->lock = &disp_dev->dev[i]->opslock;
+               q->dev = disp_dev->vpbe_dev->pdev;
+               err = vb2_queue_init(q);
+               if (err) {
+                       v4l2_err(v4l2_dev, "vb2_queue_init() failed\n");
+                       goto probe_out;
+               }
+
+               INIT_LIST_HEAD(&disp_dev->dev[i]->dma_queue);
+
+               if (register_device(disp_dev->dev[i], disp_dev, pdev)) {
+                       err = -ENODEV;
+                       goto probe_out;
+               }
+       }
+
+       v4l2_dbg(1, debug, v4l2_dev,
+                "Successfully completed the probing of vpbe v4l2 device\n");
+
+       return 0;
+
+probe_out:
+       for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) {
+               /* Unregister video device */
+               if (disp_dev->dev[k]) {
+                       video_unregister_device(&disp_dev->dev[k]->video_dev);
+                       kfree(disp_dev->dev[k]);
+               }
+       }
+       return err;
+}
+
+/*
+ * vpbe_display_remove()
+ * It un-register hardware layer from V4L2 driver
+ */
+static int vpbe_display_remove(struct platform_device *pdev)
+{
+       struct vpbe_layer *vpbe_display_layer;
+       struct vpbe_display *disp_dev = platform_get_drvdata(pdev);
+       struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
+       int i;
+
+       v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_remove\n");
+
+       /* deinitialize the vpbe display controller */
+       if (vpbe_dev->ops.deinitialize)
+               vpbe_dev->ops.deinitialize(&pdev->dev, vpbe_dev);
+       /* un-register device */
+       for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
+               /* Get the pointer to the layer object */
+               vpbe_display_layer = disp_dev->dev[i];
+               /* Unregister video device */
+               video_unregister_device(&vpbe_display_layer->video_dev);
+
+       }
+       for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
+               kfree(disp_dev->dev[i]);
+               disp_dev->dev[i] = NULL;
+       }
+
+       return 0;
+}
+
+static struct platform_driver vpbe_display_driver = {
+       .driver = {
+               .name = VPBE_DISPLAY_DRIVER,
+               .bus = &platform_bus_type,
+       },
+       .probe = vpbe_display_probe,
+       .remove = vpbe_display_remove,
+};
+
+module_platform_driver(vpbe_display_driver);
+
+MODULE_DESCRIPTION("TI DM644x/DM355/DM365 VPBE Display controller");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Texas Instruments");
diff --git a/drivers/media/platform/ti/davinci/vpbe_osd.c b/drivers/media/platform/ti/davinci/vpbe_osd.c
new file mode 100644 (file)
index 0000000..32f7ef5
--- /dev/null
@@ -0,0 +1,1582 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2007-2010 Texas Instruments Inc
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *
+ * Andy Lowe (alowe@mvista.com), MontaVista Software
+ * - Initial version
+ * Murali Karicheri (mkaricheri@gmail.com), Texas Instruments Ltd.
+ * - ported to sub device interface
+ */
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+
+#include <media/davinci/vpss.h>
+#include <media/v4l2-device.h>
+#include <media/davinci/vpbe_types.h>
+#include <media/davinci/vpbe_osd.h>
+
+#include <linux/io.h>
+#include "vpbe_osd_regs.h"
+
+#define MODULE_NAME    "davinci-vpbe-osd"
+
+static const struct platform_device_id vpbe_osd_devtype[] = {
+       {
+               .name = DM644X_VPBE_OSD_SUBDEV_NAME,
+               .driver_data = VPBE_VERSION_1,
+       }, {
+               .name = DM365_VPBE_OSD_SUBDEV_NAME,
+               .driver_data = VPBE_VERSION_2,
+       }, {
+               .name = DM355_VPBE_OSD_SUBDEV_NAME,
+               .driver_data = VPBE_VERSION_3,
+       },
+       {
+               /* sentinel */
+       }
+};
+
+MODULE_DEVICE_TABLE(platform, vpbe_osd_devtype);
+
+/* register access routines */
+static inline u32 __always_unused osd_read(struct osd_state *sd, u32 offset)
+{
+       struct osd_state *osd = sd;
+
+       return readl(osd->osd_base + offset);
+}
+
+static inline u32 osd_write(struct osd_state *sd, u32 val, u32 offset)
+{
+       struct osd_state *osd = sd;
+
+       writel(val, osd->osd_base + offset);
+
+       return val;
+}
+
+static inline u32 osd_set(struct osd_state *sd, u32 mask, u32 offset)
+{
+       struct osd_state *osd = sd;
+
+       void __iomem *addr = osd->osd_base + offset;
+       u32 val = readl(addr) | mask;
+
+       writel(val, addr);
+
+       return val;
+}
+
+static inline u32 osd_clear(struct osd_state *sd, u32 mask, u32 offset)
+{
+       struct osd_state *osd = sd;
+
+       void __iomem *addr = osd->osd_base + offset;
+       u32 val = readl(addr) & ~mask;
+
+       writel(val, addr);
+
+       return val;
+}
+
+static inline u32 osd_modify(struct osd_state *sd, u32 mask, u32 val,
+                                u32 offset)
+{
+       struct osd_state *osd = sd;
+
+       void __iomem *addr = osd->osd_base + offset;
+       u32 new_val = (readl(addr) & ~mask) | (val & mask);
+
+       writel(new_val, addr);
+
+       return new_val;
+}
+
+/* define some macros for layer and pixfmt classification */
+#define is_osd_win(layer) (((layer) == WIN_OSD0) || ((layer) == WIN_OSD1))
+#define is_vid_win(layer) (((layer) == WIN_VID0) || ((layer) == WIN_VID1))
+#define is_rgb_pixfmt(pixfmt) \
+       (((pixfmt) == PIXFMT_RGB565) || ((pixfmt) == PIXFMT_RGB888))
+#define is_yc_pixfmt(pixfmt) \
+       (((pixfmt) == PIXFMT_YCBCRI) || ((pixfmt) == PIXFMT_YCRCBI) || \
+       ((pixfmt) == PIXFMT_NV12))
+#define MAX_WIN_SIZE OSD_VIDWIN0XP_V0X
+#define MAX_LINE_LENGTH (OSD_VIDWIN0OFST_V0LO << 5)
+
+/**
+ * _osd_dm6446_vid0_pingpong() - field inversion fix for DM6446
+ * @sd: ptr to struct osd_state
+ * @field_inversion: inversion flag
+ * @fb_base_phys: frame buffer address
+ * @lconfig: ptr to layer config
+ *
+ * This routine implements a workaround for the field signal inversion silicon
+ * erratum described in Advisory 1.3.8 for the DM6446.  The fb_base_phys and
+ * lconfig parameters apply to the vid0 window.  This routine should be called
+ * whenever the vid0 layer configuration or start address is modified, or when
+ * the OSD field inversion setting is modified.
+ * Returns: 1 if the ping-pong buffers need to be toggled in the vsync isr, or
+ *          0 otherwise
+ */
+static int _osd_dm6446_vid0_pingpong(struct osd_state *sd,
+                                    int field_inversion,
+                                    unsigned long fb_base_phys,
+                                    const struct osd_layer_config *lconfig)
+{
+       struct osd_platform_data *pdata;
+
+       pdata = (struct osd_platform_data *)sd->dev->platform_data;
+       if (pdata != NULL && pdata->field_inv_wa_enable) {
+
+               if (!field_inversion || !lconfig->interlaced) {
+                       osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR);
+                       osd_write(sd, fb_base_phys & ~0x1F, OSD_PPVWIN0ADR);
+                       osd_modify(sd, OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, 0,
+                                  OSD_MISCCTL);
+                       return 0;
+               } else {
+                       unsigned miscctl = OSD_MISCCTL_PPRV;
+
+                       osd_write(sd,
+                               (fb_base_phys & ~0x1F) - lconfig->line_length,
+                               OSD_VIDWIN0ADR);
+                       osd_write(sd,
+                               (fb_base_phys & ~0x1F) + lconfig->line_length,
+                               OSD_PPVWIN0ADR);
+                       osd_modify(sd,
+                               OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, miscctl,
+                               OSD_MISCCTL);
+
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static void _osd_set_field_inversion(struct osd_state *sd, int enable)
+{
+       unsigned fsinv = 0;
+
+       if (enable)
+               fsinv = OSD_MODE_FSINV;
+
+       osd_modify(sd, OSD_MODE_FSINV, fsinv, OSD_MODE);
+}
+
+static void _osd_set_blink_attribute(struct osd_state *sd, int enable,
+                                    enum osd_blink_interval blink)
+{
+       u32 osdatrmd = 0;
+
+       if (enable) {
+               osdatrmd |= OSD_OSDATRMD_BLNK;
+               osdatrmd |= blink << OSD_OSDATRMD_BLNKINT_SHIFT;
+       }
+       /* caller must ensure that OSD1 is configured in attribute mode */
+       osd_modify(sd, OSD_OSDATRMD_BLNKINT | OSD_OSDATRMD_BLNK, osdatrmd,
+                 OSD_OSDATRMD);
+}
+
+static void _osd_set_rom_clut(struct osd_state *sd,
+                             enum osd_rom_clut rom_clut)
+{
+       if (rom_clut == ROM_CLUT0)
+               osd_clear(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL);
+       else
+               osd_set(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL);
+}
+
+static void _osd_set_palette_map(struct osd_state *sd,
+                                enum osd_win_layer osdwin,
+                                unsigned char pixel_value,
+                                unsigned char clut_index,
+                                enum osd_pix_format pixfmt)
+{
+       static const int map_2bpp[] = { 0, 5, 10, 15 };
+       static const int map_1bpp[] = { 0, 15 };
+       int bmp_offset;
+       int bmp_shift;
+       int bmp_mask;
+       int bmp_reg;
+
+       switch (pixfmt) {
+       case PIXFMT_1BPP:
+               bmp_reg = map_1bpp[pixel_value & 0x1];
+               break;
+       case PIXFMT_2BPP:
+               bmp_reg = map_2bpp[pixel_value & 0x3];
+               break;
+       case PIXFMT_4BPP:
+               bmp_reg = pixel_value & 0xf;
+               break;
+       default:
+               return;
+       }
+
+       switch (osdwin) {
+       case OSDWIN_OSD0:
+               bmp_offset = OSD_W0BMP01 + (bmp_reg >> 1) * sizeof(u32);
+               break;
+       case OSDWIN_OSD1:
+               bmp_offset = OSD_W1BMP01 + (bmp_reg >> 1) * sizeof(u32);
+               break;
+       default:
+               return;
+       }
+
+       if (bmp_reg & 1) {
+               bmp_shift = 8;
+               bmp_mask = 0xff << 8;
+       } else {
+               bmp_shift = 0;
+               bmp_mask = 0xff;
+       }
+
+       osd_modify(sd, bmp_mask, clut_index << bmp_shift, bmp_offset);
+}
+
+static void _osd_set_rec601_attenuation(struct osd_state *sd,
+                                       enum osd_win_layer osdwin, int enable)
+{
+       switch (osdwin) {
+       case OSDWIN_OSD0:
+               osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
+                         enable ? OSD_OSDWIN0MD_ATN0E : 0,
+                         OSD_OSDWIN0MD);
+               if (sd->vpbe_type == VPBE_VERSION_1)
+                       osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
+                                 enable ? OSD_OSDWIN0MD_ATN0E : 0,
+                                 OSD_OSDWIN0MD);
+               else if ((sd->vpbe_type == VPBE_VERSION_3) ||
+                          (sd->vpbe_type == VPBE_VERSION_2))
+                       osd_modify(sd, OSD_EXTMODE_ATNOSD0EN,
+                                 enable ? OSD_EXTMODE_ATNOSD0EN : 0,
+                                 OSD_EXTMODE);
+               break;
+       case OSDWIN_OSD1:
+               osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
+                         enable ? OSD_OSDWIN1MD_ATN1E : 0,
+                         OSD_OSDWIN1MD);
+               if (sd->vpbe_type == VPBE_VERSION_1)
+                       osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
+                                 enable ? OSD_OSDWIN1MD_ATN1E : 0,
+                                 OSD_OSDWIN1MD);
+               else if ((sd->vpbe_type == VPBE_VERSION_3) ||
+                          (sd->vpbe_type == VPBE_VERSION_2))
+                       osd_modify(sd, OSD_EXTMODE_ATNOSD1EN,
+                                 enable ? OSD_EXTMODE_ATNOSD1EN : 0,
+                                 OSD_EXTMODE);
+               break;
+       }
+}
+
+static void _osd_set_blending_factor(struct osd_state *sd,
+                                    enum osd_win_layer osdwin,
+                                    enum osd_blending_factor blend)
+{
+       switch (osdwin) {
+       case OSDWIN_OSD0:
+               osd_modify(sd, OSD_OSDWIN0MD_BLND0,
+                         blend << OSD_OSDWIN0MD_BLND0_SHIFT, OSD_OSDWIN0MD);
+               break;
+       case OSDWIN_OSD1:
+               osd_modify(sd, OSD_OSDWIN1MD_BLND1,
+                         blend << OSD_OSDWIN1MD_BLND1_SHIFT, OSD_OSDWIN1MD);
+               break;
+       }
+}
+
+static void _osd_enable_rgb888_pixblend(struct osd_state *sd,
+                                       enum osd_win_layer osdwin)
+{
+
+       osd_modify(sd, OSD_MISCCTL_BLDSEL, 0, OSD_MISCCTL);
+       switch (osdwin) {
+       case OSDWIN_OSD0:
+               osd_modify(sd, OSD_EXTMODE_OSD0BLDCHR,
+                         OSD_EXTMODE_OSD0BLDCHR, OSD_EXTMODE);
+               break;
+       case OSDWIN_OSD1:
+               osd_modify(sd, OSD_EXTMODE_OSD1BLDCHR,
+                         OSD_EXTMODE_OSD1BLDCHR, OSD_EXTMODE);
+               break;
+       }
+}
+
+static void _osd_enable_color_key(struct osd_state *sd,
+                                 enum osd_win_layer osdwin,
+                                 unsigned colorkey,
+                                 enum osd_pix_format pixfmt)
+{
+       switch (pixfmt) {
+       case PIXFMT_1BPP:
+       case PIXFMT_2BPP:
+       case PIXFMT_4BPP:
+       case PIXFMT_8BPP:
+               if (sd->vpbe_type == VPBE_VERSION_3) {
+                       switch (osdwin) {
+                       case OSDWIN_OSD0:
+                               osd_modify(sd, OSD_TRANSPBMPIDX_BMP0,
+                                         colorkey <<
+                                         OSD_TRANSPBMPIDX_BMP0_SHIFT,
+                                         OSD_TRANSPBMPIDX);
+                               break;
+                       case OSDWIN_OSD1:
+                               osd_modify(sd, OSD_TRANSPBMPIDX_BMP1,
+                                         colorkey <<
+                                         OSD_TRANSPBMPIDX_BMP1_SHIFT,
+                                         OSD_TRANSPBMPIDX);
+                               break;
+                       }
+               }
+               break;
+       case PIXFMT_RGB565:
+               if (sd->vpbe_type == VPBE_VERSION_1)
+                       osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS,
+                                 OSD_TRANSPVAL);
+               else if (sd->vpbe_type == VPBE_VERSION_3)
+                       osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
+                                 OSD_TRANSPVALL);
+               break;
+       case PIXFMT_YCBCRI:
+       case PIXFMT_YCRCBI:
+               if (sd->vpbe_type == VPBE_VERSION_3)
+                       osd_modify(sd, OSD_TRANSPVALU_Y, colorkey,
+                                  OSD_TRANSPVALU);
+               break;
+       case PIXFMT_RGB888:
+               if (sd->vpbe_type == VPBE_VERSION_3) {
+                       osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
+                                 OSD_TRANSPVALL);
+                       osd_modify(sd, OSD_TRANSPVALU_RGBU, colorkey >> 16,
+                                 OSD_TRANSPVALU);
+               }
+               break;
+       default:
+               break;
+       }
+
+       switch (osdwin) {
+       case OSDWIN_OSD0:
+               osd_set(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD);
+               break;
+       case OSDWIN_OSD1:
+               osd_set(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD);
+               break;
+       }
+}
+
+static void _osd_disable_color_key(struct osd_state *sd,
+                                  enum osd_win_layer osdwin)
+{
+       switch (osdwin) {
+       case OSDWIN_OSD0:
+               osd_clear(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD);
+               break;
+       case OSDWIN_OSD1:
+               osd_clear(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD);
+               break;
+       }
+}
+
+static void _osd_set_osd_clut(struct osd_state *sd,
+                             enum osd_win_layer osdwin,
+                             enum osd_clut clut)
+{
+       u32 winmd = 0;
+
+       switch (osdwin) {
+       case OSDWIN_OSD0:
+               if (clut == RAM_CLUT)
+                       winmd |= OSD_OSDWIN0MD_CLUTS0;
+               osd_modify(sd, OSD_OSDWIN0MD_CLUTS0, winmd, OSD_OSDWIN0MD);
+               break;
+       case OSDWIN_OSD1:
+               if (clut == RAM_CLUT)
+                       winmd |= OSD_OSDWIN1MD_CLUTS1;
+               osd_modify(sd, OSD_OSDWIN1MD_CLUTS1, winmd, OSD_OSDWIN1MD);
+               break;
+       }
+}
+
+static void _osd_set_zoom(struct osd_state *sd, enum osd_layer layer,
+                         enum osd_zoom_factor h_zoom,
+                         enum osd_zoom_factor v_zoom)
+{
+       u32 winmd = 0;
+
+       switch (layer) {
+       case WIN_OSD0:
+               winmd |= (h_zoom << OSD_OSDWIN0MD_OHZ0_SHIFT);
+               winmd |= (v_zoom << OSD_OSDWIN0MD_OVZ0_SHIFT);
+               osd_modify(sd, OSD_OSDWIN0MD_OHZ0 | OSD_OSDWIN0MD_OVZ0, winmd,
+                         OSD_OSDWIN0MD);
+               break;
+       case WIN_VID0:
+               winmd |= (h_zoom << OSD_VIDWINMD_VHZ0_SHIFT);
+               winmd |= (v_zoom << OSD_VIDWINMD_VVZ0_SHIFT);
+               osd_modify(sd, OSD_VIDWINMD_VHZ0 | OSD_VIDWINMD_VVZ0, winmd,
+                         OSD_VIDWINMD);
+               break;
+       case WIN_OSD1:
+               winmd |= (h_zoom << OSD_OSDWIN1MD_OHZ1_SHIFT);
+               winmd |= (v_zoom << OSD_OSDWIN1MD_OVZ1_SHIFT);
+               osd_modify(sd, OSD_OSDWIN1MD_OHZ1 | OSD_OSDWIN1MD_OVZ1, winmd,
+                         OSD_OSDWIN1MD);
+               break;
+       case WIN_VID1:
+               winmd |= (h_zoom << OSD_VIDWINMD_VHZ1_SHIFT);
+               winmd |= (v_zoom << OSD_VIDWINMD_VVZ1_SHIFT);
+               osd_modify(sd, OSD_VIDWINMD_VHZ1 | OSD_VIDWINMD_VVZ1, winmd,
+                         OSD_VIDWINMD);
+               break;
+       }
+}
+
+static void _osd_disable_layer(struct osd_state *sd, enum osd_layer layer)
+{
+       switch (layer) {
+       case WIN_OSD0:
+               osd_clear(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD);
+               break;
+       case WIN_VID0:
+               osd_clear(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD);
+               break;
+       case WIN_OSD1:
+               /* disable attribute mode as well as disabling the window */
+               osd_clear(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1,
+                         OSD_OSDWIN1MD);
+               break;
+       case WIN_VID1:
+               osd_clear(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD);
+               break;
+       }
+}
+
+static void osd_disable_layer(struct osd_state *sd, enum osd_layer layer)
+{
+       struct osd_state *osd = sd;
+       struct osd_window_state *win = &osd->win[layer];
+       unsigned long flags;
+
+       spin_lock_irqsave(&osd->lock, flags);
+
+       if (!win->is_enabled) {
+               spin_unlock_irqrestore(&osd->lock, flags);
+               return;
+       }
+       win->is_enabled = 0;
+
+       _osd_disable_layer(sd, layer);
+
+       spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void _osd_enable_attribute_mode(struct osd_state *sd)
+{
+       /* enable attribute mode for OSD1 */
+       osd_set(sd, OSD_OSDWIN1MD_OASW, OSD_OSDWIN1MD);
+}
+
+static void _osd_enable_layer(struct osd_state *sd, enum osd_layer layer)
+{
+       switch (layer) {
+       case WIN_OSD0:
+               osd_set(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD);
+               break;
+       case WIN_VID0:
+               osd_set(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD);
+               break;
+       case WIN_OSD1:
+               /* enable OSD1 and disable attribute mode */
+               osd_modify(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1,
+                         OSD_OSDWIN1MD_OACT1, OSD_OSDWIN1MD);
+               break;
+       case WIN_VID1:
+               osd_set(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD);
+               break;
+       }
+}
+
+static int osd_enable_layer(struct osd_state *sd, enum osd_layer layer,
+                           int otherwin)
+{
+       struct osd_state *osd = sd;
+       struct osd_window_state *win = &osd->win[layer];
+       struct osd_layer_config *cfg = &win->lconfig;
+       unsigned long flags;
+
+       spin_lock_irqsave(&osd->lock, flags);
+
+       /*
+        * use otherwin flag to know this is the other vid window
+        * in YUV420 mode, if is, skip this check
+        */
+       if (!otherwin && (!win->is_allocated ||
+                       !win->fb_base_phys ||
+                       !cfg->line_length ||
+                       !cfg->xsize ||
+                       !cfg->ysize)) {
+               spin_unlock_irqrestore(&osd->lock, flags);
+               return -1;
+       }
+
+       if (win->is_enabled) {
+               spin_unlock_irqrestore(&osd->lock, flags);
+               return 0;
+       }
+       win->is_enabled = 1;
+
+       if (cfg->pixfmt != PIXFMT_OSD_ATTR)
+               _osd_enable_layer(sd, layer);
+       else {
+               _osd_enable_attribute_mode(sd);
+               _osd_set_blink_attribute(sd, osd->is_blinking, osd->blink);
+       }
+
+       spin_unlock_irqrestore(&osd->lock, flags);
+
+       return 0;
+}
+
+#define OSD_SRC_ADDR_HIGH4     0x7800000
+#define OSD_SRC_ADDR_HIGH7     0x7F0000
+#define OSD_SRCADD_OFSET_SFT   23
+#define OSD_SRCADD_ADD_SFT     16
+#define OSD_WINADL_MASK                0xFFFF
+#define OSD_WINOFST_MASK       0x1000
+#define VPBE_REG_BASE          0x80000000
+
+static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer,
+                            unsigned long fb_base_phys,
+                            unsigned long cbcr_ofst)
+{
+
+       if (sd->vpbe_type == VPBE_VERSION_1) {
+               switch (layer) {
+               case WIN_OSD0:
+                       osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR);
+                       break;
+               case WIN_VID0:
+                       osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR);
+                       break;
+               case WIN_OSD1:
+                       osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR);
+                       break;
+               case WIN_VID1:
+                       osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR);
+                       break;
+             }
+       } else if (sd->vpbe_type == VPBE_VERSION_3) {
+               unsigned long fb_offset_32 =
+                   (fb_base_phys - VPBE_REG_BASE) >> 5;
+
+               switch (layer) {
+               case WIN_OSD0:
+                       osd_modify(sd, OSD_OSDWINADH_O0AH,
+                                 fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
+                                                  OSD_OSDWINADH_O0AH_SHIFT),
+                                 OSD_OSDWINADH);
+                       osd_write(sd, fb_offset_32 & OSD_OSDWIN0ADL_O0AL,
+                                 OSD_OSDWIN0ADL);
+                       break;
+               case WIN_VID0:
+                       osd_modify(sd, OSD_VIDWINADH_V0AH,
+                                 fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
+                                                  OSD_VIDWINADH_V0AH_SHIFT),
+                                 OSD_VIDWINADH);
+                       osd_write(sd, fb_offset_32 & OSD_VIDWIN0ADL_V0AL,
+                                 OSD_VIDWIN0ADL);
+                       break;
+               case WIN_OSD1:
+                       osd_modify(sd, OSD_OSDWINADH_O1AH,
+                                 fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
+                                                  OSD_OSDWINADH_O1AH_SHIFT),
+                                 OSD_OSDWINADH);
+                       osd_write(sd, fb_offset_32 & OSD_OSDWIN1ADL_O1AL,
+                                 OSD_OSDWIN1ADL);
+                       break;
+               case WIN_VID1:
+                       osd_modify(sd, OSD_VIDWINADH_V1AH,
+                                 fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
+                                                  OSD_VIDWINADH_V1AH_SHIFT),
+                                 OSD_VIDWINADH);
+                       osd_write(sd, fb_offset_32 & OSD_VIDWIN1ADL_V1AL,
+                                 OSD_VIDWIN1ADL);
+                       break;
+               }
+       } else if (sd->vpbe_type == VPBE_VERSION_2) {
+               struct osd_window_state *win = &sd->win[layer];
+               unsigned long fb_offset_32, cbcr_offset_32;
+
+               fb_offset_32 = fb_base_phys - VPBE_REG_BASE;
+               if (cbcr_ofst)
+                       cbcr_offset_32 = cbcr_ofst;
+               else
+                       cbcr_offset_32 = win->lconfig.line_length *
+                                        win->lconfig.ysize;
+               cbcr_offset_32 += fb_offset_32;
+               fb_offset_32 = fb_offset_32 >> 5;
+               cbcr_offset_32 = cbcr_offset_32 >> 5;
+               /*
+                * DM365: start address is 27-bit long address b26 - b23 are
+                * in offset register b12 - b9, and * bit 26 has to be '1'
+                */
+               if (win->lconfig.pixfmt == PIXFMT_NV12) {
+                       switch (layer) {
+                       case WIN_VID0:
+                       case WIN_VID1:
+                               /* Y is in VID0 */
+                               osd_modify(sd, OSD_VIDWIN0OFST_V0AH,
+                                        ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
+                                        (OSD_SRCADD_OFSET_SFT -
+                                        OSD_WINOFST_AH_SHIFT)) |
+                                        OSD_WINOFST_MASK, OSD_VIDWIN0OFST);
+                               osd_modify(sd, OSD_VIDWINADH_V0AH,
+                                         (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
+                                         (OSD_SRCADD_ADD_SFT -
+                                         OSD_VIDWINADH_V0AH_SHIFT),
+                                          OSD_VIDWINADH);
+                               osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
+                                         OSD_VIDWIN0ADL);
+                               /* CbCr is in VID1 */
+                               osd_modify(sd, OSD_VIDWIN1OFST_V1AH,
+                                        ((cbcr_offset_32 &
+                                        OSD_SRC_ADDR_HIGH4) >>
+                                        (OSD_SRCADD_OFSET_SFT -
+                                        OSD_WINOFST_AH_SHIFT)) |
+                                        OSD_WINOFST_MASK, OSD_VIDWIN1OFST);
+                               osd_modify(sd, OSD_VIDWINADH_V1AH,
+                                         (cbcr_offset_32 &
+                                         OSD_SRC_ADDR_HIGH7) >>
+                                         (OSD_SRCADD_ADD_SFT -
+                                         OSD_VIDWINADH_V1AH_SHIFT),
+                                         OSD_VIDWINADH);
+                               osd_write(sd, cbcr_offset_32 & OSD_WINADL_MASK,
+                                         OSD_VIDWIN1ADL);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+
+               switch (layer) {
+               case WIN_OSD0:
+                       osd_modify(sd, OSD_OSDWIN0OFST_O0AH,
+                                ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
+                                (OSD_SRCADD_OFSET_SFT -
+                                OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK,
+                                 OSD_OSDWIN0OFST);
+                       osd_modify(sd, OSD_OSDWINADH_O0AH,
+                                (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
+                                (OSD_SRCADD_ADD_SFT -
+                                OSD_OSDWINADH_O0AH_SHIFT), OSD_OSDWINADH);
+                       osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
+                                       OSD_OSDWIN0ADL);
+                       break;
+               case WIN_VID0:
+                       if (win->lconfig.pixfmt != PIXFMT_NV12) {
+                               osd_modify(sd, OSD_VIDWIN0OFST_V0AH,
+                                        ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
+                                        (OSD_SRCADD_OFSET_SFT -
+                                        OSD_WINOFST_AH_SHIFT)) |
+                                        OSD_WINOFST_MASK, OSD_VIDWIN0OFST);
+                               osd_modify(sd, OSD_VIDWINADH_V0AH,
+                                         (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
+                                         (OSD_SRCADD_ADD_SFT -
+                                         OSD_VIDWINADH_V0AH_SHIFT),
+                                         OSD_VIDWINADH);
+                               osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
+                                         OSD_VIDWIN0ADL);
+                       }
+                       break;
+               case WIN_OSD1:
+                       osd_modify(sd, OSD_OSDWIN1OFST_O1AH,
+                                ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
+                                (OSD_SRCADD_OFSET_SFT -
+                                OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK,
+                                 OSD_OSDWIN1OFST);
+                       osd_modify(sd, OSD_OSDWINADH_O1AH,
+                                 (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
+                                 (OSD_SRCADD_ADD_SFT -
+                                 OSD_OSDWINADH_O1AH_SHIFT),
+                                 OSD_OSDWINADH);
+                       osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
+                                       OSD_OSDWIN1ADL);
+                       break;
+               case WIN_VID1:
+                       if (win->lconfig.pixfmt != PIXFMT_NV12) {
+                               osd_modify(sd, OSD_VIDWIN1OFST_V1AH,
+                                        ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
+                                        (OSD_SRCADD_OFSET_SFT -
+                                        OSD_WINOFST_AH_SHIFT)) |
+                                        OSD_WINOFST_MASK, OSD_VIDWIN1OFST);
+                               osd_modify(sd, OSD_VIDWINADH_V1AH,
+                                         (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
+                                         (OSD_SRCADD_ADD_SFT -
+                                         OSD_VIDWINADH_V1AH_SHIFT),
+                                         OSD_VIDWINADH);
+                               osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
+                                         OSD_VIDWIN1ADL);
+                       }
+                       break;
+               }
+       }
+}
+
+static void osd_start_layer(struct osd_state *sd, enum osd_layer layer,
+                           unsigned long fb_base_phys,
+                           unsigned long cbcr_ofst)
+{
+       struct osd_state *osd = sd;
+       struct osd_window_state *win = &osd->win[layer];
+       struct osd_layer_config *cfg = &win->lconfig;
+       unsigned long flags;
+
+       spin_lock_irqsave(&osd->lock, flags);
+
+       win->fb_base_phys = fb_base_phys & ~0x1F;
+       _osd_start_layer(sd, layer, fb_base_phys, cbcr_ofst);
+
+       if (layer == WIN_VID0) {
+               osd->pingpong =
+                   _osd_dm6446_vid0_pingpong(sd, osd->field_inversion,
+                                                      win->fb_base_phys,
+                                                      cfg);
+       }
+
+       spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void osd_get_layer_config(struct osd_state *sd, enum osd_layer layer,
+                                struct osd_layer_config *lconfig)
+{
+       struct osd_state *osd = sd;
+       struct osd_window_state *win = &osd->win[layer];
+       unsigned long flags;
+
+       spin_lock_irqsave(&osd->lock, flags);
+
+       *lconfig = win->lconfig;
+
+       spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+/**
+ * try_layer_config() - Try a specific configuration for the layer
+ * @sd: ptr to struct osd_state
+ * @layer: layer to configure
+ * @lconfig: layer configuration to try
+ *
+ * If the requested lconfig is completely rejected and the value of lconfig on
+ * exit is the current lconfig, then try_layer_config() returns 1.  Otherwise,
+ * try_layer_config() returns 0.  A return value of 0 does not necessarily mean
+ * that the value of lconfig on exit is identical to the value of lconfig on
+ * entry, but merely that it represents a change from the current lconfig.
+ */
+static int try_layer_config(struct osd_state *sd, enum osd_layer layer,
+                           struct osd_layer_config *lconfig)
+{
+       struct osd_state *osd = sd;
+       struct osd_window_state *win = &osd->win[layer];
+       int bad_config = 0;
+
+       /* verify that the pixel format is compatible with the layer */
+       switch (lconfig->pixfmt) {
+       case PIXFMT_1BPP:
+       case PIXFMT_2BPP:
+       case PIXFMT_4BPP:
+       case PIXFMT_8BPP:
+       case PIXFMT_RGB565:
+               if (osd->vpbe_type == VPBE_VERSION_1)
+                       bad_config = !is_vid_win(layer);
+               break;
+       case PIXFMT_YCBCRI:
+       case PIXFMT_YCRCBI:
+               bad_config = !is_vid_win(layer);
+               break;
+       case PIXFMT_RGB888:
+               if (osd->vpbe_type == VPBE_VERSION_1)
+                       bad_config = !is_vid_win(layer);
+               else if ((osd->vpbe_type == VPBE_VERSION_3) ||
+                        (osd->vpbe_type == VPBE_VERSION_2))
+                       bad_config = !is_osd_win(layer);
+               break;
+       case PIXFMT_NV12:
+               if (osd->vpbe_type != VPBE_VERSION_2)
+                       bad_config = 1;
+               else
+                       bad_config = is_osd_win(layer);
+               break;
+       case PIXFMT_OSD_ATTR:
+               bad_config = (layer != WIN_OSD1);
+               break;
+       default:
+               bad_config = 1;
+               break;
+       }
+       if (bad_config) {
+               /*
+                * The requested pixel format is incompatible with the layer,
+                * so keep the current layer configuration.
+                */
+               *lconfig = win->lconfig;
+               return bad_config;
+       }
+
+       /* DM6446: */
+       /* only one OSD window at a time can use RGB pixel formats */
+       if ((osd->vpbe_type == VPBE_VERSION_1) &&
+           is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) {
+               enum osd_pix_format pixfmt;
+
+               if (layer == WIN_OSD0)
+                       pixfmt = osd->win[WIN_OSD1].lconfig.pixfmt;
+               else
+                       pixfmt = osd->win[WIN_OSD0].lconfig.pixfmt;
+
+               if (is_rgb_pixfmt(pixfmt)) {
+                       /*
+                        * The other OSD window is already configured for an
+                        * RGB, so keep the current layer configuration.
+                        */
+                       *lconfig = win->lconfig;
+                       return 1;
+               }
+       }
+
+       /* DM6446: only one video window at a time can use RGB888 */
+       if ((osd->vpbe_type == VPBE_VERSION_1) && is_vid_win(layer) &&
+               lconfig->pixfmt == PIXFMT_RGB888) {
+               enum osd_pix_format pixfmt;
+
+               if (layer == WIN_VID0)
+                       pixfmt = osd->win[WIN_VID1].lconfig.pixfmt;
+               else
+                       pixfmt = osd->win[WIN_VID0].lconfig.pixfmt;
+
+               if (pixfmt == PIXFMT_RGB888) {
+                       /*
+                        * The other video window is already configured for
+                        * RGB888, so keep the current layer configuration.
+                        */
+                       *lconfig = win->lconfig;
+                       return 1;
+               }
+       }
+
+       /* window dimensions must be non-zero */
+       if (!lconfig->line_length || !lconfig->xsize || !lconfig->ysize) {
+               *lconfig = win->lconfig;
+               return 1;
+       }
+
+       /* round line_length up to a multiple of 32 */
+       lconfig->line_length = ((lconfig->line_length + 31) / 32) * 32;
+       lconfig->line_length =
+           min(lconfig->line_length, (unsigned)MAX_LINE_LENGTH);
+       lconfig->xsize = min(lconfig->xsize, (unsigned)MAX_WIN_SIZE);
+       lconfig->ysize = min(lconfig->ysize, (unsigned)MAX_WIN_SIZE);
+       lconfig->xpos = min(lconfig->xpos, (unsigned)MAX_WIN_SIZE);
+       lconfig->ypos = min(lconfig->ypos, (unsigned)MAX_WIN_SIZE);
+       lconfig->interlaced = (lconfig->interlaced != 0);
+       if (lconfig->interlaced) {
+               /* ysize and ypos must be even for interlaced displays */
+               lconfig->ysize &= ~1;
+               lconfig->ypos &= ~1;
+       }
+
+       return 0;
+}
+
+static void _osd_disable_vid_rgb888(struct osd_state *sd)
+{
+       /*
+        * The DM6446 supports RGB888 pixel format in a single video window.
+        * This routine disables RGB888 pixel format for both video windows.
+        * The caller must ensure that neither video window is currently
+        * configured for RGB888 pixel format.
+        */
+       if (sd->vpbe_type == VPBE_VERSION_1)
+               osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL);
+}
+
+static void _osd_enable_vid_rgb888(struct osd_state *sd,
+                                  enum osd_layer layer)
+{
+       /*
+        * The DM6446 supports RGB888 pixel format in a single video window.
+        * This routine enables RGB888 pixel format for the specified video
+        * window.  The caller must ensure that the other video window is not
+        * currently configured for RGB888 pixel format, as this routine will
+        * disable RGB888 pixel format for the other window.
+        */
+       if (sd->vpbe_type == VPBE_VERSION_1) {
+               if (layer == WIN_VID0)
+                       osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
+                                 OSD_MISCCTL_RGBEN, OSD_MISCCTL);
+               else if (layer == WIN_VID1)
+                       osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
+                                 OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
+                                 OSD_MISCCTL);
+       }
+}
+
+static void _osd_set_cbcr_order(struct osd_state *sd,
+                               enum osd_pix_format pixfmt)
+{
+       /*
+        * The caller must ensure that all windows using YC pixfmt use the same
+        * Cb/Cr order.
+        */
+       if (pixfmt == PIXFMT_YCBCRI)
+               osd_clear(sd, OSD_MODE_CS, OSD_MODE);
+       else if (pixfmt == PIXFMT_YCRCBI)
+               osd_set(sd, OSD_MODE_CS, OSD_MODE);
+}
+
+static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
+                                 const struct osd_layer_config *lconfig)
+{
+       u32 winmd = 0, winmd_mask = 0, bmw = 0;
+
+       _osd_set_cbcr_order(sd, lconfig->pixfmt);
+
+       switch (layer) {
+       case WIN_OSD0:
+               if (sd->vpbe_type == VPBE_VERSION_1) {
+                       winmd_mask |= OSD_OSDWIN0MD_RGB0E;
+                       if (lconfig->pixfmt == PIXFMT_RGB565)
+                               winmd |= OSD_OSDWIN0MD_RGB0E;
+               } else if ((sd->vpbe_type == VPBE_VERSION_3) ||
+                 (sd->vpbe_type == VPBE_VERSION_2)) {
+                       winmd_mask |= OSD_OSDWIN0MD_BMP0MD;
+                       switch (lconfig->pixfmt) {
+                       case PIXFMT_RGB565:
+                                       winmd |= (1 <<
+                                       OSD_OSDWIN0MD_BMP0MD_SHIFT);
+                                       break;
+                       case PIXFMT_RGB888:
+                               winmd |= (2 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
+                               _osd_enable_rgb888_pixblend(sd, OSDWIN_OSD0);
+                               break;
+                       case PIXFMT_YCBCRI:
+                       case PIXFMT_YCRCBI:
+                               winmd |= (3 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+
+               winmd_mask |= OSD_OSDWIN0MD_BMW0 | OSD_OSDWIN0MD_OFF0;
+
+               switch (lconfig->pixfmt) {
+               case PIXFMT_1BPP:
+                       bmw = 0;
+                       break;
+               case PIXFMT_2BPP:
+                       bmw = 1;
+                       break;
+               case PIXFMT_4BPP:
+                       bmw = 2;
+                       break;
+               case PIXFMT_8BPP:
+                       bmw = 3;
+                       break;
+               default:
+                       break;
+               }
+               winmd |= (bmw << OSD_OSDWIN0MD_BMW0_SHIFT);
+
+               if (lconfig->interlaced)
+                       winmd |= OSD_OSDWIN0MD_OFF0;
+
+               osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN0MD);
+               osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN0OFST);
+               osd_write(sd, lconfig->xpos, OSD_OSDWIN0XP);
+               osd_write(sd, lconfig->xsize, OSD_OSDWIN0XL);
+               if (lconfig->interlaced) {
+                       osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN0YP);
+                       osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN0YL);
+               } else {
+                       osd_write(sd, lconfig->ypos, OSD_OSDWIN0YP);
+                       osd_write(sd, lconfig->ysize, OSD_OSDWIN0YL);
+               }
+               break;
+       case WIN_VID0:
+               winmd_mask |= OSD_VIDWINMD_VFF0;
+               if (lconfig->interlaced)
+                       winmd |= OSD_VIDWINMD_VFF0;
+
+               osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD);
+               osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN0OFST);
+               osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP);
+               osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL);
+               /*
+                * For YUV420P format the register contents are
+                * duplicated in both VID registers
+                */
+               if ((sd->vpbe_type == VPBE_VERSION_2) &&
+                               (lconfig->pixfmt == PIXFMT_NV12)) {
+                       /* other window also */
+                       if (lconfig->interlaced) {
+                               winmd_mask |= OSD_VIDWINMD_VFF1;
+                               winmd |= OSD_VIDWINMD_VFF1;
+                               osd_modify(sd, winmd_mask, winmd,
+                                         OSD_VIDWINMD);
+                       }
+
+                       osd_modify(sd, OSD_MISCCTL_S420D,
+                                   OSD_MISCCTL_S420D, OSD_MISCCTL);
+                       osd_write(sd, lconfig->line_length >> 5,
+                                 OSD_VIDWIN1OFST);
+                       osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP);
+                       osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL);
+                       /*
+                         * if NV21 pixfmt and line length not 32B
+                         * aligned (e.g. NTSC), Need to set window
+                         * X pixel size to be 32B aligned as well
+                         */
+                       if (lconfig->xsize % 32) {
+                               osd_write(sd,
+                                         ((lconfig->xsize + 31) & ~31),
+                                         OSD_VIDWIN1XL);
+                               osd_write(sd,
+                                         ((lconfig->xsize + 31) & ~31),
+                                         OSD_VIDWIN0XL);
+                       }
+               } else if ((sd->vpbe_type == VPBE_VERSION_2) &&
+                               (lconfig->pixfmt != PIXFMT_NV12)) {
+                       osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D,
+                                               OSD_MISCCTL);
+               }
+
+               if (lconfig->interlaced) {
+                       osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN0YP);
+                       osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN0YL);
+                       if ((sd->vpbe_type == VPBE_VERSION_2) &&
+                               lconfig->pixfmt == PIXFMT_NV12) {
+                               osd_write(sd, lconfig->ypos >> 1,
+                                         OSD_VIDWIN1YP);
+                               osd_write(sd, lconfig->ysize >> 1,
+                                         OSD_VIDWIN1YL);
+                       }
+               } else {
+                       osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP);
+                       osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL);
+                       if ((sd->vpbe_type == VPBE_VERSION_2) &&
+                               lconfig->pixfmt == PIXFMT_NV12) {
+                               osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP);
+                               osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL);
+                       }
+               }
+               break;
+       case WIN_OSD1:
+               /*
+                * The caller must ensure that OSD1 is disabled prior to
+                * switching from a normal mode to attribute mode or from
+                * attribute mode to a normal mode.
+                */
+               if (lconfig->pixfmt == PIXFMT_OSD_ATTR) {
+                       if (sd->vpbe_type == VPBE_VERSION_1) {
+                               winmd_mask |= OSD_OSDWIN1MD_ATN1E |
+                               OSD_OSDWIN1MD_RGB1E | OSD_OSDWIN1MD_CLUTS1 |
+                               OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1;
+                       } else {
+                               winmd_mask |= OSD_OSDWIN1MD_BMP1MD |
+                               OSD_OSDWIN1MD_CLUTS1 | OSD_OSDWIN1MD_BLND1 |
+                               OSD_OSDWIN1MD_TE1;
+                       }
+               } else {
+                       if (sd->vpbe_type == VPBE_VERSION_1) {
+                               winmd_mask |= OSD_OSDWIN1MD_RGB1E;
+                               if (lconfig->pixfmt == PIXFMT_RGB565)
+                                       winmd |= OSD_OSDWIN1MD_RGB1E;
+                       } else if ((sd->vpbe_type == VPBE_VERSION_3)
+                                  || (sd->vpbe_type == VPBE_VERSION_2)) {
+                               winmd_mask |= OSD_OSDWIN1MD_BMP1MD;
+                               switch (lconfig->pixfmt) {
+                               case PIXFMT_RGB565:
+                                       winmd |=
+                                           (1 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
+                                       break;
+                               case PIXFMT_RGB888:
+                                       winmd |=
+                                           (2 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
+                                       _osd_enable_rgb888_pixblend(sd,
+                                                       OSDWIN_OSD1);
+                                       break;
+                               case PIXFMT_YCBCRI:
+                               case PIXFMT_YCRCBI:
+                                       winmd |=
+                                           (3 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
+                                       break;
+                               default:
+                                       break;
+                               }
+                       }
+
+                       winmd_mask |= OSD_OSDWIN1MD_BMW1;
+                       switch (lconfig->pixfmt) {
+                       case PIXFMT_1BPP:
+                               bmw = 0;
+                               break;
+                       case PIXFMT_2BPP:
+                               bmw = 1;
+                               break;
+                       case PIXFMT_4BPP:
+                               bmw = 2;
+                               break;
+                       case PIXFMT_8BPP:
+                               bmw = 3;
+                               break;
+                       default:
+                               break;
+                       }
+                       winmd |= (bmw << OSD_OSDWIN1MD_BMW1_SHIFT);
+               }
+
+               winmd_mask |= OSD_OSDWIN1MD_OFF1;
+               if (lconfig->interlaced)
+                       winmd |= OSD_OSDWIN1MD_OFF1;
+
+               osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN1MD);
+               osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN1OFST);
+               osd_write(sd, lconfig->xpos, OSD_OSDWIN1XP);
+               osd_write(sd, lconfig->xsize, OSD_OSDWIN1XL);
+               if (lconfig->interlaced) {
+                       osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN1YP);
+                       osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN1YL);
+               } else {
+                       osd_write(sd, lconfig->ypos, OSD_OSDWIN1YP);
+                       osd_write(sd, lconfig->ysize, OSD_OSDWIN1YL);
+               }
+               break;
+       case WIN_VID1:
+               winmd_mask |= OSD_VIDWINMD_VFF1;
+               if (lconfig->interlaced)
+                       winmd |= OSD_VIDWINMD_VFF1;
+
+               osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD);
+               osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN1OFST);
+               osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP);
+               osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL);
+               /*
+                * For YUV420P format the register contents are
+                * duplicated in both VID registers
+                */
+               if (sd->vpbe_type == VPBE_VERSION_2) {
+                       if (lconfig->pixfmt == PIXFMT_NV12) {
+                               /* other window also */
+                               if (lconfig->interlaced) {
+                                       winmd_mask |= OSD_VIDWINMD_VFF0;
+                                       winmd |= OSD_VIDWINMD_VFF0;
+                                       osd_modify(sd, winmd_mask, winmd,
+                                                 OSD_VIDWINMD);
+                               }
+                               osd_modify(sd, OSD_MISCCTL_S420D,
+                                          OSD_MISCCTL_S420D, OSD_MISCCTL);
+                               osd_write(sd, lconfig->line_length >> 5,
+                                         OSD_VIDWIN0OFST);
+                               osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP);
+                               osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL);
+                       } else {
+                               osd_modify(sd, OSD_MISCCTL_S420D,
+                                          ~OSD_MISCCTL_S420D, OSD_MISCCTL);
+                       }
+               }
+
+               if (lconfig->interlaced) {
+                       osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN1YP);
+                       osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN1YL);
+                       if ((sd->vpbe_type == VPBE_VERSION_2) &&
+                               lconfig->pixfmt == PIXFMT_NV12) {
+                               osd_write(sd, lconfig->ypos >> 1,
+                                         OSD_VIDWIN0YP);
+                               osd_write(sd, lconfig->ysize >> 1,
+                                         OSD_VIDWIN0YL);
+                       }
+               } else {
+                       osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP);
+                       osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL);
+                       if ((sd->vpbe_type == VPBE_VERSION_2) &&
+                               lconfig->pixfmt == PIXFMT_NV12) {
+                               osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP);
+                               osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL);
+                       }
+               }
+               break;
+       }
+}
+
+static int osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
+                               struct osd_layer_config *lconfig)
+{
+       struct osd_state *osd = sd;
+       struct osd_window_state *win = &osd->win[layer];
+       struct osd_layer_config *cfg = &win->lconfig;
+       unsigned long flags;
+       int reject_config;
+
+       spin_lock_irqsave(&osd->lock, flags);
+
+       reject_config = try_layer_config(sd, layer, lconfig);
+       if (reject_config) {
+               spin_unlock_irqrestore(&osd->lock, flags);
+               return reject_config;
+       }
+
+       /* update the current Cb/Cr order */
+       if (is_yc_pixfmt(lconfig->pixfmt))
+               osd->yc_pixfmt = lconfig->pixfmt;
+
+       /*
+        * If we are switching OSD1 from normal mode to attribute mode or from
+        * attribute mode to normal mode, then we must disable the window.
+        */
+       if (layer == WIN_OSD1) {
+               if (((lconfig->pixfmt == PIXFMT_OSD_ATTR) &&
+                 (cfg->pixfmt != PIXFMT_OSD_ATTR)) ||
+                 ((lconfig->pixfmt != PIXFMT_OSD_ATTR) &&
+                 (cfg->pixfmt == PIXFMT_OSD_ATTR))) {
+                       win->is_enabled = 0;
+                       _osd_disable_layer(sd, layer);
+               }
+       }
+
+       _osd_set_layer_config(sd, layer, lconfig);
+
+       if (layer == WIN_OSD1) {
+               struct osd_osdwin_state *osdwin_state =
+                   &osd->osdwin[OSDWIN_OSD1];
+
+               if ((lconfig->pixfmt != PIXFMT_OSD_ATTR) &&
+                 (cfg->pixfmt == PIXFMT_OSD_ATTR)) {
+                       /*
+                        * We just switched OSD1 from attribute mode to normal
+                        * mode, so we must initialize the CLUT select, the
+                        * blend factor, transparency colorkey enable, and
+                        * attenuation enable (DM6446 only) bits in the
+                        * OSDWIN1MD register.
+                        */
+                       _osd_set_osd_clut(sd, OSDWIN_OSD1,
+                                                  osdwin_state->clut);
+                       _osd_set_blending_factor(sd, OSDWIN_OSD1,
+                                                         osdwin_state->blend);
+                       if (osdwin_state->colorkey_blending) {
+                               _osd_enable_color_key(sd, OSDWIN_OSD1,
+                                                              osdwin_state->
+                                                              colorkey,
+                                                              lconfig->pixfmt);
+                       } else
+                               _osd_disable_color_key(sd, OSDWIN_OSD1);
+                       _osd_set_rec601_attenuation(sd, OSDWIN_OSD1,
+                                                   osdwin_state->
+                                                   rec601_attenuation);
+               } else if ((lconfig->pixfmt == PIXFMT_OSD_ATTR) &&
+                 (cfg->pixfmt != PIXFMT_OSD_ATTR)) {
+                       /*
+                        * We just switched OSD1 from normal mode to attribute
+                        * mode, so we must initialize the blink enable and
+                        * blink interval bits in the OSDATRMD register.
+                        */
+                       _osd_set_blink_attribute(sd, osd->is_blinking,
+                                                         osd->blink);
+               }
+       }
+
+       /*
+        * If we just switched to a 1-, 2-, or 4-bits-per-pixel bitmap format
+        * then configure a default palette map.
+        */
+       if ((lconfig->pixfmt != cfg->pixfmt) &&
+         ((lconfig->pixfmt == PIXFMT_1BPP) ||
+         (lconfig->pixfmt == PIXFMT_2BPP) ||
+         (lconfig->pixfmt == PIXFMT_4BPP))) {
+               enum osd_win_layer osdwin =
+                   ((layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1);
+               struct osd_osdwin_state *osdwin_state =
+                   &osd->osdwin[osdwin];
+               unsigned char clut_index;
+               unsigned char clut_entries = 0;
+
+               switch (lconfig->pixfmt) {
+               case PIXFMT_1BPP:
+                       clut_entries = 2;
+                       break;
+               case PIXFMT_2BPP:
+                       clut_entries = 4;
+                       break;
+               case PIXFMT_4BPP:
+                       clut_entries = 16;
+                       break;
+               default:
+                       break;
+               }
+               /*
+                * The default palette map maps the pixel value to the clut
+                * index, i.e. pixel value 0 maps to clut entry 0, pixel value
+                * 1 maps to clut entry 1, etc.
+                */
+               for (clut_index = 0; clut_index < 16; clut_index++) {
+                       osdwin_state->palette_map[clut_index] = clut_index;
+                       if (clut_index < clut_entries) {
+                               _osd_set_palette_map(sd, osdwin, clut_index,
+                                                    clut_index,
+                                                    lconfig->pixfmt);
+                       }
+               }
+       }
+
+       *cfg = *lconfig;
+       /* DM6446: configure the RGB888 enable and window selection */
+       if (osd->win[WIN_VID0].lconfig.pixfmt == PIXFMT_RGB888)
+               _osd_enable_vid_rgb888(sd, WIN_VID0);
+       else if (osd->win[WIN_VID1].lconfig.pixfmt == PIXFMT_RGB888)
+               _osd_enable_vid_rgb888(sd, WIN_VID1);
+       else
+               _osd_disable_vid_rgb888(sd);
+
+       if (layer == WIN_VID0) {
+               osd->pingpong =
+                   _osd_dm6446_vid0_pingpong(sd, osd->field_inversion,
+                                                      win->fb_base_phys,
+                                                      cfg);
+       }
+
+       spin_unlock_irqrestore(&osd->lock, flags);
+
+       return 0;
+}
+
+static void osd_init_layer(struct osd_state *sd, enum osd_layer layer)
+{
+       struct osd_state *osd = sd;
+       struct osd_window_state *win = &osd->win[layer];
+       enum osd_win_layer osdwin;
+       struct osd_osdwin_state *osdwin_state;
+       struct osd_layer_config *cfg = &win->lconfig;
+       unsigned long flags;
+
+       spin_lock_irqsave(&osd->lock, flags);
+
+       win->is_enabled = 0;
+       _osd_disable_layer(sd, layer);
+
+       win->h_zoom = ZOOM_X1;
+       win->v_zoom = ZOOM_X1;
+       _osd_set_zoom(sd, layer, win->h_zoom, win->v_zoom);
+
+       win->fb_base_phys = 0;
+       _osd_start_layer(sd, layer, win->fb_base_phys, 0);
+
+       cfg->line_length = 0;
+       cfg->xsize = 0;
+       cfg->ysize = 0;
+       cfg->xpos = 0;
+       cfg->ypos = 0;
+       cfg->interlaced = 0;
+       switch (layer) {
+       case WIN_OSD0:
+       case WIN_OSD1:
+               osdwin = (layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1;
+               osdwin_state = &osd->osdwin[osdwin];
+               /*
+                * Other code relies on the fact that OSD windows default to a
+                * bitmap pixel format when they are deallocated, so don't
+                * change this default pixel format.
+                */
+               cfg->pixfmt = PIXFMT_8BPP;
+               _osd_set_layer_config(sd, layer, cfg);
+               osdwin_state->clut = RAM_CLUT;
+               _osd_set_osd_clut(sd, osdwin, osdwin_state->clut);
+               osdwin_state->colorkey_blending = 0;
+               _osd_disable_color_key(sd, osdwin);
+               osdwin_state->blend = OSD_8_VID_0;
+               _osd_set_blending_factor(sd, osdwin, osdwin_state->blend);
+               osdwin_state->rec601_attenuation = 0;
+               _osd_set_rec601_attenuation(sd, osdwin,
+                                                    osdwin_state->
+                                                    rec601_attenuation);
+               if (osdwin == OSDWIN_OSD1) {
+                       osd->is_blinking = 0;
+                       osd->blink = BLINK_X1;
+               }
+               break;
+       case WIN_VID0:
+       case WIN_VID1:
+               cfg->pixfmt = osd->yc_pixfmt;
+               _osd_set_layer_config(sd, layer, cfg);
+               break;
+       }
+
+       spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void osd_release_layer(struct osd_state *sd, enum osd_layer layer)
+{
+       struct osd_state *osd = sd;
+       struct osd_window_state *win = &osd->win[layer];
+       unsigned long flags;
+
+       spin_lock_irqsave(&osd->lock, flags);
+
+       if (!win->is_allocated) {
+               spin_unlock_irqrestore(&osd->lock, flags);
+               return;
+       }
+
+       spin_unlock_irqrestore(&osd->lock, flags);
+       osd_init_layer(sd, layer);
+       spin_lock_irqsave(&osd->lock, flags);
+
+       win->is_allocated = 0;
+
+       spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static int osd_request_layer(struct osd_state *sd, enum osd_layer layer)
+{
+       struct osd_state *osd = sd;
+       struct osd_window_state *win = &osd->win[layer];
+       unsigned long flags;
+
+       spin_lock_irqsave(&osd->lock, flags);
+
+       if (win->is_allocated) {
+               spin_unlock_irqrestore(&osd->lock, flags);
+               return -1;
+       }
+       win->is_allocated = 1;
+
+       spin_unlock_irqrestore(&osd->lock, flags);
+
+       return 0;
+}
+
+static void _osd_init(struct osd_state *sd)
+{
+       osd_write(sd, 0, OSD_MODE);
+       osd_write(sd, 0, OSD_VIDWINMD);
+       osd_write(sd, 0, OSD_OSDWIN0MD);
+       osd_write(sd, 0, OSD_OSDWIN1MD);
+       osd_write(sd, 0, OSD_RECTCUR);
+       osd_write(sd, 0, OSD_MISCCTL);
+       if (sd->vpbe_type == VPBE_VERSION_3) {
+               osd_write(sd, 0, OSD_VBNDRY);
+               osd_write(sd, 0, OSD_EXTMODE);
+               osd_write(sd, OSD_MISCCTL_DMANG, OSD_MISCCTL);
+       }
+}
+
+static void osd_set_left_margin(struct osd_state *sd, u32 val)
+{
+       osd_write(sd, val, OSD_BASEPX);
+}
+
+static void osd_set_top_margin(struct osd_state *sd, u32 val)
+{
+       osd_write(sd, val, OSD_BASEPY);
+}
+
+static int osd_initialize(struct osd_state *osd)
+{
+       if (osd == NULL)
+               return -ENODEV;
+       _osd_init(osd);
+
+       /* set default Cb/Cr order */
+       osd->yc_pixfmt = PIXFMT_YCBCRI;
+
+       if (osd->vpbe_type == VPBE_VERSION_3) {
+               /*
+                * ROM CLUT1 on the DM355 is similar (identical?) to ROM CLUT0
+                * on the DM6446, so make ROM_CLUT1 the default on the DM355.
+                */
+               osd->rom_clut = ROM_CLUT1;
+       }
+
+       _osd_set_field_inversion(osd, osd->field_inversion);
+       _osd_set_rom_clut(osd, osd->rom_clut);
+
+       osd_init_layer(osd, WIN_OSD0);
+       osd_init_layer(osd, WIN_VID0);
+       osd_init_layer(osd, WIN_OSD1);
+       osd_init_layer(osd, WIN_VID1);
+
+       return 0;
+}
+
+static const struct vpbe_osd_ops osd_ops = {
+       .initialize = osd_initialize,
+       .request_layer = osd_request_layer,
+       .release_layer = osd_release_layer,
+       .enable_layer = osd_enable_layer,
+       .disable_layer = osd_disable_layer,
+       .set_layer_config = osd_set_layer_config,
+       .get_layer_config = osd_get_layer_config,
+       .start_layer = osd_start_layer,
+       .set_left_margin = osd_set_left_margin,
+       .set_top_margin = osd_set_top_margin,
+};
+
+static int osd_probe(struct platform_device *pdev)
+{
+       const struct platform_device_id *pdev_id;
+       struct osd_state *osd;
+       struct resource *res;
+
+       pdev_id = platform_get_device_id(pdev);
+       if (!pdev_id)
+               return -EINVAL;
+
+       osd = devm_kzalloc(&pdev->dev, sizeof(struct osd_state), GFP_KERNEL);
+       if (osd == NULL)
+               return -ENOMEM;
+
+
+       osd->dev = &pdev->dev;
+       osd->vpbe_type = pdev_id->driver_data;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       osd->osd_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(osd->osd_base))
+               return PTR_ERR(osd->osd_base);
+
+       osd->osd_base_phys = res->start;
+       osd->osd_size = resource_size(res);
+       spin_lock_init(&osd->lock);
+       osd->ops = osd_ops;
+       platform_set_drvdata(pdev, osd);
+       dev_notice(osd->dev, "OSD sub device probe success\n");
+
+       return 0;
+}
+
+static int osd_remove(struct platform_device *pdev)
+{
+       return 0;
+}
+
+static struct platform_driver osd_driver = {
+       .probe          = osd_probe,
+       .remove         = osd_remove,
+       .driver         = {
+               .name   = MODULE_NAME,
+       },
+       .id_table       = vpbe_osd_devtype
+};
+
+module_platform_driver(osd_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DaVinci OSD Manager Driver");
+MODULE_AUTHOR("Texas Instruments");
diff --git a/drivers/media/platform/ti/davinci/vpbe_osd_regs.h b/drivers/media/platform/ti/davinci/vpbe_osd_regs.h
new file mode 100644 (file)
index 0000000..cecd599
--- /dev/null
@@ -0,0 +1,352 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2006-2010 Texas Instruments Inc
+ */
+#ifndef _VPBE_OSD_REGS_H
+#define _VPBE_OSD_REGS_H
+
+/* VPBE Global Registers */
+#define VPBE_PID                               0x0
+#define VPBE_PCR                               0x4
+
+/* VPSS CLock Registers */
+#define VPSSCLK_PID                            0x00
+#define VPSSCLK_CLKCTRL                                0x04
+
+/* VPSS Buffer Logic Registers */
+#define VPSSBL_PID                             0x00
+#define VPSSBL_PCR                             0x04
+#define VPSSBL_BCR                             0x08
+#define VPSSBL_INTSTAT                         0x0C
+#define VPSSBL_INTSEL                          0x10
+#define VPSSBL_EVTSEL                          0x14
+#define VPSSBL_MEMCTRL                         0x18
+#define VPSSBL_CCDCMUX                         0x1C
+
+/* DM365 ISP5 system configuration */
+#define ISP5_PID                               0x0
+#define ISP5_PCCR                              0x4
+#define ISP5_BCR                               0x8
+#define ISP5_INTSTAT                           0xC
+#define ISP5_INTSEL1                           0x10
+#define ISP5_INTSEL2                           0x14
+#define ISP5_INTSEL3                           0x18
+#define ISP5_EVTSEL                            0x1c
+#define ISP5_CCDCMUX                           0x20
+
+/* VPBE On-Screen Display Subsystem Registers (OSD) */
+#define OSD_MODE                               0x00
+#define OSD_VIDWINMD                           0x04
+#define OSD_OSDWIN0MD                          0x08
+#define OSD_OSDWIN1MD                          0x0C
+#define OSD_OSDATRMD                           0x0C
+#define OSD_RECTCUR                            0x10
+#define OSD_VIDWIN0OFST                                0x18
+#define OSD_VIDWIN1OFST                                0x1C
+#define OSD_OSDWIN0OFST                                0x20
+#define OSD_OSDWIN1OFST                                0x24
+#define OSD_VIDWINADH                          0x28
+#define OSD_VIDWIN0ADL                         0x2C
+#define OSD_VIDWIN0ADR                         0x2C
+#define OSD_VIDWIN1ADL                         0x30
+#define OSD_VIDWIN1ADR                         0x30
+#define OSD_OSDWINADH                          0x34
+#define OSD_OSDWIN0ADL                         0x38
+#define OSD_OSDWIN0ADR                         0x38
+#define OSD_OSDWIN1ADL                         0x3C
+#define OSD_OSDWIN1ADR                         0x3C
+#define OSD_BASEPX                             0x40
+#define OSD_BASEPY                             0x44
+#define OSD_VIDWIN0XP                          0x48
+#define OSD_VIDWIN0YP                          0x4C
+#define OSD_VIDWIN0XL                          0x50
+#define OSD_VIDWIN0YL                          0x54
+#define OSD_VIDWIN1XP                          0x58
+#define OSD_VIDWIN1YP                          0x5C
+#define OSD_VIDWIN1XL                          0x60
+#define OSD_VIDWIN1YL                          0x64
+#define OSD_OSDWIN0XP                          0x68
+#define OSD_OSDWIN0YP                          0x6C
+#define OSD_OSDWIN0XL                          0x70
+#define OSD_OSDWIN0YL                          0x74
+#define OSD_OSDWIN1XP                          0x78
+#define OSD_OSDWIN1YP                          0x7C
+#define OSD_OSDWIN1XL                          0x80
+#define OSD_OSDWIN1YL                          0x84
+#define OSD_CURXP                              0x88
+#define OSD_CURYP                              0x8C
+#define OSD_CURXL                              0x90
+#define OSD_CURYL                              0x94
+#define OSD_W0BMP01                            0xA0
+#define OSD_W0BMP23                            0xA4
+#define OSD_W0BMP45                            0xA8
+#define OSD_W0BMP67                            0xAC
+#define OSD_W0BMP89                            0xB0
+#define OSD_W0BMPAB                            0xB4
+#define OSD_W0BMPCD                            0xB8
+#define OSD_W0BMPEF                            0xBC
+#define OSD_W1BMP01                            0xC0
+#define OSD_W1BMP23                            0xC4
+#define OSD_W1BMP45                            0xC8
+#define OSD_W1BMP67                            0xCC
+#define OSD_W1BMP89                            0xD0
+#define OSD_W1BMPAB                            0xD4
+#define OSD_W1BMPCD                            0xD8
+#define OSD_W1BMPEF                            0xDC
+#define OSD_VBNDRY                             0xE0
+#define OSD_EXTMODE                            0xE4
+#define OSD_MISCCTL                            0xE8
+#define OSD_CLUTRAMYCB                         0xEC
+#define OSD_CLUTRAMCR                          0xF0
+#define OSD_TRANSPVAL                          0xF4
+#define OSD_TRANSPVALL                         0xF4
+#define OSD_TRANSPVALU                         0xF8
+#define OSD_TRANSPBMPIDX                       0xFC
+#define OSD_PPVWIN0ADR                         0xFC
+
+/* bit definitions */
+#define VPBE_PCR_VENC_DIV                      (1 << 1)
+#define VPBE_PCR_CLK_OFF                       (1 << 0)
+
+#define VPSSBL_INTSTAT_HSSIINT                 (1 << 14)
+#define VPSSBL_INTSTAT_CFALDINT                        (1 << 13)
+#define VPSSBL_INTSTAT_IPIPE_INT5              (1 << 12)
+#define VPSSBL_INTSTAT_IPIPE_INT4              (1 << 11)
+#define VPSSBL_INTSTAT_IPIPE_INT3              (1 << 10)
+#define VPSSBL_INTSTAT_IPIPE_INT2              (1 << 9)
+#define VPSSBL_INTSTAT_IPIPE_INT1              (1 << 8)
+#define VPSSBL_INTSTAT_IPIPE_INT0              (1 << 7)
+#define VPSSBL_INTSTAT_IPIPEIFINT              (1 << 6)
+#define VPSSBL_INTSTAT_OSDINT                  (1 << 5)
+#define VPSSBL_INTSTAT_VENCINT                 (1 << 4)
+#define VPSSBL_INTSTAT_H3AINT                  (1 << 3)
+#define VPSSBL_INTSTAT_CCDC_VDINT2             (1 << 2)
+#define VPSSBL_INTSTAT_CCDC_VDINT1             (1 << 1)
+#define VPSSBL_INTSTAT_CCDC_VDINT0             (1 << 0)
+
+/* DM365 ISP5 bit definitions */
+#define ISP5_INTSTAT_VENCINT                   (1 << 21)
+#define ISP5_INTSTAT_OSDINT                    (1 << 20)
+
+/* VMOD TVTYP options for HDMD=0 */
+#define SDTV_NTSC                              0
+#define SDTV_PAL                               1
+/* VMOD TVTYP options for HDMD=1 */
+#define HDTV_525P                              0
+#define HDTV_625P                              1
+#define HDTV_1080I                             2
+#define HDTV_720P                              3
+
+#define OSD_MODE_CS                            (1 << 15)
+#define OSD_MODE_OVRSZ                         (1 << 14)
+#define OSD_MODE_OHRSZ                         (1 << 13)
+#define OSD_MODE_EF                            (1 << 12)
+#define OSD_MODE_VVRSZ                         (1 << 11)
+#define OSD_MODE_VHRSZ                         (1 << 10)
+#define OSD_MODE_FSINV                         (1 << 9)
+#define OSD_MODE_BCLUT                         (1 << 8)
+#define OSD_MODE_CABG_SHIFT                    0
+#define OSD_MODE_CABG                          (0xff << 0)
+
+#define OSD_VIDWINMD_VFINV                     (1 << 15)
+#define OSD_VIDWINMD_V1EFC                     (1 << 14)
+#define OSD_VIDWINMD_VHZ1_SHIFT                        12
+#define OSD_VIDWINMD_VHZ1                      (3 << 12)
+#define OSD_VIDWINMD_VVZ1_SHIFT                        10
+#define OSD_VIDWINMD_VVZ1                      (3 << 10)
+#define OSD_VIDWINMD_VFF1                      (1 << 9)
+#define OSD_VIDWINMD_ACT1                      (1 << 8)
+#define OSD_VIDWINMD_V0EFC                     (1 << 6)
+#define OSD_VIDWINMD_VHZ0_SHIFT                        4
+#define OSD_VIDWINMD_VHZ0                      (3 << 4)
+#define OSD_VIDWINMD_VVZ0_SHIFT                        2
+#define OSD_VIDWINMD_VVZ0                      (3 << 2)
+#define OSD_VIDWINMD_VFF0                      (1 << 1)
+#define OSD_VIDWINMD_ACT0                      (1 << 0)
+
+#define OSD_OSDWIN0MD_ATN0E                    (1 << 14)
+#define OSD_OSDWIN0MD_RGB0E                    (1 << 13)
+#define OSD_OSDWIN0MD_BMP0MD_SHIFT             13
+#define OSD_OSDWIN0MD_BMP0MD                   (3 << 13)
+#define OSD_OSDWIN0MD_CLUTS0                   (1 << 12)
+#define OSD_OSDWIN0MD_OHZ0_SHIFT               10
+#define OSD_OSDWIN0MD_OHZ0                     (3 << 10)
+#define OSD_OSDWIN0MD_OVZ0_SHIFT               8
+#define OSD_OSDWIN0MD_OVZ0                     (3 << 8)
+#define OSD_OSDWIN0MD_BMW0_SHIFT               6
+#define OSD_OSDWIN0MD_BMW0                     (3 << 6)
+#define OSD_OSDWIN0MD_BLND0_SHIFT              3
+#define OSD_OSDWIN0MD_BLND0                    (7 << 3)
+#define OSD_OSDWIN0MD_TE0                      (1 << 2)
+#define OSD_OSDWIN0MD_OFF0                     (1 << 1)
+#define OSD_OSDWIN0MD_OACT0                    (1 << 0)
+
+#define OSD_OSDWIN1MD_OASW                     (1 << 15)
+#define OSD_OSDWIN1MD_ATN1E                    (1 << 14)
+#define OSD_OSDWIN1MD_RGB1E                    (1 << 13)
+#define OSD_OSDWIN1MD_BMP1MD_SHIFT             13
+#define OSD_OSDWIN1MD_BMP1MD                   (3 << 13)
+#define OSD_OSDWIN1MD_CLUTS1                   (1 << 12)
+#define OSD_OSDWIN1MD_OHZ1_SHIFT               10
+#define OSD_OSDWIN1MD_OHZ1                     (3 << 10)
+#define OSD_OSDWIN1MD_OVZ1_SHIFT               8
+#define OSD_OSDWIN1MD_OVZ1                     (3 << 8)
+#define OSD_OSDWIN1MD_BMW1_SHIFT               6
+#define OSD_OSDWIN1MD_BMW1                     (3 << 6)
+#define OSD_OSDWIN1MD_BLND1_SHIFT              3
+#define OSD_OSDWIN1MD_BLND1                    (7 << 3)
+#define OSD_OSDWIN1MD_TE1                      (1 << 2)
+#define OSD_OSDWIN1MD_OFF1                     (1 << 1)
+#define OSD_OSDWIN1MD_OACT1                    (1 << 0)
+
+#define OSD_OSDATRMD_OASW                      (1 << 15)
+#define OSD_OSDATRMD_OHZA_SHIFT                        10
+#define OSD_OSDATRMD_OHZA                      (3 << 10)
+#define OSD_OSDATRMD_OVZA_SHIFT                        8
+#define OSD_OSDATRMD_OVZA                      (3 << 8)
+#define OSD_OSDATRMD_BLNKINT_SHIFT             6
+#define OSD_OSDATRMD_BLNKINT                   (3 << 6)
+#define OSD_OSDATRMD_OFFA                      (1 << 1)
+#define OSD_OSDATRMD_BLNK                      (1 << 0)
+
+#define OSD_RECTCUR_RCAD_SHIFT                 8
+#define OSD_RECTCUR_RCAD                       (0xff << 8)
+#define OSD_RECTCUR_CLUTSR                     (1 << 7)
+#define OSD_RECTCUR_RCHW_SHIFT                 4
+#define OSD_RECTCUR_RCHW                       (7 << 4)
+#define OSD_RECTCUR_RCVW_SHIFT                 1
+#define OSD_RECTCUR_RCVW                       (7 << 1)
+#define OSD_RECTCUR_RCACT                      (1 << 0)
+
+#define OSD_VIDWIN0OFST_V0LO                   (0x1ff << 0)
+
+#define OSD_VIDWIN1OFST_V1LO                   (0x1ff << 0)
+
+#define OSD_OSDWIN0OFST_O0LO                   (0x1ff << 0)
+
+#define OSD_OSDWIN1OFST_O1LO                   (0x1ff << 0)
+
+#define OSD_WINOFST_AH_SHIFT                   9
+
+#define OSD_VIDWIN0OFST_V0AH                   (0xf << 9)
+#define OSD_VIDWIN1OFST_V1AH                   (0xf << 9)
+#define OSD_OSDWIN0OFST_O0AH                   (0xf << 9)
+#define OSD_OSDWIN1OFST_O1AH                   (0xf << 9)
+
+#define OSD_VIDWINADH_V1AH_SHIFT               8
+#define OSD_VIDWINADH_V1AH                     (0x7f << 8)
+#define OSD_VIDWINADH_V0AH_SHIFT               0
+#define OSD_VIDWINADH_V0AH                     (0x7f << 0)
+
+#define OSD_VIDWIN0ADL_V0AL                    (0xffff << 0)
+
+#define OSD_VIDWIN1ADL_V1AL                    (0xffff << 0)
+
+#define OSD_OSDWINADH_O1AH_SHIFT               8
+#define OSD_OSDWINADH_O1AH                     (0x7f << 8)
+#define OSD_OSDWINADH_O0AH_SHIFT               0
+#define OSD_OSDWINADH_O0AH                     (0x7f << 0)
+
+#define OSD_OSDWIN0ADL_O0AL                    (0xffff << 0)
+
+#define OSD_OSDWIN1ADL_O1AL                    (0xffff << 0)
+
+#define OSD_BASEPX_BPX                         (0x3ff << 0)
+
+#define OSD_BASEPY_BPY                         (0x1ff << 0)
+
+#define OSD_VIDWIN0XP_V0X                      (0x7ff << 0)
+
+#define OSD_VIDWIN0YP_V0Y                      (0x7ff << 0)
+
+#define OSD_VIDWIN0XL_V0W                      (0x7ff << 0)
+
+#define OSD_VIDWIN0YL_V0H                      (0x7ff << 0)
+
+#define OSD_VIDWIN1XP_V1X                      (0x7ff << 0)
+
+#define OSD_VIDWIN1YP_V1Y                      (0x7ff << 0)
+
+#define OSD_VIDWIN1XL_V1W                      (0x7ff << 0)
+
+#define OSD_VIDWIN1YL_V1H                      (0x7ff << 0)
+
+#define OSD_OSDWIN0XP_W0X                      (0x7ff << 0)
+
+#define OSD_OSDWIN0YP_W0Y                      (0x7ff << 0)
+
+#define OSD_OSDWIN0XL_W0W                      (0x7ff << 0)
+
+#define OSD_OSDWIN0YL_W0H                      (0x7ff << 0)
+
+#define OSD_OSDWIN1XP_W1X                      (0x7ff << 0)
+
+#define OSD_OSDWIN1YP_W1Y                      (0x7ff << 0)
+
+#define OSD_OSDWIN1XL_W1W                      (0x7ff << 0)
+
+#define OSD_OSDWIN1YL_W1H                      (0x7ff << 0)
+
+#define OSD_CURXP_RCSX                         (0x7ff << 0)
+
+#define OSD_CURYP_RCSY                         (0x7ff << 0)
+
+#define OSD_CURXL_RCSW                         (0x7ff << 0)
+
+#define OSD_CURYL_RCSH                         (0x7ff << 0)
+
+#define OSD_EXTMODE_EXPMDSEL                   (1 << 15)
+#define OSD_EXTMODE_SCRNHEXP_SHIFT             13
+#define OSD_EXTMODE_SCRNHEXP                   (3 << 13)
+#define OSD_EXTMODE_SCRNVEXP                   (1 << 12)
+#define OSD_EXTMODE_OSD1BLDCHR                 (1 << 11)
+#define OSD_EXTMODE_OSD0BLDCHR                 (1 << 10)
+#define OSD_EXTMODE_ATNOSD1EN                  (1 << 9)
+#define OSD_EXTMODE_ATNOSD0EN                  (1 << 8)
+#define OSD_EXTMODE_OSDHRSZ15                  (1 << 7)
+#define OSD_EXTMODE_VIDHRSZ15                  (1 << 6)
+#define OSD_EXTMODE_ZMFILV1HEN                 (1 << 5)
+#define OSD_EXTMODE_ZMFILV1VEN                 (1 << 4)
+#define OSD_EXTMODE_ZMFILV0HEN                 (1 << 3)
+#define OSD_EXTMODE_ZMFILV0VEN                 (1 << 2)
+#define OSD_EXTMODE_EXPFILHEN                  (1 << 1)
+#define OSD_EXTMODE_EXPFILVEN                  (1 << 0)
+
+#define OSD_MISCCTL_BLDSEL                     (1 << 15)
+#define OSD_MISCCTL_S420D                      (1 << 14)
+#define OSD_MISCCTL_BMAPT                      (1 << 13)
+#define OSD_MISCCTL_DM365M                     (1 << 12)
+#define OSD_MISCCTL_RGBEN                      (1 << 7)
+#define OSD_MISCCTL_RGBWIN                     (1 << 6)
+#define OSD_MISCCTL_DMANG                      (1 << 6)
+#define OSD_MISCCTL_TMON                       (1 << 5)
+#define OSD_MISCCTL_RSEL                       (1 << 4)
+#define OSD_MISCCTL_CPBSY                      (1 << 3)
+#define OSD_MISCCTL_PPSW                       (1 << 2)
+#define OSD_MISCCTL_PPRV                       (1 << 1)
+
+#define OSD_CLUTRAMYCB_Y_SHIFT                 8
+#define OSD_CLUTRAMYCB_Y                       (0xff << 8)
+#define OSD_CLUTRAMYCB_CB_SHIFT                        0
+#define OSD_CLUTRAMYCB_CB                      (0xff << 0)
+
+#define OSD_CLUTRAMCR_CR_SHIFT                 8
+#define OSD_CLUTRAMCR_CR                       (0xff << 8)
+#define OSD_CLUTRAMCR_CADDR_SHIFT              0
+#define OSD_CLUTRAMCR_CADDR                    (0xff << 0)
+
+#define OSD_TRANSPVAL_RGBTRANS                 (0xffff << 0)
+
+#define OSD_TRANSPVALL_RGBL                    (0xffff << 0)
+
+#define OSD_TRANSPVALU_Y_SHIFT                 8
+#define OSD_TRANSPVALU_Y                       (0xff << 8)
+#define OSD_TRANSPVALU_RGBU_SHIFT              0
+#define OSD_TRANSPVALU_RGBU                    (0xff << 0)
+
+#define OSD_TRANSPBMPIDX_BMP1_SHIFT            8
+#define OSD_TRANSPBMPIDX_BMP1                  (0xff << 8)
+#define OSD_TRANSPBMPIDX_BMP0_SHIFT            0
+#define OSD_TRANSPBMPIDX_BMP0                  0xff
+
+#endif                         /* _DAVINCI_VPBE_H_ */
diff --git a/drivers/media/platform/ti/davinci/vpbe_venc.c b/drivers/media/platform/ti/davinci/vpbe_venc.c
new file mode 100644 (file)
index 0000000..4c8e31d
--- /dev/null
@@ -0,0 +1,676 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2010 Texas Instruments Inc
+ */
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+
+#include <linux/platform_data/i2c-davinci.h>
+
+#include <linux/io.h>
+
+#include <media/davinci/vpbe_types.h>
+#include <media/davinci/vpbe_venc.h>
+#include <media/davinci/vpss.h>
+#include <media/v4l2-device.h>
+
+#include "vpbe_venc_regs.h"
+
+#define MODULE_NAME    "davinci-vpbe-venc"
+
+static const struct platform_device_id vpbe_venc_devtype[] = {
+       {
+               .name = DM644X_VPBE_VENC_SUBDEV_NAME,
+               .driver_data = VPBE_VERSION_1,
+       }, {
+               .name = DM365_VPBE_VENC_SUBDEV_NAME,
+               .driver_data = VPBE_VERSION_2,
+       }, {
+               .name = DM355_VPBE_VENC_SUBDEV_NAME,
+               .driver_data = VPBE_VERSION_3,
+       },
+       {
+               /* sentinel */
+       }
+};
+
+MODULE_DEVICE_TABLE(platform, vpbe_venc_devtype);
+
+static int debug = 2;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level 0-2");
+
+struct venc_state {
+       struct v4l2_subdev sd;
+       struct venc_callback *callback;
+       struct venc_platform_data *pdata;
+       struct device *pdev;
+       u32 output;
+       v4l2_std_id std;
+       spinlock_t lock;
+       void __iomem *venc_base;
+       void __iomem *vdaccfg_reg;
+       enum vpbe_version venc_type;
+};
+
+static inline struct venc_state *to_state(struct v4l2_subdev *sd)
+{
+       return container_of(sd, struct venc_state, sd);
+}
+
+static inline u32 venc_read(struct v4l2_subdev *sd, u32 offset)
+{
+       struct venc_state *venc = to_state(sd);
+
+       return readl(venc->venc_base + offset);
+}
+
+static inline u32 venc_write(struct v4l2_subdev *sd, u32 offset, u32 val)
+{
+       struct venc_state *venc = to_state(sd);
+
+       writel(val, (venc->venc_base + offset));
+
+       return val;
+}
+
+static inline u32 venc_modify(struct v4l2_subdev *sd, u32 offset,
+                                u32 val, u32 mask)
+{
+       u32 new_val = (venc_read(sd, offset) & ~mask) | (val & mask);
+
+       venc_write(sd, offset, new_val);
+
+       return new_val;
+}
+
+static inline u32 vdaccfg_write(struct v4l2_subdev *sd, u32 val)
+{
+       struct venc_state *venc = to_state(sd);
+
+       writel(val, venc->vdaccfg_reg);
+
+       val = readl(venc->vdaccfg_reg);
+
+       return val;
+}
+
+#define VDAC_COMPONENT 0x543
+#define VDAC_S_VIDEO   0x210
+/* This function sets the dac of the VPBE for various outputs
+ */
+static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index)
+{
+       switch (out_index) {
+       case 0:
+               v4l2_dbg(debug, 1, sd, "Setting output to Composite\n");
+               venc_write(sd, VENC_DACSEL, 0);
+               break;
+       case 1:
+               v4l2_dbg(debug, 1, sd, "Setting output to Component\n");
+               venc_write(sd, VENC_DACSEL, VDAC_COMPONENT);
+               break;
+       case 2:
+               v4l2_dbg(debug, 1, sd, "Setting output to S-video\n");
+               venc_write(sd, VENC_DACSEL, VDAC_S_VIDEO);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable)
+{
+       struct venc_state *venc = to_state(sd);
+
+       v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n");
+
+       if (benable) {
+               venc_write(sd, VENC_VMOD, 0);
+               venc_write(sd, VENC_CVBS, 0);
+               venc_write(sd, VENC_LCDOUT, 0);
+               venc_write(sd, VENC_HSPLS, 0);
+               venc_write(sd, VENC_HSTART, 0);
+               venc_write(sd, VENC_HVALID, 0);
+               venc_write(sd, VENC_HINT, 0);
+               venc_write(sd, VENC_VSPLS, 0);
+               venc_write(sd, VENC_VSTART, 0);
+               venc_write(sd, VENC_VVALID, 0);
+               venc_write(sd, VENC_VINT, 0);
+               venc_write(sd, VENC_YCCCTL, 0);
+               venc_write(sd, VENC_DACSEL, 0);
+
+       } else {
+               venc_write(sd, VENC_VMOD, 0);
+               /* disable VCLK output pin enable */
+               venc_write(sd, VENC_VIDCTL, 0x141);
+
+               /* Disable output sync pins */
+               venc_write(sd, VENC_SYNCCTL, 0);
+
+               /* Disable DCLOCK */
+               venc_write(sd, VENC_DCLKCTL, 0);
+               venc_write(sd, VENC_DRGBX1, 0x0000057C);
+
+               /* Disable LCD output control (accepting default polarity) */
+               venc_write(sd, VENC_LCDOUT, 0);
+               if (venc->venc_type != VPBE_VERSION_3)
+                       venc_write(sd, VENC_CMPNT, 0x100);
+               venc_write(sd, VENC_HSPLS, 0);
+               venc_write(sd, VENC_HINT, 0);
+               venc_write(sd, VENC_HSTART, 0);
+               venc_write(sd, VENC_HVALID, 0);
+
+               venc_write(sd, VENC_VSPLS, 0);
+               venc_write(sd, VENC_VINT, 0);
+               venc_write(sd, VENC_VSTART, 0);
+               venc_write(sd, VENC_VVALID, 0);
+
+               venc_write(sd, VENC_HSDLY, 0);
+               venc_write(sd, VENC_VSDLY, 0);
+
+               venc_write(sd, VENC_YCCCTL, 0);
+               venc_write(sd, VENC_VSTARTA, 0);
+
+               /* Set OSD clock and OSD Sync Adavance registers */
+               venc_write(sd, VENC_OSDCLK0, 1);
+               venc_write(sd, VENC_OSDCLK1, 2);
+       }
+}
+
+static void
+venc_enable_vpss_clock(int venc_type,
+                      enum vpbe_enc_timings_type type,
+                      unsigned int pclock)
+{
+       if (venc_type == VPBE_VERSION_1)
+               return;
+
+       if (venc_type == VPBE_VERSION_2 && (type == VPBE_ENC_STD || (type ==
+           VPBE_ENC_DV_TIMINGS && pclock <= 27000000))) {
+               vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
+               vpss_enable_clock(VPSS_VPBE_CLOCK, 1);
+               return;
+       }
+
+       if (venc_type == VPBE_VERSION_3 && type == VPBE_ENC_STD)
+               vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 0);
+}
+
+#define VDAC_CONFIG_SD_V3      0x0E21A6B6
+#define VDAC_CONFIG_SD_V2      0x081141CF
+/*
+ * setting NTSC mode
+ */
+static int venc_set_ntsc(struct v4l2_subdev *sd)
+{
+       struct venc_state *venc = to_state(sd);
+       struct venc_platform_data *pdata = venc->pdata;
+
+       v4l2_dbg(debug, 2, sd, "venc_set_ntsc\n");
+
+       /* Setup clock at VPSS & VENC for SD */
+       vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
+       if (pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_525_60) < 0)
+               return -EINVAL;
+
+       venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_STD, V4L2_STD_525_60);
+       venc_enabledigitaloutput(sd, 0);
+
+       if (venc->venc_type == VPBE_VERSION_3) {
+               venc_write(sd, VENC_CLKCTL, 0x01);
+               venc_write(sd, VENC_VIDCTL, 0);
+               vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
+       } else if (venc->venc_type == VPBE_VERSION_2) {
+               venc_write(sd, VENC_CLKCTL, 0x01);
+               venc_write(sd, VENC_VIDCTL, 0);
+               vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
+       } else {
+               /* to set VENC CLK DIV to 1 - final clock is 54 MHz */
+               venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
+               /* Set REC656 Mode */
+               venc_write(sd, VENC_YCCCTL, 0x1);
+               venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ);
+               venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS);
+       }
+
+       venc_write(sd, VENC_VMOD, 0);
+       venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
+                       VENC_VMOD_VIE);
+       venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
+       venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_TVTYP_SHIFT),
+                       VENC_VMOD_TVTYP);
+       venc_write(sd, VENC_DACTST, 0x0);
+       venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
+
+       return 0;
+}
+
+/*
+ * setting PAL mode
+ */
+static int venc_set_pal(struct v4l2_subdev *sd)
+{
+       struct venc_state *venc = to_state(sd);
+
+       v4l2_dbg(debug, 2, sd, "venc_set_pal\n");
+
+       /* Setup clock at VPSS & VENC for SD */
+       vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
+       if (venc->pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_625_50) < 0)
+               return -EINVAL;
+
+       venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_STD, V4L2_STD_625_50);
+       venc_enabledigitaloutput(sd, 0);
+
+       if (venc->venc_type == VPBE_VERSION_3) {
+               venc_write(sd, VENC_CLKCTL, 0x1);
+               venc_write(sd, VENC_VIDCTL, 0);
+               vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
+       } else if (venc->venc_type == VPBE_VERSION_2) {
+               venc_write(sd, VENC_CLKCTL, 0x1);
+               venc_write(sd, VENC_VIDCTL, 0);
+               vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
+       } else {
+               /* to set VENC CLK DIV to 1 - final clock is 54 MHz */
+               venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
+               /* Set REC656 Mode */
+               venc_write(sd, VENC_YCCCTL, 0x1);
+       }
+
+       venc_modify(sd, VENC_SYNCCTL, 1 << VENC_SYNCCTL_OVD_SHIFT,
+                       VENC_SYNCCTL_OVD);
+       venc_write(sd, VENC_VMOD, 0);
+       venc_modify(sd, VENC_VMOD,
+                       (1 << VENC_VMOD_VIE_SHIFT),
+                       VENC_VMOD_VIE);
+       venc_modify(sd, VENC_VMOD,
+                       (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
+       venc_modify(sd, VENC_VMOD,
+                       (1 << VENC_VMOD_TVTYP_SHIFT),
+                       VENC_VMOD_TVTYP);
+       venc_write(sd, VENC_DACTST, 0x0);
+       venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
+
+       return 0;
+}
+
+#define VDAC_CONFIG_HD_V2      0x081141EF
+/*
+ * venc_set_480p59_94
+ *
+ * This function configures the video encoder to EDTV(525p) component setting.
+ */
+static int venc_set_480p59_94(struct v4l2_subdev *sd)
+{
+       struct venc_state *venc = to_state(sd);
+       struct venc_platform_data *pdata = venc->pdata;
+
+       v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n");
+       if (venc->venc_type != VPBE_VERSION_1 &&
+           venc->venc_type != VPBE_VERSION_2)
+               return -EINVAL;
+
+       /* Setup clock at VPSS & VENC for SD */
+       if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 27000000) < 0)
+               return -EINVAL;
+
+       venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 27000000);
+       venc_enabledigitaloutput(sd, 0);
+
+       if (venc->venc_type == VPBE_VERSION_2)
+               vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
+       venc_write(sd, VENC_OSDCLK0, 0);
+       venc_write(sd, VENC_OSDCLK1, 1);
+
+       if (venc->venc_type == VPBE_VERSION_1) {
+               venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
+                           VENC_VDPRO_DAFRQ);
+               venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
+                           VENC_VDPRO_DAUPS);
+       }
+
+       venc_write(sd, VENC_VMOD, 0);
+       venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
+                   VENC_VMOD_VIE);
+       venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
+       venc_modify(sd, VENC_VMOD, (HDTV_525P << VENC_VMOD_TVTYP_SHIFT),
+                   VENC_VMOD_TVTYP);
+       venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
+                   VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
+
+       venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
+
+       return 0;
+}
+
+/*
+ * venc_set_625p
+ *
+ * This function configures the video encoder to HDTV(625p) component setting
+ */
+static int venc_set_576p50(struct v4l2_subdev *sd)
+{
+       struct venc_state *venc = to_state(sd);
+       struct venc_platform_data *pdata = venc->pdata;
+
+       v4l2_dbg(debug, 2, sd, "venc_set_576p50\n");
+
+       if (venc->venc_type != VPBE_VERSION_1 &&
+           venc->venc_type != VPBE_VERSION_2)
+               return -EINVAL;
+       /* Setup clock at VPSS & VENC for SD */
+       if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 27000000) < 0)
+               return -EINVAL;
+
+       venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 27000000);
+       venc_enabledigitaloutput(sd, 0);
+
+       if (venc->venc_type == VPBE_VERSION_2)
+               vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
+
+       venc_write(sd, VENC_OSDCLK0, 0);
+       venc_write(sd, VENC_OSDCLK1, 1);
+
+       if (venc->venc_type == VPBE_VERSION_1) {
+               venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
+                           VENC_VDPRO_DAFRQ);
+               venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
+                           VENC_VDPRO_DAUPS);
+       }
+
+       venc_write(sd, VENC_VMOD, 0);
+       venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
+                   VENC_VMOD_VIE);
+       venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
+       venc_modify(sd, VENC_VMOD, (HDTV_625P << VENC_VMOD_TVTYP_SHIFT),
+                   VENC_VMOD_TVTYP);
+
+       venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
+                   VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
+       venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
+
+       return 0;
+}
+
+/*
+ * venc_set_720p60_internal - Setup 720p60 in venc for dm365 only
+ */
+static int venc_set_720p60_internal(struct v4l2_subdev *sd)
+{
+       struct venc_state *venc = to_state(sd);
+       struct venc_platform_data *pdata = venc->pdata;
+
+       if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 74250000) < 0)
+               return -EINVAL;
+
+       venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 74250000);
+       venc_enabledigitaloutput(sd, 0);
+
+       venc_write(sd, VENC_OSDCLK0, 0);
+       venc_write(sd, VENC_OSDCLK1, 1);
+
+       venc_write(sd, VENC_VMOD, 0);
+       /* DM365 component HD mode */
+       venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
+           VENC_VMOD_VIE);
+       venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
+       venc_modify(sd, VENC_VMOD, (HDTV_720P << VENC_VMOD_TVTYP_SHIFT),
+                   VENC_VMOD_TVTYP);
+       venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
+       venc_write(sd, VENC_XHINTVL, 0);
+       return 0;
+}
+
+/*
+ * venc_set_1080i30_internal - Setup 1080i30 in venc for dm365 only
+ */
+static int venc_set_1080i30_internal(struct v4l2_subdev *sd)
+{
+       struct venc_state *venc = to_state(sd);
+       struct venc_platform_data *pdata = venc->pdata;
+
+       if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 74250000) < 0)
+               return -EINVAL;
+
+       venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 74250000);
+       venc_enabledigitaloutput(sd, 0);
+
+       venc_write(sd, VENC_OSDCLK0, 0);
+       venc_write(sd, VENC_OSDCLK1, 1);
+
+
+       venc_write(sd, VENC_VMOD, 0);
+       /* DM365 component HD mode */
+       venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
+                   VENC_VMOD_VIE);
+       venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
+       venc_modify(sd, VENC_VMOD, (HDTV_1080I << VENC_VMOD_TVTYP_SHIFT),
+                   VENC_VMOD_TVTYP);
+       venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
+       venc_write(sd, VENC_XHINTVL, 0);
+       return 0;
+}
+
+static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+       v4l2_dbg(debug, 1, sd, "venc_s_std_output\n");
+
+       if (norm & V4L2_STD_525_60)
+               return venc_set_ntsc(sd);
+       else if (norm & V4L2_STD_625_50)
+               return venc_set_pal(sd);
+
+       return -EINVAL;
+}
+
+static int venc_s_dv_timings(struct v4l2_subdev *sd,
+                           struct v4l2_dv_timings *dv_timings)
+{
+       struct venc_state *venc = to_state(sd);
+       u32 height = dv_timings->bt.height;
+       int ret;
+
+       v4l2_dbg(debug, 1, sd, "venc_s_dv_timings\n");
+
+       if (height == 576)
+               return venc_set_576p50(sd);
+       else if (height == 480)
+               return venc_set_480p59_94(sd);
+       else if ((height == 720) &&
+                       (venc->venc_type == VPBE_VERSION_2)) {
+               /* TBD setup internal 720p mode here */
+               ret = venc_set_720p60_internal(sd);
+               /* for DM365 VPBE, there is DAC inside */
+               vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
+               return ret;
+       } else if ((height == 1080) &&
+               (venc->venc_type == VPBE_VERSION_2)) {
+               /* TBD setup internal 1080i mode here */
+               ret = venc_set_1080i30_internal(sd);
+               /* for DM365 VPBE, there is DAC inside */
+               vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
+               return ret;
+       }
+       return -EINVAL;
+}
+
+static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
+                         u32 config)
+{
+       struct venc_state *venc = to_state(sd);
+       int ret;
+
+       v4l2_dbg(debug, 1, sd, "venc_s_routing\n");
+
+       ret = venc_set_dac(sd, output);
+       if (!ret)
+               venc->output = output;
+
+       return ret;
+}
+
+static long venc_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+       u32 val;
+
+       switch (cmd) {
+       case VENC_GET_FLD:
+               val = venc_read(sd, VENC_VSTAT);
+               *((int *)arg) = ((val & VENC_VSTAT_FIDST) ==
+               VENC_VSTAT_FIDST);
+               break;
+       default:
+               v4l2_err(sd, "Wrong IOCTL cmd\n");
+               break;
+       }
+
+       return 0;
+}
+
+static const struct v4l2_subdev_core_ops venc_core_ops = {
+       .command      = venc_command,
+};
+
+static const struct v4l2_subdev_video_ops venc_video_ops = {
+       .s_routing = venc_s_routing,
+       .s_std_output = venc_s_std_output,
+       .s_dv_timings = venc_s_dv_timings,
+};
+
+static const struct v4l2_subdev_ops venc_ops = {
+       .core = &venc_core_ops,
+       .video = &venc_video_ops,
+};
+
+static int venc_initialize(struct v4l2_subdev *sd)
+{
+       struct venc_state *venc = to_state(sd);
+       int ret;
+
+       /* Set default to output to composite and std to NTSC */
+       venc->output = 0;
+       venc->std = V4L2_STD_525_60;
+
+       ret = venc_s_routing(sd, 0, venc->output, 0);
+       if (ret < 0) {
+               v4l2_err(sd, "Error setting output during init\n");
+               return -EINVAL;
+       }
+
+       ret = venc_s_std_output(sd, venc->std);
+       if (ret < 0) {
+               v4l2_err(sd, "Error setting std during init\n");
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
+static int venc_device_get(struct device *dev, void *data)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct venc_state **venc = data;
+
+       if (strstr(pdev->name, "vpbe-venc") != NULL)
+               *venc = platform_get_drvdata(pdev);
+
+       return 0;
+}
+
+struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
+               const char *venc_name)
+{
+       struct venc_state *venc = NULL;
+
+       bus_for_each_dev(&platform_bus_type, NULL, &venc,
+                       venc_device_get);
+       if (venc == NULL)
+               return NULL;
+
+       v4l2_subdev_init(&venc->sd, &venc_ops);
+
+       strscpy(venc->sd.name, venc_name, sizeof(venc->sd.name));
+       if (v4l2_device_register_subdev(v4l2_dev, &venc->sd) < 0) {
+               v4l2_err(v4l2_dev,
+                       "vpbe unable to register venc sub device\n");
+               return NULL;
+       }
+       if (venc_initialize(&venc->sd)) {
+               v4l2_err(v4l2_dev,
+                       "vpbe venc initialization failed\n");
+               return NULL;
+       }
+
+       return &venc->sd;
+}
+EXPORT_SYMBOL(venc_sub_dev_init);
+
+static int venc_probe(struct platform_device *pdev)
+{
+       const struct platform_device_id *pdev_id;
+       struct venc_state *venc;
+
+       if (!pdev->dev.platform_data) {
+               dev_err(&pdev->dev, "No platform data for VENC sub device");
+               return -EINVAL;
+       }
+
+       pdev_id = platform_get_device_id(pdev);
+       if (!pdev_id)
+               return -EINVAL;
+
+       venc = devm_kzalloc(&pdev->dev, sizeof(struct venc_state), GFP_KERNEL);
+       if (venc == NULL)
+               return -ENOMEM;
+
+       venc->venc_type = pdev_id->driver_data;
+       venc->pdev = &pdev->dev;
+       venc->pdata = pdev->dev.platform_data;
+
+       venc->venc_base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(venc->venc_base))
+               return PTR_ERR(venc->venc_base);
+
+       if (venc->venc_type != VPBE_VERSION_1) {
+               venc->vdaccfg_reg = devm_platform_ioremap_resource(pdev, 1);
+               if (IS_ERR(venc->vdaccfg_reg))
+                       return PTR_ERR(venc->vdaccfg_reg);
+       }
+       spin_lock_init(&venc->lock);
+       platform_set_drvdata(pdev, venc);
+       dev_notice(venc->pdev, "VENC sub device probe success\n");
+
+       return 0;
+}
+
+static int venc_remove(struct platform_device *pdev)
+{
+       return 0;
+}
+
+static struct platform_driver venc_driver = {
+       .probe          = venc_probe,
+       .remove         = venc_remove,
+       .driver         = {
+               .name   = MODULE_NAME,
+       },
+       .id_table       = vpbe_venc_devtype
+};
+
+module_platform_driver(venc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("VPBE VENC Driver");
+MODULE_AUTHOR("Texas Instruments");
diff --git a/drivers/media/platform/ti/davinci/vpbe_venc_regs.h b/drivers/media/platform/ti/davinci/vpbe_venc_regs.h
new file mode 100644 (file)
index 0000000..29d8fc3
--- /dev/null
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2006-2010 Texas Instruments Inc
+ */
+#ifndef _VPBE_VENC_REGS_H
+#define _VPBE_VENC_REGS_H
+
+/* VPBE Video Encoder / Digital LCD Subsystem Registers (VENC) */
+#define VENC_VMOD                              0x00
+#define VENC_VIDCTL                            0x04
+#define VENC_VDPRO                             0x08
+#define VENC_SYNCCTL                           0x0C
+#define VENC_HSPLS                             0x10
+#define VENC_VSPLS                             0x14
+#define VENC_HINT                              0x18
+#define VENC_HSTART                            0x1C
+#define VENC_HVALID                            0x20
+#define VENC_VINT                              0x24
+#define VENC_VSTART                            0x28
+#define VENC_VVALID                            0x2C
+#define VENC_HSDLY                             0x30
+#define VENC_VSDLY                             0x34
+#define VENC_YCCCTL                            0x38
+#define VENC_RGBCTL                            0x3C
+#define VENC_RGBCLP                            0x40
+#define VENC_LINECTL                           0x44
+#define VENC_CULLLINE                          0x48
+#define VENC_LCDOUT                            0x4C
+#define VENC_BRTS                              0x50
+#define VENC_BRTW                              0x54
+#define VENC_ACCTL                             0x58
+#define VENC_PWMP                              0x5C
+#define VENC_PWMW                              0x60
+#define VENC_DCLKCTL                           0x64
+#define VENC_DCLKPTN0                          0x68
+#define VENC_DCLKPTN1                          0x6C
+#define VENC_DCLKPTN2                          0x70
+#define VENC_DCLKPTN3                          0x74
+#define VENC_DCLKPTN0A                         0x78
+#define VENC_DCLKPTN1A                         0x7C
+#define VENC_DCLKPTN2A                         0x80
+#define VENC_DCLKPTN3A                         0x84
+#define VENC_DCLKHS                            0x88
+#define VENC_DCLKHSA                           0x8C
+#define VENC_DCLKHR                            0x90
+#define VENC_DCLKVS                            0x94
+#define VENC_DCLKVR                            0x98
+#define VENC_CAPCTL                            0x9C
+#define VENC_CAPDO                             0xA0
+#define VENC_CAPDE                             0xA4
+#define VENC_ATR0                              0xA8
+#define VENC_ATR1                              0xAC
+#define VENC_ATR2                              0xB0
+#define VENC_VSTAT                             0xB8
+#define VENC_RAMADR                            0xBC
+#define VENC_RAMPORT                           0xC0
+#define VENC_DACTST                            0xC4
+#define VENC_YCOLVL                            0xC8
+#define VENC_SCPROG                            0xCC
+#define VENC_CVBS                              0xDC
+#define VENC_CMPNT                             0xE0
+#define VENC_ETMG0                             0xE4
+#define VENC_ETMG1                             0xE8
+#define VENC_ETMG2                             0xEC
+#define VENC_ETMG3                             0xF0
+#define VENC_DACSEL                            0xF4
+#define VENC_ARGBX0                            0x100
+#define VENC_ARGBX1                            0x104
+#define VENC_ARGBX2                            0x108
+#define VENC_ARGBX3                            0x10C
+#define VENC_ARGBX4                            0x110
+#define VENC_DRGBX0                            0x114
+#define VENC_DRGBX1                            0x118
+#define VENC_DRGBX2                            0x11C
+#define VENC_DRGBX3                            0x120
+#define VENC_DRGBX4                            0x124
+#define VENC_VSTARTA                           0x128
+#define VENC_OSDCLK0                           0x12C
+#define VENC_OSDCLK1                           0x130
+#define VENC_HVLDCL0                           0x134
+#define VENC_HVLDCL1                           0x138
+#define VENC_OSDHADV                           0x13C
+#define VENC_CLKCTL                            0x140
+#define VENC_GAMCTL                            0x144
+#define VENC_XHINTVL                           0x174
+
+/* bit definitions */
+#define VPBE_PCR_VENC_DIV                      (1 << 1)
+#define VPBE_PCR_CLK_OFF                       (1 << 0)
+
+#define VENC_VMOD_VDMD_SHIFT                   12
+#define VENC_VMOD_VDMD_YCBCR16                 0
+#define VENC_VMOD_VDMD_YCBCR8                  1
+#define VENC_VMOD_VDMD_RGB666                  2
+#define VENC_VMOD_VDMD_RGB8                    3
+#define VENC_VMOD_VDMD_EPSON                   4
+#define VENC_VMOD_VDMD_CASIO                   5
+#define VENC_VMOD_VDMD_UDISPQVGA               6
+#define VENC_VMOD_VDMD_STNLCD                  7
+#define VENC_VMOD_VIE_SHIFT                    1
+#define VENC_VMOD_VDMD                         (7 << 12)
+#define VENC_VMOD_ITLCL                                (1 << 11)
+#define VENC_VMOD_ITLC                         (1 << 10)
+#define VENC_VMOD_NSIT                         (1 << 9)
+#define VENC_VMOD_HDMD                         (1 << 8)
+#define VENC_VMOD_TVTYP_SHIFT                  6
+#define VENC_VMOD_TVTYP                                (3 << 6)
+#define VENC_VMOD_SLAVE                                (1 << 5)
+#define VENC_VMOD_VMD                          (1 << 4)
+#define VENC_VMOD_BLNK                         (1 << 3)
+#define VENC_VMOD_VIE                          (1 << 1)
+#define VENC_VMOD_VENC                         (1 << 0)
+
+/* VMOD TVTYP options for HDMD=0 */
+#define SDTV_NTSC                              0
+#define SDTV_PAL                               1
+/* VMOD TVTYP options for HDMD=1 */
+#define HDTV_525P                              0
+#define HDTV_625P                              1
+#define HDTV_1080I                             2
+#define HDTV_720P                              3
+
+#define VENC_VIDCTL_VCLKP                      (1 << 14)
+#define VENC_VIDCTL_VCLKE_SHIFT                        13
+#define VENC_VIDCTL_VCLKE                      (1 << 13)
+#define VENC_VIDCTL_VCLKZ_SHIFT                        12
+#define VENC_VIDCTL_VCLKZ                      (1 << 12)
+#define VENC_VIDCTL_SYDIR_SHIFT                        8
+#define VENC_VIDCTL_SYDIR                      (1 << 8)
+#define VENC_VIDCTL_DOMD_SHIFT                 4
+#define VENC_VIDCTL_DOMD                       (3 << 4)
+#define VENC_VIDCTL_YCDIR_SHIFT                        0
+#define VENC_VIDCTL_YCDIR                      (1 << 0)
+
+#define VENC_VDPRO_ATYCC_SHIFT                 5
+#define VENC_VDPRO_ATYCC                       (1 << 5)
+#define VENC_VDPRO_ATCOM_SHIFT                 4
+#define VENC_VDPRO_ATCOM                       (1 << 4)
+#define VENC_VDPRO_DAFRQ                       (1 << 3)
+#define VENC_VDPRO_DAUPS                       (1 << 2)
+#define VENC_VDPRO_CUPS                                (1 << 1)
+#define VENC_VDPRO_YUPS                                (1 << 0)
+
+#define VENC_SYNCCTL_VPL_SHIFT                 3
+#define VENC_SYNCCTL_VPL                       (1 << 3)
+#define VENC_SYNCCTL_HPL_SHIFT                 2
+#define VENC_SYNCCTL_HPL                       (1 << 2)
+#define VENC_SYNCCTL_SYEV_SHIFT                        1
+#define VENC_SYNCCTL_SYEV                      (1 << 1)
+#define VENC_SYNCCTL_SYEH_SHIFT                        0
+#define VENC_SYNCCTL_SYEH                      (1 << 0)
+#define VENC_SYNCCTL_OVD_SHIFT                 14
+#define VENC_SYNCCTL_OVD                       (1 << 14)
+
+#define VENC_DCLKCTL_DCKEC_SHIFT               11
+#define VENC_DCLKCTL_DCKEC                     (1 << 11)
+#define VENC_DCLKCTL_DCKPW_SHIFT               0
+#define VENC_DCLKCTL_DCKPW                     (0x3f << 0)
+
+#define VENC_VSTAT_FIDST                       (1 << 4)
+
+#define VENC_CMPNT_MRGB_SHIFT                  14
+#define VENC_CMPNT_MRGB                                (1 << 14)
+
+#endif                         /* _VPBE_VENC_REGS_H */
diff --git a/drivers/media/platform/ti/davinci/vpfe_capture.c b/drivers/media/platform/ti/davinci/vpfe_capture.c
new file mode 100644 (file)
index 0000000..0a2226b
--- /dev/null
@@ -0,0 +1,1902 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2008-2009 Texas Instruments Inc
+ *
+ * Driver name : VPFE Capture driver
+ *    VPFE Capture driver allows applications to capture and stream video
+ *    frames on DaVinci SoCs (DM6446, DM355 etc) from a YUV source such as
+ *    TVP5146 or  Raw Bayer RGB image data from an image sensor
+ *    such as Microns' MT9T001, MT9T031 etc.
+ *
+ *    These SoCs have, in common, a Video Processing Subsystem (VPSS) that
+ *    consists of a Video Processing Front End (VPFE) for capturing
+ *    video/raw image data and Video Processing Back End (VPBE) for displaying
+ *    YUV data through an in-built analog encoder or Digital LCD port. This
+ *    driver is for capture through VPFE. A typical EVM using these SoCs have
+ *    following high level configuration.
+ *
+ *    decoder(TVP5146/         YUV/
+ *          MT9T001)   -->  Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
+ *                             data input              |      |
+ *                                                     V      |
+ *                                                   SDRAM    |
+ *                                                            V
+ *                                                        Image Processor
+ *                                                            |
+ *                                                            V
+ *                                                          SDRAM
+ *    The data flow happens from a decoder connected to the VPFE over a
+ *    YUV embedded (BT.656/BT.1120) or separate sync or raw bayer rgb interface
+ *    and to the input of VPFE through an optional MUX (if more inputs are
+ *    to be interfaced on the EVM). The input data is first passed through
+ *    CCDC (CCD Controller, a.k.a Image Sensor Interface, ISIF). The CCDC
+ *    does very little or no processing on YUV data and does pre-process Raw
+ *    Bayer RGB data through modules such as Defect Pixel Correction (DFC)
+ *    Color Space Conversion (CSC), data gain/offset etc. After this, data
+ *    can be written to SDRAM or can be connected to the image processing
+ *    block such as IPIPE (on DM355 only).
+ *
+ *    Features supported
+ *             - MMAP IO
+ *             - Capture using TVP5146 over BT.656
+ *             - support for interfacing decoders using sub device model
+ *             - Work with DM355 or DM6446 CCDC to do Raw Bayer RGB/YUV
+ *               data capture to SDRAM.
+ *    TODO list
+ *             - Support multiple REQBUF after open
+ *             - Support for de-allocating buffers through REQBUF
+ *             - Support for Raw Bayer RGB capture
+ *             - Support for chaining Image Processor
+ *             - Support for static allocation of buffers
+ *             - Support for USERPTR IO
+ *             - Support for STREAMON before QBUF
+ *             - Support for control ioctls
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <media/v4l2-common.h>
+#include <linux/io.h>
+#include <media/davinci/vpfe_capture.h>
+#include "ccdc_hw_device.h"
+
+static int debug;
+static u32 numbuffers = 3;
+static u32 bufsize = (720 * 576 * 2);
+
+module_param(numbuffers, uint, S_IRUGO);
+module_param(bufsize, uint, S_IRUGO);
+module_param(debug, int, 0644);
+
+MODULE_PARM_DESC(numbuffers, "buffer count (default:3)");
+MODULE_PARM_DESC(bufsize, "buffer size in bytes (default:720 x 576 x 2)");
+MODULE_PARM_DESC(debug, "Debug level 0-1");
+
+MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Texas Instruments");
+
+/* standard information */
+struct vpfe_standard {
+       v4l2_std_id std_id;
+       unsigned int width;
+       unsigned int height;
+       struct v4l2_fract pixelaspect;
+       /* 0 - progressive, 1 - interlaced */
+       int frame_format;
+};
+
+/* ccdc configuration */
+struct ccdc_config {
+       /* This make sure vpfe is probed and ready to go */
+       int vpfe_probed;
+       /* name of ccdc device */
+       char name[32];
+};
+
+/* data structures */
+static struct vpfe_config_params config_params = {
+       .min_numbuffers = 3,
+       .numbuffers = 3,
+       .min_bufsize = 720 * 480 * 2,
+       .device_bufsize = 720 * 576 * 2,
+};
+
+/* ccdc device registered */
+static const struct ccdc_hw_device *ccdc_dev;
+/* lock for accessing ccdc information */
+static DEFINE_MUTEX(ccdc_lock);
+/* ccdc configuration */
+static struct ccdc_config *ccdc_cfg;
+
+static const struct vpfe_standard vpfe_standards[] = {
+       {V4L2_STD_525_60, 720, 480, {11, 10}, 1},
+       {V4L2_STD_625_50, 720, 576, {54, 59}, 1},
+};
+
+/* Used when raw Bayer image from ccdc is directly captured to SDRAM */
+static const struct vpfe_pixel_format vpfe_pix_fmts[] = {
+       {
+               .pixelformat = V4L2_PIX_FMT_SBGGR8,
+               .bpp = 1,
+       },
+       {
+               .pixelformat = V4L2_PIX_FMT_SBGGR16,
+               .bpp = 2,
+       },
+       {
+               .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
+               .bpp = 1,
+       },
+       {
+               .pixelformat = V4L2_PIX_FMT_UYVY,
+               .bpp = 2,
+       },
+       {
+               .pixelformat = V4L2_PIX_FMT_YUYV,
+               .bpp = 2,
+       },
+       {
+               .pixelformat = V4L2_PIX_FMT_NV12,
+               .bpp = 1,
+       },
+};
+
+/*
+ * vpfe_lookup_pix_format()
+ * lookup an entry in the vpfe pix format table based on pix_format
+ */
+static const struct vpfe_pixel_format *vpfe_lookup_pix_format(u32 pix_format)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(vpfe_pix_fmts); i++) {
+               if (pix_format == vpfe_pix_fmts[i].pixelformat)
+                       return &vpfe_pix_fmts[i];
+       }
+       return NULL;
+}
+
+/*
+ * vpfe_register_ccdc_device. CCDC module calls this to
+ * register with vpfe capture
+ */
+int vpfe_register_ccdc_device(const struct ccdc_hw_device *dev)
+{
+       int ret = 0;
+       printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name);
+
+       if (!dev->hw_ops.open ||
+           !dev->hw_ops.enable ||
+           !dev->hw_ops.set_hw_if_params ||
+           !dev->hw_ops.configure ||
+           !dev->hw_ops.set_buftype ||
+           !dev->hw_ops.get_buftype ||
+           !dev->hw_ops.enum_pix ||
+           !dev->hw_ops.set_frame_format ||
+           !dev->hw_ops.get_frame_format ||
+           !dev->hw_ops.get_pixel_format ||
+           !dev->hw_ops.set_pixel_format ||
+           !dev->hw_ops.set_image_window ||
+           !dev->hw_ops.get_image_window ||
+           !dev->hw_ops.get_line_length ||
+           !dev->hw_ops.getfid)
+               return -EINVAL;
+
+       mutex_lock(&ccdc_lock);
+       if (!ccdc_cfg) {
+               /*
+                * TODO. Will this ever happen? if so, we need to fix it.
+                * Probably we need to add the request to a linked list and
+                * walk through it during vpfe probe
+                */
+               printk(KERN_ERR "vpfe capture not initialized\n");
+               ret = -EFAULT;
+               goto unlock;
+       }
+
+       if (strcmp(dev->name, ccdc_cfg->name)) {
+               /* ignore this ccdc */
+               ret = -EINVAL;
+               goto unlock;
+       }
+
+       if (ccdc_dev) {
+               printk(KERN_ERR "ccdc already registered\n");
+               ret = -EINVAL;
+               goto unlock;
+       }
+
+       ccdc_dev = dev;
+unlock:
+       mutex_unlock(&ccdc_lock);
+       return ret;
+}
+EXPORT_SYMBOL(vpfe_register_ccdc_device);
+
+/*
+ * vpfe_unregister_ccdc_device. CCDC module calls this to
+ * unregister with vpfe capture
+ */
+void vpfe_unregister_ccdc_device(const struct ccdc_hw_device *dev)
+{
+       if (!dev) {
+               printk(KERN_ERR "invalid ccdc device ptr\n");
+               return;
+       }
+
+       printk(KERN_NOTICE "vpfe_unregister_ccdc_device, dev->name = %s\n",
+               dev->name);
+
+       if (strcmp(dev->name, ccdc_cfg->name)) {
+               /* ignore this ccdc */
+               return;
+       }
+
+       mutex_lock(&ccdc_lock);
+       ccdc_dev = NULL;
+       mutex_unlock(&ccdc_lock);
+}
+EXPORT_SYMBOL(vpfe_unregister_ccdc_device);
+
+/*
+ * vpfe_config_ccdc_image_format()
+ * For a pix format, configure ccdc to setup the capture
+ */
+static int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe_dev)
+{
+       enum ccdc_frmfmt frm_fmt = CCDC_FRMFMT_INTERLACED;
+       int ret = 0;
+
+       if (ccdc_dev->hw_ops.set_pixel_format(
+                       vpfe_dev->fmt.fmt.pix.pixelformat) < 0) {
+               v4l2_err(&vpfe_dev->v4l2_dev,
+                       "couldn't set pix format in ccdc\n");
+               return -EINVAL;
+       }
+       /* configure the image window */
+       ccdc_dev->hw_ops.set_image_window(&vpfe_dev->crop);
+
+       switch (vpfe_dev->fmt.fmt.pix.field) {
+       case V4L2_FIELD_INTERLACED:
+               /* do nothing, since it is default */
+               ret = ccdc_dev->hw_ops.set_buftype(
+                               CCDC_BUFTYPE_FLD_INTERLEAVED);
+               break;
+       case V4L2_FIELD_NONE:
+               frm_fmt = CCDC_FRMFMT_PROGRESSIVE;
+               /* buffer type only applicable for interlaced scan */
+               break;
+       case V4L2_FIELD_SEQ_TB:
+               ret = ccdc_dev->hw_ops.set_buftype(
+                               CCDC_BUFTYPE_FLD_SEPARATED);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* set the frame format */
+       if (!ret)
+               ret = ccdc_dev->hw_ops.set_frame_format(frm_fmt);
+       return ret;
+}
+/*
+ * vpfe_config_image_format()
+ * For a given standard, this functions sets up the default
+ * pix format & crop values in the vpfe device and ccdc.  It first
+ * starts with defaults based values from the standard table.
+ * It then checks if sub device supports get_fmt and then override the
+ * values based on that.Sets crop values to match with scan resolution
+ * starting at 0,0. It calls vpfe_config_ccdc_image_format() set the
+ * values in ccdc
+ */
+static int vpfe_config_image_format(struct vpfe_device *vpfe_dev,
+                                   v4l2_std_id std_id)
+{
+       struct vpfe_subdev_info *sdinfo = vpfe_dev->current_subdev;
+       struct v4l2_subdev_format fmt = {
+               .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+       };
+       struct v4l2_mbus_framefmt *mbus_fmt = &fmt.format;
+       struct v4l2_pix_format *pix = &vpfe_dev->fmt.fmt.pix;
+       int i, ret;
+
+       for (i = 0; i < ARRAY_SIZE(vpfe_standards); i++) {
+               if (vpfe_standards[i].std_id & std_id) {
+                       vpfe_dev->std_info.active_pixels =
+                                       vpfe_standards[i].width;
+                       vpfe_dev->std_info.active_lines =
+                                       vpfe_standards[i].height;
+                       vpfe_dev->std_info.frame_format =
+                                       vpfe_standards[i].frame_format;
+                       vpfe_dev->std_index = i;
+                       break;
+               }
+       }
+
+       if (i ==  ARRAY_SIZE(vpfe_standards)) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "standard not supported\n");
+               return -EINVAL;
+       }
+
+       vpfe_dev->crop.top = 0;
+       vpfe_dev->crop.left = 0;
+       vpfe_dev->crop.width = vpfe_dev->std_info.active_pixels;
+       vpfe_dev->crop.height = vpfe_dev->std_info.active_lines;
+       pix->width = vpfe_dev->crop.width;
+       pix->height = vpfe_dev->crop.height;
+
+       /* first field and frame format based on standard frame format */
+       if (vpfe_dev->std_info.frame_format) {
+               pix->field = V4L2_FIELD_INTERLACED;
+               /* assume V4L2_PIX_FMT_UYVY as default */
+               pix->pixelformat = V4L2_PIX_FMT_UYVY;
+               v4l2_fill_mbus_format(mbus_fmt, pix,
+                               MEDIA_BUS_FMT_YUYV10_2X10);
+       } else {
+               pix->field = V4L2_FIELD_NONE;
+               /* assume V4L2_PIX_FMT_SBGGR8 */
+               pix->pixelformat = V4L2_PIX_FMT_SBGGR8;
+               v4l2_fill_mbus_format(mbus_fmt, pix,
+                               MEDIA_BUS_FMT_SBGGR8_1X8);
+       }
+
+       /* if sub device supports get_fmt, override the defaults */
+       ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
+                       sdinfo->grp_id, pad, get_fmt, NULL, &fmt);
+
+       if (ret && ret != -ENOIOCTLCMD) {
+               v4l2_err(&vpfe_dev->v4l2_dev,
+                       "error in getting get_fmt from sub device\n");
+               return ret;
+       }
+       v4l2_fill_pix_format(pix, mbus_fmt);
+       pix->bytesperline = pix->width * 2;
+       pix->sizeimage = pix->bytesperline * pix->height;
+
+       /* Sets the values in CCDC */
+       ret = vpfe_config_ccdc_image_format(vpfe_dev);
+       if (ret)
+               return ret;
+
+       /* Update the values of sizeimage and bytesperline */
+       pix->bytesperline = ccdc_dev->hw_ops.get_line_length();
+       pix->sizeimage = pix->bytesperline * pix->height;
+
+       return 0;
+}
+
+static int vpfe_initialize_device(struct vpfe_device *vpfe_dev)
+{
+       int ret;
+
+       /* set first input of current subdevice as the current input */
+       vpfe_dev->current_input = 0;
+
+       /* set default standard */
+       vpfe_dev->std_index = 0;
+
+       /* Configure the default format information */
+       ret = vpfe_config_image_format(vpfe_dev,
+                               vpfe_standards[vpfe_dev->std_index].std_id);
+       if (ret)
+               return ret;
+
+       /* now open the ccdc device to initialize it */
+       mutex_lock(&ccdc_lock);
+       if (!ccdc_dev) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "ccdc device not registered\n");
+               ret = -ENODEV;
+               goto unlock;
+       }
+
+       if (!try_module_get(ccdc_dev->owner)) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "Couldn't lock ccdc module\n");
+               ret = -ENODEV;
+               goto unlock;
+       }
+       ret = ccdc_dev->hw_ops.open(vpfe_dev->pdev);
+       if (!ret)
+               vpfe_dev->initialized = 1;
+
+       /* Clear all VPFE/CCDC interrupts */
+       if (vpfe_dev->cfg->clr_intr)
+               vpfe_dev->cfg->clr_intr(-1);
+
+unlock:
+       mutex_unlock(&ccdc_lock);
+       return ret;
+}
+
+/*
+ * vpfe_open : It creates object of file handle structure and
+ * stores it in private_data  member of filepointer
+ */
+static int vpfe_open(struct file *file)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct video_device *vdev = video_devdata(file);
+       struct vpfe_fh *fh;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n");
+
+       if (!vpfe_dev->cfg->num_subdevs) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "No decoder registered\n");
+               return -ENODEV;
+       }
+
+       /* Allocate memory for the file handle object */
+       fh = kmalloc(sizeof(*fh), GFP_KERNEL);
+       if (!fh)
+               return -ENOMEM;
+
+       /* store pointer to fh in private_data member of file */
+       file->private_data = fh;
+       fh->vpfe_dev = vpfe_dev;
+       v4l2_fh_init(&fh->fh, vdev);
+       mutex_lock(&vpfe_dev->lock);
+       /* If decoder is not initialized. initialize it */
+       if (!vpfe_dev->initialized) {
+               if (vpfe_initialize_device(vpfe_dev)) {
+                       mutex_unlock(&vpfe_dev->lock);
+                       v4l2_fh_exit(&fh->fh);
+                       kfree(fh);
+                       return -ENODEV;
+               }
+       }
+       /* Increment device usrs counter */
+       vpfe_dev->usrs++;
+       /* Set io_allowed member to false */
+       fh->io_allowed = 0;
+       v4l2_fh_add(&fh->fh);
+       mutex_unlock(&vpfe_dev->lock);
+       return 0;
+}
+
+static void vpfe_schedule_next_buffer(struct vpfe_device *vpfe_dev)
+{
+       unsigned long addr;
+
+       vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
+                                       struct videobuf_buffer, queue);
+       list_del(&vpfe_dev->next_frm->queue);
+       vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE;
+       addr = videobuf_to_dma_contig(vpfe_dev->next_frm);
+
+       ccdc_dev->hw_ops.setfbaddr(addr);
+}
+
+static void vpfe_schedule_bottom_field(struct vpfe_device *vpfe_dev)
+{
+       unsigned long addr;
+
+       addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
+       addr += vpfe_dev->field_off;
+       ccdc_dev->hw_ops.setfbaddr(addr);
+}
+
+static void vpfe_process_buffer_complete(struct vpfe_device *vpfe_dev)
+{
+       vpfe_dev->cur_frm->ts = ktime_get_ns();
+       vpfe_dev->cur_frm->state = VIDEOBUF_DONE;
+       vpfe_dev->cur_frm->size = vpfe_dev->fmt.fmt.pix.sizeimage;
+       wake_up_interruptible(&vpfe_dev->cur_frm->done);
+       vpfe_dev->cur_frm = vpfe_dev->next_frm;
+}
+
+/* ISR for VINT0*/
+static irqreturn_t vpfe_isr(int irq, void *dev_id)
+{
+       struct vpfe_device *vpfe_dev = dev_id;
+       enum v4l2_field field;
+       int fid;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nStarting vpfe_isr...\n");
+       field = vpfe_dev->fmt.fmt.pix.field;
+
+       /* if streaming not started, don't do anything */
+       if (!vpfe_dev->started)
+               goto clear_intr;
+
+       /* only for 6446 this will be applicable */
+       if (ccdc_dev->hw_ops.reset)
+               ccdc_dev->hw_ops.reset();
+
+       if (field == V4L2_FIELD_NONE) {
+               /* handle progressive frame capture */
+               v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+                       "frame format is progressive...\n");
+               if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
+                       vpfe_process_buffer_complete(vpfe_dev);
+               goto clear_intr;
+       }
+
+       /* interlaced or TB capture check which field we are in hardware */
+       fid = ccdc_dev->hw_ops.getfid();
+
+       /* switch the software maintained field id */
+       vpfe_dev->field_id ^= 1;
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "field id = %x:%x.\n",
+               fid, vpfe_dev->field_id);
+       if (fid == vpfe_dev->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_dev->cur_frm != vpfe_dev->next_frm)
+                               vpfe_process_buffer_complete(vpfe_dev);
+                       /*
+                        * based on whether the two fields are stored
+                        * interleavely or separately in memory, reconfigure
+                        * the CCDC memory address
+                        */
+                       if (field == V4L2_FIELD_SEQ_TB)
+                               vpfe_schedule_bottom_field(vpfe_dev);
+                       goto clear_intr;
+               }
+               /*
+                * 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
+                */
+               spin_lock(&vpfe_dev->dma_queue_lock);
+               if (!list_empty(&vpfe_dev->dma_queue) &&
+                   vpfe_dev->cur_frm == vpfe_dev->next_frm)
+                       vpfe_schedule_next_buffer(vpfe_dev);
+               spin_unlock(&vpfe_dev->dma_queue_lock);
+       } else if (fid == 0) {
+               /*
+                * out of sync. Recover from any hardware out-of-sync.
+                * May loose one frame
+                */
+               vpfe_dev->field_id = fid;
+       }
+clear_intr:
+       if (vpfe_dev->cfg->clr_intr)
+               vpfe_dev->cfg->clr_intr(irq);
+
+       return IRQ_HANDLED;
+}
+
+/* vdint1_isr - isr handler for VINT1 interrupt */
+static irqreturn_t vdint1_isr(int irq, void *dev_id)
+{
+       struct vpfe_device *vpfe_dev = dev_id;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nInside vdint1_isr...\n");
+
+       /* if streaming not started, don't do anything */
+       if (!vpfe_dev->started) {
+               if (vpfe_dev->cfg->clr_intr)
+                       vpfe_dev->cfg->clr_intr(irq);
+               return IRQ_HANDLED;
+       }
+
+       spin_lock(&vpfe_dev->dma_queue_lock);
+       if ((vpfe_dev->fmt.fmt.pix.field == V4L2_FIELD_NONE) &&
+           !list_empty(&vpfe_dev->dma_queue) &&
+           vpfe_dev->cur_frm == vpfe_dev->next_frm)
+               vpfe_schedule_next_buffer(vpfe_dev);
+       spin_unlock(&vpfe_dev->dma_queue_lock);
+
+       if (vpfe_dev->cfg->clr_intr)
+               vpfe_dev->cfg->clr_intr(irq);
+
+       return IRQ_HANDLED;
+}
+
+static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
+{
+       enum ccdc_frmfmt frame_format;
+
+       frame_format = ccdc_dev->hw_ops.get_frame_format();
+       if (frame_format == CCDC_FRMFMT_PROGRESSIVE)
+               free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
+}
+
+static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
+{
+       enum ccdc_frmfmt frame_format;
+
+       frame_format = ccdc_dev->hw_ops.get_frame_format();
+       if (frame_format == CCDC_FRMFMT_PROGRESSIVE) {
+               return request_irq(vpfe_dev->ccdc_irq1, vdint1_isr,
+                                   0, "vpfe_capture1",
+                                   vpfe_dev);
+       }
+       return 0;
+}
+
+/* vpfe_stop_ccdc_capture: stop streaming in ccdc/isif */
+static void vpfe_stop_ccdc_capture(struct vpfe_device *vpfe_dev)
+{
+       vpfe_dev->started = 0;
+       ccdc_dev->hw_ops.enable(0);
+       if (ccdc_dev->hw_ops.enable_out_to_sdram)
+               ccdc_dev->hw_ops.enable_out_to_sdram(0);
+}
+
+/*
+ * vpfe_release : This function deletes buffer queue, frees the
+ * buffers and the vpfe file  handle
+ */
+static int vpfe_release(struct file *file)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct vpfe_fh *fh = file->private_data;
+       struct vpfe_subdev_info *sdinfo;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_release\n");
+
+       /* Get the device lock */
+       mutex_lock(&vpfe_dev->lock);
+       /* if this instance is doing IO */
+       if (fh->io_allowed) {
+               if (vpfe_dev->started) {
+                       sdinfo = vpfe_dev->current_subdev;
+                       ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
+                                                        sdinfo->grp_id,
+                                                        video, s_stream, 0);
+                       if (ret && (ret != -ENOIOCTLCMD))
+                               v4l2_err(&vpfe_dev->v4l2_dev,
+                               "stream off failed in subdev\n");
+                       vpfe_stop_ccdc_capture(vpfe_dev);
+                       vpfe_detach_irq(vpfe_dev);
+                       videobuf_streamoff(&vpfe_dev->buffer_queue);
+               }
+               vpfe_dev->io_usrs = 0;
+               vpfe_dev->numbuffers = config_params.numbuffers;
+               videobuf_stop(&vpfe_dev->buffer_queue);
+               videobuf_mmap_free(&vpfe_dev->buffer_queue);
+       }
+
+       /* Decrement device usrs counter */
+       vpfe_dev->usrs--;
+       v4l2_fh_del(&fh->fh);
+       v4l2_fh_exit(&fh->fh);
+       /* If this is the last file handle */
+       if (!vpfe_dev->usrs) {
+               vpfe_dev->initialized = 0;
+               if (ccdc_dev->hw_ops.close)
+                       ccdc_dev->hw_ops.close(vpfe_dev->pdev);
+               module_put(ccdc_dev->owner);
+       }
+       mutex_unlock(&vpfe_dev->lock);
+       file->private_data = NULL;
+       /* Free memory allocated to file handle object */
+       kfree(fh);
+       return 0;
+}
+
+/*
+ * vpfe_mmap : It is used to map kernel space buffers
+ * into user spaces
+ */
+static int vpfe_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       /* Get the device object and file handle object */
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_mmap\n");
+
+       return videobuf_mmap_mapper(&vpfe_dev->buffer_queue, vma);
+}
+
+/*
+ * vpfe_poll: It is used for select/poll system call
+ */
+static __poll_t vpfe_poll(struct file *file, poll_table *wait)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_poll\n");
+
+       if (vpfe_dev->started)
+               return videobuf_poll_stream(file,
+                                           &vpfe_dev->buffer_queue, wait);
+       return 0;
+}
+
+/* vpfe capture driver file operations */
+static const struct v4l2_file_operations vpfe_fops = {
+       .owner = THIS_MODULE,
+       .open = vpfe_open,
+       .release = vpfe_release,
+       .unlocked_ioctl = video_ioctl2,
+       .mmap = vpfe_mmap,
+       .poll = vpfe_poll
+};
+
+/*
+ * vpfe_check_format()
+ * This function adjust the input pixel format as per hardware
+ * capabilities and update the same in pixfmt.
+ * Following algorithm used :-
+ *
+ *     If given pixformat is not in the vpfe list of pix formats or not
+ *     supported by the hardware, current value of pixformat in the device
+ *     is used
+ *     If given field is not supported, then current field is used. If field
+ *     is different from current, then it is matched with that from sub device.
+ *     Minimum height is 2 lines for interlaced or tb field and 1 line for
+ *     progressive. Maximum height is clamped to active active lines of scan
+ *     Minimum width is 32 bytes in memory and width is clamped to active
+ *     pixels of scan.
+ *     bytesperline is a multiple of 32.
+ */
+static const struct vpfe_pixel_format *
+       vpfe_check_format(struct vpfe_device *vpfe_dev,
+                         struct v4l2_pix_format *pixfmt)
+{
+       u32 min_height = 1, min_width = 32, max_width, max_height;
+       const struct vpfe_pixel_format *vpfe_pix_fmt;
+       u32 pix;
+       int temp, found;
+
+       vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
+       if (!vpfe_pix_fmt) {
+               /*
+                * use current pixel format in the vpfe device. We
+                * will find this pix format in the table
+                */
+               pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
+               vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
+       }
+
+       /* check if hw supports it */
+       temp = 0;
+       found = 0;
+       while (ccdc_dev->hw_ops.enum_pix(&pix, temp) >= 0) {
+               if (vpfe_pix_fmt->pixelformat == pix) {
+                       found = 1;
+                       break;
+               }
+               temp++;
+       }
+
+       if (!found) {
+               /* use current pixel format */
+               pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
+               /*
+                * Since this is currently used in the vpfe device, we
+                * will find this pix format in the table
+                */
+               vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
+       }
+
+       /* check what field format is supported */
+       if (pixfmt->field == V4L2_FIELD_ANY) {
+               /* if field is any, use current value as default */
+               pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
+       }
+
+       /*
+        * if field is not same as current field in the vpfe device
+        * try matching the field with the sub device field
+        */
+       if (vpfe_dev->fmt.fmt.pix.field != pixfmt->field) {
+               /*
+                * If field value is not in the supported fields, use current
+                * field used in the device as default
+                */
+               switch (pixfmt->field) {
+               case V4L2_FIELD_INTERLACED:
+               case V4L2_FIELD_SEQ_TB:
+                       /* if sub device is supporting progressive, use that */
+                       if (!vpfe_dev->std_info.frame_format)
+                               pixfmt->field = V4L2_FIELD_NONE;
+                       break;
+               case V4L2_FIELD_NONE:
+                       if (vpfe_dev->std_info.frame_format)
+                               pixfmt->field = V4L2_FIELD_INTERLACED;
+                       break;
+
+               default:
+                       /* use current field as default */
+                       pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
+                       break;
+               }
+       }
+
+       /* Now adjust image resolutions supported */
+       if (pixfmt->field == V4L2_FIELD_INTERLACED ||
+           pixfmt->field == V4L2_FIELD_SEQ_TB)
+               min_height = 2;
+
+       max_width = vpfe_dev->std_info.active_pixels;
+       max_height = vpfe_dev->std_info.active_lines;
+       min_width /= vpfe_pix_fmt->bpp;
+
+       v4l2_info(&vpfe_dev->v4l2_dev, "width = %d, height = %d, bpp = %d\n",
+                 pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp);
+
+       pixfmt->width = clamp((pixfmt->width), min_width, max_width);
+       pixfmt->height = clamp((pixfmt->height), min_height, max_height);
+
+       /* If interlaced, adjust height to be a multiple of 2 */
+       if (pixfmt->field == V4L2_FIELD_INTERLACED)
+               pixfmt->height &= (~1);
+       /*
+        * recalculate bytesperline and sizeimage since width
+        * and height might have changed
+        */
+       pixfmt->bytesperline = (((pixfmt->width * vpfe_pix_fmt->bpp) + 31)
+                               & ~31);
+       if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
+               pixfmt->sizeimage =
+                       pixfmt->bytesperline * pixfmt->height +
+                       ((pixfmt->bytesperline * pixfmt->height) >> 1);
+       else
+               pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
+
+       v4l2_info(&vpfe_dev->v4l2_dev, "adjusted width = %d, height = %d, bpp = %d, bytesperline = %d, sizeimage = %d\n",
+                pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp,
+                pixfmt->bytesperline, pixfmt->sizeimage);
+       return vpfe_pix_fmt;
+}
+
+static int vpfe_querycap(struct file *file, void  *priv,
+                              struct v4l2_capability *cap)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querycap\n");
+
+       strscpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
+       strscpy(cap->bus_info, "VPFE", sizeof(cap->bus_info));
+       strscpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card));
+       return 0;
+}
+
+static int vpfe_g_fmt_vid_cap(struct file *file, void *priv,
+                               struct v4l2_format *fmt)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_fmt_vid_cap\n");
+       /* Fill in the information about format */
+       *fmt = vpfe_dev->fmt;
+       return 0;
+}
+
+static int vpfe_enum_fmt_vid_cap(struct file *file, void  *priv,
+                                  struct v4l2_fmtdesc *fmt)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       const struct vpfe_pixel_format *pix_fmt;
+       u32 pix;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt_vid_cap\n");
+
+       if (ccdc_dev->hw_ops.enum_pix(&pix, fmt->index) < 0)
+               return -EINVAL;
+
+       /* Fill in the information about format */
+       pix_fmt = vpfe_lookup_pix_format(pix);
+       if (pix_fmt) {
+               fmt->pixelformat = pix_fmt->pixelformat;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static int vpfe_s_fmt_vid_cap(struct file *file, void *priv,
+                               struct v4l2_format *fmt)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       const struct vpfe_pixel_format *pix_fmts;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt_vid_cap\n");
+
+       /* If streaming is started, return error */
+       if (vpfe_dev->started) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is started\n");
+               return -EBUSY;
+       }
+
+       /* Check for valid frame format */
+       pix_fmts = vpfe_check_format(vpfe_dev, &fmt->fmt.pix);
+       if (!pix_fmts)
+               return -EINVAL;
+
+       /* store the pixel format in the device  object */
+       ret = mutex_lock_interruptible(&vpfe_dev->lock);
+       if (ret)
+               return ret;
+
+       /* First detach any IRQ if currently attached */
+       vpfe_detach_irq(vpfe_dev);
+       vpfe_dev->fmt = *fmt;
+       /* set image capture parameters in the ccdc */
+       ret = vpfe_config_ccdc_image_format(vpfe_dev);
+       mutex_unlock(&vpfe_dev->lock);
+       return ret;
+}
+
+static int vpfe_try_fmt_vid_cap(struct file *file, void *priv,
+                                 struct v4l2_format *f)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       const struct vpfe_pixel_format *pix_fmts;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt_vid_cap\n");
+
+       pix_fmts = vpfe_check_format(vpfe_dev, &f->fmt.pix);
+       if (!pix_fmts)
+               return -EINVAL;
+       return 0;
+}
+
+/*
+ * vpfe_get_subdev_input_index - Get subdev index and subdev input index for a
+ * given app input index
+ */
+static int vpfe_get_subdev_input_index(struct vpfe_device *vpfe_dev,
+                                       int *subdev_index,
+                                       int *subdev_input_index,
+                                       int app_input_index)
+{
+       struct vpfe_config *cfg = vpfe_dev->cfg;
+       struct vpfe_subdev_info *sdinfo;
+       int i, j = 0;
+
+       for (i = 0; i < cfg->num_subdevs; i++) {
+               sdinfo = &cfg->sub_devs[i];
+               if (app_input_index < (j + sdinfo->num_inputs)) {
+                       *subdev_index = i;
+                       *subdev_input_index = app_input_index - j;
+                       return 0;
+               }
+               j += sdinfo->num_inputs;
+       }
+       return -EINVAL;
+}
+
+/*
+ * vpfe_get_app_input - Get app input index for a given subdev input index
+ * driver stores the input index of the current sub device and translate it
+ * when application request the current input
+ */
+static int vpfe_get_app_input_index(struct vpfe_device *vpfe_dev,
+                                   int *app_input_index)
+{
+       struct vpfe_config *cfg = vpfe_dev->cfg;
+       struct vpfe_subdev_info *sdinfo;
+       int i, j = 0;
+
+       for (i = 0; i < cfg->num_subdevs; i++) {
+               sdinfo = &cfg->sub_devs[i];
+               if (!strcmp(sdinfo->name, vpfe_dev->current_subdev->name)) {
+                       if (vpfe_dev->current_input >= sdinfo->num_inputs)
+                               return -1;
+                       *app_input_index = j + vpfe_dev->current_input;
+                       return 0;
+               }
+               j += sdinfo->num_inputs;
+       }
+       return -EINVAL;
+}
+
+static int vpfe_enum_input(struct file *file, void *priv,
+                                struct v4l2_input *inp)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct vpfe_subdev_info *sdinfo;
+       int subdev, index ;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_input\n");
+
+       if (vpfe_get_subdev_input_index(vpfe_dev,
+                                       &subdev,
+                                       &index,
+                                       inp->index) < 0) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "input information not found for the subdev\n");
+               return -EINVAL;
+       }
+       sdinfo = &vpfe_dev->cfg->sub_devs[subdev];
+       *inp = sdinfo->inputs[index];
+       return 0;
+}
+
+static int vpfe_g_input(struct file *file, void *priv, unsigned int *index)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_input\n");
+
+       return vpfe_get_app_input_index(vpfe_dev, index);
+}
+
+
+static int vpfe_s_input(struct file *file, void *priv, unsigned int index)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct v4l2_subdev *sd;
+       struct vpfe_subdev_info *sdinfo;
+       int subdev_index, inp_index;
+       struct vpfe_route *route;
+       u32 input, output;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n");
+
+       ret = mutex_lock_interruptible(&vpfe_dev->lock);
+       if (ret)
+               return ret;
+
+       /*
+        * If streaming is started return device busy
+        * error
+        */
+       if (vpfe_dev->started) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is on\n");
+               ret = -EBUSY;
+               goto unlock_out;
+       }
+       ret = vpfe_get_subdev_input_index(vpfe_dev,
+                                         &subdev_index,
+                                         &inp_index,
+                                         index);
+       if (ret < 0) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "invalid input index\n");
+               goto unlock_out;
+       }
+
+       sdinfo = &vpfe_dev->cfg->sub_devs[subdev_index];
+       sd = vpfe_dev->sd[subdev_index];
+       route = &sdinfo->routes[inp_index];
+       if (route && sdinfo->can_route) {
+               input = route->input;
+               output = route->output;
+       } else {
+               input = 0;
+               output = 0;
+       }
+
+       if (sd)
+               ret = v4l2_subdev_call(sd, video, s_routing, input, output, 0);
+
+       if (ret) {
+               v4l2_err(&vpfe_dev->v4l2_dev,
+                       "vpfe_doioctl:error in setting input in decoder\n");
+               ret = -EINVAL;
+               goto unlock_out;
+       }
+       vpfe_dev->current_subdev = sdinfo;
+       if (sd)
+               vpfe_dev->v4l2_dev.ctrl_handler = sd->ctrl_handler;
+       vpfe_dev->current_input = index;
+       vpfe_dev->std_index = 0;
+
+       /* set the bus/interface parameter for the sub device in ccdc */
+       ret = ccdc_dev->hw_ops.set_hw_if_params(&sdinfo->ccdc_if_params);
+       if (ret)
+               goto unlock_out;
+
+       /* set the default image parameters in the device */
+       ret = vpfe_config_image_format(vpfe_dev,
+                               vpfe_standards[vpfe_dev->std_index].std_id);
+unlock_out:
+       mutex_unlock(&vpfe_dev->lock);
+       return ret;
+}
+
+static int vpfe_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct vpfe_subdev_info *sdinfo;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querystd\n");
+
+       ret = mutex_lock_interruptible(&vpfe_dev->lock);
+       sdinfo = vpfe_dev->current_subdev;
+       if (ret)
+               return ret;
+       /* Call querystd function of decoder device */
+       ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+                                        video, querystd, std_id);
+       mutex_unlock(&vpfe_dev->lock);
+       return ret;
+}
+
+static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id std_id)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct vpfe_subdev_info *sdinfo;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n");
+
+       /* Call decoder driver function to set the standard */
+       ret = mutex_lock_interruptible(&vpfe_dev->lock);
+       if (ret)
+               return ret;
+
+       sdinfo = vpfe_dev->current_subdev;
+       /* If streaming is started, return device busy error */
+       if (vpfe_dev->started) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "streaming is started\n");
+               ret = -EBUSY;
+               goto unlock_out;
+       }
+
+       ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+                                        video, s_std, std_id);
+       if (ret < 0) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n");
+               goto unlock_out;
+       }
+       ret = vpfe_config_image_format(vpfe_dev, std_id);
+
+unlock_out:
+       mutex_unlock(&vpfe_dev->lock);
+       return ret;
+}
+
+static int vpfe_g_std(struct file *file, void *priv, v4l2_std_id *std_id)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_std\n");
+
+       *std_id = vpfe_standards[vpfe_dev->std_index].std_id;
+       return 0;
+}
+/*
+ *  Videobuf operations
+ */
+static int vpfe_videobuf_setup(struct videobuf_queue *vq,
+                               unsigned int *count,
+                               unsigned int *size)
+{
+       struct vpfe_fh *fh = vq->priv_data;
+       struct vpfe_device *vpfe_dev = fh->vpfe_dev;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_setup\n");
+       *size = vpfe_dev->fmt.fmt.pix.sizeimage;
+       if (vpfe_dev->memory == V4L2_MEMORY_MMAP &&
+               vpfe_dev->fmt.fmt.pix.sizeimage > config_params.device_bufsize)
+               *size = config_params.device_bufsize;
+
+       if (*count < config_params.min_numbuffers)
+               *count = config_params.min_numbuffers;
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+               "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)
+{
+       struct vpfe_fh *fh = vq->priv_data;
+       struct vpfe_device *vpfe_dev = fh->vpfe_dev;
+       unsigned long addr;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n");
+
+       /* If buffer is not initialized, initialize it */
+       if (VIDEOBUF_NEEDS_INIT == vb->state) {
+               vb->width = vpfe_dev->fmt.fmt.pix.width;
+               vb->height = vpfe_dev->fmt.fmt.pix.height;
+               vb->size = vpfe_dev->fmt.fmt.pix.sizeimage;
+               vb->field = field;
+
+               ret = videobuf_iolock(vq, vb, NULL);
+               if (ret < 0)
+                       return ret;
+
+               addr = videobuf_to_dma_contig(vb);
+               /* Make sure user addresses are aligned to 32 bytes */
+               if (!ALIGN(addr, 32))
+                       return -EINVAL;
+
+               vb->state = VIDEOBUF_PREPARED;
+       }
+       return 0;
+}
+
+static void vpfe_videobuf_queue(struct videobuf_queue *vq,
+                               struct videobuf_buffer *vb)
+{
+       /* Get the file handle object and device object */
+       struct vpfe_fh *fh = vq->priv_data;
+       struct vpfe_device *vpfe_dev = fh->vpfe_dev;
+       unsigned long flags;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_queue\n");
+
+       /* add the buffer to the DMA queue */
+       spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
+       list_add_tail(&vb->queue, &vpfe_dev->dma_queue);
+       spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
+
+       /* Change state of the buffer */
+       vb->state = VIDEOBUF_QUEUED;
+}
+
+static void vpfe_videobuf_release(struct videobuf_queue *vq,
+                                 struct videobuf_buffer *vb)
+{
+       struct vpfe_fh *fh = vq->priv_data;
+       struct vpfe_device *vpfe_dev = fh->vpfe_dev;
+       unsigned long flags;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_videobuf_release\n");
+
+       /*
+        * We need to flush the buffer from the dma queue since
+        * they are de-allocated
+        */
+       spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
+       INIT_LIST_HEAD(&vpfe_dev->dma_queue);
+       spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
+       videobuf_dma_contig_free(vq, vb);
+       vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+static const 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,
+};
+
+/*
+ * vpfe_reqbufs. currently support REQBUF only once opening
+ * the device.
+ */
+static int vpfe_reqbufs(struct file *file, void *priv,
+                       struct v4l2_requestbuffers *req_buf)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct vpfe_fh *fh = file->private_data;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs\n");
+
+       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != req_buf->type) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buffer type\n");
+               return -EINVAL;
+       }
+
+       ret = mutex_lock_interruptible(&vpfe_dev->lock);
+       if (ret)
+               return ret;
+
+       if (vpfe_dev->io_usrs != 0) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n");
+               ret = -EBUSY;
+               goto unlock_out;
+       }
+
+       vpfe_dev->memory = req_buf->memory;
+       videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue,
+                               &vpfe_videobuf_qops,
+                               vpfe_dev->pdev,
+                               &vpfe_dev->irqlock,
+                               req_buf->type,
+                               vpfe_dev->fmt.fmt.pix.field,
+                               sizeof(struct videobuf_buffer),
+                               fh, NULL);
+
+       fh->io_allowed = 1;
+       vpfe_dev->io_usrs = 1;
+       INIT_LIST_HEAD(&vpfe_dev->dma_queue);
+       ret = videobuf_reqbufs(&vpfe_dev->buffer_queue, req_buf);
+unlock_out:
+       mutex_unlock(&vpfe_dev->lock);
+       return ret;
+}
+
+static int vpfe_querybuf(struct file *file, void *priv,
+                        struct v4l2_buffer *buf)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querybuf\n");
+
+       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
+               return  -EINVAL;
+       }
+
+       if (vpfe_dev->memory != V4L2_MEMORY_MMAP) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid memory\n");
+               return -EINVAL;
+       }
+       /* Call videobuf_querybuf to get information */
+       return videobuf_querybuf(&vpfe_dev->buffer_queue, buf);
+}
+
+static int vpfe_qbuf(struct file *file, void *priv,
+                    struct v4l2_buffer *p)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct vpfe_fh *fh = file->private_data;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_qbuf\n");
+
+       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != p->type) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
+               return -EINVAL;
+       }
+
+       /*
+        * If this file handle is not allowed to do IO,
+        * return error
+        */
+       if (!fh->io_allowed) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
+               return -EACCES;
+       }
+       return videobuf_qbuf(&vpfe_dev->buffer_queue, p);
+}
+
+static int vpfe_dqbuf(struct file *file, void *priv,
+                     struct v4l2_buffer *buf)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_dqbuf\n");
+
+       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
+               return -EINVAL;
+       }
+       return videobuf_dqbuf(&vpfe_dev->buffer_queue,
+                                     buf, file->f_flags & O_NONBLOCK);
+}
+
+/*
+ * vpfe_calculate_offsets : This function calculates buffers offset
+ * for top and bottom field
+ */
+static void vpfe_calculate_offsets(struct vpfe_device *vpfe_dev)
+{
+       struct v4l2_rect image_win;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_calculate_offsets\n");
+
+       ccdc_dev->hw_ops.get_image_window(&image_win);
+       vpfe_dev->field_off = image_win.height * image_win.width;
+}
+
+/* vpfe_start_ccdc_capture: start streaming in ccdc/isif */
+static void vpfe_start_ccdc_capture(struct vpfe_device *vpfe_dev)
+{
+       ccdc_dev->hw_ops.enable(1);
+       if (ccdc_dev->hw_ops.enable_out_to_sdram)
+               ccdc_dev->hw_ops.enable_out_to_sdram(1);
+       vpfe_dev->started = 1;
+}
+
+/*
+ * vpfe_streamon. Assume the DMA queue is not empty.
+ * application is expected to call QBUF before calling
+ * this ioctl. If not, driver returns error
+ */
+static int vpfe_streamon(struct file *file, void *priv,
+                        enum v4l2_buf_type buf_type)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct vpfe_fh *fh = file->private_data;
+       struct vpfe_subdev_info *sdinfo;
+       unsigned long addr;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamon\n");
+
+       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
+               return -EINVAL;
+       }
+
+       /* If file handle is not allowed IO, return error */
+       if (!fh->io_allowed) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
+               return -EACCES;
+       }
+
+       sdinfo = vpfe_dev->current_subdev;
+       ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+                                       video, s_stream, 1);
+
+       if (ret && (ret != -ENOIOCTLCMD)) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "stream on failed in subdev\n");
+               return -EINVAL;
+       }
+
+       /* If buffer queue is empty, return error */
+       if (list_empty(&vpfe_dev->buffer_queue.stream)) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "buffer queue is empty\n");
+               return -EIO;
+       }
+
+       /* Call videobuf_streamon to start streaming * in videobuf */
+       ret = videobuf_streamon(&vpfe_dev->buffer_queue);
+       if (ret)
+               return ret;
+
+
+       ret = mutex_lock_interruptible(&vpfe_dev->lock);
+       if (ret)
+               goto streamoff;
+       /* Get the next frame from the buffer queue */
+       vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
+                                       struct videobuf_buffer, queue);
+       vpfe_dev->cur_frm = vpfe_dev->next_frm;
+       /* Remove buffer from the buffer queue */
+       list_del(&vpfe_dev->cur_frm->queue);
+       /* Mark state of the current frame to active */
+       vpfe_dev->cur_frm->state = VIDEOBUF_ACTIVE;
+       /* Initialize field_id and started member */
+       vpfe_dev->field_id = 0;
+       addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
+
+       /* Calculate field offset */
+       vpfe_calculate_offsets(vpfe_dev);
+
+       if (vpfe_attach_irq(vpfe_dev) < 0) {
+               v4l2_err(&vpfe_dev->v4l2_dev,
+                        "Error in attaching interrupt handle\n");
+               ret = -EFAULT;
+               goto unlock_out;
+       }
+       if (ccdc_dev->hw_ops.configure() < 0) {
+               v4l2_err(&vpfe_dev->v4l2_dev,
+                        "Error in configuring ccdc\n");
+               ret = -EINVAL;
+               goto unlock_out;
+       }
+       ccdc_dev->hw_ops.setfbaddr((unsigned long)(addr));
+       vpfe_start_ccdc_capture(vpfe_dev);
+       mutex_unlock(&vpfe_dev->lock);
+       return ret;
+unlock_out:
+       mutex_unlock(&vpfe_dev->lock);
+streamoff:
+       videobuf_streamoff(&vpfe_dev->buffer_queue);
+       return ret;
+}
+
+static int vpfe_streamoff(struct file *file, void *priv,
+                         enum v4l2_buf_type buf_type)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct vpfe_fh *fh = file->private_data;
+       struct vpfe_subdev_info *sdinfo;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamoff\n");
+
+       if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
+               return -EINVAL;
+       }
+
+       /* If io is allowed for this file handle, return error */
+       if (!fh->io_allowed) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
+               return -EACCES;
+       }
+
+       /* If streaming is not started, return error */
+       if (!vpfe_dev->started) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "device started\n");
+               return -EINVAL;
+       }
+
+       ret = mutex_lock_interruptible(&vpfe_dev->lock);
+       if (ret)
+               return ret;
+
+       vpfe_stop_ccdc_capture(vpfe_dev);
+       vpfe_detach_irq(vpfe_dev);
+
+       sdinfo = vpfe_dev->current_subdev;
+       ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+                                       video, s_stream, 0);
+
+       if (ret && (ret != -ENOIOCTLCMD))
+               v4l2_err(&vpfe_dev->v4l2_dev, "stream off failed in subdev\n");
+       ret = videobuf_streamoff(&vpfe_dev->buffer_queue);
+       mutex_unlock(&vpfe_dev->lock);
+       return ret;
+}
+
+static int vpfe_g_pixelaspect(struct file *file, void *priv,
+                             int type, struct v4l2_fract *f)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_pixelaspect\n");
+
+       if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+       /* If std_index is invalid, then just return (== 1:1 aspect) */
+       if (vpfe_dev->std_index >= ARRAY_SIZE(vpfe_standards))
+               return 0;
+
+       *f = vpfe_standards[vpfe_dev->std_index].pixelaspect;
+       return 0;
+}
+
+static int vpfe_g_selection(struct file *file, void *priv,
+                           struct v4l2_selection *sel)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_selection\n");
+
+       if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP:
+               sel->r = vpfe_dev->crop;
+               break;
+       case V4L2_SEL_TGT_CROP_DEFAULT:
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+               sel->r.width = vpfe_standards[vpfe_dev->std_index].width;
+               sel->r.height = vpfe_standards[vpfe_dev->std_index].height;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int vpfe_s_selection(struct file *file, void *priv,
+                           struct v4l2_selection *sel)
+{
+       struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct v4l2_rect rect = sel->r;
+       int ret;
+
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_selection\n");
+
+       if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+           sel->target != V4L2_SEL_TGT_CROP)
+               return -EINVAL;
+
+       if (vpfe_dev->started) {
+               /* make sure streaming is not started */
+               v4l2_err(&vpfe_dev->v4l2_dev,
+                       "Cannot change crop when streaming is ON\n");
+               return -EBUSY;
+       }
+
+       ret = mutex_lock_interruptible(&vpfe_dev->lock);
+       if (ret)
+               return ret;
+
+       if (rect.top < 0 || rect.left < 0) {
+               v4l2_err(&vpfe_dev->v4l2_dev,
+                       "doesn't support negative values for top & left\n");
+               ret = -EINVAL;
+               goto unlock_out;
+       }
+
+       /* adjust the width to 16 pixel boundary */
+       rect.width = ((rect.width + 15) & ~0xf);
+
+       /* make sure parameters are valid */
+       if ((rect.left + rect.width >
+               vpfe_dev->std_info.active_pixels) ||
+           (rect.top + rect.height >
+               vpfe_dev->std_info.active_lines)) {
+               v4l2_err(&vpfe_dev->v4l2_dev, "Error in S_SELECTION params\n");
+               ret = -EINVAL;
+               goto unlock_out;
+       }
+       ccdc_dev->hw_ops.set_image_window(&rect);
+       vpfe_dev->fmt.fmt.pix.width = rect.width;
+       vpfe_dev->fmt.fmt.pix.height = rect.height;
+       vpfe_dev->fmt.fmt.pix.bytesperline =
+               ccdc_dev->hw_ops.get_line_length();
+       vpfe_dev->fmt.fmt.pix.sizeimage =
+               vpfe_dev->fmt.fmt.pix.bytesperline *
+               vpfe_dev->fmt.fmt.pix.height;
+       vpfe_dev->crop = rect;
+       sel->r = rect;
+unlock_out:
+       mutex_unlock(&vpfe_dev->lock);
+       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_g_pixelaspect    = vpfe_g_pixelaspect,
+       .vidioc_g_selection      = vpfe_g_selection,
+       .vidioc_s_selection      = vpfe_s_selection,
+};
+
+static struct vpfe_device *vpfe_initialize(void)
+{
+       struct vpfe_device *vpfe_dev;
+
+       /* Default number of buffers should be 3 */
+       if ((numbuffers > 0) &&
+           (numbuffers < config_params.min_numbuffers))
+               numbuffers = config_params.min_numbuffers;
+
+       /*
+        * Set buffer size to min buffers size if invalid buffer size is
+        * given
+        */
+       if (bufsize < config_params.min_bufsize)
+               bufsize = config_params.min_bufsize;
+
+       config_params.numbuffers = numbuffers;
+
+       if (numbuffers)
+               config_params.device_bufsize = bufsize;
+
+       /* Allocate memory for device objects */
+       vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL);
+
+       return vpfe_dev;
+}
+
+/*
+ * vpfe_probe : This function creates device entries by register
+ * itself to the V4L2 driver and initializes fields of each
+ * device objects
+ */
+static int vpfe_probe(struct platform_device *pdev)
+{
+       struct vpfe_subdev_info *sdinfo;
+       struct vpfe_config *vpfe_cfg;
+       struct resource *res1;
+       struct vpfe_device *vpfe_dev;
+       struct i2c_adapter *i2c_adap;
+       struct video_device *vfd;
+       int ret, i, j;
+       int num_subdevs = 0;
+
+       /* Get the pointer to the device object */
+       vpfe_dev = vpfe_initialize();
+
+       if (!vpfe_dev) {
+               v4l2_err(pdev->dev.driver,
+                       "Failed to allocate memory for vpfe_dev\n");
+               return -ENOMEM;
+       }
+
+       vpfe_dev->pdev = &pdev->dev;
+
+       if (!pdev->dev.platform_data) {
+               v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
+               ret = -ENODEV;
+               goto probe_free_dev_mem;
+       }
+
+       vpfe_cfg = pdev->dev.platform_data;
+       vpfe_dev->cfg = vpfe_cfg;
+       if (!vpfe_cfg->ccdc || !vpfe_cfg->card_name || !vpfe_cfg->sub_devs) {
+               v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n");
+               ret = -ENOENT;
+               goto probe_free_dev_mem;
+       }
+
+       /* Allocate memory for ccdc configuration */
+       ccdc_cfg = kmalloc(sizeof(*ccdc_cfg), GFP_KERNEL);
+       if (!ccdc_cfg) {
+               ret = -ENOMEM;
+               goto probe_free_dev_mem;
+       }
+
+       mutex_lock(&ccdc_lock);
+
+       strscpy(ccdc_cfg->name, vpfe_cfg->ccdc, sizeof(ccdc_cfg->name));
+       /* Get VINT0 irq resource */
+       res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!res1) {
+               v4l2_err(pdev->dev.driver,
+                        "Unable to get interrupt for VINT0\n");
+               ret = -ENODEV;
+               goto probe_free_ccdc_cfg_mem;
+       }
+       vpfe_dev->ccdc_irq0 = res1->start;
+
+       /* Get VINT1 irq resource */
+       res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+       if (!res1) {
+               v4l2_err(pdev->dev.driver,
+                        "Unable to get interrupt for VINT1\n");
+               ret = -ENODEV;
+               goto probe_free_ccdc_cfg_mem;
+       }
+       vpfe_dev->ccdc_irq1 = res1->start;
+
+       ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, 0,
+                         "vpfe_capture0", vpfe_dev);
+
+       if (0 != ret) {
+               v4l2_err(pdev->dev.driver, "Unable to request interrupt\n");
+               goto probe_free_ccdc_cfg_mem;
+       }
+
+       vfd = &vpfe_dev->video_dev;
+       /* Initialize field of video device */
+       vfd->release            = video_device_release_empty;
+       vfd->fops               = &vpfe_fops;
+       vfd->ioctl_ops          = &vpfe_ioctl_ops;
+       vfd->tvnorms            = 0;
+       vfd->v4l2_dev           = &vpfe_dev->v4l2_dev;
+       vfd->device_caps        = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+       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);
+
+       ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev);
+       if (ret) {
+               v4l2_err(pdev->dev.driver,
+                       "Unable to register v4l2 device.\n");
+               goto probe_out_release_irq;
+       }
+       v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n");
+       spin_lock_init(&vpfe_dev->irqlock);
+       spin_lock_init(&vpfe_dev->dma_queue_lock);
+       mutex_init(&vpfe_dev->lock);
+
+       /* Initialize field of the device objects */
+       vpfe_dev->numbuffers = config_params.numbuffers;
+
+       /* register video device */
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+               "trying to register vpfe device.\n");
+       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+               "video_dev=%p\n", &vpfe_dev->video_dev);
+       vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       ret = video_register_device(&vpfe_dev->video_dev,
+                                   VFL_TYPE_VIDEO, -1);
+
+       if (ret) {
+               v4l2_err(pdev->dev.driver,
+                       "Unable to register video device.\n");
+               goto probe_out_v4l2_unregister;
+       }
+
+       v4l2_info(&vpfe_dev->v4l2_dev, "video device registered\n");
+       /* set the driver data in platform device */
+       platform_set_drvdata(pdev, vpfe_dev);
+       /* set driver private data */
+       video_set_drvdata(&vpfe_dev->video_dev, vpfe_dev);
+       i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id);
+       num_subdevs = vpfe_cfg->num_subdevs;
+       vpfe_dev->sd = kmalloc_array(num_subdevs,
+                                    sizeof(*vpfe_dev->sd),
+                                    GFP_KERNEL);
+       if (!vpfe_dev->sd) {
+               ret = -ENOMEM;
+               goto probe_out_video_unregister;
+       }
+
+       for (i = 0; i < num_subdevs; i++) {
+               struct v4l2_input *inps;
+
+               sdinfo = &vpfe_cfg->sub_devs[i];
+
+               /* Load up the subdevice */
+               vpfe_dev->sd[i] =
+                       v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
+                                                 i2c_adap,
+                                                 &sdinfo->board_info,
+                                                 NULL);
+               if (vpfe_dev->sd[i]) {
+                       v4l2_info(&vpfe_dev->v4l2_dev,
+                                 "v4l2 sub device %s registered\n",
+                                 sdinfo->name);
+                       vpfe_dev->sd[i]->grp_id = sdinfo->grp_id;
+                       /* update tvnorms from the sub devices */
+                       for (j = 0; j < sdinfo->num_inputs; j++) {
+                               inps = &sdinfo->inputs[j];
+                               vfd->tvnorms |= inps->std;
+                       }
+               } else {
+                       v4l2_info(&vpfe_dev->v4l2_dev,
+                                 "v4l2 sub device %s register fails\n",
+                                 sdinfo->name);
+                       ret = -ENXIO;
+                       goto probe_sd_out;
+               }
+       }
+
+       /* set first sub device as current one */
+       vpfe_dev->current_subdev = &vpfe_cfg->sub_devs[0];
+       vpfe_dev->v4l2_dev.ctrl_handler = vpfe_dev->sd[0]->ctrl_handler;
+
+       /* We have at least one sub device to work with */
+       mutex_unlock(&ccdc_lock);
+       return 0;
+
+probe_sd_out:
+       kfree(vpfe_dev->sd);
+probe_out_video_unregister:
+       video_unregister_device(&vpfe_dev->video_dev);
+probe_out_v4l2_unregister:
+       v4l2_device_unregister(&vpfe_dev->v4l2_dev);
+probe_out_release_irq:
+       free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
+probe_free_ccdc_cfg_mem:
+       kfree(ccdc_cfg);
+       mutex_unlock(&ccdc_lock);
+probe_free_dev_mem:
+       kfree(vpfe_dev);
+       return ret;
+}
+
+/*
+ * vpfe_remove : It un-register device from V4L2 driver
+ */
+static int vpfe_remove(struct platform_device *pdev)
+{
+       struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
+
+       v4l2_info(pdev->dev.driver, "vpfe_remove\n");
+
+       free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
+       kfree(vpfe_dev->sd);
+       v4l2_device_unregister(&vpfe_dev->v4l2_dev);
+       video_unregister_device(&vpfe_dev->video_dev);
+       kfree(vpfe_dev);
+       kfree(ccdc_cfg);
+       return 0;
+}
+
+static int vpfe_suspend(struct device *dev)
+{
+       return 0;
+}
+
+static int vpfe_resume(struct device *dev)
+{
+       return 0;
+}
+
+static const struct dev_pm_ops vpfe_dev_pm_ops = {
+       .suspend = vpfe_suspend,
+       .resume = vpfe_resume,
+};
+
+static struct platform_driver vpfe_driver = {
+       .driver = {
+               .name = CAPTURE_DRV_NAME,
+               .pm = &vpfe_dev_pm_ops,
+       },
+       .probe = vpfe_probe,
+       .remove = vpfe_remove,
+};
+
+module_platform_driver(vpfe_driver);
diff --git a/drivers/media/platform/ti/davinci/vpif.c b/drivers/media/platform/ti/davinci/vpif.c
new file mode 100644 (file)
index 0000000..97ef770
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+ * vpif - Video Port Interface driver
+ * VPIF is a receiver and transmitter for video data. It has two channels(0, 1)
+ * that receiving video byte stream and two channels(2, 3) for video output.
+ * The hardware supports SDTV, HDTV formats, raw data capture.
+ * Currently, the driver supports NTSC and PAL standards.
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * 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 version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/spinlock.h>
+#include <linux/v4l2-dv-timings.h>
+#include <linux/of_graph.h>
+
+#include "vpif.h"
+
+MODULE_DESCRIPTION("TI DaVinci Video Port Interface driver");
+MODULE_LICENSE("GPL");
+
+#define VPIF_DRIVER_NAME       "vpif"
+MODULE_ALIAS("platform:" VPIF_DRIVER_NAME);
+
+#define VPIF_CH0_MAX_MODES     22
+#define VPIF_CH1_MAX_MODES     2
+#define VPIF_CH2_MAX_MODES     15
+#define VPIF_CH3_MAX_MODES     2
+
+struct vpif_data {
+       struct platform_device *capture;
+       struct platform_device *display;
+};
+
+DEFINE_SPINLOCK(vpif_lock);
+EXPORT_SYMBOL_GPL(vpif_lock);
+
+void __iomem *vpif_base;
+EXPORT_SYMBOL_GPL(vpif_base);
+
+/*
+ * vpif_ch_params: video standard configuration parameters for vpif
+ *
+ * The table must include all presets from supported subdevices.
+ */
+const struct vpif_channel_config_params vpif_ch_params[] = {
+       /* HDTV formats */
+       {
+               .name = "480p59_94",
+               .width = 720,
+               .height = 480,
+               .frm_fmt = 1,
+               .ycmux_mode = 0,
+               .eav2sav = 138-8,
+               .sav2eav = 720,
+               .l1 = 1,
+               .l3 = 43,
+               .l5 = 523,
+               .vsize = 525,
+               .capture_format = 0,
+               .vbi_supported = 0,
+               .hd_sd = 1,
+               .dv_timings = V4L2_DV_BT_CEA_720X480P59_94,
+       },
+       {
+               .name = "576p50",
+               .width = 720,
+               .height = 576,
+               .frm_fmt = 1,
+               .ycmux_mode = 0,
+               .eav2sav = 144-8,
+               .sav2eav = 720,
+               .l1 = 1,
+               .l3 = 45,
+               .l5 = 621,
+               .vsize = 625,
+               .capture_format = 0,
+               .vbi_supported = 0,
+               .hd_sd = 1,
+               .dv_timings = V4L2_DV_BT_CEA_720X576P50,
+       },
+       {
+               .name = "720p50",
+               .width = 1280,
+               .height = 720,
+               .frm_fmt = 1,
+               .ycmux_mode = 0,
+               .eav2sav = 700-8,
+               .sav2eav = 1280,
+               .l1 = 1,
+               .l3 = 26,
+               .l5 = 746,
+               .vsize = 750,
+               .capture_format = 0,
+               .vbi_supported = 0,
+               .hd_sd = 1,
+               .dv_timings = V4L2_DV_BT_CEA_1280X720P50,
+       },
+       {
+               .name = "720p60",
+               .width = 1280,
+               .height = 720,
+               .frm_fmt = 1,
+               .ycmux_mode = 0,
+               .eav2sav = 370 - 8,
+               .sav2eav = 1280,
+               .l1 = 1,
+               .l3 = 26,
+               .l5 = 746,
+               .vsize = 750,
+               .capture_format = 0,
+               .vbi_supported = 0,
+               .hd_sd = 1,
+               .dv_timings = V4L2_DV_BT_CEA_1280X720P60,
+       },
+       {
+               .name = "1080I50",
+               .width = 1920,
+               .height = 1080,
+               .frm_fmt = 0,
+               .ycmux_mode = 0,
+               .eav2sav = 720 - 8,
+               .sav2eav = 1920,
+               .l1 = 1,
+               .l3 = 21,
+               .l5 = 561,
+               .l7 = 563,
+               .l9 = 584,
+               .l11 = 1124,
+               .vsize = 1125,
+               .capture_format = 0,
+               .vbi_supported = 0,
+               .hd_sd = 1,
+               .dv_timings = V4L2_DV_BT_CEA_1920X1080I50,
+       },
+       {
+               .name = "1080I60",
+               .width = 1920,
+               .height = 1080,
+               .frm_fmt = 0,
+               .ycmux_mode = 0,
+               .eav2sav = 280 - 8,
+               .sav2eav = 1920,
+               .l1 = 1,
+               .l3 = 21,
+               .l5 = 561,
+               .l7 = 563,
+               .l9 = 584,
+               .l11 = 1124,
+               .vsize = 1125,
+               .capture_format = 0,
+               .vbi_supported = 0,
+               .hd_sd = 1,
+               .dv_timings = V4L2_DV_BT_CEA_1920X1080I60,
+       },
+       {
+               .name = "1080p60",
+               .width = 1920,
+               .height = 1080,
+               .frm_fmt = 1,
+               .ycmux_mode = 0,
+               .eav2sav = 280 - 8,
+               .sav2eav = 1920,
+               .l1 = 1,
+               .l3 = 42,
+               .l5 = 1122,
+               .vsize = 1125,
+               .capture_format = 0,
+               .vbi_supported = 0,
+               .hd_sd = 1,
+               .dv_timings = V4L2_DV_BT_CEA_1920X1080P60,
+       },
+
+       /* SDTV formats */
+       {
+               .name = "NTSC_M",
+               .width = 720,
+               .height = 480,
+               .frm_fmt = 0,
+               .ycmux_mode = 1,
+               .eav2sav = 268,
+               .sav2eav = 1440,
+               .l1 = 1,
+               .l3 = 23,
+               .l5 = 263,
+               .l7 = 266,
+               .l9 = 286,
+               .l11 = 525,
+               .vsize = 525,
+               .capture_format = 0,
+               .vbi_supported = 1,
+               .hd_sd = 0,
+               .stdid = V4L2_STD_525_60,
+       },
+       {
+               .name = "PAL_BDGHIK",
+               .width = 720,
+               .height = 576,
+               .frm_fmt = 0,
+               .ycmux_mode = 1,
+               .eav2sav = 280,
+               .sav2eav = 1440,
+               .l1 = 1,
+               .l3 = 23,
+               .l5 = 311,
+               .l7 = 313,
+               .l9 = 336,
+               .l11 = 624,
+               .vsize = 625,
+               .capture_format = 0,
+               .vbi_supported = 1,
+               .hd_sd = 0,
+               .stdid = V4L2_STD_625_50,
+       },
+};
+EXPORT_SYMBOL_GPL(vpif_ch_params);
+
+const unsigned int vpif_ch_params_count = ARRAY_SIZE(vpif_ch_params);
+EXPORT_SYMBOL_GPL(vpif_ch_params_count);
+
+static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val)
+{
+       if (val)
+               vpif_set_bit(reg, bit);
+       else
+               vpif_clr_bit(reg, bit);
+}
+
+/* This structure is used to keep track of VPIF size register's offsets */
+struct vpif_registers {
+       u32 h_cfg, v_cfg_00, v_cfg_01, v_cfg_02, v_cfg, ch_ctrl;
+       u32 line_offset, vanc0_strt, vanc0_size, vanc1_strt;
+       u32 vanc1_size, width_mask, len_mask;
+       u8 max_modes;
+};
+
+static const struct vpif_registers vpifregs[VPIF_NUM_CHANNELS] = {
+       /* Channel0 */
+       {
+               VPIF_CH0_H_CFG, VPIF_CH0_V_CFG_00, VPIF_CH0_V_CFG_01,
+               VPIF_CH0_V_CFG_02, VPIF_CH0_V_CFG_03, VPIF_CH0_CTRL,
+               VPIF_CH0_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
+               VPIF_CH0_MAX_MODES,
+       },
+       /* Channel1 */
+       {
+               VPIF_CH1_H_CFG, VPIF_CH1_V_CFG_00, VPIF_CH1_V_CFG_01,
+               VPIF_CH1_V_CFG_02, VPIF_CH1_V_CFG_03, VPIF_CH1_CTRL,
+               VPIF_CH1_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
+               VPIF_CH1_MAX_MODES,
+       },
+       /* Channel2 */
+       {
+               VPIF_CH2_H_CFG, VPIF_CH2_V_CFG_00, VPIF_CH2_V_CFG_01,
+               VPIF_CH2_V_CFG_02, VPIF_CH2_V_CFG_03, VPIF_CH2_CTRL,
+               VPIF_CH2_IMG_ADD_OFST, VPIF_CH2_VANC0_STRT, VPIF_CH2_VANC0_SIZE,
+               VPIF_CH2_VANC1_STRT, VPIF_CH2_VANC1_SIZE, 0x7FF, 0x7FF,
+               VPIF_CH2_MAX_MODES
+       },
+       /* Channel3 */
+       {
+               VPIF_CH3_H_CFG, VPIF_CH3_V_CFG_00, VPIF_CH3_V_CFG_01,
+               VPIF_CH3_V_CFG_02, VPIF_CH3_V_CFG_03, VPIF_CH3_CTRL,
+               VPIF_CH3_IMG_ADD_OFST, VPIF_CH3_VANC0_STRT, VPIF_CH3_VANC0_SIZE,
+               VPIF_CH3_VANC1_STRT, VPIF_CH3_VANC1_SIZE, 0x7FF, 0x7FF,
+               VPIF_CH3_MAX_MODES
+       },
+};
+
+/* vpif_set_mode_info:
+ * This function is used to set horizontal and vertical config parameters
+ * As per the standard in the channel, configure the values of L1, L3,
+ * L5, L7  L9, L11 in VPIF Register , also write width and height
+ */
+static void vpif_set_mode_info(const struct vpif_channel_config_params *config,
+                               u8 channel_id, u8 config_channel_id)
+{
+       u32 value;
+
+       value = (config->eav2sav & vpifregs[config_channel_id].width_mask);
+       value <<= VPIF_CH_LEN_SHIFT;
+       value |= (config->sav2eav & vpifregs[config_channel_id].width_mask);
+       regw(value, vpifregs[channel_id].h_cfg);
+
+       value = (config->l1 & vpifregs[config_channel_id].len_mask);
+       value <<= VPIF_CH_LEN_SHIFT;
+       value |= (config->l3 & vpifregs[config_channel_id].len_mask);
+       regw(value, vpifregs[channel_id].v_cfg_00);
+
+       value = (config->l5 & vpifregs[config_channel_id].len_mask);
+       value <<= VPIF_CH_LEN_SHIFT;
+       value |= (config->l7 & vpifregs[config_channel_id].len_mask);
+       regw(value, vpifregs[channel_id].v_cfg_01);
+
+       value = (config->l9 & vpifregs[config_channel_id].len_mask);
+       value <<= VPIF_CH_LEN_SHIFT;
+       value |= (config->l11 & vpifregs[config_channel_id].len_mask);
+       regw(value, vpifregs[channel_id].v_cfg_02);
+
+       value = (config->vsize & vpifregs[config_channel_id].len_mask);
+       regw(value, vpifregs[channel_id].v_cfg);
+}
+
+/* config_vpif_params
+ * Function to set the parameters of a channel
+ * Mainly modifies the channel ciontrol register
+ * It sets frame format, yc mux mode
+ */
+static void config_vpif_params(struct vpif_params *vpifparams,
+                               u8 channel_id, u8 found)
+{
+       const struct vpif_channel_config_params *config = &vpifparams->std_info;
+       u32 value, ch_nip, reg;
+       u8 start, end;
+       int i;
+
+       start = channel_id;
+       end = channel_id + found;
+
+       for (i = start; i < end; i++) {
+               reg = vpifregs[i].ch_ctrl;
+               if (channel_id < 2)
+                       ch_nip = VPIF_CAPTURE_CH_NIP;
+               else
+                       ch_nip = VPIF_DISPLAY_CH_NIP;
+
+               vpif_wr_bit(reg, ch_nip, config->frm_fmt);
+               vpif_wr_bit(reg, VPIF_CH_YC_MUX_BIT, config->ycmux_mode);
+               vpif_wr_bit(reg, VPIF_CH_INPUT_FIELD_FRAME_BIT,
+                                       vpifparams->video_params.storage_mode);
+
+               /* Set raster scanning SDR Format */
+               vpif_clr_bit(reg, VPIF_CH_SDR_FMT_BIT);
+               vpif_wr_bit(reg, VPIF_CH_DATA_MODE_BIT, config->capture_format);
+
+               if (channel_id > 1)     /* Set the Pixel enable bit */
+                       vpif_set_bit(reg, VPIF_DISPLAY_PIX_EN_BIT);
+               else if (config->capture_format) {
+                       /* Set the polarity of various pins */
+                       vpif_wr_bit(reg, VPIF_CH_FID_POLARITY_BIT,
+                                       vpifparams->iface.fid_pol);
+                       vpif_wr_bit(reg, VPIF_CH_V_VALID_POLARITY_BIT,
+                                       vpifparams->iface.vd_pol);
+                       vpif_wr_bit(reg, VPIF_CH_H_VALID_POLARITY_BIT,
+                                       vpifparams->iface.hd_pol);
+
+                       value = regr(reg);
+                       /* Set data width */
+                       value &= ~(0x3u <<
+                                       VPIF_CH_DATA_WIDTH_BIT);
+                       value |= ((vpifparams->params.data_sz) <<
+                                                    VPIF_CH_DATA_WIDTH_BIT);
+                       regw(value, reg);
+               }
+
+               /* Write the pitch in the driver */
+               regw((vpifparams->video_params.hpitch),
+                                               vpifregs[i].line_offset);
+       }
+}
+
+/* vpif_set_video_params
+ * This function is used to set video parameters in VPIF register
+ */
+int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id)
+{
+       const struct vpif_channel_config_params *config = &vpifparams->std_info;
+       int found = 1;
+
+       vpif_set_mode_info(config, channel_id, channel_id);
+       if (!config->ycmux_mode) {
+               /* YC are on separate channels (HDTV formats) */
+               vpif_set_mode_info(config, channel_id + 1, channel_id);
+               found = 2;
+       }
+
+       config_vpif_params(vpifparams, channel_id, found);
+
+       regw(0x80, VPIF_REQ_SIZE);
+       regw(0x01, VPIF_EMULATION_CTRL);
+
+       return found;
+}
+EXPORT_SYMBOL(vpif_set_video_params);
+
+void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
+                               u8 channel_id)
+{
+       u32 value;
+
+       value = 0x3F8 & (vbiparams->hstart0);
+       value |= 0x3FFFFFF & ((vbiparams->vstart0) << 16);
+       regw(value, vpifregs[channel_id].vanc0_strt);
+
+       value = 0x3F8 & (vbiparams->hstart1);
+       value |= 0x3FFFFFF & ((vbiparams->vstart1) << 16);
+       regw(value, vpifregs[channel_id].vanc1_strt);
+
+       value = 0x3F8 & (vbiparams->hsize0);
+       value |= 0x3FFFFFF & ((vbiparams->vsize0) << 16);
+       regw(value, vpifregs[channel_id].vanc0_size);
+
+       value = 0x3F8 & (vbiparams->hsize1);
+       value |= 0x3FFFFFF & ((vbiparams->vsize1) << 16);
+       regw(value, vpifregs[channel_id].vanc1_size);
+
+}
+EXPORT_SYMBOL(vpif_set_vbi_display_params);
+
+int vpif_channel_getfid(u8 channel_id)
+{
+       return (regr(vpifregs[channel_id].ch_ctrl) & VPIF_CH_FID_MASK)
+                                       >> VPIF_CH_FID_SHIFT;
+}
+EXPORT_SYMBOL(vpif_channel_getfid);
+
+static void vpif_pdev_release(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+
+       kfree(pdev);
+}
+
+static int vpif_probe(struct platform_device *pdev)
+{
+       static struct resource res_irq;
+       struct platform_device *pdev_capture, *pdev_display;
+       struct device_node *endpoint = NULL;
+       struct vpif_data *data;
+       int ret;
+       int irq;
+
+       vpif_base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(vpif_base))
+               return PTR_ERR(vpif_base);
+
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       platform_set_drvdata(pdev, data);
+
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_get(&pdev->dev);
+
+       /*
+        * If VPIF Node has endpoints, assume "new" DT support,
+        * where capture and display drivers don't have DT nodes
+        * so their devices need to be registered manually here
+        * for their legacy platform_drivers to work.
+        */
+       endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
+                                             endpoint);
+       if (!endpoint)
+               return 0;
+
+       /*
+        * For DT platforms, manually create platform_devices for
+        * capture/display drivers.
+        */
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = irq;
+               goto err_put_rpm;
+       }
+       res_irq = (struct resource)DEFINE_RES_IRQ_NAMED(irq, of_node_full_name(pdev->dev.of_node));
+       res_irq.flags |= irq_get_trigger_type(irq);
+
+       pdev_capture = kzalloc(sizeof(*pdev_capture), GFP_KERNEL);
+       if (!pdev_capture) {
+               ret = -ENOMEM;
+               goto err_put_rpm;
+       }
+
+       pdev_capture->name = "vpif_capture";
+       pdev_capture->id = -1;
+       pdev_capture->resource = &res_irq;
+       pdev_capture->num_resources = 1;
+       pdev_capture->dev.dma_mask = pdev->dev.dma_mask;
+       pdev_capture->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
+       pdev_capture->dev.parent = &pdev->dev;
+       pdev_capture->dev.release = vpif_pdev_release;
+
+       ret = platform_device_register(pdev_capture);
+       if (ret)
+               goto err_put_pdev_capture;
+
+       pdev_display = kzalloc(sizeof(*pdev_display), GFP_KERNEL);
+       if (!pdev_display) {
+               ret = -ENOMEM;
+               goto err_put_pdev_capture;
+       }
+
+       pdev_display->name = "vpif_display";
+       pdev_display->id = -1;
+       pdev_display->resource = &res_irq;
+       pdev_display->num_resources = 1;
+       pdev_display->dev.dma_mask = pdev->dev.dma_mask;
+       pdev_display->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
+       pdev_display->dev.parent = &pdev->dev;
+       pdev_display->dev.release = vpif_pdev_release;
+
+       ret = platform_device_register(pdev_display);
+       if (ret)
+               goto err_put_pdev_display;
+
+       data->capture = pdev_capture;
+       data->display = pdev_display;
+
+       return 0;
+
+err_put_pdev_display:
+       platform_device_put(pdev_display);
+err_put_pdev_capture:
+       platform_device_put(pdev_capture);
+err_put_rpm:
+       pm_runtime_put(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+       kfree(data);
+
+       return ret;
+}
+
+static int vpif_remove(struct platform_device *pdev)
+{
+       struct vpif_data *data = platform_get_drvdata(pdev);
+
+       if (data->capture)
+               platform_device_unregister(data->capture);
+       if (data->display)
+               platform_device_unregister(data->display);
+
+       pm_runtime_put(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+
+       kfree(data);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int vpif_suspend(struct device *dev)
+{
+       pm_runtime_put(dev);
+       return 0;
+}
+
+static int vpif_resume(struct device *dev)
+{
+       pm_runtime_get(dev);
+       return 0;
+}
+
+static const struct dev_pm_ops vpif_pm = {
+       .suspend        = vpif_suspend,
+       .resume         = vpif_resume,
+};
+
+#define vpif_pm_ops (&vpif_pm)
+#else
+#define vpif_pm_ops NULL
+#endif
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id vpif_of_match[] = {
+       { .compatible = "ti,da850-vpif", },
+       { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, vpif_of_match);
+#endif
+
+static struct platform_driver vpif_driver = {
+       .driver = {
+               .of_match_table = of_match_ptr(vpif_of_match),
+               .name   = VPIF_DRIVER_NAME,
+               .pm     = vpif_pm_ops,
+       },
+       .remove = vpif_remove,
+       .probe = vpif_probe,
+};
+
+static void vpif_exit(void)
+{
+       platform_driver_unregister(&vpif_driver);
+}
+
+static int __init vpif_init(void)
+{
+       return platform_driver_register(&vpif_driver);
+}
+subsys_initcall(vpif_init);
+module_exit(vpif_exit);
+
diff --git a/drivers/media/platform/ti/davinci/vpif.h b/drivers/media/platform/ti/davinci/vpif.h
new file mode 100644 (file)
index 0000000..c6d1d89
--- /dev/null
@@ -0,0 +1,688 @@
+/*
+ * VPIF header file
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * 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 version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef VPIF_H
+#define VPIF_H
+
+#include <linux/io.h>
+#include <linux/videodev2.h>
+#include <media/davinci/vpif_types.h>
+
+/* Maximum channel allowed */
+#define VPIF_NUM_CHANNELS              (4)
+#define VPIF_CAPTURE_NUM_CHANNELS      (2)
+#define VPIF_DISPLAY_NUM_CHANNELS      (2)
+
+/* Macros to read/write registers */
+extern void __iomem *vpif_base;
+extern spinlock_t vpif_lock;
+
+#define regr(reg)               readl((reg) + vpif_base)
+#define regw(value, reg)        writel(value, (reg + vpif_base))
+
+/* Register Address Offsets */
+#define VPIF_PID                       (0x0000)
+#define VPIF_CH0_CTRL                  (0x0004)
+#define VPIF_CH1_CTRL                  (0x0008)
+#define VPIF_CH2_CTRL                  (0x000C)
+#define VPIF_CH3_CTRL                  (0x0010)
+
+#define VPIF_INTEN                     (0x0020)
+#define VPIF_INTEN_SET                 (0x0024)
+#define VPIF_INTEN_CLR                 (0x0028)
+#define VPIF_STATUS                    (0x002C)
+#define VPIF_STATUS_CLR                        (0x0030)
+#define VPIF_EMULATION_CTRL            (0x0034)
+#define VPIF_REQ_SIZE                  (0x0038)
+
+#define VPIF_CH0_TOP_STRT_ADD_LUMA     (0x0040)
+#define VPIF_CH0_BTM_STRT_ADD_LUMA     (0x0044)
+#define VPIF_CH0_TOP_STRT_ADD_CHROMA   (0x0048)
+#define VPIF_CH0_BTM_STRT_ADD_CHROMA   (0x004c)
+#define VPIF_CH0_TOP_STRT_ADD_HANC     (0x0050)
+#define VPIF_CH0_BTM_STRT_ADD_HANC     (0x0054)
+#define VPIF_CH0_TOP_STRT_ADD_VANC     (0x0058)
+#define VPIF_CH0_BTM_STRT_ADD_VANC     (0x005c)
+#define VPIF_CH0_SP_CFG                        (0x0060)
+#define VPIF_CH0_IMG_ADD_OFST          (0x0064)
+#define VPIF_CH0_HANC_ADD_OFST         (0x0068)
+#define VPIF_CH0_H_CFG                 (0x006c)
+#define VPIF_CH0_V_CFG_00              (0x0070)
+#define VPIF_CH0_V_CFG_01              (0x0074)
+#define VPIF_CH0_V_CFG_02              (0x0078)
+#define VPIF_CH0_V_CFG_03              (0x007c)
+
+#define VPIF_CH1_TOP_STRT_ADD_LUMA     (0x0080)
+#define VPIF_CH1_BTM_STRT_ADD_LUMA     (0x0084)
+#define VPIF_CH1_TOP_STRT_ADD_CHROMA   (0x0088)
+#define VPIF_CH1_BTM_STRT_ADD_CHROMA   (0x008c)
+#define VPIF_CH1_TOP_STRT_ADD_HANC     (0x0090)
+#define VPIF_CH1_BTM_STRT_ADD_HANC     (0x0094)
+#define VPIF_CH1_TOP_STRT_ADD_VANC     (0x0098)
+#define VPIF_CH1_BTM_STRT_ADD_VANC     (0x009c)
+#define VPIF_CH1_SP_CFG                        (0x00a0)
+#define VPIF_CH1_IMG_ADD_OFST          (0x00a4)
+#define VPIF_CH1_HANC_ADD_OFST         (0x00a8)
+#define VPIF_CH1_H_CFG                 (0x00ac)
+#define VPIF_CH1_V_CFG_00              (0x00b0)
+#define VPIF_CH1_V_CFG_01              (0x00b4)
+#define VPIF_CH1_V_CFG_02              (0x00b8)
+#define VPIF_CH1_V_CFG_03              (0x00bc)
+
+#define VPIF_CH2_TOP_STRT_ADD_LUMA     (0x00c0)
+#define VPIF_CH2_BTM_STRT_ADD_LUMA     (0x00c4)
+#define VPIF_CH2_TOP_STRT_ADD_CHROMA   (0x00c8)
+#define VPIF_CH2_BTM_STRT_ADD_CHROMA   (0x00cc)
+#define VPIF_CH2_TOP_STRT_ADD_HANC     (0x00d0)
+#define VPIF_CH2_BTM_STRT_ADD_HANC     (0x00d4)
+#define VPIF_CH2_TOP_STRT_ADD_VANC     (0x00d8)
+#define VPIF_CH2_BTM_STRT_ADD_VANC     (0x00dc)
+#define VPIF_CH2_SP_CFG                        (0x00e0)
+#define VPIF_CH2_IMG_ADD_OFST          (0x00e4)
+#define VPIF_CH2_HANC_ADD_OFST         (0x00e8)
+#define VPIF_CH2_H_CFG                 (0x00ec)
+#define VPIF_CH2_V_CFG_00              (0x00f0)
+#define VPIF_CH2_V_CFG_01              (0x00f4)
+#define VPIF_CH2_V_CFG_02              (0x00f8)
+#define VPIF_CH2_V_CFG_03              (0x00fc)
+#define VPIF_CH2_HANC0_STRT            (0x0100)
+#define VPIF_CH2_HANC0_SIZE            (0x0104)
+#define VPIF_CH2_HANC1_STRT            (0x0108)
+#define VPIF_CH2_HANC1_SIZE            (0x010c)
+#define VPIF_CH2_VANC0_STRT            (0x0110)
+#define VPIF_CH2_VANC0_SIZE            (0x0114)
+#define VPIF_CH2_VANC1_STRT            (0x0118)
+#define VPIF_CH2_VANC1_SIZE            (0x011c)
+
+#define VPIF_CH3_TOP_STRT_ADD_LUMA     (0x0140)
+#define VPIF_CH3_BTM_STRT_ADD_LUMA     (0x0144)
+#define VPIF_CH3_TOP_STRT_ADD_CHROMA   (0x0148)
+#define VPIF_CH3_BTM_STRT_ADD_CHROMA   (0x014c)
+#define VPIF_CH3_TOP_STRT_ADD_HANC     (0x0150)
+#define VPIF_CH3_BTM_STRT_ADD_HANC     (0x0154)
+#define VPIF_CH3_TOP_STRT_ADD_VANC     (0x0158)
+#define VPIF_CH3_BTM_STRT_ADD_VANC     (0x015c)
+#define VPIF_CH3_SP_CFG                        (0x0160)
+#define VPIF_CH3_IMG_ADD_OFST          (0x0164)
+#define VPIF_CH3_HANC_ADD_OFST         (0x0168)
+#define VPIF_CH3_H_CFG                 (0x016c)
+#define VPIF_CH3_V_CFG_00              (0x0170)
+#define VPIF_CH3_V_CFG_01              (0x0174)
+#define VPIF_CH3_V_CFG_02              (0x0178)
+#define VPIF_CH3_V_CFG_03              (0x017c)
+#define VPIF_CH3_HANC0_STRT            (0x0180)
+#define VPIF_CH3_HANC0_SIZE            (0x0184)
+#define VPIF_CH3_HANC1_STRT            (0x0188)
+#define VPIF_CH3_HANC1_SIZE            (0x018c)
+#define VPIF_CH3_VANC0_STRT            (0x0190)
+#define VPIF_CH3_VANC0_SIZE            (0x0194)
+#define VPIF_CH3_VANC1_STRT            (0x0198)
+#define VPIF_CH3_VANC1_SIZE            (0x019c)
+
+#define VPIF_IODFT_CTRL                        (0x01c0)
+
+/* Functions for bit Manipulation */
+static inline void vpif_set_bit(u32 reg, u32 bit)
+{
+       regw((regr(reg)) | (0x01 << bit), reg);
+}
+
+static inline void vpif_clr_bit(u32 reg, u32 bit)
+{
+       regw(((regr(reg)) & ~(0x01 << bit)), reg);
+}
+
+/* Macro for Generating mask */
+#ifdef GENERATE_MASK
+#undef GENERATE_MASK
+#endif
+
+#define GENERATE_MASK(bits, pos) \
+               ((((0xFFFFFFFF) << (32 - bits)) >> (32 - bits)) << pos)
+
+/* Bit positions in the channel control registers */
+#define VPIF_CH_DATA_MODE_BIT  (2)
+#define VPIF_CH_YC_MUX_BIT     (3)
+#define VPIF_CH_SDR_FMT_BIT    (4)
+#define VPIF_CH_HANC_EN_BIT    (8)
+#define VPIF_CH_VANC_EN_BIT    (9)
+
+#define VPIF_CAPTURE_CH_NIP    (10)
+#define VPIF_DISPLAY_CH_NIP    (11)
+
+#define VPIF_DISPLAY_PIX_EN_BIT        (10)
+
+#define VPIF_CH_INPUT_FIELD_FRAME_BIT  (12)
+
+#define VPIF_CH_FID_POLARITY_BIT       (15)
+#define VPIF_CH_V_VALID_POLARITY_BIT   (14)
+#define VPIF_CH_H_VALID_POLARITY_BIT   (13)
+#define VPIF_CH_DATA_WIDTH_BIT         (28)
+
+#define VPIF_CH_CLK_EDGE_CTRL_BIT      (31)
+
+/* Mask various length */
+#define VPIF_CH_EAVSAV_MASK    GENERATE_MASK(13, 0)
+#define VPIF_CH_LEN_MASK       GENERATE_MASK(12, 0)
+#define VPIF_CH_WIDTH_MASK     GENERATE_MASK(13, 0)
+#define VPIF_CH_LEN_SHIFT      (16)
+
+/* VPIF masks for registers */
+#define VPIF_REQ_SIZE_MASK     (0x1ff)
+
+/* bit posotion of interrupt vpif_ch_intr register */
+#define VPIF_INTEN_FRAME_CH0   (0x00000001)
+#define VPIF_INTEN_FRAME_CH1   (0x00000002)
+#define VPIF_INTEN_FRAME_CH2   (0x00000004)
+#define VPIF_INTEN_FRAME_CH3   (0x00000008)
+
+/* bit position of clock and channel enable in vpif_chn_ctrl register */
+
+#define VPIF_CH0_CLK_EN                (0x00000002)
+#define VPIF_CH0_EN            (0x00000001)
+#define VPIF_CH1_CLK_EN                (0x00000002)
+#define VPIF_CH1_EN            (0x00000001)
+#define VPIF_CH2_CLK_EN                (0x00000002)
+#define VPIF_CH2_EN            (0x00000001)
+#define VPIF_CH3_CLK_EN                (0x00000002)
+#define VPIF_CH3_EN            (0x00000001)
+#define VPIF_CH_CLK_EN         (0x00000002)
+#define VPIF_CH_EN             (0x00000001)
+
+#define VPIF_INT_TOP   (0x00)
+#define VPIF_INT_BOTTOM        (0x01)
+#define VPIF_INT_BOTH  (0x02)
+
+#define VPIF_CH0_INT_CTRL_SHIFT        (6)
+#define VPIF_CH1_INT_CTRL_SHIFT        (6)
+#define VPIF_CH2_INT_CTRL_SHIFT        (6)
+#define VPIF_CH3_INT_CTRL_SHIFT        (6)
+#define VPIF_CH_INT_CTRL_SHIFT (6)
+
+#define VPIF_CH2_CLIP_ANC_EN   14
+#define VPIF_CH2_CLIP_ACTIVE_EN        13
+
+#define VPIF_CH3_CLIP_ANC_EN   14
+#define VPIF_CH3_CLIP_ACTIVE_EN        13
+
+/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
+#define channel0_intr_assert() (regw((regr(VPIF_CH0_CTRL)|\
+       (VPIF_INT_BOTH << VPIF_CH0_INT_CTRL_SHIFT)), VPIF_CH0_CTRL))
+
+/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
+#define channel1_intr_assert() (regw((regr(VPIF_CH1_CTRL)|\
+       (VPIF_INT_BOTH << VPIF_CH1_INT_CTRL_SHIFT)), VPIF_CH1_CTRL))
+
+/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
+#define channel2_intr_assert() (regw((regr(VPIF_CH2_CTRL)|\
+       (VPIF_INT_BOTH << VPIF_CH2_INT_CTRL_SHIFT)), VPIF_CH2_CTRL))
+
+/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
+#define channel3_intr_assert() (regw((regr(VPIF_CH3_CTRL)|\
+       (VPIF_INT_BOTH << VPIF_CH3_INT_CTRL_SHIFT)), VPIF_CH3_CTRL))
+
+#define VPIF_CH_FID_MASK       (0x20)
+#define VPIF_CH_FID_SHIFT      (5)
+
+#define VPIF_NTSC_VBI_START_FIELD0     (1)
+#define VPIF_NTSC_VBI_START_FIELD1     (263)
+#define VPIF_PAL_VBI_START_FIELD0      (624)
+#define VPIF_PAL_VBI_START_FIELD1      (311)
+
+#define VPIF_NTSC_HBI_START_FIELD0     (1)
+#define VPIF_NTSC_HBI_START_FIELD1     (263)
+#define VPIF_PAL_HBI_START_FIELD0      (624)
+#define VPIF_PAL_HBI_START_FIELD1      (311)
+
+#define VPIF_NTSC_VBI_COUNT_FIELD0     (20)
+#define VPIF_NTSC_VBI_COUNT_FIELD1     (19)
+#define VPIF_PAL_VBI_COUNT_FIELD0      (24)
+#define VPIF_PAL_VBI_COUNT_FIELD1      (25)
+
+#define VPIF_NTSC_HBI_COUNT_FIELD0     (263)
+#define VPIF_NTSC_HBI_COUNT_FIELD1     (262)
+#define VPIF_PAL_HBI_COUNT_FIELD0      (312)
+#define VPIF_PAL_HBI_COUNT_FIELD1      (313)
+
+#define VPIF_NTSC_VBI_SAMPLES_PER_LINE (720)
+#define VPIF_PAL_VBI_SAMPLES_PER_LINE  (720)
+#define VPIF_NTSC_HBI_SAMPLES_PER_LINE (268)
+#define VPIF_PAL_HBI_SAMPLES_PER_LINE  (280)
+
+#define VPIF_CH_VANC_EN                        (0x20)
+#define VPIF_DMA_REQ_SIZE              (0x080)
+#define VPIF_EMULATION_DISABLE         (0x01)
+
+extern u8 irq_vpif_capture_channel[VPIF_NUM_CHANNELS];
+
+/* inline function to enable/disable channel0 */
+static inline void enable_channel0(int enable)
+{
+       if (enable)
+               regw((regr(VPIF_CH0_CTRL) | (VPIF_CH0_EN)), VPIF_CH0_CTRL);
+       else
+               regw((regr(VPIF_CH0_CTRL) & (~VPIF_CH0_EN)), VPIF_CH0_CTRL);
+}
+
+/* inline function to enable/disable channel1 */
+static inline void enable_channel1(int enable)
+{
+       if (enable)
+               regw((regr(VPIF_CH1_CTRL) | (VPIF_CH1_EN)), VPIF_CH1_CTRL);
+       else
+               regw((regr(VPIF_CH1_CTRL) & (~VPIF_CH1_EN)), VPIF_CH1_CTRL);
+}
+
+/* inline function to enable interrupt for channel0 */
+static inline void channel0_intr_enable(int enable)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&vpif_lock, flags);
+
+       if (enable) {
+               regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
+               regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
+
+               regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH0), VPIF_INTEN);
+               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
+                                                       VPIF_INTEN_SET);
+       } else {
+               regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH0)), VPIF_INTEN);
+               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
+                                                       VPIF_INTEN_SET);
+       }
+       spin_unlock_irqrestore(&vpif_lock, flags);
+}
+
+/* inline function to enable interrupt for channel1 */
+static inline void channel1_intr_enable(int enable)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&vpif_lock, flags);
+
+       if (enable) {
+               regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
+               regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
+
+               regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH1), VPIF_INTEN);
+               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
+                                                       VPIF_INTEN_SET);
+       } else {
+               regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH1)), VPIF_INTEN);
+               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
+                                                       VPIF_INTEN_SET);
+       }
+       spin_unlock_irqrestore(&vpif_lock, flags);
+}
+
+/* inline function to set buffer addresses in case of Y/C non mux mode */
+static inline void ch0_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
+                                                unsigned long btm_strt_luma,
+                                                unsigned long top_strt_chroma,
+                                                unsigned long btm_strt_chroma)
+{
+       regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
+       regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
+       regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
+       regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
+}
+
+/* inline function to set buffer addresses in VPIF registers for video data */
+static inline void ch0_set_videobuf_addr(unsigned long top_strt_luma,
+                                        unsigned long btm_strt_luma,
+                                        unsigned long top_strt_chroma,
+                                        unsigned long btm_strt_chroma)
+{
+       regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
+       regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
+       regw(top_strt_chroma, VPIF_CH0_TOP_STRT_ADD_CHROMA);
+       regw(btm_strt_chroma, VPIF_CH0_BTM_STRT_ADD_CHROMA);
+}
+
+static inline void ch1_set_videobuf_addr(unsigned long top_strt_luma,
+                                        unsigned long btm_strt_luma,
+                                        unsigned long top_strt_chroma,
+                                        unsigned long btm_strt_chroma)
+{
+
+       regw(top_strt_luma, VPIF_CH1_TOP_STRT_ADD_LUMA);
+       regw(btm_strt_luma, VPIF_CH1_BTM_STRT_ADD_LUMA);
+       regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
+       regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
+}
+
+static inline void ch0_set_vbi_addr(unsigned long top_vbi,
+       unsigned long btm_vbi, unsigned long a, unsigned long b)
+{
+       regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_VANC);
+       regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_VANC);
+}
+
+static inline void ch0_set_hbi_addr(unsigned long top_vbi,
+       unsigned long btm_vbi, unsigned long a, unsigned long b)
+{
+       regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_HANC);
+       regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_HANC);
+}
+
+static inline void ch1_set_vbi_addr(unsigned long top_vbi,
+       unsigned long btm_vbi, unsigned long a, unsigned long b)
+{
+       regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_VANC);
+       regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_VANC);
+}
+
+static inline void ch1_set_hbi_addr(unsigned long top_vbi,
+       unsigned long btm_vbi, unsigned long a, unsigned long b)
+{
+       regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_HANC);
+       regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_HANC);
+}
+
+/* Inline function to enable raw vbi in the given channel */
+static inline void disable_raw_feature(u8 channel_id, u8 index)
+{
+       u32 ctrl_reg;
+       if (0 == channel_id)
+               ctrl_reg = VPIF_CH0_CTRL;
+       else
+               ctrl_reg = VPIF_CH1_CTRL;
+
+       if (1 == index)
+               vpif_clr_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
+       else
+               vpif_clr_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
+}
+
+static inline void enable_raw_feature(u8 channel_id, u8 index)
+{
+       u32 ctrl_reg;
+       if (0 == channel_id)
+               ctrl_reg = VPIF_CH0_CTRL;
+       else
+               ctrl_reg = VPIF_CH1_CTRL;
+
+       if (1 == index)
+               vpif_set_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
+       else
+               vpif_set_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
+}
+
+/* inline function to enable/disable channel2 */
+static inline void enable_channel2(int enable)
+{
+       if (enable) {
+               regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
+               regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_EN)), VPIF_CH2_CTRL);
+       } else {
+               regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
+               regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_EN)), VPIF_CH2_CTRL);
+       }
+}
+
+/* inline function to enable/disable channel3 */
+static inline void enable_channel3(int enable)
+{
+       if (enable) {
+               regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
+               regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_EN)), VPIF_CH3_CTRL);
+       } else {
+               regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
+               regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_EN)), VPIF_CH3_CTRL);
+       }
+}
+
+/* inline function to enable interrupt for channel2 */
+static inline void channel2_intr_enable(int enable)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&vpif_lock, flags);
+
+       if (enable) {
+               regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
+               regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
+               regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH2), VPIF_INTEN);
+               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
+                                                       VPIF_INTEN_SET);
+       } else {
+               regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH2)), VPIF_INTEN);
+               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
+                                                       VPIF_INTEN_SET);
+       }
+       spin_unlock_irqrestore(&vpif_lock, flags);
+}
+
+/* inline function to enable interrupt for channel3 */
+static inline void channel3_intr_enable(int enable)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&vpif_lock, flags);
+
+       if (enable) {
+               regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
+               regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
+
+               regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH3), VPIF_INTEN);
+               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
+                                                       VPIF_INTEN_SET);
+       } else {
+               regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH3)), VPIF_INTEN);
+               regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
+                                                       VPIF_INTEN_SET);
+       }
+       spin_unlock_irqrestore(&vpif_lock, flags);
+}
+
+/* inline function to enable raw vbi data for channel2 */
+static inline void channel2_raw_enable(int enable, u8 index)
+{
+       u32 mask;
+
+       if (1 == index)
+               mask = VPIF_CH_VANC_EN_BIT;
+       else
+               mask = VPIF_CH_HANC_EN_BIT;
+
+       if (enable)
+               vpif_set_bit(VPIF_CH2_CTRL, mask);
+       else
+               vpif_clr_bit(VPIF_CH2_CTRL, mask);
+}
+
+/* inline function to enable raw vbi data for channel3*/
+static inline void channel3_raw_enable(int enable, u8 index)
+{
+       u32 mask;
+
+       if (1 == index)
+               mask = VPIF_CH_VANC_EN_BIT;
+       else
+               mask = VPIF_CH_HANC_EN_BIT;
+
+       if (enable)
+               vpif_set_bit(VPIF_CH3_CTRL, mask);
+       else
+               vpif_clr_bit(VPIF_CH3_CTRL, mask);
+}
+
+/* function to enable clipping (for both active and blanking regions) on ch 2 */
+static inline void channel2_clipping_enable(int enable)
+{
+       if (enable) {
+               vpif_set_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ANC_EN);
+               vpif_set_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ACTIVE_EN);
+       } else {
+               vpif_clr_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ANC_EN);
+               vpif_clr_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ACTIVE_EN);
+       }
+}
+
+/* function to enable clipping (for both active and blanking regions) on ch 3 */
+static inline void channel3_clipping_enable(int enable)
+{
+       if (enable) {
+               vpif_set_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ANC_EN);
+               vpif_set_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ACTIVE_EN);
+       } else {
+               vpif_clr_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ANC_EN);
+               vpif_clr_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ACTIVE_EN);
+       }
+}
+
+/* inline function to set buffer addresses in case of Y/C non mux mode */
+static inline void ch2_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
+                                                unsigned long btm_strt_luma,
+                                                unsigned long top_strt_chroma,
+                                                unsigned long btm_strt_chroma)
+{
+       regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
+       regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
+       regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
+       regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
+}
+
+/* inline function to set buffer addresses in VPIF registers for video data */
+static inline void ch2_set_videobuf_addr(unsigned long top_strt_luma,
+                                        unsigned long btm_strt_luma,
+                                        unsigned long top_strt_chroma,
+                                        unsigned long btm_strt_chroma)
+{
+       regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
+       regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
+       regw(top_strt_chroma, VPIF_CH2_TOP_STRT_ADD_CHROMA);
+       regw(btm_strt_chroma, VPIF_CH2_BTM_STRT_ADD_CHROMA);
+}
+
+static inline void ch3_set_videobuf_addr(unsigned long top_strt_luma,
+                                        unsigned long btm_strt_luma,
+                                        unsigned long top_strt_chroma,
+                                        unsigned long btm_strt_chroma)
+{
+       regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_LUMA);
+       regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_LUMA);
+       regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
+       regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
+}
+
+/* inline function to set buffer addresses in VPIF registers for vbi data */
+static inline void ch2_set_vbi_addr(unsigned long top_strt_luma,
+                                        unsigned long btm_strt_luma,
+                                        unsigned long top_strt_chroma,
+                                        unsigned long btm_strt_chroma)
+{
+       regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_VANC);
+       regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_VANC);
+}
+
+static inline void ch3_set_vbi_addr(unsigned long top_strt_luma,
+                                        unsigned long btm_strt_luma,
+                                        unsigned long top_strt_chroma,
+                                        unsigned long btm_strt_chroma)
+{
+       regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_VANC);
+       regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_VANC);
+}
+
+static inline int vpif_intr_status(int channel)
+{
+       int status = 0;
+       int mask;
+
+       if (channel < 0 || channel > 3)
+               return 0;
+
+       mask = 1 << channel;
+       status = regr(VPIF_STATUS) & mask;
+       regw(status, VPIF_STATUS_CLR);
+
+       return status;
+}
+
+#define VPIF_MAX_NAME  (30)
+
+/* This structure will store size parameters as per the mode selected by user */
+struct vpif_channel_config_params {
+       char name[VPIF_MAX_NAME];       /* Name of the mode */
+       u16 width;                      /* Indicates width of the image */
+       u16 height;                     /* Indicates height of the image */
+       u8 frm_fmt;                     /* Interlaced (0) or progressive (1) */
+       u8 ycmux_mode;                  /* This mode requires one (0) or two (1)
+                                          channels */
+       u16 eav2sav;                    /* length of eav 2 sav */
+       u16 sav2eav;                    /* length of sav 2 eav */
+       u16 l1, l3, l5, l7, l9, l11;    /* Other parameter configurations */
+       u16 vsize;                      /* Vertical size of the image */
+       u8 capture_format;              /* Indicates whether capture format
+                                        * is in BT or in CCD/CMOS */
+       u8  vbi_supported;              /* Indicates whether this mode
+                                        * supports capturing vbi or not */
+       u8 hd_sd;                       /* HDTV (1) or SDTV (0) format */
+       v4l2_std_id stdid;              /* SDTV format */
+       struct v4l2_dv_timings dv_timings;      /* HDTV format */
+};
+
+extern const unsigned int vpif_ch_params_count;
+extern const struct vpif_channel_config_params vpif_ch_params[];
+
+struct vpif_video_params;
+struct vpif_params;
+struct vpif_vbi_params;
+
+int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id);
+void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
+                                                       u8 channel_id);
+int vpif_channel_getfid(u8 channel_id);
+
+enum data_size {
+       _8BITS = 0,
+       _10BITS,
+       _12BITS,
+};
+
+/* Structure for vpif parameters for raw vbi data */
+struct vpif_vbi_params {
+       __u32 hstart0;  /* Horizontal start of raw vbi data for first field */
+       __u32 vstart0;  /* Vertical start of raw vbi data for first field */
+       __u32 hsize0;   /* Horizontal size of raw vbi data for first field */
+       __u32 vsize0;   /* Vertical size of raw vbi data for first field */
+       __u32 hstart1;  /* Horizontal start of raw vbi data for second field */
+       __u32 vstart1;  /* Vertical start of raw vbi data for second field */
+       __u32 hsize1;   /* Horizontal size of raw vbi data for second field */
+       __u32 vsize1;   /* Vertical size of raw vbi data for second field */
+};
+
+/* structure for vpif parameters */
+struct vpif_video_params {
+       __u8 storage_mode;      /* Indicates field or frame mode */
+       unsigned long hpitch;
+       v4l2_std_id stdid;
+};
+
+struct vpif_params {
+       struct vpif_interface iface;
+       struct vpif_video_params video_params;
+       struct vpif_channel_config_params std_info;
+       union param {
+               struct vpif_vbi_params  vbi_params;
+               enum data_size data_sz;
+       } params;
+};
+
+#endif                         /* End of #ifndef VPIF_H */
+
diff --git a/drivers/media/platform/ti/davinci/vpif_capture.c b/drivers/media/platform/ti/davinci/vpif_capture.c
new file mode 100644 (file)
index 0000000..bf76c5c
--- /dev/null
@@ -0,0 +1,1823 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2009 Texas Instruments Inc
+ * Copyright (C) 2014 Lad, Prabhakar <prabhakar.csengg@gmail.com>
+ *
+ * TODO : add support for VBI & HBI data service
+ *       add static buffer allocation
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-ioctl.h>
+#include <media/i2c/tvp514x.h>
+#include <media/v4l2-mediabus.h>
+
+#include <linux/videodev2.h>
+
+#include "vpif.h"
+#include "vpif_capture.h"
+
+MODULE_DESCRIPTION("TI DaVinci VPIF Capture driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(VPIF_CAPTURE_VERSION);
+
+#define vpif_err(fmt, arg...)  v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
+#define vpif_dbg(level, debug, fmt, arg...)    \
+               v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
+
+static int debug = 1;
+
+module_param(debug, int, 0644);
+
+MODULE_PARM_DESC(debug, "Debug level 0-1");
+
+#define VPIF_DRIVER_NAME       "vpif_capture"
+MODULE_ALIAS("platform:" VPIF_DRIVER_NAME);
+
+/* global variables */
+static struct vpif_device vpif_obj = { {NULL} };
+static struct device *vpif_dev;
+static void vpif_calculate_offsets(struct channel_obj *ch);
+static void vpif_config_addr(struct channel_obj *ch, int muxmode);
+
+static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] = { {1, 1} };
+
+/* Is set to 1 in case of SDTV formats, 2 in case of HDTV formats. */
+static int ycmux_mode;
+
+static inline
+struct vpif_cap_buffer *to_vpif_buffer(struct vb2_v4l2_buffer *vb)
+{
+       return container_of(vb, struct vpif_cap_buffer, vb);
+}
+
+/**
+ * vpif_buffer_prepare :  callback function for buffer prepare
+ * @vb: ptr to vb2_buffer
+ *
+ * This is the callback function for buffer prepare when vb2_qbuf()
+ * function is called. The buffer is prepared and user space virtual address
+ * or user address is converted into  physical address
+ */
+static int vpif_buffer_prepare(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct vb2_queue *q = vb->vb2_queue;
+       struct channel_obj *ch = vb2_get_drv_priv(q);
+       struct common_obj *common;
+       unsigned long addr;
+
+       vpif_dbg(2, debug, "vpif_buffer_prepare\n");
+
+       common = &ch->common[VPIF_VIDEO_INDEX];
+
+       vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
+       if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
+               return -EINVAL;
+
+       vbuf->field = common->fmt.fmt.pix.field;
+
+       addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+       if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
+               !IS_ALIGNED((addr + common->ybtm_off), 8) ||
+               !IS_ALIGNED((addr + common->ctop_off), 8) ||
+               !IS_ALIGNED((addr + common->cbtm_off), 8)) {
+               vpif_dbg(1, debug, "offset is not aligned\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/**
+ * vpif_buffer_queue_setup : Callback function for buffer setup.
+ * @vq: vb2_queue ptr
+ * @nbuffers: ptr to number of buffers requested by application
+ * @nplanes: contains number of distinct video planes needed to hold a frame
+ * @sizes: contains the size (in bytes) of each plane.
+ * @alloc_devs: ptr to allocation context
+ *
+ * This callback function is called when reqbuf() is called to adjust
+ * the buffer count and buffer size
+ */
+static int vpif_buffer_queue_setup(struct vb2_queue *vq,
+                               unsigned int *nbuffers, unsigned int *nplanes,
+                               unsigned int sizes[], struct device *alloc_devs[])
+{
+       struct channel_obj *ch = vb2_get_drv_priv(vq);
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       unsigned size = common->fmt.fmt.pix.sizeimage;
+
+       vpif_dbg(2, debug, "vpif_buffer_setup\n");
+
+       if (*nplanes) {
+               if (sizes[0] < size)
+                       return -EINVAL;
+               size = sizes[0];
+       }
+
+       if (vq->num_buffers + *nbuffers < 3)
+               *nbuffers = 3 - vq->num_buffers;
+
+       *nplanes = 1;
+       sizes[0] = size;
+
+       /* Calculate the offset for Y and C data in the buffer */
+       vpif_calculate_offsets(ch);
+
+       return 0;
+}
+
+/**
+ * vpif_buffer_queue : Callback function to add buffer to DMA queue
+ * @vb: ptr to vb2_buffer
+ */
+static void vpif_buffer_queue(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
+       struct vpif_cap_buffer *buf = to_vpif_buffer(vbuf);
+       struct common_obj *common;
+       unsigned long flags;
+
+       common = &ch->common[VPIF_VIDEO_INDEX];
+
+       vpif_dbg(2, debug, "vpif_buffer_queue\n");
+
+       spin_lock_irqsave(&common->irqlock, flags);
+       /* add the buffer to the DMA queue */
+       list_add_tail(&buf->list, &common->dma_queue);
+       spin_unlock_irqrestore(&common->irqlock, flags);
+}
+
+/**
+ * vpif_start_streaming : Starts the DMA engine for streaming
+ * @vq: ptr to vb2_buffer
+ * @count: number of buffers
+ */
+static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+       struct vpif_capture_config *vpif_config_data =
+                                       vpif_dev->platform_data;
+       struct channel_obj *ch = vb2_get_drv_priv(vq);
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct vpif_params *vpif = &ch->vpifparams;
+       struct vpif_cap_buffer *buf, *tmp;
+       unsigned long addr, flags;
+       int ret;
+
+       /* Initialize field_id */
+       ch->field_id = 0;
+
+       /* configure 1 or 2 channel mode */
+       if (vpif_config_data->setup_input_channel_mode) {
+               ret = vpif_config_data->
+                       setup_input_channel_mode(vpif->std_info.ycmux_mode);
+               if (ret < 0) {
+                       vpif_dbg(1, debug, "can't set vpif channel mode\n");
+                       goto err;
+               }
+       }
+
+       ret = v4l2_subdev_call(ch->sd, video, s_stream, 1);
+       if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
+               vpif_dbg(1, debug, "stream on failed in subdev\n");
+               goto err;
+       }
+
+       /* Call vpif_set_params function to set the parameters and addresses */
+       ret = vpif_set_video_params(vpif, ch->channel_id);
+       if (ret < 0) {
+               vpif_dbg(1, debug, "can't set video params\n");
+               goto err;
+       }
+
+       ycmux_mode = ret;
+       vpif_config_addr(ch, ret);
+
+       /* Get the next frame from the buffer queue */
+       spin_lock_irqsave(&common->irqlock, flags);
+       common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
+                                   struct vpif_cap_buffer, list);
+       /* Remove buffer from the buffer queue */
+       list_del(&common->cur_frm->list);
+       spin_unlock_irqrestore(&common->irqlock, flags);
+
+       addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb.vb2_buf, 0);
+
+       common->set_addr(addr + common->ytop_off,
+                        addr + common->ybtm_off,
+                        addr + common->ctop_off,
+                        addr + common->cbtm_off);
+
+       /**
+        * Set interrupt for both the fields in VPIF Register enable channel in
+        * VPIF register
+        */
+       channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
+       if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
+               channel0_intr_assert();
+               channel0_intr_enable(1);
+               enable_channel0(1);
+       }
+       if (VPIF_CHANNEL1_VIDEO == ch->channel_id ||
+               ycmux_mode == 2) {
+               channel1_intr_assert();
+               channel1_intr_enable(1);
+               enable_channel1(1);
+       }
+
+       return 0;
+
+err:
+       spin_lock_irqsave(&common->irqlock, flags);
+       list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
+               list_del(&buf->list);
+               vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
+       }
+       spin_unlock_irqrestore(&common->irqlock, flags);
+
+       return ret;
+}
+
+/**
+ * vpif_stop_streaming : Stop the DMA engine
+ * @vq: ptr to vb2_queue
+ *
+ * This callback stops the DMA engine and any remaining buffers
+ * in the DMA queue are released.
+ */
+static void vpif_stop_streaming(struct vb2_queue *vq)
+{
+       struct channel_obj *ch = vb2_get_drv_priv(vq);
+       struct common_obj *common;
+       unsigned long flags;
+       int ret;
+
+       common = &ch->common[VPIF_VIDEO_INDEX];
+
+       /* Disable channel as per its device type and channel id */
+       if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
+               enable_channel0(0);
+               channel0_intr_enable(0);
+       }
+       if (VPIF_CHANNEL1_VIDEO == ch->channel_id ||
+               ycmux_mode == 2) {
+               enable_channel1(0);
+               channel1_intr_enable(0);
+       }
+
+       ycmux_mode = 0;
+
+       ret = v4l2_subdev_call(ch->sd, video, s_stream, 0);
+       if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
+               vpif_dbg(1, debug, "stream off failed in subdev\n");
+
+       /* release all active buffers */
+       if (common->cur_frm == common->next_frm) {
+               vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
+                               VB2_BUF_STATE_ERROR);
+       } else {
+               if (common->cur_frm)
+                       vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
+                                       VB2_BUF_STATE_ERROR);
+               if (common->next_frm)
+                       vb2_buffer_done(&common->next_frm->vb.vb2_buf,
+                                       VB2_BUF_STATE_ERROR);
+       }
+
+       spin_lock_irqsave(&common->irqlock, flags);
+       while (!list_empty(&common->dma_queue)) {
+               common->next_frm = list_entry(common->dma_queue.next,
+                                               struct vpif_cap_buffer, list);
+               list_del(&common->next_frm->list);
+               vb2_buffer_done(&common->next_frm->vb.vb2_buf,
+                               VB2_BUF_STATE_ERROR);
+       }
+       spin_unlock_irqrestore(&common->irqlock, flags);
+}
+
+static const struct vb2_ops video_qops = {
+       .queue_setup            = vpif_buffer_queue_setup,
+       .buf_prepare            = vpif_buffer_prepare,
+       .start_streaming        = vpif_start_streaming,
+       .stop_streaming         = vpif_stop_streaming,
+       .buf_queue              = vpif_buffer_queue,
+       .wait_prepare           = vb2_ops_wait_prepare,
+       .wait_finish            = vb2_ops_wait_finish,
+};
+
+/**
+ * vpif_process_buffer_complete: process a completed buffer
+ * @common: ptr to common channel object
+ *
+ * This function time stamp the buffer and mark it as DONE. It also
+ * wake up any process waiting on the QUEUE and set the next buffer
+ * as current
+ */
+static void vpif_process_buffer_complete(struct common_obj *common)
+{
+       common->cur_frm->vb.vb2_buf.timestamp = ktime_get_ns();
+       vb2_buffer_done(&common->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
+       /* Make curFrm pointing to nextFrm */
+       common->cur_frm = common->next_frm;
+}
+
+/**
+ * vpif_schedule_next_buffer: set next buffer address for capture
+ * @common : ptr to common channel object
+ *
+ * This function will get next buffer from the dma queue and
+ * set the buffer address in the vpif register for capture.
+ * the buffer is marked active
+ */
+static void vpif_schedule_next_buffer(struct common_obj *common)
+{
+       unsigned long addr = 0;
+
+       spin_lock(&common->irqlock);
+       common->next_frm = list_entry(common->dma_queue.next,
+                                    struct vpif_cap_buffer, list);
+       /* Remove that buffer from the buffer queue */
+       list_del(&common->next_frm->list);
+       spin_unlock(&common->irqlock);
+       addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb.vb2_buf, 0);
+
+       /* Set top and bottom field addresses in VPIF registers */
+       common->set_addr(addr + common->ytop_off,
+                        addr + common->ybtm_off,
+                        addr + common->ctop_off,
+                        addr + common->cbtm_off);
+}
+
+/**
+ * vpif_channel_isr : ISR handler for vpif capture
+ * @irq: irq number
+ * @dev_id: dev_id ptr
+ *
+ * It changes status of the captured buffer, takes next buffer from the queue
+ * and sets its address in VPIF registers
+ */
+static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
+{
+       struct vpif_device *dev = &vpif_obj;
+       struct common_obj *common;
+       struct channel_obj *ch;
+       int channel_id;
+       int fid = -1, i;
+
+       channel_id = *(int *)(dev_id);
+       if (!vpif_intr_status(channel_id))
+               return IRQ_NONE;
+
+       ch = dev->dev[channel_id];
+
+       for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) {
+               common = &ch->common[i];
+               /* skip If streaming is not started in this channel */
+               /* Check the field format */
+               if (1 == ch->vpifparams.std_info.frm_fmt ||
+                   common->fmt.fmt.pix.field == V4L2_FIELD_NONE) {
+                       /* Progressive mode */
+                       spin_lock(&common->irqlock);
+                       if (list_empty(&common->dma_queue)) {
+                               spin_unlock(&common->irqlock);
+                               continue;
+                       }
+                       spin_unlock(&common->irqlock);
+
+                       if (!channel_first_int[i][channel_id])
+                               vpif_process_buffer_complete(common);
+
+                       channel_first_int[i][channel_id] = 0;
+
+                       vpif_schedule_next_buffer(common);
+
+
+                       channel_first_int[i][channel_id] = 0;
+               } else {
+                       /**
+                        * Interlaced mode. If it is first interrupt, ignore
+                        * it
+                        */
+                       if (channel_first_int[i][channel_id]) {
+                               channel_first_int[i][channel_id] = 0;
+                               continue;
+                       }
+                       if (0 == i) {
+                               ch->field_id ^= 1;
+                               /* Get field id from VPIF registers */
+                               fid = vpif_channel_getfid(ch->channel_id);
+                               if (fid != ch->field_id) {
+                                       /**
+                                        * If field id does not match stored
+                                        * field id, make them in sync
+                                        */
+                                       if (0 == fid)
+                                               ch->field_id = fid;
+                                       return IRQ_HANDLED;
+                               }
+                       }
+                       /* device field id and local field id are in sync */
+                       if (0 == fid) {
+                               /* this is even field */
+                               if (common->cur_frm == common->next_frm)
+                                       continue;
+
+                               /* mark the current buffer as done */
+                               vpif_process_buffer_complete(common);
+                       } else if (1 == fid) {
+                               /* odd field */
+                               spin_lock(&common->irqlock);
+                               if (list_empty(&common->dma_queue) ||
+                                   (common->cur_frm != common->next_frm)) {
+                                       spin_unlock(&common->irqlock);
+                                       continue;
+                               }
+                               spin_unlock(&common->irqlock);
+
+                               vpif_schedule_next_buffer(common);
+                       }
+               }
+       }
+       return IRQ_HANDLED;
+}
+
+/**
+ * vpif_update_std_info() - update standard related info
+ * @ch: ptr to channel object
+ *
+ * For a given standard selected by application, update values
+ * in the device data structures
+ */
+static int vpif_update_std_info(struct channel_obj *ch)
+{
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct vpif_params *vpifparams = &ch->vpifparams;
+       const struct vpif_channel_config_params *config;
+       struct vpif_channel_config_params *std_info = &vpifparams->std_info;
+       struct video_obj *vid_ch = &ch->video;
+       int index;
+       struct v4l2_pix_format *pixfmt = &common->fmt.fmt.pix;
+
+       vpif_dbg(2, debug, "vpif_update_std_info\n");
+
+       /*
+        * if called after try_fmt or g_fmt, there will already be a size
+        * so use that by default.
+        */
+       if (pixfmt->width && pixfmt->height) {
+               if (pixfmt->field == V4L2_FIELD_ANY ||
+                   pixfmt->field == V4L2_FIELD_NONE)
+                       pixfmt->field = V4L2_FIELD_NONE;
+
+               vpifparams->iface.if_type = VPIF_IF_BT656;
+               if (pixfmt->pixelformat == V4L2_PIX_FMT_SGRBG10 ||
+                   pixfmt->pixelformat == V4L2_PIX_FMT_SBGGR8)
+                       vpifparams->iface.if_type = VPIF_IF_RAW_BAYER;
+
+               if (pixfmt->pixelformat == V4L2_PIX_FMT_SGRBG10)
+                       vpifparams->params.data_sz = 1; /* 10 bits/pixel.  */
+
+               /*
+                * For raw formats from camera sensors, we don't need
+                * the std_info from table lookup, so nothing else to do here.
+                */
+               if (vpifparams->iface.if_type == VPIF_IF_RAW_BAYER) {
+                       memset(std_info, 0, sizeof(struct vpif_channel_config_params));
+                       vpifparams->std_info.capture_format = 1; /* CCD/raw mode */
+                       return 0;
+               }
+       }
+
+       for (index = 0; index < vpif_ch_params_count; index++) {
+               config = &vpif_ch_params[index];
+               if (config->hd_sd == 0) {
+                       vpif_dbg(2, debug, "SD format\n");
+                       if (config->stdid & vid_ch->stdid) {
+                               memcpy(std_info, config, sizeof(*config));
+                               break;
+                       }
+               } else {
+                       vpif_dbg(2, debug, "HD format\n");
+                       if (!memcmp(&config->dv_timings, &vid_ch->dv_timings,
+                               sizeof(vid_ch->dv_timings))) {
+                               memcpy(std_info, config, sizeof(*config));
+                               break;
+                       }
+               }
+       }
+
+       /* standard not found */
+       if (index == vpif_ch_params_count)
+               return -EINVAL;
+
+       common->fmt.fmt.pix.width = std_info->width;
+       common->width = std_info->width;
+       common->fmt.fmt.pix.height = std_info->height;
+       common->height = std_info->height;
+       common->fmt.fmt.pix.sizeimage = common->height * common->width * 2;
+       common->fmt.fmt.pix.bytesperline = std_info->width;
+       vpifparams->video_params.hpitch = std_info->width;
+       vpifparams->video_params.storage_mode = std_info->frm_fmt;
+
+       if (vid_ch->stdid)
+               common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+       else
+               common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
+
+       if (ch->vpifparams.std_info.frm_fmt)
+               common->fmt.fmt.pix.field = V4L2_FIELD_NONE;
+       else
+               common->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
+
+       if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
+               common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
+       else
+               common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV16;
+
+       common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+       return 0;
+}
+
+/**
+ * vpif_calculate_offsets : This function calculates buffers offsets
+ * @ch : ptr to channel object
+ *
+ * This function calculates buffer offsets for Y and C in the top and
+ * bottom field
+ */
+static void vpif_calculate_offsets(struct channel_obj *ch)
+{
+       unsigned int hpitch, sizeimage;
+       struct video_obj *vid_ch = &(ch->video);
+       struct vpif_params *vpifparams = &ch->vpifparams;
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       enum v4l2_field field = common->fmt.fmt.pix.field;
+
+       vpif_dbg(2, debug, "vpif_calculate_offsets\n");
+
+       if (V4L2_FIELD_ANY == field) {
+               if (vpifparams->std_info.frm_fmt)
+                       vid_ch->buf_field = V4L2_FIELD_NONE;
+               else
+                       vid_ch->buf_field = V4L2_FIELD_INTERLACED;
+       } else
+               vid_ch->buf_field = common->fmt.fmt.pix.field;
+
+       sizeimage = common->fmt.fmt.pix.sizeimage;
+
+       hpitch = common->fmt.fmt.pix.bytesperline;
+
+       if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
+           (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
+               /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
+               common->ytop_off = 0;
+               common->ybtm_off = hpitch;
+               common->ctop_off = sizeimage / 2;
+               common->cbtm_off = sizeimage / 2 + hpitch;
+       } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
+               /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
+               common->ytop_off = 0;
+               common->ybtm_off = sizeimage / 4;
+               common->ctop_off = sizeimage / 2;
+               common->cbtm_off = common->ctop_off + sizeimage / 4;
+       } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
+               /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
+               common->ybtm_off = 0;
+               common->ytop_off = sizeimage / 4;
+               common->cbtm_off = sizeimage / 2;
+               common->ctop_off = common->cbtm_off + sizeimage / 4;
+       }
+       if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
+           (V4L2_FIELD_INTERLACED == vid_ch->buf_field))
+               vpifparams->video_params.storage_mode = 1;
+       else
+               vpifparams->video_params.storage_mode = 0;
+
+       if (1 == vpifparams->std_info.frm_fmt)
+               vpifparams->video_params.hpitch =
+                   common->fmt.fmt.pix.bytesperline;
+       else {
+               if ((field == V4L2_FIELD_ANY)
+                   || (field == V4L2_FIELD_INTERLACED))
+                       vpifparams->video_params.hpitch =
+                           common->fmt.fmt.pix.bytesperline * 2;
+               else
+                       vpifparams->video_params.hpitch =
+                           common->fmt.fmt.pix.bytesperline;
+       }
+
+       ch->vpifparams.video_params.stdid = vpifparams->std_info.stdid;
+}
+
+/**
+ * vpif_config_addr() - function to configure buffer address in vpif
+ * @ch: channel ptr
+ * @muxmode: channel mux mode
+ */
+static void vpif_config_addr(struct channel_obj *ch, int muxmode)
+{
+       struct common_obj *common;
+
+       vpif_dbg(2, debug, "vpif_config_addr\n");
+
+       common = &(ch->common[VPIF_VIDEO_INDEX]);
+
+       if (VPIF_CHANNEL1_VIDEO == ch->channel_id)
+               common->set_addr = ch1_set_videobuf_addr;
+       else if (2 == muxmode)
+               common->set_addr = ch0_set_videobuf_addr_yc_nmux;
+       else
+               common->set_addr = ch0_set_videobuf_addr;
+}
+
+/**
+ * vpif_input_to_subdev() - Maps input to sub device
+ * @vpif_cfg: global config ptr
+ * @chan_cfg: channel config ptr
+ * @input_index: Given input index from application
+ *
+ * lookup the sub device information for a given input index.
+ * we report all the inputs to application. inputs table also
+ * has sub device name for the each input
+ */
+static int vpif_input_to_subdev(
+               struct vpif_capture_config *vpif_cfg,
+               struct vpif_capture_chan_config *chan_cfg,
+               int input_index)
+{
+       struct vpif_subdev_info *subdev_info;
+       const char *subdev_name;
+       int i;
+
+       vpif_dbg(2, debug, "vpif_input_to_subdev\n");
+
+       if (!chan_cfg)
+               return -1;
+       if (input_index >= chan_cfg->input_count)
+               return -1;
+       subdev_name = chan_cfg->inputs[input_index].subdev_name;
+       if (!subdev_name)
+               return -1;
+
+       /* loop through the sub device list to get the sub device info */
+       for (i = 0; i < vpif_cfg->subdev_count; i++) {
+               subdev_info = &vpif_cfg->subdev_info[i];
+               if (subdev_info && !strcmp(subdev_info->name, subdev_name))
+                       return i;
+       }
+       return -1;
+}
+
+/**
+ * vpif_set_input() - Select an input
+ * @vpif_cfg: global config ptr
+ * @ch: channel
+ * @index: Given input index from application
+ *
+ * Select the given input.
+ */
+static int vpif_set_input(
+               struct vpif_capture_config *vpif_cfg,
+               struct channel_obj *ch,
+               int index)
+{
+       struct vpif_capture_chan_config *chan_cfg =
+                       &vpif_cfg->chan_config[ch->channel_id];
+       struct vpif_subdev_info *subdev_info = NULL;
+       struct v4l2_subdev *sd = NULL;
+       u32 input = 0, output = 0;
+       int sd_index;
+       int ret;
+
+       sd_index = vpif_input_to_subdev(vpif_cfg, chan_cfg, index);
+       if (sd_index >= 0) {
+               sd = vpif_obj.sd[sd_index];
+               subdev_info = &vpif_cfg->subdev_info[sd_index];
+       } else {
+               /* no subdevice, no input to setup */
+               return 0;
+       }
+
+       /* first setup input path from sub device to vpif */
+       if (sd && vpif_cfg->setup_input_path) {
+               ret = vpif_cfg->setup_input_path(ch->channel_id,
+                                      subdev_info->name);
+               if (ret < 0) {
+                       vpif_dbg(1, debug, "couldn't setup input path for the" \
+                       " sub device %s, for input index %d\n",
+                       subdev_info->name, index);
+                       return ret;
+               }
+       }
+
+       if (sd) {
+               input = chan_cfg->inputs[index].input_route;
+               output = chan_cfg->inputs[index].output_route;
+               ret = v4l2_subdev_call(sd, video, s_routing,
+                               input, output, 0);
+               if (ret < 0 && ret != -ENOIOCTLCMD) {
+                       vpif_dbg(1, debug, "Failed to set input\n");
+                       return ret;
+               }
+       }
+       ch->input_idx = index;
+       ch->sd = sd;
+       /* copy interface parameters to vpif */
+       ch->vpifparams.iface = chan_cfg->vpif_if;
+
+       /* update tvnorms from the sub device input info */
+       ch->video_dev.tvnorms = chan_cfg->inputs[index].input.std;
+       return 0;
+}
+
+/**
+ * vpif_querystd() - querystd handler
+ * @file: file ptr
+ * @priv: file handle
+ * @std_id: ptr to std id
+ *
+ * This function is called to detect standard at the selected input
+ */
+static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
+{
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       int ret;
+
+       vpif_dbg(2, debug, "vpif_querystd\n");
+
+       /* Call querystd function of decoder device */
+       ret = v4l2_subdev_call(ch->sd, video, querystd, std_id);
+
+       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
+               return -ENODATA;
+       if (ret) {
+               vpif_dbg(1, debug, "Failed to query standard for sub devices\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+/**
+ * vpif_g_std() - get STD handler
+ * @file: file ptr
+ * @priv: file handle
+ * @std: ptr to std id
+ */
+static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
+{
+       struct vpif_capture_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct vpif_capture_chan_config *chan_cfg;
+       struct v4l2_input input;
+
+       vpif_dbg(2, debug, "vpif_g_std\n");
+
+       if (!config->chan_config[ch->channel_id].inputs)
+               return -ENODATA;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+       input = chan_cfg->inputs[ch->input_idx].input;
+       if (input.capabilities != V4L2_IN_CAP_STD)
+               return -ENODATA;
+
+       *std = ch->video.stdid;
+       return 0;
+}
+
+/**
+ * vpif_s_std() - set STD handler
+ * @file: file ptr
+ * @priv: file handle
+ * @std_id: ptr to std id
+ */
+static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
+{
+       struct vpif_capture_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct vpif_capture_chan_config *chan_cfg;
+       struct v4l2_input input;
+       int ret;
+
+       vpif_dbg(2, debug, "vpif_s_std\n");
+
+       if (!config->chan_config[ch->channel_id].inputs)
+               return -ENODATA;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+       input = chan_cfg->inputs[ch->input_idx].input;
+       if (input.capabilities != V4L2_IN_CAP_STD)
+               return -ENODATA;
+
+       if (vb2_is_busy(&common->buffer_queue))
+               return -EBUSY;
+
+       /* Call encoder subdevice function to set the standard */
+       ch->video.stdid = std_id;
+       memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
+
+       /* Get the information about the standard */
+       if (vpif_update_std_info(ch)) {
+               vpif_err("Error getting the standard info\n");
+               return -EINVAL;
+       }
+
+       /* set standard in the sub device */
+       ret = v4l2_subdev_call(ch->sd, video, s_std, std_id);
+       if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
+               vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
+               return ret;
+       }
+       return 0;
+}
+
+/**
+ * vpif_enum_input() - ENUMINPUT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @input: ptr to input structure
+ */
+static int vpif_enum_input(struct file *file, void *priv,
+                               struct v4l2_input *input)
+{
+
+       struct vpif_capture_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct vpif_capture_chan_config *chan_cfg;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+
+       if (input->index >= chan_cfg->input_count)
+               return -EINVAL;
+
+       memcpy(input, &chan_cfg->inputs[input->index].input,
+               sizeof(*input));
+       return 0;
+}
+
+/**
+ * vpif_g_input() - Get INPUT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @index: ptr to input index
+ */
+static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
+{
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+
+       *index = ch->input_idx;
+       return 0;
+}
+
+/**
+ * vpif_s_input() - Set INPUT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @index: input index
+ */
+static int vpif_s_input(struct file *file, void *priv, unsigned int index)
+{
+       struct vpif_capture_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct vpif_capture_chan_config *chan_cfg;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+
+       if (index >= chan_cfg->input_count)
+               return -EINVAL;
+
+       if (vb2_is_busy(&common->buffer_queue))
+               return -EBUSY;
+
+       return vpif_set_input(config, ch, index);
+}
+
+/**
+ * vpif_enum_fmt_vid_cap() - ENUM_FMT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @fmt: ptr to V4L2 format descriptor
+ */
+static int vpif_enum_fmt_vid_cap(struct file *file, void  *priv,
+                                       struct v4l2_fmtdesc *fmt)
+{
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+
+       if (fmt->index != 0) {
+               vpif_dbg(1, debug, "Invalid format index\n");
+               return -EINVAL;
+       }
+
+       /* Fill in the information about format */
+       if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
+               fmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
+       else
+               fmt->pixelformat = V4L2_PIX_FMT_NV16;
+       return 0;
+}
+
+/**
+ * vpif_try_fmt_vid_cap() - TRY_FMT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @fmt: ptr to v4l2 format structure
+ */
+static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
+                               struct v4l2_format *fmt)
+{
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+       struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
+
+       common->fmt = *fmt;
+       vpif_update_std_info(ch);
+
+       pixfmt->field = common->fmt.fmt.pix.field;
+       pixfmt->colorspace = common->fmt.fmt.pix.colorspace;
+       pixfmt->bytesperline = common->fmt.fmt.pix.width;
+       pixfmt->width = common->fmt.fmt.pix.width;
+       pixfmt->height = common->fmt.fmt.pix.height;
+       pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2;
+       if (pixfmt->pixelformat == V4L2_PIX_FMT_SGRBG10) {
+               pixfmt->bytesperline = common->fmt.fmt.pix.width * 2;
+               pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
+       }
+
+       dev_dbg(vpif_dev, "%s: %d x %d; pitch=%d pixelformat=0x%08x, field=%d, size=%d\n", __func__,
+               pixfmt->width, pixfmt->height,
+               pixfmt->bytesperline, pixfmt->pixelformat,
+               pixfmt->field, pixfmt->sizeimage);
+
+       return 0;
+}
+
+
+/**
+ * vpif_g_fmt_vid_cap() - Set INPUT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @fmt: ptr to v4l2 format structure
+ */
+static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
+                               struct v4l2_format *fmt)
+{
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct v4l2_pix_format *pix_fmt = &fmt->fmt.pix;
+       struct v4l2_subdev_format format = {
+               .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+       };
+       struct v4l2_mbus_framefmt *mbus_fmt = &format.format;
+       int ret;
+
+       /* Check the validity of the buffer type */
+       if (common->fmt.type != fmt->type)
+               return -EINVAL;
+
+       /* By default, use currently set fmt */
+       *fmt = common->fmt;
+
+       /* If subdev has get_fmt, use that to override */
+       ret = v4l2_subdev_call(ch->sd, pad, get_fmt, NULL, &format);
+       if (!ret && mbus_fmt->code) {
+               v4l2_fill_pix_format(pix_fmt, mbus_fmt);
+               pix_fmt->bytesperline = pix_fmt->width;
+               if (mbus_fmt->code == MEDIA_BUS_FMT_SGRBG10_1X10) {
+                       /* e.g. mt9v032 */
+                       pix_fmt->pixelformat = V4L2_PIX_FMT_SGRBG10;
+                       pix_fmt->bytesperline = pix_fmt->width * 2;
+               } else if (mbus_fmt->code == MEDIA_BUS_FMT_UYVY8_2X8) {
+                       /* e.g. tvp514x */
+                       pix_fmt->pixelformat = V4L2_PIX_FMT_NV16;
+                       pix_fmt->bytesperline = pix_fmt->width * 2;
+               } else {
+                       dev_warn(vpif_dev, "%s: Unhandled media-bus format 0x%x\n",
+                                __func__, mbus_fmt->code);
+               }
+               pix_fmt->sizeimage = pix_fmt->bytesperline * pix_fmt->height;
+               dev_dbg(vpif_dev, "%s: %d x %d; pitch=%d, pixelformat=0x%08x, code=0x%x, field=%d, size=%d\n", __func__,
+                       pix_fmt->width, pix_fmt->height,
+                       pix_fmt->bytesperline, pix_fmt->pixelformat,
+                       mbus_fmt->code, pix_fmt->field, pix_fmt->sizeimage);
+
+               common->fmt = *fmt;
+               vpif_update_std_info(ch);
+       }
+
+       return 0;
+}
+
+/**
+ * vpif_s_fmt_vid_cap() - Set FMT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @fmt: ptr to v4l2 format structure
+ */
+static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
+                               struct v4l2_format *fmt)
+{
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       int ret;
+
+       vpif_dbg(2, debug, "%s\n", __func__);
+
+       if (vb2_is_busy(&common->buffer_queue))
+               return -EBUSY;
+
+       ret = vpif_try_fmt_vid_cap(file, priv, fmt);
+       if (ret)
+               return ret;
+
+       /* store the format in the channel object */
+       common->fmt = *fmt;
+       return 0;
+}
+
+/**
+ * vpif_querycap() - QUERYCAP handler
+ * @file: file ptr
+ * @priv: file handle
+ * @cap: ptr to v4l2_capability structure
+ */
+static int vpif_querycap(struct file *file, void  *priv,
+                               struct v4l2_capability *cap)
+{
+       struct vpif_capture_config *config = vpif_dev->platform_data;
+
+       strscpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));
+       snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+                dev_name(vpif_dev));
+       strscpy(cap->card, config->card_name, sizeof(cap->card));
+
+       return 0;
+}
+
+/**
+ * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @timings: input timings
+ */
+static int
+vpif_enum_dv_timings(struct file *file, void *priv,
+                    struct v4l2_enum_dv_timings *timings)
+{
+       struct vpif_capture_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct vpif_capture_chan_config *chan_cfg;
+       struct v4l2_input input;
+       int ret;
+
+       if (!config->chan_config[ch->channel_id].inputs)
+               return -ENODATA;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+       input = chan_cfg->inputs[ch->input_idx].input;
+       if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)
+               return -ENODATA;
+
+       timings->pad = 0;
+
+       ret = v4l2_subdev_call(ch->sd, pad, enum_dv_timings, timings);
+       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
+               return -EINVAL;
+
+       return ret;
+}
+
+/**
+ * vpif_query_dv_timings() - QUERY_DV_TIMINGS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @timings: input timings
+ */
+static int
+vpif_query_dv_timings(struct file *file, void *priv,
+                     struct v4l2_dv_timings *timings)
+{
+       struct vpif_capture_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct vpif_capture_chan_config *chan_cfg;
+       struct v4l2_input input;
+       int ret;
+
+       if (!config->chan_config[ch->channel_id].inputs)
+               return -ENODATA;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+       input = chan_cfg->inputs[ch->input_idx].input;
+       if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)
+               return -ENODATA;
+
+       ret = v4l2_subdev_call(ch->sd, video, query_dv_timings, timings);
+       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
+               return -ENODATA;
+
+       return ret;
+}
+
+/**
+ * vpif_s_dv_timings() - S_DV_TIMINGS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @timings: digital video timings
+ */
+static int vpif_s_dv_timings(struct file *file, void *priv,
+               struct v4l2_dv_timings *timings)
+{
+       struct vpif_capture_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct vpif_params *vpifparams = &ch->vpifparams;
+       struct vpif_channel_config_params *std_info = &vpifparams->std_info;
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct video_obj *vid_ch = &ch->video;
+       struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt;
+       struct vpif_capture_chan_config *chan_cfg;
+       struct v4l2_input input;
+       int ret;
+
+       if (!config->chan_config[ch->channel_id].inputs)
+               return -ENODATA;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+       input = chan_cfg->inputs[ch->input_idx].input;
+       if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)
+               return -ENODATA;
+
+       if (timings->type != V4L2_DV_BT_656_1120) {
+               vpif_dbg(2, debug, "Timing type not defined\n");
+               return -EINVAL;
+       }
+
+       if (vb2_is_busy(&common->buffer_queue))
+               return -EBUSY;
+
+       /* Configure subdevice timings, if any */
+       ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings);
+       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
+               ret = 0;
+       if (ret < 0) {
+               vpif_dbg(2, debug, "Error setting custom DV timings\n");
+               return ret;
+       }
+
+       if (!(timings->bt.width && timings->bt.height &&
+                               (timings->bt.hbackporch ||
+                                timings->bt.hfrontporch ||
+                                timings->bt.hsync) &&
+                               timings->bt.vfrontporch &&
+                               (timings->bt.vbackporch ||
+                                timings->bt.vsync))) {
+               vpif_dbg(2, debug, "Timings for width, height, horizontal back porch, horizontal sync, horizontal front porch, vertical back porch, vertical sync and vertical back porch must be defined\n");
+               return -EINVAL;
+       }
+
+       vid_ch->dv_timings = *timings;
+
+       /* Configure video port timings */
+
+       std_info->eav2sav = V4L2_DV_BT_BLANKING_WIDTH(bt) - 8;
+       std_info->sav2eav = bt->width;
+
+       std_info->l1 = 1;
+       std_info->l3 = bt->vsync + bt->vbackporch + 1;
+
+       std_info->vsize = V4L2_DV_BT_FRAME_HEIGHT(bt);
+       if (bt->interlaced) {
+               if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
+                       std_info->l5 = std_info->vsize/2 -
+                               (bt->vfrontporch - 1);
+                       std_info->l7 = std_info->vsize/2 + 1;
+                       std_info->l9 = std_info->l7 + bt->il_vsync +
+                               bt->il_vbackporch + 1;
+                       std_info->l11 = std_info->vsize -
+                               (bt->il_vfrontporch - 1);
+               } else {
+                       vpif_dbg(2, debug, "Required timing values for interlaced BT format missing\n");
+                       return -EINVAL;
+               }
+       } else {
+               std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
+       }
+       strscpy(std_info->name, "Custom timings BT656/1120",
+               sizeof(std_info->name));
+       std_info->width = bt->width;
+       std_info->height = bt->height;
+       std_info->frm_fmt = bt->interlaced ? 0 : 1;
+       std_info->ycmux_mode = 0;
+       std_info->capture_format = 0;
+       std_info->vbi_supported = 0;
+       std_info->hd_sd = 1;
+       std_info->stdid = 0;
+
+       vid_ch->stdid = 0;
+       return 0;
+}
+
+/**
+ * vpif_g_dv_timings() - G_DV_TIMINGS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @timings: digital video timings
+ */
+static int vpif_g_dv_timings(struct file *file, void *priv,
+               struct v4l2_dv_timings *timings)
+{
+       struct vpif_capture_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct video_obj *vid_ch = &ch->video;
+       struct vpif_capture_chan_config *chan_cfg;
+       struct v4l2_input input;
+
+       if (!config->chan_config[ch->channel_id].inputs)
+               return -ENODATA;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+       input = chan_cfg->inputs[ch->input_idx].input;
+       if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)
+               return -ENODATA;
+
+       *timings = vid_ch->dv_timings;
+
+       return 0;
+}
+
+/*
+ * vpif_log_status() - Status information
+ * @file: file ptr
+ * @priv: file handle
+ *
+ * Returns zero.
+ */
+static int vpif_log_status(struct file *filep, void *priv)
+{
+       /* status for sub devices */
+       v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
+
+       return 0;
+}
+
+/* vpif capture ioctl operations */
+static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
+       .vidioc_querycap                = vpif_querycap,
+       .vidioc_enum_fmt_vid_cap        = vpif_enum_fmt_vid_cap,
+       .vidioc_g_fmt_vid_cap           = vpif_g_fmt_vid_cap,
+       .vidioc_s_fmt_vid_cap           = vpif_s_fmt_vid_cap,
+       .vidioc_try_fmt_vid_cap         = vpif_try_fmt_vid_cap,
+
+       .vidioc_enum_input              = vpif_enum_input,
+       .vidioc_s_input                 = vpif_s_input,
+       .vidioc_g_input                 = vpif_g_input,
+
+       .vidioc_reqbufs                 = vb2_ioctl_reqbufs,
+       .vidioc_create_bufs             = vb2_ioctl_create_bufs,
+       .vidioc_querybuf                = vb2_ioctl_querybuf,
+       .vidioc_qbuf                    = vb2_ioctl_qbuf,
+       .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
+       .vidioc_expbuf                  = vb2_ioctl_expbuf,
+       .vidioc_streamon                = vb2_ioctl_streamon,
+       .vidioc_streamoff               = vb2_ioctl_streamoff,
+
+       .vidioc_querystd                = vpif_querystd,
+       .vidioc_s_std                   = vpif_s_std,
+       .vidioc_g_std                   = vpif_g_std,
+
+       .vidioc_enum_dv_timings         = vpif_enum_dv_timings,
+       .vidioc_query_dv_timings        = vpif_query_dv_timings,
+       .vidioc_s_dv_timings            = vpif_s_dv_timings,
+       .vidioc_g_dv_timings            = vpif_g_dv_timings,
+
+       .vidioc_log_status              = vpif_log_status,
+};
+
+/* vpif file operations */
+static const struct v4l2_file_operations vpif_fops = {
+       .owner = THIS_MODULE,
+       .open = v4l2_fh_open,
+       .release = vb2_fop_release,
+       .unlocked_ioctl = video_ioctl2,
+       .mmap = vb2_fop_mmap,
+       .poll = vb2_fop_poll
+};
+
+/**
+ * initialize_vpif() - Initialize vpif data structures
+ *
+ * Allocate memory for data structures and initialize them
+ */
+static int initialize_vpif(void)
+{
+       int err, i, j;
+       int free_channel_objects_index;
+
+       /* Allocate memory for six channel objects */
+       for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
+               vpif_obj.dev[i] =
+                   kzalloc(sizeof(*vpif_obj.dev[i]), GFP_KERNEL);
+               /* If memory allocation fails, return error */
+               if (!vpif_obj.dev[i]) {
+                       free_channel_objects_index = i;
+                       err = -ENOMEM;
+                       goto vpif_init_free_channel_objects;
+               }
+       }
+       return 0;
+
+vpif_init_free_channel_objects:
+       for (j = 0; j < free_channel_objects_index; j++)
+               kfree(vpif_obj.dev[j]);
+       return err;
+}
+
+static inline void free_vpif_objs(void)
+{
+       int i;
+
+       for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++)
+               kfree(vpif_obj.dev[i]);
+}
+
+static int vpif_async_bound(struct v4l2_async_notifier *notifier,
+                           struct v4l2_subdev *subdev,
+                           struct v4l2_async_subdev *asd)
+{
+       int i;
+
+       for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) {
+               struct v4l2_async_subdev *_asd = vpif_obj.config->asd[i];
+               const struct fwnode_handle *fwnode = _asd->match.fwnode;
+
+               if (fwnode == subdev->fwnode) {
+                       vpif_obj.sd[i] = subdev;
+                       vpif_obj.config->chan_config->inputs[i].subdev_name =
+                               (char *)to_of_node(subdev->fwnode)->full_name;
+                       vpif_dbg(2, debug,
+                                "%s: setting input %d subdev_name = %s\n",
+                                __func__, i,
+                               vpif_obj.config->chan_config->inputs[i].subdev_name);
+                       return 0;
+               }
+       }
+
+       for (i = 0; i < vpif_obj.config->subdev_count; i++)
+               if (!strcmp(vpif_obj.config->subdev_info[i].name,
+                           subdev->name)) {
+                       vpif_obj.sd[i] = subdev;
+                       return 0;
+               }
+
+       return -EINVAL;
+}
+
+static int vpif_probe_complete(void)
+{
+       struct common_obj *common;
+       struct video_device *vdev;
+       struct channel_obj *ch;
+       struct vb2_queue *q;
+       int j, err, k;
+
+       for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
+               ch = vpif_obj.dev[j];
+               ch->channel_id = j;
+               common = &(ch->common[VPIF_VIDEO_INDEX]);
+               spin_lock_init(&common->irqlock);
+               mutex_init(&common->lock);
+
+               /* select input 0 */
+               err = vpif_set_input(vpif_obj.config, ch, 0);
+               if (err)
+                       goto probe_out;
+
+               /* set initial format */
+               ch->video.stdid = V4L2_STD_525_60;
+               memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
+               common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+               vpif_update_std_info(ch);
+
+               /* Initialize vb2 queue */
+               q = &common->buffer_queue;
+               q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+               q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+               q->drv_priv = ch;
+               q->ops = &video_qops;
+               q->mem_ops = &vb2_dma_contig_memops;
+               q->buf_struct_size = sizeof(struct vpif_cap_buffer);
+               q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+               q->min_buffers_needed = 1;
+               q->lock = &common->lock;
+               q->dev = vpif_dev;
+
+               err = vb2_queue_init(q);
+               if (err) {
+                       vpif_err("vpif_capture: vb2_queue_init() failed\n");
+                       goto probe_out;
+               }
+
+               INIT_LIST_HEAD(&common->dma_queue);
+
+               /* Initialize the video_device structure */
+               vdev = &ch->video_dev;
+               strscpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
+               vdev->release = video_device_release_empty;
+               vdev->fops = &vpif_fops;
+               vdev->ioctl_ops = &vpif_ioctl_ops;
+               vdev->v4l2_dev = &vpif_obj.v4l2_dev;
+               vdev->vfl_dir = VFL_DIR_RX;
+               vdev->queue = q;
+               vdev->lock = &common->lock;
+               vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+               video_set_drvdata(&ch->video_dev, ch);
+               err = video_register_device(vdev,
+                                           VFL_TYPE_VIDEO, (j ? 1 : 0));
+               if (err)
+                       goto probe_out;
+       }
+
+       v4l2_info(&vpif_obj.v4l2_dev, "VPIF capture driver initialized\n");
+       return 0;
+
+probe_out:
+       for (k = 0; k < j; k++) {
+               /* Get the pointer to the channel object */
+               ch = vpif_obj.dev[k];
+               /* Unregister video device */
+               video_unregister_device(&ch->video_dev);
+       }
+
+       return err;
+}
+
+static int vpif_async_complete(struct v4l2_async_notifier *notifier)
+{
+       return vpif_probe_complete();
+}
+
+static const struct v4l2_async_notifier_operations vpif_async_ops = {
+       .bound = vpif_async_bound,
+       .complete = vpif_async_complete,
+};
+
+static struct vpif_capture_config *
+vpif_capture_get_pdata(struct platform_device *pdev)
+{
+       struct device_node *endpoint = NULL;
+       struct device_node *rem = NULL;
+       struct vpif_capture_config *pdata;
+       struct vpif_subdev_info *sdinfo;
+       struct vpif_capture_chan_config *chan;
+       unsigned int i;
+
+       v4l2_async_nf_init(&vpif_obj.notifier);
+
+       /*
+        * DT boot: OF node from parent device contains
+        * video ports & endpoints data.
+        */
+       if (pdev->dev.parent && pdev->dev.parent->of_node)
+               pdev->dev.of_node = pdev->dev.parent->of_node;
+       if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
+               return pdev->dev.platform_data;
+
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return NULL;
+       pdata->subdev_info =
+               devm_kcalloc(&pdev->dev,
+                            VPIF_CAPTURE_NUM_CHANNELS,
+                            sizeof(*pdata->subdev_info),
+                            GFP_KERNEL);
+
+       if (!pdata->subdev_info)
+               return NULL;
+
+       for (i = 0; i < VPIF_CAPTURE_NUM_CHANNELS; i++) {
+               struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
+               unsigned int flags;
+               int err;
+
+               endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
+                                                     endpoint);
+               if (!endpoint)
+                       break;
+
+               rem = of_graph_get_remote_port_parent(endpoint);
+               if (!rem) {
+                       dev_dbg(&pdev->dev, "Remote device at %pOF not found\n",
+                               endpoint);
+                       goto done;
+               }
+
+               sdinfo = &pdata->subdev_info[i];
+               chan = &pdata->chan_config[i];
+               chan->inputs = devm_kcalloc(&pdev->dev,
+                                           VPIF_CAPTURE_NUM_CHANNELS,
+                                           sizeof(*chan->inputs),
+                                           GFP_KERNEL);
+               if (!chan->inputs)
+                       goto err_cleanup;
+
+               chan->input_count++;
+               chan->inputs[i].input.type = V4L2_INPUT_TYPE_CAMERA;
+               chan->inputs[i].input.std = V4L2_STD_ALL;
+               chan->inputs[i].input.capabilities = V4L2_IN_CAP_STD;
+
+               err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
+                                                &bus_cfg);
+               if (err) {
+                       dev_err(&pdev->dev, "Could not parse the endpoint\n");
+                       of_node_put(rem);
+                       goto done;
+               }
+
+               dev_dbg(&pdev->dev, "Endpoint %pOF, bus_width = %d\n",
+                       endpoint, bus_cfg.bus.parallel.bus_width);
+
+               flags = bus_cfg.bus.parallel.flags;
+
+               if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+                       chan->vpif_if.hd_pol = 1;
+
+               if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
+                       chan->vpif_if.vd_pol = 1;
+
+               dev_dbg(&pdev->dev, "Remote device %pOF found\n", rem);
+               sdinfo->name = rem->full_name;
+
+               pdata->asd[i] = v4l2_async_nf_add_fwnode(&vpif_obj.notifier,
+                                                        of_fwnode_handle(rem),
+                                                        struct
+                                                        v4l2_async_subdev);
+               if (IS_ERR(pdata->asd[i]))
+                       goto err_cleanup;
+
+               of_node_put(rem);
+       }
+
+done:
+       of_node_put(endpoint);
+       pdata->asd_sizes[0] = i;
+       pdata->subdev_count = i;
+       pdata->card_name = "DA850/OMAP-L138 Video Capture";
+
+       return pdata;
+
+err_cleanup:
+       of_node_put(rem);
+       of_node_put(endpoint);
+       v4l2_async_nf_cleanup(&vpif_obj.notifier);
+
+       return NULL;
+}
+
+/**
+ * vpif_probe : This function probes the vpif capture driver
+ * @pdev: platform device pointer
+ *
+ * This creates device entries by register itself to the V4L2 driver and
+ * initializes fields of each channel objects
+ */
+static __init int vpif_probe(struct platform_device *pdev)
+{
+       struct vpif_subdev_info *subdevdata;
+       struct i2c_adapter *i2c_adap;
+       int subdev_count;
+       int res_idx = 0;
+       int i, err;
+
+       pdev->dev.platform_data = vpif_capture_get_pdata(pdev);
+       if (!pdev->dev.platform_data) {
+               dev_warn(&pdev->dev, "Missing platform data.  Giving up.\n");
+               return -EINVAL;
+       }
+
+       vpif_dev = &pdev->dev;
+
+       err = initialize_vpif();
+       if (err) {
+               v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
+               goto cleanup;
+       }
+
+       err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
+       if (err) {
+               v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
+               goto vpif_free;
+       }
+
+       do {
+               int irq;
+
+               err = platform_get_irq_optional(pdev, res_idx);
+               if (err < 0 && err != -ENXIO)
+                       goto vpif_unregister;
+               if (err > 0)
+                       irq = err;
+               else
+                       break;
+
+               err = devm_request_irq(&pdev->dev, irq, vpif_channel_isr,
+                                      IRQF_SHARED, VPIF_DRIVER_NAME,
+                                      (void *)(&vpif_obj.dev[res_idx]->channel_id));
+               if (err)
+                       goto vpif_unregister;
+       } while (++res_idx);
+
+       vpif_obj.config = pdev->dev.platform_data;
+
+       subdev_count = vpif_obj.config->subdev_count;
+       vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL);
+       if (!vpif_obj.sd) {
+               err = -ENOMEM;
+               goto vpif_unregister;
+       }
+
+       if (!vpif_obj.config->asd_sizes[0]) {
+               int i2c_id = vpif_obj.config->i2c_adapter_id;
+
+               i2c_adap = i2c_get_adapter(i2c_id);
+               WARN_ON(!i2c_adap);
+               for (i = 0; i < subdev_count; i++) {
+                       subdevdata = &vpif_obj.config->subdev_info[i];
+                       vpif_obj.sd[i] =
+                               v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
+                                                         i2c_adap,
+                                                         &subdevdata->
+                                                         board_info,
+                                                         NULL);
+
+                       if (!vpif_obj.sd[i]) {
+                               vpif_err("Error registering v4l2 subdevice\n");
+                               err = -ENODEV;
+                               goto probe_subdev_out;
+                       }
+                       v4l2_info(&vpif_obj.v4l2_dev,
+                                 "registered sub device %s\n",
+                                  subdevdata->name);
+               }
+               err = vpif_probe_complete();
+               if (err)
+                       goto probe_subdev_out;
+       } else {
+               vpif_obj.notifier.ops = &vpif_async_ops;
+               err = v4l2_async_nf_register(&vpif_obj.v4l2_dev,
+                                            &vpif_obj.notifier);
+               if (err) {
+                       vpif_err("Error registering async notifier\n");
+                       err = -EINVAL;
+                       goto probe_subdev_out;
+               }
+       }
+
+       return 0;
+
+probe_subdev_out:
+       /* free sub devices memory */
+       kfree(vpif_obj.sd);
+vpif_unregister:
+       v4l2_device_unregister(&vpif_obj.v4l2_dev);
+vpif_free:
+       free_vpif_objs();
+cleanup:
+       v4l2_async_nf_cleanup(&vpif_obj.notifier);
+
+       return err;
+}
+
+/**
+ * vpif_remove() - driver remove handler
+ * @device: ptr to platform device structure
+ *
+ * The vidoe device is unregistered
+ */
+static int vpif_remove(struct platform_device *device)
+{
+       struct channel_obj *ch;
+       int i;
+
+       v4l2_async_nf_unregister(&vpif_obj.notifier);
+       v4l2_async_nf_cleanup(&vpif_obj.notifier);
+       v4l2_device_unregister(&vpif_obj.v4l2_dev);
+
+       kfree(vpif_obj.sd);
+       /* un-register device */
+       for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
+               /* Get the pointer to the channel object */
+               ch = vpif_obj.dev[i];
+               /* Unregister video device */
+               video_unregister_device(&ch->video_dev);
+               kfree(vpif_obj.dev[i]);
+       }
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+/**
+ * vpif_suspend: vpif device suspend
+ * @dev: pointer to &struct device
+ */
+static int vpif_suspend(struct device *dev)
+{
+
+       struct common_obj *common;
+       struct channel_obj *ch;
+       int i;
+
+       for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
+               /* Get the pointer to the channel object */
+               ch = vpif_obj.dev[i];
+               common = &ch->common[VPIF_VIDEO_INDEX];
+
+               if (!vb2_start_streaming_called(&common->buffer_queue))
+                       continue;
+
+               mutex_lock(&common->lock);
+               /* Disable channel */
+               if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
+                       enable_channel0(0);
+                       channel0_intr_enable(0);
+               }
+               if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
+                       ycmux_mode == 2) {
+                       enable_channel1(0);
+                       channel1_intr_enable(0);
+               }
+               mutex_unlock(&common->lock);
+       }
+
+       return 0;
+}
+
+/*
+ * vpif_resume: vpif device suspend
+ */
+static int vpif_resume(struct device *dev)
+{
+       struct common_obj *common;
+       struct channel_obj *ch;
+       int i;
+
+       for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
+               /* Get the pointer to the channel object */
+               ch = vpif_obj.dev[i];
+               common = &ch->common[VPIF_VIDEO_INDEX];
+
+               if (!vb2_start_streaming_called(&common->buffer_queue))
+                       continue;
+
+               mutex_lock(&common->lock);
+               /* Enable channel */
+               if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
+                       enable_channel0(1);
+                       channel0_intr_enable(1);
+               }
+               if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
+                       ycmux_mode == 2) {
+                       enable_channel1(1);
+                       channel1_intr_enable(1);
+               }
+               mutex_unlock(&common->lock);
+       }
+
+       return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume);
+
+static __refdata struct platform_driver vpif_driver = {
+       .driver = {
+               .name   = VPIF_DRIVER_NAME,
+               .pm     = &vpif_pm_ops,
+       },
+       .probe = vpif_probe,
+       .remove = vpif_remove,
+};
+
+module_platform_driver(vpif_driver);
diff --git a/drivers/media/platform/ti/davinci/vpif_capture.h b/drivers/media/platform/ti/davinci/vpif_capture.h
new file mode 100644 (file)
index 0000000..d5951f6
--- /dev/null
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2009 Texas Instruments Inc
+ */
+
+#ifndef VPIF_CAPTURE_H
+#define VPIF_CAPTURE_H
+
+/* Header files */
+#include <media/videobuf2-dma-contig.h>
+#include <media/v4l2-device.h>
+
+#include "vpif.h"
+
+/* Macros */
+#define VPIF_CAPTURE_VERSION           "0.0.2"
+
+#define VPIF_VALID_FIELD(field)                (((V4L2_FIELD_ANY == field) || \
+       (V4L2_FIELD_NONE == field)) || \
+       (((V4L2_FIELD_INTERLACED == field) || \
+       (V4L2_FIELD_SEQ_TB == field)) || \
+       (V4L2_FIELD_SEQ_BT == field)))
+
+#define VPIF_CAPTURE_MAX_DEVICES       2
+#define VPIF_VIDEO_INDEX               0
+#define VPIF_NUMBER_OF_OBJECTS         1
+
+/* Enumerated data type to give id to each device per channel */
+enum vpif_channel_id {
+       VPIF_CHANNEL0_VIDEO = 0,
+       VPIF_CHANNEL1_VIDEO,
+};
+
+struct video_obj {
+       enum v4l2_field buf_field;
+       /* Currently selected or default standard */
+       v4l2_std_id stdid;
+       struct v4l2_dv_timings dv_timings;
+};
+
+struct vpif_cap_buffer {
+       struct vb2_v4l2_buffer vb;
+       struct list_head list;
+};
+
+struct common_obj {
+       /* Pointer pointing to current v4l2_buffer */
+       struct vpif_cap_buffer *cur_frm;
+       /* Pointer pointing to current v4l2_buffer */
+       struct vpif_cap_buffer *next_frm;
+       /* Used to store pixel format */
+       struct v4l2_format fmt;
+       /* Buffer queue used in video-buf */
+       struct vb2_queue buffer_queue;
+       /* Queue of filled frames */
+       struct list_head dma_queue;
+       /* Protects the dma_queue field */
+       spinlock_t irqlock;
+       /* lock used to access this structure */
+       struct mutex lock;
+       /* Function pointer to set the addresses */
+       void (*set_addr) (unsigned long, unsigned long, unsigned long,
+                         unsigned long);
+       /* offset where Y top starts from the starting of the buffer */
+       u32 ytop_off;
+       /* offset where Y bottom starts from the starting of the buffer */
+       u32 ybtm_off;
+       /* offset where C top starts from the starting of the buffer */
+       u32 ctop_off;
+       /* offset where C bottom starts from the starting of the buffer */
+       u32 cbtm_off;
+       /* Indicates width of the image data */
+       u32 width;
+       /* Indicates height of the image data */
+       u32 height;
+};
+
+struct channel_obj {
+       /* Identifies video device for this channel */
+       struct video_device video_dev;
+       /* Indicates id of the field which is being displayed */
+       u32 field_id;
+       /* flag to indicate whether decoder is initialized */
+       u8 initialized;
+       /* Identifies channel */
+       enum vpif_channel_id channel_id;
+       /* Current input */
+       u32 input_idx;
+       /* subdev corresponding to the current input, may be NULL */
+       struct v4l2_subdev *sd;
+       /* vpif configuration params */
+       struct vpif_params vpifparams;
+       /* common object array */
+       struct common_obj common[VPIF_NUMBER_OF_OBJECTS];
+       /* video object */
+       struct video_obj video;
+};
+
+struct vpif_device {
+       struct v4l2_device v4l2_dev;
+       struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS];
+       struct v4l2_subdev **sd;
+       struct v4l2_async_notifier notifier;
+       struct vpif_capture_config *config;
+};
+
+#endif                         /* VPIF_CAPTURE_H */
diff --git a/drivers/media/platform/ti/davinci/vpif_display.c b/drivers/media/platform/ti/davinci/vpif_display.c
new file mode 100644 (file)
index 0000000..fca148b
--- /dev/null
@@ -0,0 +1,1408 @@
+/*
+ * vpif-display - VPIF display driver
+ * Display driver for TI DaVinci VPIF
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2014 Lad, Prabhakar <prabhakar.csengg@gmail.com>
+ *
+ * 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 version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-ioctl.h>
+
+#include "vpif.h"
+#include "vpif_display.h"
+
+MODULE_DESCRIPTION("TI DaVinci VPIF Display driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(VPIF_DISPLAY_VERSION);
+
+#define VPIF_V4L2_STD (V4L2_STD_525_60 | V4L2_STD_625_50)
+
+#define vpif_err(fmt, arg...)  v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
+#define vpif_dbg(level, debug, fmt, arg...)    \
+               v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
+
+static int debug = 1;
+
+module_param(debug, int, 0644);
+
+MODULE_PARM_DESC(debug, "Debug level 0-1");
+
+#define VPIF_DRIVER_NAME       "vpif_display"
+MODULE_ALIAS("platform:" VPIF_DRIVER_NAME);
+
+/* Is set to 1 in case of SDTV formats, 2 in case of HDTV formats. */
+static int ycmux_mode;
+
+static u8 channel_first_int[VPIF_NUMOBJECTS][2] = { {1, 1} };
+
+static struct vpif_device vpif_obj = { {NULL} };
+static struct device *vpif_dev;
+static void vpif_calculate_offsets(struct channel_obj *ch);
+static void vpif_config_addr(struct channel_obj *ch, int muxmode);
+
+static inline
+struct vpif_disp_buffer *to_vpif_buffer(struct vb2_v4l2_buffer *vb)
+{
+       return container_of(vb, struct vpif_disp_buffer, vb);
+}
+
+/**
+ * vpif_buffer_prepare :  callback function for buffer prepare
+ * @vb: ptr to vb2_buffer
+ *
+ * This is the callback function for buffer prepare when vb2_qbuf()
+ * function is called. The buffer is prepared and user space virtual address
+ * or user address is converted into  physical address
+ */
+static int vpif_buffer_prepare(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
+       struct common_obj *common;
+
+       common = &ch->common[VPIF_VIDEO_INDEX];
+
+       vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
+       if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
+               return -EINVAL;
+
+       vbuf->field = common->fmt.fmt.pix.field;
+
+       if (vb->vb2_queue->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
+               unsigned long addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+
+               if (!ISALIGNED(addr + common->ytop_off) ||
+                       !ISALIGNED(addr + common->ybtm_off) ||
+                       !ISALIGNED(addr + common->ctop_off) ||
+                       !ISALIGNED(addr + common->cbtm_off)) {
+                       vpif_err("buffer offset not aligned to 8 bytes\n");
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+/**
+ * vpif_buffer_queue_setup : Callback function for buffer setup.
+ * @vq: vb2_queue ptr
+ * @nbuffers: ptr to number of buffers requested by application
+ * @nplanes: contains number of distinct video planes needed to hold a frame
+ * @sizes: contains the size (in bytes) of each plane.
+ * @alloc_devs: ptr to allocation context
+ *
+ * This callback function is called when reqbuf() is called to adjust
+ * the buffer count and buffer size
+ */
+static int vpif_buffer_queue_setup(struct vb2_queue *vq,
+                               unsigned int *nbuffers, unsigned int *nplanes,
+                               unsigned int sizes[], struct device *alloc_devs[])
+{
+       struct channel_obj *ch = vb2_get_drv_priv(vq);
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       unsigned size = common->fmt.fmt.pix.sizeimage;
+
+       if (*nplanes) {
+               if (sizes[0] < size)
+                       return -EINVAL;
+               size = sizes[0];
+       }
+
+       if (vq->num_buffers + *nbuffers < 3)
+               *nbuffers = 3 - vq->num_buffers;
+
+       *nplanes = 1;
+       sizes[0] = size;
+
+       /* Calculate the offset for Y and C data  in the buffer */
+       vpif_calculate_offsets(ch);
+
+       return 0;
+}
+
+/**
+ * vpif_buffer_queue : Callback function to add buffer to DMA queue
+ * @vb: ptr to vb2_buffer
+ *
+ * This callback function queues the buffer to DMA engine
+ */
+static void vpif_buffer_queue(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct vpif_disp_buffer *buf = to_vpif_buffer(vbuf);
+       struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
+       struct common_obj *common;
+       unsigned long flags;
+
+       common = &ch->common[VPIF_VIDEO_INDEX];
+
+       /* add the buffer to the DMA queue */
+       spin_lock_irqsave(&common->irqlock, flags);
+       list_add_tail(&buf->list, &common->dma_queue);
+       spin_unlock_irqrestore(&common->irqlock, flags);
+}
+
+/**
+ * vpif_start_streaming : Starts the DMA engine for streaming
+ * @vq: ptr to vb2_buffer
+ * @count: number of buffers
+ */
+static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+       struct vpif_display_config *vpif_config_data =
+                                       vpif_dev->platform_data;
+       struct channel_obj *ch = vb2_get_drv_priv(vq);
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct vpif_params *vpif = &ch->vpifparams;
+       struct vpif_disp_buffer *buf, *tmp;
+       unsigned long addr, flags;
+       int ret;
+
+       spin_lock_irqsave(&common->irqlock, flags);
+
+       /* Initialize field_id */
+       ch->field_id = 0;
+
+       /* clock settings */
+       if (vpif_config_data->set_clock) {
+               ret = vpif_config_data->set_clock(ch->vpifparams.std_info.
+               ycmux_mode, ch->vpifparams.std_info.hd_sd);
+               if (ret < 0) {
+                       vpif_err("can't set clock\n");
+                       goto err;
+               }
+       }
+
+       /* set the parameters and addresses */
+       ret = vpif_set_video_params(vpif, ch->channel_id + 2);
+       if (ret < 0)
+               goto err;
+
+       ycmux_mode = ret;
+       vpif_config_addr(ch, ret);
+       /* Get the next frame from the buffer queue */
+       common->next_frm = common->cur_frm =
+                           list_entry(common->dma_queue.next,
+                                      struct vpif_disp_buffer, list);
+
+       list_del(&common->cur_frm->list);
+       spin_unlock_irqrestore(&common->irqlock, flags);
+
+       addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb.vb2_buf, 0);
+       common->set_addr((addr + common->ytop_off),
+                           (addr + common->ybtm_off),
+                           (addr + common->ctop_off),
+                           (addr + common->cbtm_off));
+
+       /*
+        * Set interrupt for both the fields in VPIF
+        * Register enable channel in VPIF register
+        */
+       channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
+       if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
+               channel2_intr_assert();
+               channel2_intr_enable(1);
+               enable_channel2(1);
+               if (vpif_config_data->chan_config[VPIF_CHANNEL2_VIDEO].clip_en)
+                       channel2_clipping_enable(1);
+       }
+
+       if (VPIF_CHANNEL3_VIDEO == ch->channel_id || ycmux_mode == 2) {
+               channel3_intr_assert();
+               channel3_intr_enable(1);
+               enable_channel3(1);
+               if (vpif_config_data->chan_config[VPIF_CHANNEL3_VIDEO].clip_en)
+                       channel3_clipping_enable(1);
+       }
+
+       return 0;
+
+err:
+       list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
+               list_del(&buf->list);
+               vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
+       }
+       spin_unlock_irqrestore(&common->irqlock, flags);
+
+       return ret;
+}
+
+/**
+ * vpif_stop_streaming : Stop the DMA engine
+ * @vq: ptr to vb2_queue
+ *
+ * This callback stops the DMA engine and any remaining buffers
+ * in the DMA queue are released.
+ */
+static void vpif_stop_streaming(struct vb2_queue *vq)
+{
+       struct channel_obj *ch = vb2_get_drv_priv(vq);
+       struct common_obj *common;
+       unsigned long flags;
+
+       common = &ch->common[VPIF_VIDEO_INDEX];
+
+       /* Disable channel */
+       if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
+               enable_channel2(0);
+               channel2_intr_enable(0);
+       }
+       if (VPIF_CHANNEL3_VIDEO == ch->channel_id || ycmux_mode == 2) {
+               enable_channel3(0);
+               channel3_intr_enable(0);
+       }
+
+       /* release all active buffers */
+       spin_lock_irqsave(&common->irqlock, flags);
+       if (common->cur_frm == common->next_frm) {
+               vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
+                               VB2_BUF_STATE_ERROR);
+       } else {
+               if (common->cur_frm)
+                       vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
+                                       VB2_BUF_STATE_ERROR);
+               if (common->next_frm)
+                       vb2_buffer_done(&common->next_frm->vb.vb2_buf,
+                                       VB2_BUF_STATE_ERROR);
+       }
+
+       while (!list_empty(&common->dma_queue)) {
+               common->next_frm = list_entry(common->dma_queue.next,
+                                               struct vpif_disp_buffer, list);
+               list_del(&common->next_frm->list);
+               vb2_buffer_done(&common->next_frm->vb.vb2_buf,
+                               VB2_BUF_STATE_ERROR);
+       }
+       spin_unlock_irqrestore(&common->irqlock, flags);
+}
+
+static const struct vb2_ops video_qops = {
+       .queue_setup            = vpif_buffer_queue_setup,
+       .wait_prepare           = vb2_ops_wait_prepare,
+       .wait_finish            = vb2_ops_wait_finish,
+       .buf_prepare            = vpif_buffer_prepare,
+       .start_streaming        = vpif_start_streaming,
+       .stop_streaming         = vpif_stop_streaming,
+       .buf_queue              = vpif_buffer_queue,
+};
+
+static void process_progressive_mode(struct common_obj *common)
+{
+       unsigned long addr;
+
+       spin_lock(&common->irqlock);
+       /* Get the next buffer from buffer queue */
+       common->next_frm = list_entry(common->dma_queue.next,
+                               struct vpif_disp_buffer, list);
+       /* Remove that buffer from the buffer queue */
+       list_del(&common->next_frm->list);
+       spin_unlock(&common->irqlock);
+
+       /* Set top and bottom field addrs in VPIF registers */
+       addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb.vb2_buf, 0);
+       common->set_addr(addr + common->ytop_off,
+                                addr + common->ybtm_off,
+                                addr + common->ctop_off,
+                                addr + common->cbtm_off);
+}
+
+static void process_interlaced_mode(int fid, struct common_obj *common)
+{
+       /* device field id and local field id are in sync */
+       /* If this is even field */
+       if (0 == fid) {
+               if (common->cur_frm == common->next_frm)
+                       return;
+
+               /* one frame is displayed If next frame is
+                *  available, release cur_frm and move on */
+               /* Copy frame display time */
+               common->cur_frm->vb.vb2_buf.timestamp = ktime_get_ns();
+               /* Change status of the cur_frm */
+               vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
+                                       VB2_BUF_STATE_DONE);
+               /* Make cur_frm pointing to next_frm */
+               common->cur_frm = common->next_frm;
+
+       } else if (1 == fid) {  /* odd field */
+               spin_lock(&common->irqlock);
+               if (list_empty(&common->dma_queue)
+                   || (common->cur_frm != common->next_frm)) {
+                       spin_unlock(&common->irqlock);
+                       return;
+               }
+               spin_unlock(&common->irqlock);
+               /* one field is displayed configure the next
+                * frame if it is available else hold on current
+                * frame */
+               /* Get next from the buffer queue */
+               process_progressive_mode(common);
+       }
+}
+
+/*
+ * vpif_channel_isr: It changes status of the displayed buffer, takes next
+ * buffer from the queue and sets its address in VPIF registers
+ */
+static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
+{
+       struct vpif_device *dev = &vpif_obj;
+       struct channel_obj *ch;
+       struct common_obj *common;
+       int fid = -1, i;
+       int channel_id;
+
+       channel_id = *(int *)(dev_id);
+       if (!vpif_intr_status(channel_id + 2))
+               return IRQ_NONE;
+
+       ch = dev->dev[channel_id];
+       for (i = 0; i < VPIF_NUMOBJECTS; i++) {
+               common = &ch->common[i];
+               /* If streaming is started in this channel */
+
+               if (1 == ch->vpifparams.std_info.frm_fmt) {
+                       spin_lock(&common->irqlock);
+                       if (list_empty(&common->dma_queue)) {
+                               spin_unlock(&common->irqlock);
+                               continue;
+                       }
+                       spin_unlock(&common->irqlock);
+
+                       /* Progressive mode */
+                       if (!channel_first_int[i][channel_id]) {
+                               /* Mark status of the cur_frm to
+                                * done and unlock semaphore on it */
+                               common->cur_frm->vb.vb2_buf.timestamp =
+                                               ktime_get_ns();
+                               vb2_buffer_done(&common->cur_frm->vb.vb2_buf,
+                                               VB2_BUF_STATE_DONE);
+                               /* Make cur_frm pointing to next_frm */
+                               common->cur_frm = common->next_frm;
+                       }
+
+                       channel_first_int[i][channel_id] = 0;
+                       process_progressive_mode(common);
+               } else {
+                       /* Interlaced mode */
+                       /* If it is first interrupt, ignore it */
+
+                       if (channel_first_int[i][channel_id]) {
+                               channel_first_int[i][channel_id] = 0;
+                               continue;
+                       }
+
+                       if (0 == i) {
+                               ch->field_id ^= 1;
+                               /* Get field id from VPIF registers */
+                               fid = vpif_channel_getfid(ch->channel_id + 2);
+                               /* If fid does not match with stored field id */
+                               if (fid != ch->field_id) {
+                                       /* Make them in sync */
+                                       if (0 == fid)
+                                               ch->field_id = fid;
+
+                                       return IRQ_HANDLED;
+                               }
+                       }
+                       process_interlaced_mode(fid, common);
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+static int vpif_update_std_info(struct channel_obj *ch)
+{
+       struct video_obj *vid_ch = &ch->video;
+       struct vpif_params *vpifparams = &ch->vpifparams;
+       struct vpif_channel_config_params *std_info = &vpifparams->std_info;
+       const struct vpif_channel_config_params *config;
+
+       int i;
+
+       for (i = 0; i < vpif_ch_params_count; i++) {
+               config = &vpif_ch_params[i];
+               if (config->hd_sd == 0) {
+                       vpif_dbg(2, debug, "SD format\n");
+                       if (config->stdid & vid_ch->stdid) {
+                               memcpy(std_info, config, sizeof(*config));
+                               break;
+                       }
+               }
+       }
+
+       if (i == vpif_ch_params_count) {
+               vpif_dbg(1, debug, "Format not found\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int vpif_update_resolution(struct channel_obj *ch)
+{
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct video_obj *vid_ch = &ch->video;
+       struct vpif_params *vpifparams = &ch->vpifparams;
+       struct vpif_channel_config_params *std_info = &vpifparams->std_info;
+
+       if (!vid_ch->stdid && !vid_ch->dv_timings.bt.height)
+               return -EINVAL;
+
+       if (vid_ch->stdid) {
+               if (vpif_update_std_info(ch))
+                       return -EINVAL;
+       }
+
+       common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
+       common->fmt.fmt.pix.width = std_info->width;
+       common->fmt.fmt.pix.height = std_info->height;
+       vpif_dbg(1, debug, "Pixel details: Width = %d,Height = %d\n",
+                       common->fmt.fmt.pix.width, common->fmt.fmt.pix.height);
+
+       /* Set height and width paramateres */
+       common->height = std_info->height;
+       common->width = std_info->width;
+       common->fmt.fmt.pix.sizeimage = common->height * common->width * 2;
+
+       if (vid_ch->stdid)
+               common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+       else
+               common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
+
+       if (ch->vpifparams.std_info.frm_fmt)
+               common->fmt.fmt.pix.field = V4L2_FIELD_NONE;
+       else
+               common->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
+
+       return 0;
+}
+
+/*
+ * vpif_calculate_offsets: This function calculates buffers offset for Y and C
+ * in the top and bottom field
+ */
+static void vpif_calculate_offsets(struct channel_obj *ch)
+{
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct vpif_params *vpifparams = &ch->vpifparams;
+       enum v4l2_field field = common->fmt.fmt.pix.field;
+       struct video_obj *vid_ch = &ch->video;
+       unsigned int hpitch, sizeimage;
+
+       if (V4L2_FIELD_ANY == common->fmt.fmt.pix.field) {
+               if (ch->vpifparams.std_info.frm_fmt)
+                       vid_ch->buf_field = V4L2_FIELD_NONE;
+               else
+                       vid_ch->buf_field = V4L2_FIELD_INTERLACED;
+       } else {
+               vid_ch->buf_field = common->fmt.fmt.pix.field;
+       }
+
+       sizeimage = common->fmt.fmt.pix.sizeimage;
+
+       hpitch = common->fmt.fmt.pix.bytesperline;
+       if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
+           (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
+               common->ytop_off = 0;
+               common->ybtm_off = hpitch;
+               common->ctop_off = sizeimage / 2;
+               common->cbtm_off = sizeimage / 2 + hpitch;
+       } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
+               common->ytop_off = 0;
+               common->ybtm_off = sizeimage / 4;
+               common->ctop_off = sizeimage / 2;
+               common->cbtm_off = common->ctop_off + sizeimage / 4;
+       } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
+               common->ybtm_off = 0;
+               common->ytop_off = sizeimage / 4;
+               common->cbtm_off = sizeimage / 2;
+               common->ctop_off = common->cbtm_off + sizeimage / 4;
+       }
+
+       if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
+           (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
+               vpifparams->video_params.storage_mode = 1;
+       } else {
+               vpifparams->video_params.storage_mode = 0;
+       }
+
+       if (ch->vpifparams.std_info.frm_fmt == 1) {
+               vpifparams->video_params.hpitch =
+                   common->fmt.fmt.pix.bytesperline;
+       } else {
+               if ((field == V4L2_FIELD_ANY) ||
+                       (field == V4L2_FIELD_INTERLACED))
+                       vpifparams->video_params.hpitch =
+                           common->fmt.fmt.pix.bytesperline * 2;
+               else
+                       vpifparams->video_params.hpitch =
+                           common->fmt.fmt.pix.bytesperline;
+       }
+
+       ch->vpifparams.video_params.stdid = ch->vpifparams.std_info.stdid;
+}
+
+static void vpif_config_addr(struct channel_obj *ch, int muxmode)
+{
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+       if (VPIF_CHANNEL3_VIDEO == ch->channel_id) {
+               common->set_addr = ch3_set_videobuf_addr;
+       } else {
+               if (2 == muxmode)
+                       common->set_addr = ch2_set_videobuf_addr_yc_nmux;
+               else
+                       common->set_addr = ch2_set_videobuf_addr;
+       }
+}
+
+/* functions implementing ioctls */
+/**
+ * vpif_querycap() - QUERYCAP handler
+ * @file: file ptr
+ * @priv: file handle
+ * @cap: ptr to v4l2_capability structure
+ */
+static int vpif_querycap(struct file *file, void  *priv,
+                               struct v4l2_capability *cap)
+{
+       struct vpif_display_config *config = vpif_dev->platform_data;
+
+       strscpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));
+       snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+                dev_name(vpif_dev));
+       strscpy(cap->card, config->card_name, sizeof(cap->card));
+
+       return 0;
+}
+
+static int vpif_enum_fmt_vid_out(struct file *file, void  *priv,
+                                       struct v4l2_fmtdesc *fmt)
+{
+       if (fmt->index != 0)
+               return -EINVAL;
+
+       /* Fill in the information about format */
+       fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
+       return 0;
+}
+
+static int vpif_g_fmt_vid_out(struct file *file, void *priv,
+                               struct v4l2_format *fmt)
+{
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+       /* Check the validity of the buffer type */
+       if (common->fmt.type != fmt->type)
+               return -EINVAL;
+
+       if (vpif_update_resolution(ch))
+               return -EINVAL;
+       *fmt = common->fmt;
+       return 0;
+}
+
+static int vpif_try_fmt_vid_out(struct file *file, void *priv,
+                               struct v4l2_format *fmt)
+{
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+
+       /*
+        * to suppress v4l-compliance warnings silently correct
+        * the pixelformat
+        */
+       if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P)
+               pixfmt->pixelformat = common->fmt.fmt.pix.pixelformat;
+
+       if (vpif_update_resolution(ch))
+               return -EINVAL;
+
+       pixfmt->colorspace = common->fmt.fmt.pix.colorspace;
+       pixfmt->field = common->fmt.fmt.pix.field;
+       pixfmt->bytesperline = common->fmt.fmt.pix.width;
+       pixfmt->width = common->fmt.fmt.pix.width;
+       pixfmt->height = common->fmt.fmt.pix.height;
+       pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2;
+
+       return 0;
+}
+
+static int vpif_s_fmt_vid_out(struct file *file, void *priv,
+                               struct v4l2_format *fmt)
+{
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+       int ret;
+
+       if (vb2_is_busy(&common->buffer_queue))
+               return -EBUSY;
+
+       ret = vpif_try_fmt_vid_out(file, priv, fmt);
+       if (ret)
+               return ret;
+
+       /* store the pix format in the channel object */
+       common->fmt.fmt.pix = *pixfmt;
+
+       /* store the format in the channel object */
+       common->fmt = *fmt;
+       return 0;
+}
+
+static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
+{
+       struct vpif_display_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct vpif_display_chan_config *chan_cfg;
+       struct v4l2_output output;
+       int ret;
+
+       if (!config->chan_config[ch->channel_id].outputs)
+               return -ENODATA;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+       output = chan_cfg->outputs[ch->output_idx].output;
+       if (output.capabilities != V4L2_OUT_CAP_STD)
+               return -ENODATA;
+
+       if (vb2_is_busy(&common->buffer_queue))
+               return -EBUSY;
+
+
+       if (!(std_id & VPIF_V4L2_STD))
+               return -EINVAL;
+
+       /* Call encoder subdevice function to set the standard */
+       ch->video.stdid = std_id;
+       memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
+       /* Get the information about the standard */
+       if (vpif_update_resolution(ch))
+               return -EINVAL;
+
+       common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width;
+
+       ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
+                                               s_std_output, std_id);
+       if (ret < 0) {
+               vpif_err("Failed to set output standard\n");
+               return ret;
+       }
+
+       ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
+                                                       s_std, std_id);
+       if (ret < 0)
+               vpif_err("Failed to set standard for sub devices\n");
+       return ret;
+}
+
+static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
+{
+       struct vpif_display_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct vpif_display_chan_config *chan_cfg;
+       struct v4l2_output output;
+
+       if (!config->chan_config[ch->channel_id].outputs)
+               return -ENODATA;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+       output = chan_cfg->outputs[ch->output_idx].output;
+       if (output.capabilities != V4L2_OUT_CAP_STD)
+               return -ENODATA;
+
+       *std = ch->video.stdid;
+       return 0;
+}
+
+static int vpif_enum_output(struct file *file, void *fh,
+                               struct v4l2_output *output)
+{
+
+       struct vpif_display_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct vpif_display_chan_config *chan_cfg;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+       if (output->index >= chan_cfg->output_count) {
+               vpif_dbg(1, debug, "Invalid output index\n");
+               return -EINVAL;
+       }
+
+       *output = chan_cfg->outputs[output->index].output;
+       return 0;
+}
+
+/**
+ * vpif_output_to_subdev() - Maps output to sub device
+ * @vpif_cfg: global config ptr
+ * @chan_cfg: channel config ptr
+ * @index: Given output index from application
+ *
+ * lookup the sub device information for a given output index.
+ * we report all the output to application. output table also
+ * has sub device name for the each output
+ */
+static int
+vpif_output_to_subdev(struct vpif_display_config *vpif_cfg,
+                     struct vpif_display_chan_config *chan_cfg, int index)
+{
+       struct vpif_subdev_info *subdev_info;
+       const char *subdev_name;
+       int i;
+
+       vpif_dbg(2, debug, "vpif_output_to_subdev\n");
+
+       if (!chan_cfg->outputs)
+               return -1;
+
+       subdev_name = chan_cfg->outputs[index].subdev_name;
+       if (!subdev_name)
+               return -1;
+
+       /* loop through the sub device list to get the sub device info */
+       for (i = 0; i < vpif_cfg->subdev_count; i++) {
+               subdev_info = &vpif_cfg->subdevinfo[i];
+               if (!strcmp(subdev_info->name, subdev_name))
+                       return i;
+       }
+       return -1;
+}
+
+/**
+ * vpif_set_output() - Select an output
+ * @vpif_cfg: global config ptr
+ * @ch: channel
+ * @index: Given output index from application
+ *
+ * Select the given output.
+ */
+static int vpif_set_output(struct vpif_display_config *vpif_cfg,
+                     struct channel_obj *ch, int index)
+{
+       struct vpif_display_chan_config *chan_cfg =
+               &vpif_cfg->chan_config[ch->channel_id];
+       struct v4l2_subdev *sd = NULL;
+       u32 input = 0, output = 0;
+       int sd_index;
+       int ret;
+
+       sd_index = vpif_output_to_subdev(vpif_cfg, chan_cfg, index);
+       if (sd_index >= 0)
+               sd = vpif_obj.sd[sd_index];
+
+       if (sd) {
+               input = chan_cfg->outputs[index].input_route;
+               output = chan_cfg->outputs[index].output_route;
+               ret = v4l2_subdev_call(sd, video, s_routing, input, output, 0);
+               if (ret < 0 && ret != -ENOIOCTLCMD) {
+                       vpif_err("Failed to set output\n");
+                       return ret;
+               }
+
+       }
+       ch->output_idx = index;
+       ch->sd = sd;
+       if (chan_cfg->outputs)
+               /* update tvnorms from the sub device output info */
+               ch->video_dev.tvnorms = chan_cfg->outputs[index].output.std;
+       return 0;
+}
+
+static int vpif_s_output(struct file *file, void *priv, unsigned int i)
+{
+       struct vpif_display_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct vpif_display_chan_config *chan_cfg;
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+       if (vb2_is_busy(&common->buffer_queue))
+               return -EBUSY;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+
+       if (i >= chan_cfg->output_count)
+               return -EINVAL;
+
+       return vpif_set_output(config, ch, i);
+}
+
+static int vpif_g_output(struct file *file, void *priv, unsigned int *i)
+{
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+
+       *i = ch->output_idx;
+
+       return 0;
+}
+
+/**
+ * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @timings: input timings
+ */
+static int
+vpif_enum_dv_timings(struct file *file, void *priv,
+                    struct v4l2_enum_dv_timings *timings)
+{
+       struct vpif_display_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct vpif_display_chan_config *chan_cfg;
+       struct v4l2_output output;
+       int ret;
+
+       if (!config->chan_config[ch->channel_id].outputs)
+               return -ENODATA;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+       output = chan_cfg->outputs[ch->output_idx].output;
+       if (output.capabilities != V4L2_OUT_CAP_DV_TIMINGS)
+               return -ENODATA;
+
+       timings->pad = 0;
+
+       ret = v4l2_subdev_call(ch->sd, pad, enum_dv_timings, timings);
+       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
+               return -EINVAL;
+       return ret;
+}
+
+/**
+ * vpif_s_dv_timings() - S_DV_TIMINGS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @timings: digital video timings
+ */
+static int vpif_s_dv_timings(struct file *file, void *priv,
+               struct v4l2_dv_timings *timings)
+{
+       struct vpif_display_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct vpif_params *vpifparams = &ch->vpifparams;
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct vpif_channel_config_params *std_info = &vpifparams->std_info;
+       struct video_obj *vid_ch = &ch->video;
+       struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt;
+       struct vpif_display_chan_config *chan_cfg;
+       struct v4l2_output output;
+       int ret;
+
+       if (!config->chan_config[ch->channel_id].outputs)
+               return -ENODATA;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+       output = chan_cfg->outputs[ch->output_idx].output;
+       if (output.capabilities != V4L2_OUT_CAP_DV_TIMINGS)
+               return -ENODATA;
+
+       if (vb2_is_busy(&common->buffer_queue))
+               return -EBUSY;
+
+       if (timings->type != V4L2_DV_BT_656_1120) {
+               vpif_dbg(2, debug, "Timing type not defined\n");
+               return -EINVAL;
+       }
+
+       /* Configure subdevice timings, if any */
+       ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings);
+       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
+               ret = 0;
+       if (ret < 0) {
+               vpif_dbg(2, debug, "Error setting custom DV timings\n");
+               return ret;
+       }
+
+       if (!(timings->bt.width && timings->bt.height &&
+                               (timings->bt.hbackporch ||
+                                timings->bt.hfrontporch ||
+                                timings->bt.hsync) &&
+                               timings->bt.vfrontporch &&
+                               (timings->bt.vbackporch ||
+                                timings->bt.vsync))) {
+               vpif_dbg(2, debug, "Timings for width, height, horizontal back porch, horizontal sync, horizontal front porch, vertical back porch, vertical sync and vertical back porch must be defined\n");
+               return -EINVAL;
+       }
+
+       vid_ch->dv_timings = *timings;
+
+       /* Configure video port timings */
+
+       std_info->eav2sav = V4L2_DV_BT_BLANKING_WIDTH(bt) - 8;
+       std_info->sav2eav = bt->width;
+
+       std_info->l1 = 1;
+       std_info->l3 = bt->vsync + bt->vbackporch + 1;
+
+       std_info->vsize = V4L2_DV_BT_FRAME_HEIGHT(bt);
+       if (bt->interlaced) {
+               if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
+                       std_info->l5 = std_info->vsize/2 -
+                               (bt->vfrontporch - 1);
+                       std_info->l7 = std_info->vsize/2 + 1;
+                       std_info->l9 = std_info->l7 + bt->il_vsync +
+                               bt->il_vbackporch + 1;
+                       std_info->l11 = std_info->vsize -
+                               (bt->il_vfrontporch - 1);
+               } else {
+                       vpif_dbg(2, debug, "Required timing values for interlaced BT format missing\n");
+                       return -EINVAL;
+               }
+       } else {
+               std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
+       }
+       strscpy(std_info->name, "Custom timings BT656/1120",
+               sizeof(std_info->name));
+       std_info->width = bt->width;
+       std_info->height = bt->height;
+       std_info->frm_fmt = bt->interlaced ? 0 : 1;
+       std_info->ycmux_mode = 0;
+       std_info->capture_format = 0;
+       std_info->vbi_supported = 0;
+       std_info->hd_sd = 1;
+       std_info->stdid = 0;
+       vid_ch->stdid = 0;
+
+       return 0;
+}
+
+/**
+ * vpif_g_dv_timings() - G_DV_TIMINGS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @timings: digital video timings
+ */
+static int vpif_g_dv_timings(struct file *file, void *priv,
+               struct v4l2_dv_timings *timings)
+{
+       struct vpif_display_config *config = vpif_dev->platform_data;
+       struct video_device *vdev = video_devdata(file);
+       struct channel_obj *ch = video_get_drvdata(vdev);
+       struct vpif_display_chan_config *chan_cfg;
+       struct video_obj *vid_ch = &ch->video;
+       struct v4l2_output output;
+
+       if (!config->chan_config[ch->channel_id].outputs)
+               goto error;
+
+       chan_cfg = &config->chan_config[ch->channel_id];
+       output = chan_cfg->outputs[ch->output_idx].output;
+
+       if (output.capabilities != V4L2_OUT_CAP_DV_TIMINGS)
+               goto error;
+
+       *timings = vid_ch->dv_timings;
+
+       return 0;
+error:
+       return -ENODATA;
+}
+
+/*
+ * vpif_log_status() - Status information
+ * @file: file ptr
+ * @priv: file handle
+ *
+ * Returns zero.
+ */
+static int vpif_log_status(struct file *filep, void *priv)
+{
+       /* status for sub devices */
+       v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
+
+       return 0;
+}
+
+/* vpif display ioctl operations */
+static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
+       .vidioc_querycap                = vpif_querycap,
+       .vidioc_enum_fmt_vid_out        = vpif_enum_fmt_vid_out,
+       .vidioc_g_fmt_vid_out           = vpif_g_fmt_vid_out,
+       .vidioc_s_fmt_vid_out           = vpif_s_fmt_vid_out,
+       .vidioc_try_fmt_vid_out         = vpif_try_fmt_vid_out,
+
+       .vidioc_reqbufs                 = vb2_ioctl_reqbufs,
+       .vidioc_create_bufs             = vb2_ioctl_create_bufs,
+       .vidioc_querybuf                = vb2_ioctl_querybuf,
+       .vidioc_qbuf                    = vb2_ioctl_qbuf,
+       .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
+       .vidioc_expbuf                  = vb2_ioctl_expbuf,
+       .vidioc_streamon                = vb2_ioctl_streamon,
+       .vidioc_streamoff               = vb2_ioctl_streamoff,
+
+       .vidioc_s_std                   = vpif_s_std,
+       .vidioc_g_std                   = vpif_g_std,
+
+       .vidioc_enum_output             = vpif_enum_output,
+       .vidioc_s_output                = vpif_s_output,
+       .vidioc_g_output                = vpif_g_output,
+
+       .vidioc_enum_dv_timings         = vpif_enum_dv_timings,
+       .vidioc_s_dv_timings            = vpif_s_dv_timings,
+       .vidioc_g_dv_timings            = vpif_g_dv_timings,
+
+       .vidioc_log_status              = vpif_log_status,
+};
+
+static const struct v4l2_file_operations vpif_fops = {
+       .owner          = THIS_MODULE,
+       .open           = v4l2_fh_open,
+       .release        = vb2_fop_release,
+       .unlocked_ioctl = video_ioctl2,
+       .mmap           = vb2_fop_mmap,
+       .poll           = vb2_fop_poll
+};
+
+/*Configure the channels, buffer sizei, request irq */
+static int initialize_vpif(void)
+{
+       int free_channel_objects_index;
+       int err, i, j;
+
+       /* Allocate memory for six channel objects */
+       for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
+               vpif_obj.dev[i] =
+                   kzalloc(sizeof(struct channel_obj), GFP_KERNEL);
+               /* If memory allocation fails, return error */
+               if (!vpif_obj.dev[i]) {
+                       free_channel_objects_index = i;
+                       err = -ENOMEM;
+                       goto vpif_init_free_channel_objects;
+               }
+       }
+
+       return 0;
+
+vpif_init_free_channel_objects:
+       for (j = 0; j < free_channel_objects_index; j++)
+               kfree(vpif_obj.dev[j]);
+       return err;
+}
+
+static void free_vpif_objs(void)
+{
+       int i;
+
+       for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++)
+               kfree(vpif_obj.dev[i]);
+}
+
+static int vpif_probe_complete(void)
+{
+       struct common_obj *common;
+       struct video_device *vdev;
+       struct channel_obj *ch;
+       struct vb2_queue *q;
+       int j, err, k;
+
+       for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
+               ch = vpif_obj.dev[j];
+               /* Initialize field of the channel objects */
+               for (k = 0; k < VPIF_NUMOBJECTS; k++) {
+                       common = &ch->common[k];
+                       spin_lock_init(&common->irqlock);
+                       mutex_init(&common->lock);
+                       common->set_addr = NULL;
+                       common->ytop_off = 0;
+                       common->ybtm_off = 0;
+                       common->ctop_off = 0;
+                       common->cbtm_off = 0;
+                       common->cur_frm = NULL;
+                       common->next_frm = NULL;
+                       memset(&common->fmt, 0, sizeof(common->fmt));
+               }
+               ch->initialized = 0;
+               if (vpif_obj.config->subdev_count)
+                       ch->sd = vpif_obj.sd[0];
+               ch->channel_id = j;
+
+               memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
+
+               ch->common[VPIF_VIDEO_INDEX].fmt.type =
+                                               V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+               /* select output 0 */
+               err = vpif_set_output(vpif_obj.config, ch, 0);
+               if (err)
+                       goto probe_out;
+
+               /* set initial format */
+               ch->video.stdid = V4L2_STD_525_60;
+               memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
+               vpif_update_resolution(ch);
+
+               /* Initialize vb2 queue */
+               q = &common->buffer_queue;
+               q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+               q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+               q->drv_priv = ch;
+               q->ops = &video_qops;
+               q->mem_ops = &vb2_dma_contig_memops;
+               q->buf_struct_size = sizeof(struct vpif_disp_buffer);
+               q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+               q->min_buffers_needed = 1;
+               q->lock = &common->lock;
+               q->dev = vpif_dev;
+               err = vb2_queue_init(q);
+               if (err) {
+                       vpif_err("vpif_display: vb2_queue_init() failed\n");
+                       goto probe_out;
+               }
+
+               INIT_LIST_HEAD(&common->dma_queue);
+
+               /* register video device */
+               vpif_dbg(1, debug, "channel=%p,channel->video_dev=%p\n",
+                        ch, &ch->video_dev);
+
+               /* Initialize the video_device structure */
+               vdev = &ch->video_dev;
+               strscpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
+               vdev->release = video_device_release_empty;
+               vdev->fops = &vpif_fops;
+               vdev->ioctl_ops = &vpif_ioctl_ops;
+               vdev->v4l2_dev = &vpif_obj.v4l2_dev;
+               vdev->vfl_dir = VFL_DIR_TX;
+               vdev->queue = q;
+               vdev->lock = &common->lock;
+               vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
+               video_set_drvdata(&ch->video_dev, ch);
+               err = video_register_device(vdev, VFL_TYPE_VIDEO,
+                                           (j ? 3 : 2));
+               if (err < 0)
+                       goto probe_out;
+       }
+
+       return 0;
+
+probe_out:
+       for (k = 0; k < j; k++) {
+               ch = vpif_obj.dev[k];
+               video_unregister_device(&ch->video_dev);
+       }
+       return err;
+}
+
+/*
+ * vpif_probe: This function creates device entries by register itself to the
+ * V4L2 driver and initializes fields of each channel objects
+ */
+static __init int vpif_probe(struct platform_device *pdev)
+{
+       struct vpif_subdev_info *subdevdata;
+       struct i2c_adapter *i2c_adap;
+       int subdev_count;
+       int res_idx = 0;
+       int i, err;
+
+       if (!pdev->dev.platform_data) {
+               dev_warn(&pdev->dev, "Missing platform data.  Giving up.\n");
+               return -EINVAL;
+       }
+
+       vpif_dev = &pdev->dev;
+       err = initialize_vpif();
+
+       if (err) {
+               v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
+               return err;
+       }
+
+       err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
+       if (err) {
+               v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
+               goto vpif_free;
+       }
+
+       do {
+               int irq;
+
+               err = platform_get_irq_optional(pdev, res_idx);
+               if (err < 0 && err != -ENXIO)
+                       goto vpif_unregister;
+               if (err > 0)
+                       irq = err;
+               else
+                       break;
+
+               err = devm_request_irq(&pdev->dev, irq, vpif_channel_isr,
+                                      IRQF_SHARED, VPIF_DRIVER_NAME,
+                                      (void *)(&vpif_obj.dev[res_idx]->channel_id));
+               if (err) {
+                       vpif_err("VPIF IRQ request failed\n");
+                       goto vpif_unregister;
+               }
+       } while (++res_idx);
+
+       vpif_obj.config = pdev->dev.platform_data;
+       subdev_count = vpif_obj.config->subdev_count;
+       subdevdata = vpif_obj.config->subdevinfo;
+       vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL);
+       if (!vpif_obj.sd) {
+               err = -ENOMEM;
+               goto vpif_unregister;
+       }
+
+       i2c_adap = i2c_get_adapter(vpif_obj.config->i2c_adapter_id);
+       for (i = 0; i < subdev_count; i++) {
+               vpif_obj.sd[i] =
+                       v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
+                                                 i2c_adap,
+                                                 &subdevdata[i].board_info,
+                                                 NULL);
+               if (!vpif_obj.sd[i]) {
+                       vpif_err("Error registering v4l2 subdevice\n");
+                       err = -ENODEV;
+                       goto probe_subdev_out;
+               }
+
+               if (vpif_obj.sd[i])
+                       vpif_obj.sd[i]->grp_id = 1 << i;
+       }
+       err = vpif_probe_complete();
+       if (err)
+               goto probe_subdev_out;
+
+       return 0;
+
+probe_subdev_out:
+       kfree(vpif_obj.sd);
+vpif_unregister:
+       v4l2_device_unregister(&vpif_obj.v4l2_dev);
+vpif_free:
+       free_vpif_objs();
+
+       return err;
+}
+
+/*
+ * vpif_remove: It un-register channels from V4L2 driver
+ */
+static int vpif_remove(struct platform_device *device)
+{
+       struct channel_obj *ch;
+       int i;
+
+       v4l2_device_unregister(&vpif_obj.v4l2_dev);
+
+       kfree(vpif_obj.sd);
+       /* un-register device */
+       for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
+               /* Get the pointer to the channel object */
+               ch = vpif_obj.dev[i];
+               /* Unregister video device */
+               video_unregister_device(&ch->video_dev);
+       }
+       free_vpif_objs();
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int vpif_suspend(struct device *dev)
+{
+       struct common_obj *common;
+       struct channel_obj *ch;
+       int i;
+
+       for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
+               /* Get the pointer to the channel object */
+               ch = vpif_obj.dev[i];
+               common = &ch->common[VPIF_VIDEO_INDEX];
+
+               if (!vb2_start_streaming_called(&common->buffer_queue))
+                       continue;
+
+               mutex_lock(&common->lock);
+               /* Disable channel */
+               if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
+                       enable_channel2(0);
+                       channel2_intr_enable(0);
+               }
+               if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
+                       ycmux_mode == 2) {
+                       enable_channel3(0);
+                       channel3_intr_enable(0);
+               }
+               mutex_unlock(&common->lock);
+       }
+
+       return 0;
+}
+
+static int vpif_resume(struct device *dev)
+{
+
+       struct common_obj *common;
+       struct channel_obj *ch;
+       int i;
+
+       for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
+               /* Get the pointer to the channel object */
+               ch = vpif_obj.dev[i];
+               common = &ch->common[VPIF_VIDEO_INDEX];
+
+               if (!vb2_start_streaming_called(&common->buffer_queue))
+                       continue;
+
+               mutex_lock(&common->lock);
+               /* Enable channel */
+               if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
+                       enable_channel2(1);
+                       channel2_intr_enable(1);
+               }
+               if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
+                               ycmux_mode == 2) {
+                       enable_channel3(1);
+                       channel3_intr_enable(1);
+               }
+               mutex_unlock(&common->lock);
+       }
+
+       return 0;
+}
+
+#endif
+
+static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume);
+
+static __refdata struct platform_driver vpif_driver = {
+       .driver = {
+                       .name   = VPIF_DRIVER_NAME,
+                       .pm     = &vpif_pm_ops,
+       },
+       .probe  = vpif_probe,
+       .remove = vpif_remove,
+};
+
+module_platform_driver(vpif_driver);
diff --git a/drivers/media/platform/ti/davinci/vpif_display.h b/drivers/media/platform/ti/davinci/vpif_display.h
new file mode 100644 (file)
index 0000000..f98062e
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * VPIF display header file
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * 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 version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef VPIF_DISPLAY_H
+#define VPIF_DISPLAY_H
+
+/* Header files */
+#include <media/videobuf2-dma-contig.h>
+#include <media/v4l2-device.h>
+
+#include "vpif.h"
+
+/* Macros */
+#define VPIF_DISPLAY_VERSION   "0.0.2"
+
+#define VPIF_VALID_FIELD(field) \
+       (((V4L2_FIELD_ANY == field) || (V4L2_FIELD_NONE == field)) || \
+       (((V4L2_FIELD_INTERLACED == field) || (V4L2_FIELD_SEQ_TB == field)) || \
+       (V4L2_FIELD_SEQ_BT == field)))
+
+#define VPIF_DISPLAY_MAX_DEVICES       (2)
+#define VPIF_SLICED_BUF_SIZE           (256)
+#define VPIF_SLICED_MAX_SERVICES       (3)
+#define VPIF_VIDEO_INDEX               (0)
+#define VPIF_VBI_INDEX                 (1)
+#define VPIF_HBI_INDEX                 (2)
+
+/* Setting it to 1 as HBI/VBI support yet to be added , else 3*/
+#define VPIF_NUMOBJECTS        (1)
+
+/* Macros */
+#define ISALIGNED(a)    (0 == ((a) & 7))
+
+/* enumerated data types */
+/* Enumerated data type to give id to each device per channel */
+enum vpif_channel_id {
+       VPIF_CHANNEL2_VIDEO = 0,        /* Channel2 Video */
+       VPIF_CHANNEL3_VIDEO,            /* Channel3 Video */
+};
+
+/* structures */
+
+struct video_obj {
+       enum v4l2_field buf_field;
+       u32 latest_only;                /* indicate whether to return
+                                        * most recent displayed frame only */
+       v4l2_std_id stdid;              /* Currently selected or default
+                                        * standard */
+       struct v4l2_dv_timings dv_timings;
+};
+
+struct vpif_disp_buffer {
+       struct vb2_v4l2_buffer vb;
+       struct list_head list;
+};
+
+struct common_obj {
+       struct vpif_disp_buffer *cur_frm;       /* Pointer pointing to current
+                                                * vb2_buffer */
+       struct vpif_disp_buffer *next_frm;      /* Pointer pointing to next
+                                                * vb2_buffer */
+       struct v4l2_format fmt;                 /* Used to store the format */
+       struct vb2_queue buffer_queue;          /* Buffer queue used in
+                                                * video-buf */
+
+       struct list_head dma_queue;             /* Queue of filled frames */
+       spinlock_t irqlock;                     /* Used in video-buf */
+
+       /* channel specific parameters */
+       struct mutex lock;                      /* lock used to access this
+                                                * structure */
+       u32 ytop_off;                           /* offset of Y top from the
+                                                * starting of the buffer */
+       u32 ybtm_off;                           /* offset of Y bottom from the
+                                                * starting of the buffer */
+       u32 ctop_off;                           /* offset of C top from the
+                                                * starting of the buffer */
+       u32 cbtm_off;                           /* offset of C bottom from the
+                                                * starting of the buffer */
+       /* Function pointer to set the addresses */
+       void (*set_addr)(unsigned long, unsigned long,
+                               unsigned long, unsigned long);
+       u32 height;
+       u32 width;
+};
+
+struct channel_obj {
+       /* V4l2 specific parameters */
+       struct video_device video_dev;  /* Identifies video device for
+                                        * this channel */
+       u32 field_id;                   /* Indicates id of the field
+                                        * which is being displayed */
+       u8 initialized;                 /* flag to indicate whether
+                                        * encoder is initialized */
+       u32 output_idx;                 /* Current output index */
+       struct v4l2_subdev *sd;         /* Current output subdev(may be NULL) */
+
+       enum vpif_channel_id channel_id;/* Identifies channel */
+       struct vpif_params vpifparams;
+       struct common_obj common[VPIF_NUMOBJECTS];
+       struct video_obj video;
+};
+
+/* vpif device structure */
+struct vpif_device {
+       struct v4l2_device v4l2_dev;
+       struct channel_obj *dev[VPIF_DISPLAY_NUM_CHANNELS];
+       struct v4l2_subdev **sd;
+       struct vpif_display_config *config;
+};
+
+#endif                         /* VPIF_DISPLAY_H */
diff --git a/drivers/media/platform/ti/davinci/vpss.c b/drivers/media/platform/ti/davinci/vpss.c
new file mode 100644 (file)
index 0000000..d15b991
--- /dev/null
@@ -0,0 +1,529 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2009 Texas Instruments.
+ *
+ * common vpss system module platform driver for all video drivers.
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/err.h>
+
+#include <media/davinci/vpss.h>
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("VPSS Driver");
+MODULE_AUTHOR("Texas Instruments");
+
+/* DM644x defines */
+#define DM644X_SBL_PCR_VPSS            (4)
+
+#define DM355_VPSSBL_INTSEL            0x10
+#define DM355_VPSSBL_EVTSEL            0x14
+/* vpss BL register offsets */
+#define DM355_VPSSBL_CCDCMUX           0x1c
+/* vpss CLK register offsets */
+#define DM355_VPSSCLK_CLKCTRL          0x04
+/* masks and shifts */
+#define VPSS_HSSISEL_SHIFT             4
+/*
+ * VDINT0 - vpss_int0, VDINT1 - vpss_int1, H3A - vpss_int4,
+ * IPIPE_INT1_SDR - vpss_int5
+ */
+#define DM355_VPSSBL_INTSEL_DEFAULT    0xff83ff10
+/* VENCINT - vpss_int8 */
+#define DM355_VPSSBL_EVTSEL_DEFAULT    0x4
+
+#define DM365_ISP5_PCCR                                0x04
+#define DM365_ISP5_PCCR_BL_CLK_ENABLE          BIT(0)
+#define DM365_ISP5_PCCR_ISIF_CLK_ENABLE                BIT(1)
+#define DM365_ISP5_PCCR_H3A_CLK_ENABLE         BIT(2)
+#define DM365_ISP5_PCCR_RSZ_CLK_ENABLE         BIT(3)
+#define DM365_ISP5_PCCR_IPIPE_CLK_ENABLE       BIT(4)
+#define DM365_ISP5_PCCR_IPIPEIF_CLK_ENABLE     BIT(5)
+#define DM365_ISP5_PCCR_RSV                    BIT(6)
+
+#define DM365_ISP5_BCR                 0x08
+#define DM365_ISP5_BCR_ISIF_OUT_ENABLE BIT(1)
+
+#define DM365_ISP5_INTSEL1             0x10
+#define DM365_ISP5_INTSEL2             0x14
+#define DM365_ISP5_INTSEL3             0x18
+#define DM365_ISP5_CCDCMUX             0x20
+#define DM365_ISP5_PG_FRAME_SIZE       0x28
+#define DM365_VPBE_CLK_CTRL            0x00
+
+#define VPSS_CLK_CTRL                  0x01c40044
+#define VPSS_CLK_CTRL_VENCCLKEN                BIT(3)
+#define VPSS_CLK_CTRL_DACCLKEN         BIT(4)
+
+/*
+ * vpss interrupts. VDINT0 - vpss_int0, VDINT1 - vpss_int1,
+ * AF - vpss_int3
+ */
+#define DM365_ISP5_INTSEL1_DEFAULT     0x0b1f0100
+/* AEW - vpss_int6, RSZ_INT_DMA - vpss_int5 */
+#define DM365_ISP5_INTSEL2_DEFAULT     0x1f0a0f1f
+/* VENC - vpss_int8 */
+#define DM365_ISP5_INTSEL3_DEFAULT     0x00000015
+
+/* masks and shifts for DM365*/
+#define DM365_CCDC_PG_VD_POL_SHIFT     0
+#define DM365_CCDC_PG_HD_POL_SHIFT     1
+
+#define CCD_SRC_SEL_MASK               (BIT_MASK(5) | BIT_MASK(4))
+#define CCD_SRC_SEL_SHIFT              4
+
+/* Different SoC platforms supported by this driver */
+enum vpss_platform_type {
+       DM644X,
+       DM355,
+       DM365,
+};
+
+/*
+ * vpss operations. Depends on platform. Not all functions are available
+ * on all platforms. The api, first check if a function is available before
+ * invoking it. In the probe, the function ptrs are initialized based on
+ * vpss name. vpss name can be "dm355_vpss", "dm644x_vpss" etc.
+ */
+struct vpss_hw_ops {
+       /* enable clock */
+       int (*enable_clock)(enum vpss_clock_sel clock_sel, int en);
+       /* select input to ccdc */
+       void (*select_ccdc_source)(enum vpss_ccdc_source_sel src_sel);
+       /* clear wbl overflow bit */
+       int (*clear_wbl_overflow)(enum vpss_wbl_sel wbl_sel);
+       /* set sync polarity */
+       void (*set_sync_pol)(struct vpss_sync_pol);
+       /* set the PG_FRAME_SIZE register*/
+       void (*set_pg_frame_size)(struct vpss_pg_frame_size);
+       /* check and clear interrupt if occurred */
+       int (*dma_complete_interrupt)(void);
+};
+
+/* vpss configuration */
+struct vpss_oper_config {
+       __iomem void *vpss_regs_base0;
+       __iomem void *vpss_regs_base1;
+       __iomem void *vpss_regs_base2;
+       enum vpss_platform_type platform;
+       spinlock_t vpss_lock;
+       struct vpss_hw_ops hw_ops;
+};
+
+static struct vpss_oper_config oper_cfg;
+
+/* register access routines */
+static inline u32 bl_regr(u32 offset)
+{
+       return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
+}
+
+static inline void bl_regw(u32 val, u32 offset)
+{
+       __raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
+}
+
+static inline u32 vpss_regr(u32 offset)
+{
+       return __raw_readl(oper_cfg.vpss_regs_base1 + offset);
+}
+
+static inline void vpss_regw(u32 val, u32 offset)
+{
+       __raw_writel(val, oper_cfg.vpss_regs_base1 + offset);
+}
+
+/* For DM365 only */
+static inline u32 isp5_read(u32 offset)
+{
+       return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
+}
+
+/* For DM365 only */
+static inline void isp5_write(u32 val, u32 offset)
+{
+       __raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
+}
+
+static void dm365_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
+{
+       u32 temp = isp5_read(DM365_ISP5_CCDCMUX) & ~CCD_SRC_SEL_MASK;
+
+       /* if we are using pattern generator, enable it */
+       if (src_sel == VPSS_PGLPBK || src_sel == VPSS_CCDCPG)
+               temp |= 0x08;
+
+       temp |= (src_sel << CCD_SRC_SEL_SHIFT);
+       isp5_write(temp, DM365_ISP5_CCDCMUX);
+}
+
+static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
+{
+       bl_regw(src_sel << VPSS_HSSISEL_SHIFT, DM355_VPSSBL_CCDCMUX);
+}
+
+int vpss_dma_complete_interrupt(void)
+{
+       if (!oper_cfg.hw_ops.dma_complete_interrupt)
+               return 2;
+       return oper_cfg.hw_ops.dma_complete_interrupt();
+}
+EXPORT_SYMBOL(vpss_dma_complete_interrupt);
+
+int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
+{
+       if (!oper_cfg.hw_ops.select_ccdc_source)
+               return -EINVAL;
+
+       oper_cfg.hw_ops.select_ccdc_source(src_sel);
+       return 0;
+}
+EXPORT_SYMBOL(vpss_select_ccdc_source);
+
+static int dm644x_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
+{
+       u32 mask = 1, val;
+
+       if (wbl_sel < VPSS_PCR_AEW_WBL_0 ||
+           wbl_sel > VPSS_PCR_CCDC_WBL_O)
+               return -EINVAL;
+
+       /* writing a 0 clear the overflow */
+       mask = ~(mask << wbl_sel);
+       val = bl_regr(DM644X_SBL_PCR_VPSS) & mask;
+       bl_regw(val, DM644X_SBL_PCR_VPSS);
+       return 0;
+}
+
+void vpss_set_sync_pol(struct vpss_sync_pol sync)
+{
+       if (!oper_cfg.hw_ops.set_sync_pol)
+               return;
+
+       oper_cfg.hw_ops.set_sync_pol(sync);
+}
+EXPORT_SYMBOL(vpss_set_sync_pol);
+
+int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
+{
+       if (!oper_cfg.hw_ops.clear_wbl_overflow)
+               return -EINVAL;
+
+       return oper_cfg.hw_ops.clear_wbl_overflow(wbl_sel);
+}
+EXPORT_SYMBOL(vpss_clear_wbl_overflow);
+
+/*
+ *  dm355_enable_clock - Enable VPSS Clock
+ *  @clock_sel: Clock to be enabled/disabled
+ *  @en: enable/disable flag
+ *
+ *  This is called to enable or disable a vpss clock
+ */
+static int dm355_enable_clock(enum vpss_clock_sel clock_sel, int en)
+{
+       unsigned long flags;
+       u32 utemp, mask = 0x1, shift = 0;
+
+       switch (clock_sel) {
+       case VPSS_VPBE_CLOCK:
+               /* nothing since lsb */
+               break;
+       case VPSS_VENC_CLOCK_SEL:
+               shift = 2;
+               break;
+       case VPSS_CFALD_CLOCK:
+               shift = 3;
+               break;
+       case VPSS_H3A_CLOCK:
+               shift = 4;
+               break;
+       case VPSS_IPIPE_CLOCK:
+               shift = 5;
+               break;
+       case VPSS_CCDC_CLOCK:
+               shift = 6;
+               break;
+       default:
+               printk(KERN_ERR "dm355_enable_clock: Invalid selector: %d\n",
+                      clock_sel);
+               return -EINVAL;
+       }
+
+       spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
+       utemp = vpss_regr(DM355_VPSSCLK_CLKCTRL);
+       if (!en)
+               utemp &= ~(mask << shift);
+       else
+               utemp |= (mask << shift);
+
+       vpss_regw(utemp, DM355_VPSSCLK_CLKCTRL);
+       spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
+       return 0;
+}
+
+static int dm365_enable_clock(enum vpss_clock_sel clock_sel, int en)
+{
+       unsigned long flags;
+       u32 utemp, mask = 0x1, shift = 0, offset = DM365_ISP5_PCCR;
+       u32 (*read)(u32 offset) = isp5_read;
+       void(*write)(u32 val, u32 offset) = isp5_write;
+
+       switch (clock_sel) {
+       case VPSS_BL_CLOCK:
+               break;
+       case VPSS_CCDC_CLOCK:
+               shift = 1;
+               break;
+       case VPSS_H3A_CLOCK:
+               shift = 2;
+               break;
+       case VPSS_RSZ_CLOCK:
+               shift = 3;
+               break;
+       case VPSS_IPIPE_CLOCK:
+               shift = 4;
+               break;
+       case VPSS_IPIPEIF_CLOCK:
+               shift = 5;
+               break;
+       case VPSS_PCLK_INTERNAL:
+               shift = 6;
+               break;
+       case VPSS_PSYNC_CLOCK_SEL:
+               shift = 7;
+               break;
+       case VPSS_VPBE_CLOCK:
+               read = vpss_regr;
+               write = vpss_regw;
+               offset = DM365_VPBE_CLK_CTRL;
+               break;
+       case VPSS_VENC_CLOCK_SEL:
+               shift = 2;
+               read = vpss_regr;
+               write = vpss_regw;
+               offset = DM365_VPBE_CLK_CTRL;
+               break;
+       case VPSS_LDC_CLOCK:
+               shift = 3;
+               read = vpss_regr;
+               write = vpss_regw;
+               offset = DM365_VPBE_CLK_CTRL;
+               break;
+       case VPSS_FDIF_CLOCK:
+               shift = 4;
+               read = vpss_regr;
+               write = vpss_regw;
+               offset = DM365_VPBE_CLK_CTRL;
+               break;
+       case VPSS_OSD_CLOCK_SEL:
+               shift = 6;
+               read = vpss_regr;
+               write = vpss_regw;
+               offset = DM365_VPBE_CLK_CTRL;
+               break;
+       case VPSS_LDC_CLOCK_SEL:
+               shift = 7;
+               read = vpss_regr;
+               write = vpss_regw;
+               offset = DM365_VPBE_CLK_CTRL;
+               break;
+       default:
+               printk(KERN_ERR "dm365_enable_clock: Invalid selector: %d\n",
+                      clock_sel);
+               return -1;
+       }
+
+       spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
+       utemp = read(offset);
+       if (!en) {
+               mask = ~mask;
+               utemp &= (mask << shift);
+       } else
+               utemp |= (mask << shift);
+
+       write(utemp, offset);
+       spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
+
+       return 0;
+}
+
+int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en)
+{
+       if (!oper_cfg.hw_ops.enable_clock)
+               return -EINVAL;
+
+       return oper_cfg.hw_ops.enable_clock(clock_sel, en);
+}
+EXPORT_SYMBOL(vpss_enable_clock);
+
+void dm365_vpss_set_sync_pol(struct vpss_sync_pol sync)
+{
+       int val = 0;
+       val = isp5_read(DM365_ISP5_CCDCMUX);
+
+       val |= (sync.ccdpg_hdpol << DM365_CCDC_PG_HD_POL_SHIFT);
+       val |= (sync.ccdpg_vdpol << DM365_CCDC_PG_VD_POL_SHIFT);
+
+       isp5_write(val, DM365_ISP5_CCDCMUX);
+}
+EXPORT_SYMBOL(dm365_vpss_set_sync_pol);
+
+void vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size)
+{
+       if (!oper_cfg.hw_ops.set_pg_frame_size)
+               return;
+
+       oper_cfg.hw_ops.set_pg_frame_size(frame_size);
+}
+EXPORT_SYMBOL(vpss_set_pg_frame_size);
+
+void dm365_vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size)
+{
+       int current_reg = ((frame_size.hlpfr >> 1) - 1) << 16;
+
+       current_reg |= (frame_size.pplen - 1);
+       isp5_write(current_reg, DM365_ISP5_PG_FRAME_SIZE);
+}
+EXPORT_SYMBOL(dm365_vpss_set_pg_frame_size);
+
+static int vpss_probe(struct platform_device *pdev)
+{
+       char *platform_name;
+
+       if (!pdev->dev.platform_data) {
+               dev_err(&pdev->dev, "no platform data\n");
+               return -ENOENT;
+       }
+
+       platform_name = pdev->dev.platform_data;
+       if (!strcmp(platform_name, "dm355_vpss"))
+               oper_cfg.platform = DM355;
+       else if (!strcmp(platform_name, "dm365_vpss"))
+               oper_cfg.platform = DM365;
+       else if (!strcmp(platform_name, "dm644x_vpss"))
+               oper_cfg.platform = DM644X;
+       else {
+               dev_err(&pdev->dev, "vpss driver not supported on this platform\n");
+               return -ENODEV;
+       }
+
+       dev_info(&pdev->dev, "%s vpss probed\n", platform_name);
+       oper_cfg.vpss_regs_base0 = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(oper_cfg.vpss_regs_base0))
+               return PTR_ERR(oper_cfg.vpss_regs_base0);
+
+       if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) {
+               oper_cfg.vpss_regs_base1 = devm_platform_ioremap_resource(pdev, 1);
+               if (IS_ERR(oper_cfg.vpss_regs_base1))
+                       return PTR_ERR(oper_cfg.vpss_regs_base1);
+       }
+
+       if (oper_cfg.platform == DM355) {
+               oper_cfg.hw_ops.enable_clock = dm355_enable_clock;
+               oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source;
+               /* Setup vpss interrupts */
+               bl_regw(DM355_VPSSBL_INTSEL_DEFAULT, DM355_VPSSBL_INTSEL);
+               bl_regw(DM355_VPSSBL_EVTSEL_DEFAULT, DM355_VPSSBL_EVTSEL);
+       } else if (oper_cfg.platform == DM365) {
+               oper_cfg.hw_ops.enable_clock = dm365_enable_clock;
+               oper_cfg.hw_ops.select_ccdc_source = dm365_select_ccdc_source;
+               /* Setup vpss interrupts */
+               isp5_write((isp5_read(DM365_ISP5_PCCR) |
+                                     DM365_ISP5_PCCR_BL_CLK_ENABLE |
+                                     DM365_ISP5_PCCR_ISIF_CLK_ENABLE |
+                                     DM365_ISP5_PCCR_H3A_CLK_ENABLE |
+                                     DM365_ISP5_PCCR_RSZ_CLK_ENABLE |
+                                     DM365_ISP5_PCCR_IPIPE_CLK_ENABLE |
+                                     DM365_ISP5_PCCR_IPIPEIF_CLK_ENABLE |
+                                     DM365_ISP5_PCCR_RSV), DM365_ISP5_PCCR);
+               isp5_write((isp5_read(DM365_ISP5_BCR) |
+                           DM365_ISP5_BCR_ISIF_OUT_ENABLE), DM365_ISP5_BCR);
+               isp5_write(DM365_ISP5_INTSEL1_DEFAULT, DM365_ISP5_INTSEL1);
+               isp5_write(DM365_ISP5_INTSEL2_DEFAULT, DM365_ISP5_INTSEL2);
+               isp5_write(DM365_ISP5_INTSEL3_DEFAULT, DM365_ISP5_INTSEL3);
+       } else
+               oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow;
+
+       pm_runtime_enable(&pdev->dev);
+
+       pm_runtime_get(&pdev->dev);
+
+       spin_lock_init(&oper_cfg.vpss_lock);
+       dev_info(&pdev->dev, "%s vpss probe success\n", platform_name);
+
+       return 0;
+}
+
+static int vpss_remove(struct platform_device *pdev)
+{
+       pm_runtime_disable(&pdev->dev);
+       return 0;
+}
+
+static int vpss_suspend(struct device *dev)
+{
+       pm_runtime_put(dev);
+       return 0;
+}
+
+static int vpss_resume(struct device *dev)
+{
+       pm_runtime_get(dev);
+       return 0;
+}
+
+static const struct dev_pm_ops vpss_pm_ops = {
+       .suspend = vpss_suspend,
+       .resume = vpss_resume,
+};
+
+static struct platform_driver vpss_driver = {
+       .driver = {
+               .name   = "vpss",
+               .pm = &vpss_pm_ops,
+       },
+       .remove = vpss_remove,
+       .probe = vpss_probe,
+};
+
+static void vpss_exit(void)
+{
+       platform_driver_unregister(&vpss_driver);
+       iounmap(oper_cfg.vpss_regs_base2);
+       release_mem_region(VPSS_CLK_CTRL, 4);
+}
+
+static int __init vpss_init(void)
+{
+       int ret;
+
+       if (!request_mem_region(VPSS_CLK_CTRL, 4, "vpss_clock_control"))
+               return -EBUSY;
+
+       oper_cfg.vpss_regs_base2 = ioremap(VPSS_CLK_CTRL, 4);
+       if (unlikely(!oper_cfg.vpss_regs_base2)) {
+               ret = -ENOMEM;
+               goto err_ioremap;
+       }
+
+       writel(VPSS_CLK_CTRL_VENCCLKEN |
+              VPSS_CLK_CTRL_DACCLKEN, oper_cfg.vpss_regs_base2);
+
+       ret = platform_driver_register(&vpss_driver);
+       if (ret)
+               goto err_pd_register;
+
+       return 0;
+
+err_pd_register:
+       iounmap(oper_cfg.vpss_regs_base2);
+err_ioremap:
+       release_mem_region(VPSS_CLK_CTRL, 4);
+       return ret;
+}
+subsys_initcall(vpss_init);
+module_exit(vpss_exit);