summaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux-omap-psp-2.6.32/cam/0031-BeagleXM-Cam-Add-support-for-MT9V113-VGA-Sensor.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes/linux/linux-omap-psp-2.6.32/cam/0031-BeagleXM-Cam-Add-support-for-MT9V113-VGA-Sensor.patch')
-rw-r--r--recipes/linux/linux-omap-psp-2.6.32/cam/0031-BeagleXM-Cam-Add-support-for-MT9V113-VGA-Sensor.patch2441
1 files changed, 2441 insertions, 0 deletions
diff --git a/recipes/linux/linux-omap-psp-2.6.32/cam/0031-BeagleXM-Cam-Add-support-for-MT9V113-VGA-Sensor.patch b/recipes/linux/linux-omap-psp-2.6.32/cam/0031-BeagleXM-Cam-Add-support-for-MT9V113-VGA-Sensor.patch
new file mode 100644
index 0000000000..ccec95ce3e
--- /dev/null
+++ b/recipes/linux/linux-omap-psp-2.6.32/cam/0031-BeagleXM-Cam-Add-support-for-MT9V113-VGA-Sensor.patch
@@ -0,0 +1,2441 @@
+From eed14c95dbe46b0e34b489ad5e0452654e0f1661 Mon Sep 17 00:00:00 2001
+From: Vaibhav Hiremath <hvaibhav@ti.com>
+Date: Wed, 7 Jul 2010 11:55:43 +0530
+Subject: [PATCH 31/71] BeagleXM:Cam: Add support for MT9V113 VGA Sensor
+
+This patch replaces the MT9T111 to MT9V113 sensor.
+---
+ arch/arm/mach-omap2/board-omap3beagle-camera.c | 132 ++-
+ arch/arm/mach-omap2/board-omap3beagle.c | 32 +-
+ drivers/media/video/Kconfig | 10 +
+ drivers/media/video/Makefile | 1 +
+ drivers/media/video/mt9v113.c | 1522 ++++++++++++++++++++++++
+ drivers/media/video/mt9v113_regs.h | 294 +++++
+ include/media/mt9v113.h | 83 ++
+ include/media/v4l2-int-device.h | 27 +
+ 8 files changed, 2023 insertions(+), 78 deletions(-)
+ create mode 100644 drivers/media/video/mt9v113.c
+ create mode 100644 drivers/media/video/mt9v113_regs.h
+ create mode 100644 include/media/mt9v113.h
+
+diff --git a/arch/arm/mach-omap2/board-omap3beagle-camera.c b/arch/arm/mach-omap2/board-omap3beagle-camera.c
+index 8faa437..6c06265 100644
+--- a/arch/arm/mach-omap2/board-omap3beagle-camera.c
++++ b/arch/arm/mach-omap2/board-omap3beagle-camera.c
+@@ -37,7 +37,7 @@
+ #include <plat/control.h>
+
+ #include <media/v4l2-int-device.h>
+-#include <media/mt9t111.h>
++#include <media/mt9v113.h>
+
+ /* Include V4L2 ISP-Camera driver related header file */
+ #include <../drivers/media/video/omap34xxcam.h>
+@@ -50,99 +50,99 @@
+
+ #define CAM_USE_XCLKA 0
+
+-#define ISP_MT9T111_MCLK 216000000
++#define ISP_MT9V113_MCLK 216000000
+
+ #define LEOPARD_RESET_GPIO 98
+
+-static struct regulator *beagle_mt9t111_1_8v1;
+-static struct regulator *beagle_mt9t111_1_8v2;
++static struct regulator *beagle_mt9v113_1_8v1;
++static struct regulator *beagle_mt9v113_1_8v2;
+
+-#if defined(CONFIG_VIDEO_MT9T111) || defined(CONFIG_VIDEO_MT9T111_MODULE)
++#if defined(CONFIG_VIDEO_MT9V113) || defined(CONFIG_VIDEO_MT9V113_MODULE)
+
+ /* Arbitrary memory handling limit */
+-#define MT9T111_BIGGEST_FRAME_BYTE_SIZE PAGE_ALIGN(2048 * 1536 * 4)
++#define MT9V113_BIGGEST_FRAME_BYTE_SIZE PAGE_ALIGN(2048 * 1536 * 4)
+
+-static struct isp_interface_config mt9t111_if_config = {
+- .ccdc_par_ser = ISP_PARLL,
++static struct isp_interface_config mt9v113_if_config = {
++ .ccdc_par_ser = ISP_PARLL,
+ .dataline_shift = 0x0,
+ .hsvs_syncdetect = ISPCTRL_SYNC_DETECT_VSRISE,
+ .strobe = 0x0,
+ .prestrobe = 0x0,
+ .shutter = 0x0,
+- .cam_mclk = ISP_MT9T111_MCLK,
++ .cam_mclk = ISP_MT9V113_MCLK,
+ .wenlog = ISPCCDC_CFG_WENLOG_AND,
+ .wait_hs_vs = 2,
+ .u.par.par_bridge = 0x1,
+ .u.par.par_clk_pol = 0x0,
+ };
+
+-static struct v4l2_ifparm mt9t111_ifparm_s = {
++static struct v4l2_ifparm mt9v113_ifparm_s = {
+ #if 1
+- .if_type = V4L2_IF_TYPE_RAW,
++ .if_type = V4L2_IF_TYPE_RAW,
+ .u = {
+- .raw = {
++ .raw = {
+ .frame_start_on_rising_vs = 1,
+ .bt_sync_correct = 0,
+ .swap = 0,
+ .latch_clk_inv = 0,
+ .nobt_hs_inv = 0, /* active high */
+ .nobt_vs_inv = 0, /* active high */
+- .clock_min = MT9T111_CLK_MIN,
+- .clock_max = MT9T111_CLK_MAX,
++ .clock_min = MT9V113_CLK_MIN,
++ .clock_max = MT9V113_CLK_MAX,
+ },
+ },
+-#else
+- .if_type = V4L2_IF_TYPE_YCbCr,
++#else
++ .if_type = V4L2_IF_TYPE_YCbCr,
+ .u = {
+- .ycbcr = {
++ .ycbcr = {
+ .frame_start_on_rising_vs = 1,
+ .bt_sync_correct = 0,
+ .swap = 0,
+ .latch_clk_inv = 0,
+ .nobt_hs_inv = 0, /* active high */
+ .nobt_vs_inv = 0, /* active high */
+- .clock_min = MT9T111_CLK_MIN,
+- .clock_max = MT9T111_CLK_MAX,
++ .clock_min = MT9V113_CLK_MIN,
++ .clock_max = MT9V113_CLK_MAX,
+ },
+ },
+ #endif
+ };
+
+ /**
+- * @brief mt9t111_ifparm - Returns the mt9t111 interface parameters
++ * @brief mt9v113_ifparm - Returns the mt9v113 interface parameters
+ *
+ * @param p - pointer to v4l2_ifparm structure
+ *
+ * @return result of operation - 0 is success
+ */
+-static int mt9t111_ifparm(struct v4l2_ifparm *p)
++static int mt9v113_ifparm(struct v4l2_ifparm *p)
+ {
+ if (p == NULL)
+ return -EINVAL;
+
+- *p = mt9t111_ifparm_s;
++ *p = mt9v113_ifparm_s;
+ return 0;
+ }
+
+ #if defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
+-static struct omap34xxcam_hw_config mt9t111_hwc = {
++static struct omap34xxcam_hw_config mt9v113_hwc = {
+ .dev_index = 0,
+ .dev_minor = 0,
+ .dev_type = OMAP34XXCAM_SLAVE_SENSOR,
+ .u.sensor.sensor_isp = 1,
+- .u.sensor.capture_mem = MT9T111_BIGGEST_FRAME_BYTE_SIZE * 2,
++ .u.sensor.capture_mem = MT9V113_BIGGEST_FRAME_BYTE_SIZE * 2,
+ .u.sensor.ival_default = { 1, 10 },
+ };
+ #endif
+
+ /**
+- * @brief mt9t111_set_prv_data - Returns mt9t111 omap34xx driver private data
++ * @brief mt9v113_set_prv_data - Returns mt9v113 omap34xx driver private data
+ *
+ * @param priv - pointer to omap34xxcam_hw_config structure
+ *
+ * @return result of operation - 0 is success
+ */
+-static int mt9t111_set_prv_data(void *priv)
++static int mt9v113_set_prv_data(void *priv)
+ {
+ #if defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
+ struct omap34xxcam_hw_config *hwc = priv;
+@@ -150,10 +150,10 @@ static int mt9t111_set_prv_data(void *priv)
+ if (priv == NULL)
+ return -EINVAL;
+
+- hwc->u.sensor = mt9t111_hwc.u.sensor;
+- hwc->dev_index = mt9t111_hwc.dev_index;
+- hwc->dev_minor = mt9t111_hwc.dev_minor;
+- hwc->dev_type = mt9t111_hwc.dev_type;
++ hwc->u.sensor = mt9v113_hwc.u.sensor;
++ hwc->dev_index = mt9v113_hwc.dev_index;
++ hwc->dev_minor = mt9v113_hwc.dev_minor;
++ hwc->dev_type = mt9v113_hwc.dev_type;
+ return 0;
+ #else
+ return -EINVAL;
+@@ -161,13 +161,13 @@ static int mt9t111_set_prv_data(void *priv)
+ }
+
+ /**
+- * @brief mt9t111_power_set - Power-on or power-off TVP5146 device
++ * @brief mt9v113_power_set - Power-on or power-off TVP5146 device
+ *
+ * @param power - enum, Power on/off, resume/standby
+ *
+ * @return result of operation - 0 is success
+ */
+-static int mt9t111_power_set(struct v4l2_int_device *s, enum v4l2_power power)
++static int mt9v113_power_set(struct v4l2_int_device *s, enum v4l2_power power)
+ {
+ struct omap34xxcam_videodev *vdev = s->u.slave->master->priv;
+
+@@ -176,32 +176,32 @@ static int mt9t111_power_set(struct v4l2_int_device *s, enum v4l2_power power)
+ case V4L2_POWER_STANDBY:
+ isp_set_xclk(vdev->cam->isp, 0, CAM_USE_XCLKA);
+
+- if (regulator_is_enabled(beagle_mt9t111_1_8v1))
+- regulator_disable(beagle_mt9t111_1_8v1);
+- if (regulator_is_enabled(beagle_mt9t111_1_8v2))
+- regulator_disable(beagle_mt9t111_1_8v2);
++ if (regulator_is_enabled(beagle_mt9v113_1_8v1))
++ regulator_disable(beagle_mt9v113_1_8v1);
++ if (regulator_is_enabled(beagle_mt9v113_1_8v2))
++ regulator_disable(beagle_mt9v113_1_8v2);
+ break;
+
+ case V4L2_POWER_ON:
+ #if defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
+- isp_configure_interface(vdev->cam->isp, &mt9t111_if_config);
++ isp_configure_interface(vdev->cam->isp, &mt9v113_if_config);
+ #endif
+
+ /* Set RESET_BAR to 0 */
+ gpio_set_value(LEOPARD_RESET_GPIO, 0);
+
+ /* turn on VDD */
+- regulator_enable(beagle_mt9t111_1_8v1);
++ regulator_enable(beagle_mt9v113_1_8v1);
+
+ mdelay(1);
+
+ /* turn on VDD_IO */
+- regulator_enable(beagle_mt9t111_1_8v2);
++ regulator_enable(beagle_mt9v113_1_8v2);
+
+ mdelay(50);
+
+ /* Enable EXTCLK */
+- isp_set_xclk(vdev->cam->isp, MT9T111_CLK_MIN, CAM_USE_XCLKA);
++ isp_set_xclk(vdev->cam->isp, MT9V113_CLK_MIN, CAM_USE_XCLKA);
+
+ /*
+ * Wait at least 70 CLK cycles (w/EXTCLK = 6MHz, or CLK_MIN):
+@@ -229,44 +229,48 @@ static int mt9t111_power_set(struct v4l2_int_device *s, enum v4l2_power power)
+ return 0;
+ }
+
+-struct mt9t111_platform_data mt9t111_pdata = {
++struct mt9v113_platform_data mt9v113_pdata = {
+ .master = "omap34xxcam",
+- .power_set = mt9t111_power_set,
+- .priv_data_set = mt9t111_set_prv_data,
+- .ifparm = mt9t111_ifparm,
++ .power_set = mt9v113_power_set,
++ .priv_data_set = mt9v113_set_prv_data,
++ .ifparm = mt9v113_ifparm,
+ /* Some interface dependent params */
+ .clk_polarity = 0, /* data clocked out on falling edge */
+ .hs_polarity = 1, /* 0 - Active low, 1- Active high */
+ .vs_polarity = 1, /* 0 - Active low, 1- Active high */
+ };
+
+-#endif /* #ifdef CONFIG_VIDEO_MT9T111 */
++#endif /* #ifdef CONFIG_VIDEO_MT9V113 */
+
+
+ static int beagle_cam_probe(struct platform_device *pdev)
+ {
+ int err;
+
+- beagle_mt9t111_1_8v1 = regulator_get(&pdev->dev, "vaux3_1");
+- if (IS_ERR(beagle_mt9t111_1_8v1)) {
++ printk("%s:%d\n", __func__, __LINE__);
++ beagle_mt9v113_1_8v1 = regulator_get(&pdev->dev, "vaux3_1");
++ if (IS_ERR(beagle_mt9v113_1_8v1)) {
+ dev_err(&pdev->dev, "vaux3_1 regulator missing\n");
+- return PTR_ERR(beagle_mt9t111_1_8v1);
++ return PTR_ERR(beagle_mt9v113_1_8v1);
+ }
+- beagle_mt9t111_1_8v2 = regulator_get(&pdev->dev, "vaux4_1");
+- if (IS_ERR(beagle_mt9t111_1_8v2)) {
++ printk("%s:%d\n", __func__, __LINE__);
++ beagle_mt9v113_1_8v2 = regulator_get(&pdev->dev, "vaux4_1");
++ if (IS_ERR(beagle_mt9v113_1_8v2)) {
+ dev_err(&pdev->dev, "vaux4_1 regulator missing\n");
+- regulator_put(beagle_mt9t111_1_8v1);
+- return PTR_ERR(beagle_mt9t111_1_8v2);
++ regulator_put(beagle_mt9v113_1_8v1);
++ return PTR_ERR(beagle_mt9v113_1_8v2);
+ }
+
++ printk("%s:%d\n", __func__, __LINE__);
+ if (gpio_request(LEOPARD_RESET_GPIO, "cam_rst") != 0) {
+ dev_err(&pdev->dev, "Could not request GPIO %d",
+ LEOPARD_RESET_GPIO);
+- regulator_put(beagle_mt9t111_1_8v2);
+- regulator_put(beagle_mt9t111_1_8v1);
++ regulator_put(beagle_mt9v113_1_8v2);
++ regulator_put(beagle_mt9v113_1_8v1);
+ return -ENODEV;
+ }
+
++ printk("%s:%d\n", __func__, __LINE__);
+ /* set to output mode, default value 0 */
+ gpio_direction_output(LEOPARD_RESET_GPIO, 0);
+
+@@ -277,12 +281,13 @@ static int beagle_cam_probe(struct platform_device *pdev)
+
+ static int beagle_cam_remove(struct platform_device *pdev)
+ {
+- if (regulator_is_enabled(beagle_mt9t111_1_8v1))
+- regulator_disable(beagle_mt9t111_1_8v1);
+- regulator_put(beagle_mt9t111_1_8v1);
+- if (regulator_is_enabled(beagle_mt9t111_1_8v2))
+- regulator_disable(beagle_mt9t111_1_8v2);
+- regulator_put(beagle_mt9t111_1_8v2);
++ printk("%s:%d\n", __func__, __LINE__);
++ if (regulator_is_enabled(beagle_mt9v113_1_8v1))
++ regulator_disable(beagle_mt9v113_1_8v1);
++ regulator_put(beagle_mt9v113_1_8v1);
++ if (regulator_is_enabled(beagle_mt9v113_1_8v2))
++ regulator_disable(beagle_mt9v113_1_8v2);
++ regulator_put(beagle_mt9v113_1_8v2);
+
+ gpio_free(LEOPARD_RESET_GPIO);
+
+@@ -355,9 +360,12 @@ static struct platform_driver beagle_cam_driver = {
+ */
+ int __init omap3beaglelmb_init(void)
+ {
++ printk("%s:%d\n", __func__, __LINE__);
+ if (cpu_is_omap3630()) {
+- platform_driver_register(&beagle_cam_driver);
++ printk("%s:%d\n", __func__, __LINE__);
++ platform_driver_register(&beagle_cam_driver);
+ }
+- return 0;
++ printk("%s:%d\n", __func__, __LINE__);
++ return 0;
+ }
+ late_initcall(omap3beaglelmb_init);
+diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
+index af9b818..d4b0b0a 100644
+--- a/arch/arm/mach-omap2/board-omap3beagle.c
++++ b/arch/arm/mach-omap2/board-omap3beagle.c
+@@ -71,10 +71,10 @@ static struct omap_opp * _omap35x_l3_rate_table = NULL;
+ static struct omap_opp * _omap37x_l3_rate_table = NULL;
+ #endif /* CONFIG_PM */
+
+-#if defined(CONFIG_VIDEO_MT9T111) || defined(CONFIG_VIDEO_MT9T111_MODULE)
++#if defined(CONFIG_VIDEO_MT9V113) || defined(CONFIG_VIDEO_MT9V113_MODULE)
+ #include <media/v4l2-int-device.h>
+-#include <media/mt9t111.h>
+-extern struct mt9t111_platform_data mt9t111_pdata;
++#include <media/mt9v113.h>
++extern struct mt9v113_platform_data mt9v113_pdata;
+ #endif
+
+ #define GPMC_CS0_BASE 0x60
+@@ -159,7 +159,7 @@ static void __init omap3beagle_ks8851_init(void)
+ printk(KERN_ERR "could not obtain gpio for KS8851_IRQ\n");
+ return;
+ }
+-
++
+ spi_register_board_info(omap3beagle_zippy2_spi_board_info,
+ ARRAY_SIZE(omap3beagle_zippy2_spi_board_info));
+ }
+@@ -369,9 +369,9 @@ static int beagle_twl_gpio_setup(struct device *dev,
+ */
+
+ if (cpu_is_omap3630()) {
+- /* Power on DVI, Serial and PWR led */
++ /* Power on DVI, Serial and PWR led */
+ gpio_request(gpio + 1, "nDVI_PWR_EN");
+- gpio_direction_output(gpio + 1, 0);
++ gpio_direction_output(gpio + 1, 0);
+
+ /* Power on camera interface */
+ gpio_request(gpio + 2, "CAM_EN");
+@@ -560,7 +560,7 @@ static struct i2c_board_info __initdata beagle_i2c1_boardinfo[] = {
+ },
+ };
+
+-
++
+ #if defined(CONFIG_EEPROM_AT24) || defined(CONFIG_EEPROM_AT24_MODULE)
+ #include <linux/i2c/at24.h>
+
+@@ -594,10 +594,10 @@ static struct i2c_board_info __initdata beagle_zippy_i2c2_boardinfo[] = {};
+ #endif
+
+ static struct i2c_board_info __initdata beagle_i2c2_boardinfo[] = {
+-#if defined(CONFIG_VIDEO_MT9T111) || defined(CONFIG_VIDEO_MT9T111_MODULE)
++#if defined(CONFIG_VIDEO_MT9V113) || defined(CONFIG_VIDEO_MT9V113_MODULE)
+ {
+- I2C_BOARD_INFO("mt9t111", MT9T111_I2C_ADDR),
+- .platform_data = &mt9t111_pdata,
++ I2C_BOARD_INFO("mt9v113", MT9V113_I2C_ADDR),
++ .platform_data = &mt9v113_pdata,
+ },
+ #endif
+ };
+@@ -606,7 +606,7 @@ static int __init omap3_beagle_i2c_init(void)
+ {
+ omap_register_i2c_bus(1, 2600, beagle_i2c1_boardinfo,
+ ARRAY_SIZE(beagle_i2c1_boardinfo));
+- if(!strcmp(expansionboard_name, "zippy") || !strcmp(expansionboard_name, "zippy2"))
++ if(!strcmp(expansionboard_name, "zippy") || !strcmp(expansionboard_name, "zippy2"))
+ {
+ printk(KERN_INFO "Beagle expansionboard: registering i2c2 bus for zippy/zippy2\n");
+ omap_register_i2c_bus(2, 400, beagle_zippy_i2c2_boardinfo,
+@@ -681,7 +681,7 @@ static struct spi_board_info beaglefpga_mcspi_board_info[] = {
+ .modalias = "spidev",
+ .max_speed_hz = 48000000, //48 Mbps
+ .bus_num = 4,
+- .chip_select = 0,
++ .chip_select = 0,
+ .mode = SPI_MODE_1,
+ },
+ };
+@@ -830,7 +830,7 @@ static void __init omap3_beagle_init(void)
+ /* REVISIT leave DVI powered down until it's needed ... */
+ gpio_direction_output(170, true);
+
+- if(!strcmp(expansionboard_name, "zippy"))
++ if(!strcmp(expansionboard_name, "zippy"))
+ {
+ printk(KERN_INFO "Beagle expansionboard: initializing enc28j60\n");
+ omap3beagle_enc28j60_init();
+@@ -838,8 +838,8 @@ static void __init omap3_beagle_init(void)
+ mmc[1].gpio_wp = 141;
+ mmc[1].gpio_cd = 162;
+ }
+-
+- if(!strcmp(expansionboard_name, "zippy2"))
++
++ if(!strcmp(expansionboard_name, "zippy2"))
+ {
+ printk(KERN_INFO "Beagle expansionboard: initializing ks_8851\n");
+ omap3beagle_ks8851_init();
+@@ -880,7 +880,7 @@ static void __init omap3_beagle_init(void)
+ }
+
+ if(!strcmp(expansionboard_name, "beaglefpga"))
+- {
++ {
+ printk(KERN_INFO "Beagle expansionboard: Using McSPI for SPI\n");
+ beaglefpga_init_spi();
+ }
+diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
+index f67ed46..c14d758 100644
+--- a/drivers/media/video/Kconfig
++++ b/drivers/media/video/Kconfig
+@@ -329,6 +329,16 @@ config VIDEO_MT9V011
+ mt0v011 1.3 Mpixel camera. It currently only works with the
+ em28xx driver.
+
++config VIDEO_MT9V113
++ tristate "Aptina MT9V113 VGA CMOS IMAGE SENSOR"
++ depends on VIDEO_V4L2 && I2C
++ ---help---
++ This is a Video4Linux2 sensor-level driver for the Aptina MT9V113
++ image sensor.
++
++ To compile this driver as a module, choose M here: the
++ module will be called mt9v113.
++
+ config VIDEO_TCM825X
+ tristate "TCM825x camera sensor support"
+ depends on I2C && VIDEO_V4L2
+diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
+index 31688bf..763c157 100644
+--- a/drivers/media/video/Makefile
++++ b/drivers/media/video/Makefile
+@@ -75,6 +75,7 @@ obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
+ obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
+ obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
+ obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
++obj-$(CONFIG_VIDEO_MT9V113) += mt9v113.o
+
+ obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
+ obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
+diff --git a/drivers/media/video/mt9v113.c b/drivers/media/video/mt9v113.c
+new file mode 100644
+index 0000000..755a88a
+--- /dev/null
++++ b/drivers/media/video/mt9v113.c
+@@ -0,0 +1,1522 @@
++/*
++ * drivers/media/video/mt9v113.c
++ *
++ * Based on TI TVP5146/47 decoder driver
++ *
++ *
++ * This package is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++#include <linux/i2c.h>
++#include <linux/delay.h>
++#include <linux/videodev2.h>
++#include <media/v4l2-int-device.h>
++#include <media/mt9v113.h>
++#include <mach/hardware.h>
++#include <linux/io.h>
++
++#include "mt9v113_regs.h"
++
++/* Module Name */
++#define MT9V113_MODULE_NAME "mt9v113"
++
++/* Private macros for TVP */
++#define I2C_RETRY_COUNT (5)
++#define LOCK_RETRY_COUNT (5)
++#define LOCK_RETRY_DELAY (200)
++
++/* Debug functions */
++static int debug = 1;
++module_param(debug, bool, 0644);
++MODULE_PARM_DESC(debug, "Debug level (0-1)");
++
++#define dump_reg(client, reg, val) \
++ do { \
++ val = mt9v113_read_reg(client, reg); \
++ v4l_info(client, "Reg(0x%.2X): 0x%.2X\n", reg, val); \
++ } while (0)
++
++/**
++ * enum mt9v113_std - enum for supported standards
++ */
++enum mt9v113_std {
++ MT9V113_STD_VGA = 0,
++ MT9V113_STD_QVGA,
++ MT9V113_STD_INVALID
++};
++
++/**
++ * enum mt9v113_state - enum for different decoder states
++ */
++enum mt9v113_state {
++ STATE_NOT_DETECTED,
++ STATE_DETECTED
++};
++
++/**
++ * struct mt9v113_std_info - Structure to store standard informations
++ * @width: Line width in pixels
++ * @height:Number of active lines
++ * @video_std: Value to write in REG_VIDEO_STD register
++ * @standard: v4l2 standard structure information
++ */
++struct mt9v113_std_info {
++ unsigned long width;
++ unsigned long height;
++ u8 video_std;
++ struct v4l2_standard standard;
++};
++
++/**
++ * struct mt9v113_decoded - decoder object
++ * @v4l2_int_device: Slave handle
++ * @pdata: Board specific
++ * @client: I2C client data
++ * @id: Entry from I2C table
++ * @ver: Chip version
++ * @state: decoder state - detected or not-detected
++ * @pix: Current pixel format
++ * @num_fmts: Number of formats
++ * @fmt_list: Format list
++ * @current_std: Current standard
++ * @num_stds: Number of standards
++ * @std_list: Standards list
++ * @route: input and output routing at chip level
++ */
++struct mt9v113_decoder {
++ struct v4l2_int_device *v4l2_int_device;
++ const struct mt9v113_platform_data *pdata;
++ struct i2c_client *client;
++
++ struct i2c_device_id *id;
++
++ int ver;
++ enum mt9v113_state state;
++
++ struct v4l2_pix_format pix;
++ int num_fmts;
++ const struct v4l2_fmtdesc *fmt_list;
++
++ enum mt9v113_std current_std;
++ int num_stds;
++ struct mt9v113_std_info *std_list;
++
++ struct v4l2_routing route;
++};
++
++/* MT9V113 register set for VGA mode */
++static struct mt9v113_reg mt9v113_vga_reg[] = {
++ {TOK_WRITE, 0x098C, 0x2739},
++ {TOK_WRITE, 0x0990, 0x0000},
++ {TOK_WRITE, 0x098C, 0x273B},
++ {TOK_WRITE, 0x0990, 0x027F},
++ {TOK_WRITE, 0x098C, 0x273D},
++ {TOK_WRITE, 0x0990, 0x0000},
++ {TOK_WRITE, 0x098C, 0x273F},
++ {TOK_WRITE, 0x0990, 0x01DF},
++ {TOK_WRITE, 0x098C, 0x2703},
++ {TOK_WRITE, 0x0990, 0x0280},
++ {TOK_WRITE, 0x098C, 0x2705},
++ {TOK_WRITE, 0x0990, 0x01E0},
++ {TOK_WRITE, 0x098C, 0xA103},
++ {TOK_WRITE, 0x0990, 0x0005},
++ {TOK_DELAY, 0, 100},
++ {TOK_TERM, 0, 0},
++};
++
++/* MT9V113 default register values */
++static struct mt9v113_reg mt9v113_reg_list[] = {
++ {TOK_WRITE, 0x0018, 0x4028},
++ {TOK_DELAY, 0, 100},
++ {TOK_WRITE, 0x001A, 0x0011},
++ {TOK_WRITE, 0x001A, 0x0010},
++ {TOK_WRITE, 0x0018, 0x4028},
++ {TOK_DELAY, 0, 100},
++ {TOK_WRITE, 0x098C, 0x02F0},
++ {TOK_WRITE, 0x0990, 0x0000},
++ {TOK_WRITE, 0x098C, 0x02F2},
++ {TOK_WRITE, 0x0990, 0x0210},
++ {TOK_WRITE, 0x098C, 0x02F4},
++ {TOK_WRITE, 0x0990, 0x001A},
++ {TOK_WRITE, 0x098C, 0x2145},
++ {TOK_WRITE, 0x0990, 0x02F4},
++ {TOK_WRITE, 0x098C, 0xA134},
++ {TOK_WRITE, 0x0990, 0x0001},
++ {TOK_WRITE, 0x31E0, 0x0001},
++ {TOK_WRITE, 0x001A, 0x0210},
++ {TOK_WRITE, 0x001E, 0x0777},
++ {TOK_WRITE, 0x0016, 0x42DF},
++ {TOK_WRITE, 0x0014, 0x2145},
++ {TOK_WRITE, 0x0014, 0x2145},
++ {TOK_WRITE, 0x0010, 0x0431},
++ {TOK_WRITE, 0x0012, 0x0000},
++ {TOK_WRITE, 0x0014, 0x244B},
++ {TOK_WRITE, 0x0014, 0x304B},
++ {TOK_DELAY, 0, 100},
++ {TOK_WRITE, 0x0014, 0xB04A},
++ {TOK_WRITE, 0x098C, 0xAB1F},
++ {TOK_WRITE, 0x0990, 0x00C7},
++ {TOK_WRITE, 0x098C, 0xAB31},
++ {TOK_WRITE, 0x0990, 0x001E},
++ {TOK_WRITE, 0x098C, 0x274F},
++ {TOK_WRITE, 0x0990, 0x0004},
++ {TOK_WRITE, 0x098C, 0x2741},
++ {TOK_WRITE, 0x0990, 0x0004},
++ {TOK_WRITE, 0x098C, 0xAB20},
++ {TOK_WRITE, 0x0990, 0x0054},
++ {TOK_WRITE, 0x098C, 0xAB21},
++ {TOK_WRITE, 0x0990, 0x0046},
++ {TOK_WRITE, 0x098C, 0xAB22},
++ {TOK_WRITE, 0x0990, 0x0002},
++ {TOK_WRITE, 0x098C, 0xAB24},
++ {TOK_WRITE, 0x0990, 0x0005},
++ {TOK_WRITE, 0x098C, 0x2B28},
++ {TOK_WRITE, 0x0990, 0x170C},
++ {TOK_WRITE, 0x098C, 0x2B2A},
++ {TOK_WRITE, 0x0990, 0x3E80},
++ {TOK_WRITE, 0x3210, 0x09A8},
++ {TOK_WRITE, 0x098C, 0x2306},
++ {TOK_WRITE, 0x0990, 0x0315},
++ {TOK_WRITE, 0x098C, 0x2308},
++ {TOK_WRITE, 0x0990, 0xFDDC},
++ {TOK_WRITE, 0x098C, 0x230A},
++ {TOK_WRITE, 0x0990, 0x003A},
++ {TOK_WRITE, 0x098C, 0x230C},
++ {TOK_WRITE, 0x0990, 0xFF58},
++ {TOK_WRITE, 0x098C, 0x230E},
++ {TOK_WRITE, 0x0990, 0x02B7},
++ {TOK_WRITE, 0x098C, 0x2310},
++ {TOK_WRITE, 0x0990, 0xFF31},
++ {TOK_WRITE, 0x098C, 0x2312},
++ {TOK_WRITE, 0x0990, 0xFF4C},
++ {TOK_WRITE, 0x098C, 0x2314},
++ {TOK_WRITE, 0x0990, 0xFE4C},
++ {TOK_WRITE, 0x098C, 0x2316},
++ {TOK_WRITE, 0x0990, 0x039E},
++ {TOK_WRITE, 0x098C, 0x2318},
++ {TOK_WRITE, 0x0990, 0x001C},
++ {TOK_WRITE, 0x098C, 0x231A},
++ {TOK_WRITE, 0x0990, 0x0039},
++ {TOK_WRITE, 0x098C, 0x231C},
++ {TOK_WRITE, 0x0990, 0x007F},
++ {TOK_WRITE, 0x098C, 0x231E},
++ {TOK_WRITE, 0x0990, 0xFF77},
++ {TOK_WRITE, 0x098C, 0x2320},
++ {TOK_WRITE, 0x0990, 0x000A},
++ {TOK_WRITE, 0x098C, 0x2322},
++ {TOK_WRITE, 0x0990, 0x0020},
++ {TOK_WRITE, 0x098C, 0x2324},
++ {TOK_WRITE, 0x0990, 0x001B},
++ {TOK_WRITE, 0x098C, 0x2326},
++ {TOK_WRITE, 0x0990, 0xFFC6},
++ {TOK_WRITE, 0x098C, 0x2328},
++ {TOK_WRITE, 0x0990, 0x0086},
++ {TOK_WRITE, 0x098C, 0x232A},
++ {TOK_WRITE, 0x0990, 0x00B5},
++ {TOK_WRITE, 0x098C, 0x232C},
++ {TOK_WRITE, 0x0990, 0xFEC3},
++ {TOK_WRITE, 0x098C, 0x232E},
++ {TOK_WRITE, 0x0990, 0x0001},
++ {TOK_WRITE, 0x098C, 0x2330},
++ {TOK_WRITE, 0x0990, 0xFFEF},
++ {TOK_WRITE, 0x098C, 0xA348},
++ {TOK_WRITE, 0x0990, 0x0008},
++ {TOK_WRITE, 0x098C, 0xA349},
++ {TOK_WRITE, 0x0990, 0x0002},
++ {TOK_WRITE, 0x098C, 0xA34A},
++ {TOK_WRITE, 0x0990, 0x0090},
++ {TOK_WRITE, 0x098C, 0xA34B},
++ {TOK_WRITE, 0x0990, 0x00FF},
++ {TOK_WRITE, 0x098C, 0xA34C},
++ {TOK_WRITE, 0x0990, 0x0075},
++ {TOK_WRITE, 0x098C, 0xA34D},
++ {TOK_WRITE, 0x0990, 0x00EF},
++ {TOK_WRITE, 0x098C, 0xA351},
++ {TOK_WRITE, 0x0990, 0x0000},
++ {TOK_WRITE, 0x098C, 0xA352},
++ {TOK_WRITE, 0x0990, 0x007F},
++ {TOK_WRITE, 0x098C, 0xA354},
++ {TOK_WRITE, 0x0990, 0x0043},
++ {TOK_WRITE, 0x098C, 0xA355},
++ {TOK_WRITE, 0x0990, 0x0001},
++ {TOK_WRITE, 0x098C, 0xA35D},
++ {TOK_WRITE, 0x0990, 0x0078},
++ {TOK_WRITE, 0x098C, 0xA35E},
++ {TOK_WRITE, 0x0990, 0x0086},
++ {TOK_WRITE, 0x098C, 0xA35F},
++ {TOK_WRITE, 0x0990, 0x007E},
++ {TOK_WRITE, 0x098C, 0xA360},
++ {TOK_WRITE, 0x0990, 0x0082},
++ {TOK_WRITE, 0x098C, 0x2361},
++ {TOK_WRITE, 0x0990, 0x0040},
++ {TOK_WRITE, 0x098C, 0xA363},
++ {TOK_WRITE, 0x0990, 0x00D2},
++ {TOK_WRITE, 0x098C, 0xA364},
++ {TOK_WRITE, 0x0990, 0x00F6},
++ {TOK_WRITE, 0x098C, 0xA302},
++ {TOK_WRITE, 0x0990, 0x0000},
++ {TOK_WRITE, 0x098C, 0xA303},
++ {TOK_WRITE, 0x0990, 0x00EF},
++ {TOK_WRITE, 0x098C, 0xAB20},
++ {TOK_WRITE, 0x0990, 0x0024},
++ {TOK_WRITE, 0x098C, 0xA103},
++ {TOK_WRITE, 0x0990, 0x0006},
++ {TOK_DELAY, 0, 100},
++ {TOK_WRITE, 0x098C, 0xA103},
++ {TOK_WRITE, 0x0990, 0x0005},
++ {TOK_DELAY, 0, 100},
++ {TOK_WRITE, 0x098C, 0x222D},
++ {TOK_WRITE, 0x0990, 0x0088},
++ {TOK_WRITE, 0x098C, 0xA408},
++ {TOK_WRITE, 0x0990, 0x0020},
++ {TOK_WRITE, 0x098C, 0xA409},
++ {TOK_WRITE, 0x0990, 0x0023},
++ {TOK_WRITE, 0x098C, 0xA40A},
++ {TOK_WRITE, 0x0990, 0x0027},
++ {TOK_WRITE, 0x098C, 0xA40B},
++ {TOK_WRITE, 0x0990, 0x002A},
++ {TOK_WRITE, 0x098C, 0x2411},
++ {TOK_WRITE, 0x0990, 0x0088},
++ {TOK_WRITE, 0x098C, 0x2413},
++ {TOK_WRITE, 0x0990, 0x00A4},
++ {TOK_WRITE, 0x098C, 0x2415},
++ {TOK_WRITE, 0x0990, 0x0088},
++ {TOK_WRITE, 0x098C, 0x2417},
++ {TOK_WRITE, 0x0990, 0x00A4},
++ {TOK_WRITE, 0x098C, 0xA404},
++ {TOK_WRITE, 0x0990, 0x0010},
++ {TOK_WRITE, 0x098C, 0xA40D},
++ {TOK_WRITE, 0x0990, 0x0002},
++ {TOK_WRITE, 0x098C, 0xA40E},
++ {TOK_WRITE, 0x0990, 0x0003},
++ {TOK_WRITE, 0x098C, 0xA103},
++ {TOK_WRITE, 0x0990, 0x0006},
++ {TOK_DELAY, 0, 100},
++ /* test pattern all white*/
++ /* {TOK_WRITE, 0x098C, 0xA766},
++ {TOK_WRITE, 0x0990, 0x0001},
++ */
++ {TOK_WRITE, 0x098C, 0xA103},
++ {TOK_WRITE, 0x0990, 0x0005},
++ {TOK_DELAY, 0, 100},
++ {TOK_TERM, 0, 0},
++};
++
++/* List of image formats supported by mt9v113
++ * Currently we are using 8 bit mode only, but can be
++ * extended to 10/20 bit mode.
++ */
++static const struct v4l2_fmtdesc mt9v113_fmt_list[] = {
++ {
++ .index = 0,
++ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
++ .flags = 0,
++ .description = "8-bit UYVY 4:2:2 Format",
++ .pixelformat = V4L2_PIX_FMT_UYVY,
++ },
++};
++
++/*
++ * Supported standards -
++ *
++ * Currently supports two standards only, need to add support for rest of the
++ * modes, like SECAM, etc...
++ */
++static struct mt9v113_std_info mt9v113_std_list[] = {
++ /* Standard: STD_NTSC_MJ */
++ [MT9V113_STD_VGA] = {
++ .width = VGA_NUM_ACTIVE_PIXELS,
++ .height = VGA_NUM_ACTIVE_LINES,
++ .video_std = MT9V113_IMAGE_STD_VGA,
++ .standard = {
++ .index = 0,
++ .id = MT9V113_IMAGE_STD_VGA,
++ .name = "VGA",
++ .frameperiod = {1001, 30000},
++ .framelines = 480
++ },
++ /* Standard: STD_PAL_BDGHIN */
++ },
++ [MT9V113_STD_QVGA] = {
++ .width = QVGA_NUM_ACTIVE_PIXELS,
++ .height = QVGA_NUM_ACTIVE_LINES,
++ .video_std = MT9V113_IMAGE_STD_QVGA,
++ .standard = {
++ .index = 1,
++ .id = MT9V113_IMAGE_STD_QVGA,
++ .name = "QVGA",
++ .frameperiod = {1001, 30000},
++ .framelines = 320
++ },
++ },
++ /* Standard: need to add for additional standard */
++};
++/*
++ * Control structure for Auto Gain
++ * This is temporary data, will get replaced once
++ * v4l2_ctrl_query_fill supports it.
++ */
++static const struct v4l2_queryctrl mt9v113_autogain_ctrl = {
++ .id = V4L2_CID_AUTOGAIN,
++ .name = "Gain, Automatic",
++ .type = V4L2_CTRL_TYPE_BOOLEAN,
++ .minimum = 0,
++ .maximum = 1,
++ .step = 1,
++ .default_value = 1,
++};
++
++static int mt9v113_read_reg(struct i2c_client *client, unsigned short reg)
++{
++ int err = 0;
++ struct i2c_msg msg[1];
++ unsigned char data[2];
++ unsigned short val = 0;
++
++ if (!client->adapter) {
++ err = -ENODEV;
++ return err;
++ }else {
++ // TODO: addr should be set up where else
++ msg->addr = MT9V113_I2C_ADDR;//client->addr;
++ msg->flags = 0;
++ msg->len = I2C_TWO_BYTE_TRANSFER;
++ msg->buf = data;
++ data[0] = (reg & I2C_TXRX_DATA_MASK_UPPER) >>
++ I2C_TXRX_DATA_SHIFT;
++ data[1] = (reg & I2C_TXRX_DATA_MASK);
++ err = i2c_transfer(client->adapter, msg, 1);
++ if (err >= 0) {
++ msg->flags = I2C_M_RD;
++ msg->len = I2C_TWO_BYTE_TRANSFER; /* 2 byte read */
++ err = i2c_transfer(client->adapter, msg, 1);
++ if (err >= 0) {
++ val = ((data[0] & I2C_TXRX_DATA_MASK)
++ << I2C_TXRX_DATA_SHIFT)
++ | (data[1] & I2C_TXRX_DATA_MASK);
++ }
++ }
++ }
++ return (int)(0x0000ffff & val);
++}
++
++
++
++static int mt9v113_write_reg(struct i2c_client *client, unsigned short reg, unsigned short val)
++{
++ int err = 0;
++ int trycnt = 0;
++
++ struct i2c_msg msg[1];
++ unsigned char data[4];
++ err = -1;
++
++ v4l_dbg(1, debug, client,
++ "mt9v113_write_reg reg=0x%x, val=0x%x\n",
++ reg,val);
++
++ while ((err < 0) && (trycnt < I2C_RETRY_COUNT)) {
++ trycnt++;
++ if (!client->adapter) {
++ err = -ENODEV;
++ } else {
++ // TODO: addr should be set up where else
++ msg->addr = MT9V113_I2C_ADDR;//client->addr;
++ msg->flags = 0;
++ msg->len = I2C_FOUR_BYTE_TRANSFER;
++ msg->buf = data;
++ data[0] = (reg & I2C_TXRX_DATA_MASK_UPPER) >>
++ I2C_TXRX_DATA_SHIFT;
++ data[1] = (reg & I2C_TXRX_DATA_MASK);
++ data[2] = (val & I2C_TXRX_DATA_MASK_UPPER) >>
++ I2C_TXRX_DATA_SHIFT;
++ data[3] = (val & I2C_TXRX_DATA_MASK);
++ err = i2c_transfer(client->adapter, msg, 1);
++ }
++ }
++ if (err < 0) {
++ printk(KERN_INFO "\n I2C write failed");
++ }
++ return err;
++}
++
++/* configure mux, for DM355 EVM only */
++#ifndef CONFIG_MACH_DM355_LEOPARD
++static int mt9v113_en_mux(struct i2c_client *client)
++{
++ int err = 0;
++ int trycnt = 0;
++ /* unsigned short readval = 0;*/
++
++ struct i2c_msg msg[1];
++ unsigned char data[4];
++ err = -1;
++ printk(KERN_INFO
++ "\n entering mt9v113_en_mux \n");
++
++ while ((err < 0) && (trycnt < 5)) {
++ trycnt++;
++ if (!client->adapter) {
++ err = -ENODEV;
++ } else {
++ msg->addr = 0x25;
++ msg->flags = 0;
++ msg->len = I2C_TWO_BYTE_TRANSFER;
++ msg->buf = data;
++ data[0] = (unsigned char)(0x08 & I2C_TXRX_DATA_MASK);
++ data[1] = (unsigned char)(0x80 & I2C_TXRX_DATA_MASK);
++
++ err = i2c_transfer(client->adapter, msg, 1);
++ if (err < 0) {
++ printk(KERN_INFO
++ "\n ERROR in ECP register write\n");
++ }
++ }
++ }
++ if (err < 0) {
++ printk(KERN_INFO "\n I2C write failed");
++ }
++ return err;
++}
++#endif
++
++/*
++ * mt9v113_write_regs : Initializes a list of registers
++ * if token is TOK_TERM, then entire write operation terminates
++ * if token is TOK_DELAY, then a delay of 'val' msec is introduced
++ * if token is TOK_SKIP, then the register write is skipped
++ * if token is TOK_WRITE, then the register write is performed
++ *
++ * reglist - list of registers to be written
++ * Returns zero if successful, or non-zero otherwise.
++ */
++static int mt9v113_write_regs(struct i2c_client *client,
++ const struct mt9v113_reg reglist[])
++{
++ int err;
++ const struct mt9v113_reg *next = reglist;
++
++ for (; next->token != TOK_TERM; next++) {
++ if (next->token == TOK_DELAY) {
++ msleep(next->val);
++ continue;
++ }
++
++ if (next->token == TOK_SKIP)
++ continue;
++
++ err = mt9v113_write_reg(client, next->reg, next->val);
++ if (err < 0) {
++ v4l_err(client, "Write failed. Err[%d]\n", err);
++ return err;
++ }
++ }
++ return 0;
++}
++
++/*
++ * mt9v113_get_current_std:
++ * Returns the current standard
++ */
++static enum mt9v113_std mt9v113_get_current_std(struct mt9v113_decoder
++ *decoder)
++{
++ return MT9V113_STD_VGA;
++}
++
++/*
++ * Configure the mt9v113 with the current register settings
++ * Returns zero if successful, or non-zero otherwise.
++ */
++static int mt9v113_configure(struct mt9v113_decoder *decoder)
++{
++ int err;
++
++ /* common register initialization */
++ err =
++ mt9v113_write_regs(decoder->client, mt9v113_reg_list);
++ if (err)
++ return err;
++
++// if (debug)
++// mt9v113_reg_dump(decoder);
++
++ return 0;
++}
++
++/*
++ * Configure the MT9V113 to VGA mode
++ * Returns zero if successful, or non-zero otherwise.
++ */
++static int mt9v113_vga_mode(struct mt9v113_decoder *decoder)
++{
++ int err;
++
++ err =
++ mt9v113_write_regs(decoder->client, mt9v113_vga_reg);
++ if (err)
++ return err;
++
++ return 0;
++}
++
++
++/*
++ * Detect if an mt9v113 is present, and if so which revision.
++ * A device is considered to be detected if the chip ID (LSB and MSB)
++ * registers match the expected values.
++ * Any value of the rom version register is accepted.
++ * Returns ENODEV error number if no device is detected, or zero
++ * if a device is detected.
++ */
++static int mt9v113_detect(struct mt9v113_decoder *decoder)
++{
++ unsigned short val=0;
++
++#ifndef CONFIG_MACH_DM355_LEOPARD
++// mt9v113_en_mux(decoder->client);
++#endif
++
++ val = mt9v113_read_reg(decoder->client, REG_CHIP_ID);
++
++ v4l_dbg(1, debug, decoder->client,
++ "chip id detected 0x%x\n",
++ val);
++
++ if (MT9V113_CHIP_ID != val) {
++ /* We didn't read the values we expected, so this must not be
++ * MT9V113.
++ */
++ v4l_err(decoder->client,
++ "chip id mismatch read 0x%x, expecting 0x%x\n", val, MT9V113_CHIP_ID);
++ return -ENODEV;
++ }
++
++ decoder->ver = val;
++ decoder->state = STATE_DETECTED;
++
++ v4l_info(decoder->client,
++ "%s found at 0x%x (%s)\n", decoder->client->name,
++ decoder->client->addr << 1,
++ decoder->client->adapter->name);
++
++ return 0;
++}
++
++/*
++ * Following are decoder interface functions implemented by
++ * mt9v113 decoder driver.
++ */
++
++/**
++ * ioctl_querystd - V4L2 decoder interface handler for VIDIOC_QUERYSTD ioctl
++ * @s: pointer to standard V4L2 device structure
++ * @std_id: standard V4L2 std_id ioctl enum
++ *
++ * Returns the current standard detected by mt9v113. If no active input is
++ * detected, returns -EINVAL
++ */
++static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++ enum mt9v113_std current_std;
++
++ if (std_id == NULL)
++ return -EINVAL;
++
++ /* get the current standard */
++ current_std = mt9v113_get_current_std(decoder);
++ if (current_std == MT9V113_IMAGE_STD_INVALID)
++ return -EINVAL;
++
++ decoder->current_std = current_std;
++ *std_id = decoder->std_list[current_std].standard.id;
++
++ v4l_dbg(1, debug, decoder->client, "Current STD: %s",
++ decoder->std_list[current_std].standard.name);
++ return 0;
++}
++
++/**
++ * ioctl_s_std - V4L2 decoder interface handler for VIDIOC_S_STD ioctl
++ * @s: pointer to standard V4L2 device structure
++ * @std_id: standard V4L2 v4l2_std_id ioctl enum
++ *
++ * If std_id is supported, sets the requested standard. Otherwise, returns
++ * -EINVAL
++ */
++static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++ int err, i;
++
++ if (std_id == NULL)
++ return -EINVAL;
++
++ for (i = 0; i < decoder->num_stds; i++)
++ if (*std_id & decoder->std_list[i].standard.id)
++ break;
++
++ if ((i == decoder->num_stds) || (i == MT9V113_STD_INVALID))
++ return -EINVAL;
++
++ err = mt9v113_write_reg(decoder->client, REG_VIDEO_STD,
++ decoder->std_list[i].video_std);
++ if (err)
++ return err;
++
++ decoder->current_std = i;
++ mt9v113_reg_list[REG_VIDEO_STD].val = decoder->std_list[i].video_std;
++
++ v4l_dbg(1, debug, decoder->client, "Standard set to: %s",
++ decoder->std_list[i].standard.name);
++ return 0;
++}
++
++/**
++ * ioctl_s_routing - V4L2 decoder interface handler for VIDIOC_S_INPUT ioctl
++ * @s: pointer to standard V4L2 device structure
++ * @index: number of the input
++ *
++ * If index is valid, selects the requested input. Otherwise, returns -EINVAL if
++ * the input is not supported or there is no active signal present in the
++ * selected input.
++ */
++static int ioctl_s_routing(struct v4l2_int_device *s,
++ struct v4l2_routing *route)
++{
++ return 0;
++}
++
++/**
++ * ioctl_queryctrl - V4L2 decoder interface handler for VIDIOC_QUERYCTRL ioctl
++ * @s: pointer to standard V4L2 device structure
++ * @qctrl: standard V4L2 v4l2_queryctrl structure
++ *
++ * If the requested control is supported, returns the control information.
++ * Otherwise, returns -EINVAL if the control is not supported.
++ */
++static int
++ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++ int err = -EINVAL;
++
++ if (qctrl == NULL)
++ return err;
++
++ switch (qctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ /* Brightness supported is same as standard one (0-255),
++ * so make use of standard API provided.
++ */
++ err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
++ break;
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ /* Saturation and Contrast supported is -
++ * Contrast: 0 - 255 (Default - 128)
++ * Saturation: 0 - 255 (Default - 128)
++ */
++ err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
++ break;
++ case V4L2_CID_HUE:
++ /* Hue Supported is -
++ * Hue - -180 - +180 (Default - 0, Step - +180)
++ */
++ err = v4l2_ctrl_query_fill(qctrl, -180, 180, 180, 0);
++ break;
++ case V4L2_CID_AUTOGAIN:
++ /* Autogain is either 0 or 1*/
++ memcpy(qctrl, &mt9v113_autogain_ctrl,
++ sizeof(struct v4l2_queryctrl));
++ err = 0;
++ break;
++ default:
++ v4l_err(decoder->client,
++ "invalid control id %d\n", qctrl->id);
++ return err;
++ }
++
++ v4l_dbg(1, debug, decoder->client,
++ "Query Control: %s : Min - %d, Max - %d, Def - %d",
++ qctrl->name,
++ qctrl->minimum,
++ qctrl->maximum,
++ qctrl->default_value);
++
++ return err;
++}
++
++/**
++ * ioctl_g_ctrl - V4L2 decoder interface handler for VIDIOC_G_CTRL ioctl
++ * @s: pointer to standard V4L2 device structure
++ * @ctrl: pointer to v4l2_control structure
++ *
++ * If the requested control is supported, returns the control's current
++ * value from the decoder. Otherwise, returns -EINVAL if the control is not
++ * supported.
++ */
++static int
++ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++
++ if (ctrl == NULL)
++ return -EINVAL;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ ctrl->value = mt9v113_reg_list[REG_BRIGHTNESS].val;
++ break;
++ case V4L2_CID_CONTRAST:
++ ctrl->value = mt9v113_reg_list[REG_CONTRAST].val;
++ break;
++ case V4L2_CID_SATURATION:
++ ctrl->value = mt9v113_reg_list[REG_SATURATION].val;
++ break;
++ case V4L2_CID_HUE:
++ ctrl->value = mt9v113_reg_list[REG_HUE].val;
++ if (ctrl->value == 0x7F)
++ ctrl->value = 180;
++ else if (ctrl->value == 0x80)
++ ctrl->value = -180;
++ else
++ ctrl->value = 0;
++
++ break;
++ case V4L2_CID_AUTOGAIN:
++ ctrl->value = mt9v113_reg_list[REG_AFE_GAIN_CTRL].val;
++ if ((ctrl->value & 0x3) == 3)
++ ctrl->value = 1;
++ else
++ ctrl->value = 0;
++
++ break;
++ default:
++ v4l_err(decoder->client,
++ "invalid control id %d\n", ctrl->id);
++ return -EINVAL;
++ }
++
++ v4l_dbg(1, debug, decoder->client,
++ "Get Control: ID - %d - %d",
++ ctrl->id, ctrl->value);
++ return 0;
++}
++
++/**
++ * ioctl_s_ctrl - V4L2 decoder interface handler for VIDIOC_S_CTRL ioctl
++ * @s: pointer to standard V4L2 device structure
++ * @ctrl: pointer to v4l2_control structure
++ *
++ * If the requested control is supported, sets the control's current
++ * value in HW. Otherwise, returns -EINVAL if the control is not supported.
++ */
++static int
++ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++ int err = -EINVAL, value;
++
++ if (ctrl == NULL)
++ return err;
++
++ value = (__s32) ctrl->value;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ if (ctrl->value < 0 || ctrl->value > 255) {
++ v4l_err(decoder->client,
++ "invalid brightness setting %d\n",
++ ctrl->value);
++ return -ERANGE;
++ }
++ err = mt9v113_write_reg(decoder->client, REG_BRIGHTNESS,
++ value);
++ if (err)
++ return err;
++ mt9v113_reg_list[REG_BRIGHTNESS].val = value;
++ break;
++ case V4L2_CID_CONTRAST:
++ if (ctrl->value < 0 || ctrl->value > 255) {
++ v4l_err(decoder->client,
++ "invalid contrast setting %d\n",
++ ctrl->value);
++ return -ERANGE;
++ }
++ err = mt9v113_write_reg(decoder->client, REG_CONTRAST,
++ value);
++ if (err)
++ return err;
++ mt9v113_reg_list[REG_CONTRAST].val = value;
++ break;
++ case V4L2_CID_SATURATION:
++ if (ctrl->value < 0 || ctrl->value > 255) {
++ v4l_err(decoder->client,
++ "invalid saturation setting %d\n",
++ ctrl->value);
++ return -ERANGE;
++ }
++ err = mt9v113_write_reg(decoder->client, REG_SATURATION,
++ value);
++ if (err)
++ return err;
++ mt9v113_reg_list[REG_SATURATION].val = value;
++ break;
++ case V4L2_CID_HUE:
++ if (value == 180)
++ value = 0x7F;
++ else if (value == -180)
++ value = 0x80;
++ else if (value == 0)
++ value = 0;
++ else {
++ v4l_err(decoder->client,
++ "invalid hue setting %d\n",
++ ctrl->value);
++ return -ERANGE;
++ }
++ err = mt9v113_write_reg(decoder->client, REG_HUE,
++ value);
++ if (err)
++ return err;
++ mt9v113_reg_list[REG_HUE].val = value;
++ break;
++ case V4L2_CID_AUTOGAIN:
++ if (value == 1)
++ value = 0x0F;
++ else if (value == 0)
++ value = 0x0C;
++ else {
++ v4l_err(decoder->client,
++ "invalid auto gain setting %d\n",
++ ctrl->value);
++ return -ERANGE;
++ }
++ err = mt9v113_write_reg(decoder->client, REG_AFE_GAIN_CTRL,
++ value);
++ if (err)
++ return err;
++ mt9v113_reg_list[REG_AFE_GAIN_CTRL].val = value;
++ break;
++ default:
++ v4l_err(decoder->client,
++ "invalid control id %d\n", ctrl->id);
++ return err;
++ }
++
++ v4l_dbg(1, debug, decoder->client,
++ "Set Control: ID - %d - %d",
++ ctrl->id, ctrl->value);
++
++ return err;
++}
++
++/**
++ * ioctl_enum_fmt_cap - Implement the CAPTURE buffer VIDIOC_ENUM_FMT ioctl
++ * @s: pointer to standard V4L2 device structure
++ * @fmt: standard V4L2 VIDIOC_ENUM_FMT ioctl structure
++ *
++ * Implement the VIDIOC_ENUM_FMT ioctl to enumerate supported formats
++ */
++static int
++ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++ int index;
++
++ if (fmt == NULL)
++ return -EINVAL;
++
++ index = fmt->index;
++ if ((index >= decoder->num_fmts) || (index < 0))
++ return -EINVAL; /* Index out of bound */
++
++ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL; /* only capture is supported */
++
++ memcpy(fmt, &decoder->fmt_list[index],
++ sizeof(struct v4l2_fmtdesc));
++
++ v4l_dbg(1, debug, decoder->client,
++ "Current FMT: index - %d (%s)",
++ decoder->fmt_list[index].index,
++ decoder->fmt_list[index].description);
++ return 0;
++}
++
++/**
++ * ioctl_try_fmt_cap - Implement the CAPTURE buffer VIDIOC_TRY_FMT ioctl
++ * @s: pointer to standard V4L2 device structure
++ * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure
++ *
++ * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This
++ * ioctl is used to negotiate the image capture size and pixel format
++ * without actually making it take effect.
++ */
++static int
++ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++ int ifmt;
++ struct v4l2_pix_format *pix;
++ enum mt9v113_std current_std;
++
++ if (f == NULL)
++ return -EINVAL;
++
++ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++
++ pix = &f->fmt.pix;
++
++ /* Calculate height and width based on current standard */
++ current_std = mt9v113_get_current_std(decoder);
++ if (current_std == MT9V113_STD_INVALID)
++ return -EINVAL;
++
++ decoder->current_std = current_std;
++ pix->width = decoder->std_list[current_std].width;
++ pix->height = decoder->std_list[current_std].height;
++
++ for (ifmt = 0; ifmt < decoder->num_fmts; ifmt++) {
++ if (pix->pixelformat ==
++ decoder->fmt_list[ifmt].pixelformat)
++ break;
++ }
++ if (ifmt == decoder->num_fmts)
++ ifmt = 0; /* None of the format matched, select default */
++ pix->pixelformat = decoder->fmt_list[ifmt].pixelformat;
++
++ pix->field = V4L2_FIELD_NONE;
++ pix->bytesperline = pix->width * 2;
++ pix->sizeimage = pix->bytesperline * pix->height;
++ pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ pix->priv = 0;
++
++ v4l_dbg(1, debug, decoder->client,
++ "Try FMT: pixelformat - %s, bytesperline - %d"
++ "Width - %d, Height - %d",
++ decoder->fmt_list[ifmt].description, pix->bytesperline,
++ pix->width, pix->height);
++ return 0;
++}
++
++/**
++ * ioctl_s_fmt_cap - V4L2 decoder interface handler for VIDIOC_S_FMT ioctl
++ * @s: pointer to standard V4L2 device structure
++ * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure
++ *
++ * If the requested format is supported, configures the HW to use that
++ * format, returns error code if format not supported or HW can't be
++ * correctly configured.
++ */
++static int
++ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++ struct v4l2_pix_format *pix;
++ int rval;
++
++ if (f == NULL)
++ return -EINVAL;
++
++ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL; /* only capture is supported */
++
++ pix = &f->fmt.pix;
++ rval = ioctl_try_fmt_cap(s, f);
++ if (rval)
++ return rval;
++
++ decoder->pix = *pix;
++
++ return rval;
++}
++
++/**
++ * ioctl_g_fmt_cap - V4L2 decoder interface handler for ioctl_g_fmt_cap
++ * @s: pointer to standard V4L2 device structure
++ * @f: pointer to standard V4L2 v4l2_format structure
++ *
++ * Returns the decoder's current pixel format in the v4l2_format
++ * parameter.
++ */
++static int
++ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++
++ if (f == NULL)
++ return -EINVAL;
++
++ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL; /* only capture is supported */
++
++ f->fmt.pix = decoder->pix;
++
++ v4l_dbg(1, debug, decoder->client,
++ "Current FMT: bytesperline - %d"
++ "Width - %d, Height - %d",
++ decoder->pix.bytesperline,
++ decoder->pix.width, decoder->pix.height);
++ return 0;
++}
++
++/**
++ * ioctl_g_parm - V4L2 decoder interface handler for VIDIOC_G_PARM ioctl
++ * @s: pointer to standard V4L2 device structure
++ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
++ *
++ * Returns the decoder's video CAPTURE parameters.
++ */
++static int
++ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++ struct v4l2_captureparm *cparm;
++ enum mt9v113_std current_std;
++
++ if (a == NULL)
++ return -EINVAL;
++
++ if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL; /* only capture is supported */
++
++ memset(a, 0, sizeof(*a));
++ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++
++ /* get the current standard */
++ current_std = mt9v113_get_current_std(decoder);
++ if (current_std == MT9V113_STD_INVALID)
++ return -EINVAL;
++
++ decoder->current_std = current_std;
++
++ cparm = &a->parm.capture;
++ cparm->capability = V4L2_CAP_TIMEPERFRAME;
++ cparm->timeperframe =
++ decoder->std_list[current_std].standard.frameperiod;
++
++ return 0;
++}
++
++/**
++ * ioctl_s_parm - V4L2 decoder interface handler for VIDIOC_S_PARM ioctl
++ * @s: pointer to standard V4L2 device structure
++ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
++ *
++ * Configures the decoder to use the input parameters, if possible. If
++ * not possible, returns the appropriate error code.
++ */
++static int
++ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++ struct v4l2_fract *timeperframe;
++ enum mt9v113_std current_std;
++
++ if (a == NULL)
++ return -EINVAL;
++
++ if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL; /* only capture is supported */
++
++ timeperframe = &a->parm.capture.timeperframe;
++
++ /* get the current standard */
++ current_std = mt9v113_get_current_std(decoder);
++ if (current_std == MT9V113_STD_INVALID)
++ return -EINVAL;
++
++ decoder->current_std = current_std;
++
++ *timeperframe =
++ decoder->std_list[current_std].standard.frameperiod;
++
++ return 0;
++}
++
++/**
++ * ioctl_g_ifparm - V4L2 decoder interface handler for vidioc_int_g_ifparm_num
++ * @s: pointer to standard V4L2 device structure
++ * @p: pointer to standard V4L2 vidioc_int_g_ifparm_num ioctl structure
++ *
++ * Gets slave interface parameters.
++ * Calculates the required xclk value to support the requested
++ * clock parameters in p. This value is returned in the p
++ * parameter.
++ */
++static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++ int rval;
++
++ if (p == NULL)
++ return -EINVAL;
++
++ if (NULL == decoder->pdata->ifparm)
++ return -EINVAL;
++
++ rval = decoder->pdata->ifparm(p);
++ if (rval) {
++ v4l_err(decoder->client, "g_ifparm.Err[%d]\n", rval);
++ return rval;
++ }
++
++ p->u.bt656.clock_curr = 27000000; // TODO: read clock rate from sensor
++
++ return 0;
++}
++
++/**
++ * ioctl_g_priv - V4L2 decoder interface handler for vidioc_int_g_priv_num
++ * @s: pointer to standard V4L2 device structure
++ * @p: void pointer to hold decoder's private data address
++ *
++ * Returns device's (decoder's) private data area address in p parameter
++ */
++static int ioctl_g_priv(struct v4l2_int_device *s, void *p)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++
++ if (NULL == decoder->pdata->priv_data_set)
++ return -EINVAL;
++
++ return decoder->pdata->priv_data_set(p);
++}
++
++/**
++ * ioctl_s_power - V4L2 decoder interface handler for vidioc_int_s_power_num
++ * @s: pointer to standard V4L2 device structure
++ * @on: power state to which device is to be set
++ *
++ * Sets devices power state to requrested state, if possible.
++ */
++static int ioctl_s_power(struct v4l2_int_device *s, enum v4l2_power on)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++ int err = 0;
++
++ switch (on) {
++ case V4L2_POWER_OFF:
++ /* Power Down Sequence */
++ err =
++ mt9v113_write_reg(decoder->client, REG_OPERATION_MODE,
++ 0x01);
++ /* Disable mux for mt9v113 data path */
++ if (decoder->pdata->power_set)
++ err |= decoder->pdata->power_set(s, on);
++ decoder->state = STATE_NOT_DETECTED;
++ break;
++
++ case V4L2_POWER_STANDBY:
++ if (decoder->pdata->power_set)
++ err = decoder->pdata->power_set(s, on);
++ break;
++
++ case V4L2_POWER_ON:
++ /* Enable mux for mt9v113 data path */
++ if ((decoder->pdata->power_set) &&
++ (decoder->state == STATE_NOT_DETECTED)) {
++
++ err = decoder->pdata->power_set(s, on);
++
++ /* Detect the sensor is not already detected */
++ err |= mt9v113_detect(decoder);
++ if (err) {
++ v4l_err(decoder->client,
++ "Unable to detect decoder\n");
++ return err;
++ }
++ }
++ // Only VGA mode for now
++ err |= mt9v113_vga_mode(decoder);
++ break;
++
++ default:
++ err = -ENODEV;
++ break;
++ }
++
++ return err;
++}
++
++/**
++ * ioctl_init - V4L2 decoder interface handler for VIDIOC_INT_INIT
++ * @s: pointer to standard V4L2 device structure
++ *
++ * Initialize the decoder device (calls mt9v113_configure())
++ */
++static int ioctl_init(struct v4l2_int_device *s)
++{
++// struct mt9v113_decoder *decoder = s->priv;
++ int err = 0;
++
++ /* Set default standard to auto */
++ //mt9v113_reg_list[REG_VIDEO_STD].val =
++ // VIDEO_STD_AUTO_SWITCH_BIT;
++// err |= mt9v113_configure(decoder);
++// err |= mt9v113_vga_mode(decoder);
++
++ return err;
++}
++
++/**
++ * ioctl_dev_exit - V4L2 decoder interface handler for vidioc_int_dev_exit_num
++ * @s: pointer to standard V4L2 device structure
++ *
++ * Delinitialise the dev. at slave detach. The complement of ioctl_dev_init.
++ */
++static int ioctl_dev_exit(struct v4l2_int_device *s)
++{
++ return 0;
++}
++
++/**
++ * ioctl_dev_init - V4L2 decoder interface handler for vidioc_int_dev_init_num
++ * @s: pointer to standard V4L2 device structure
++ *
++ * Initialise the device when slave attaches to the master. Returns 0 if
++ * mt9v113 device could be found, otherwise returns appropriate error.
++ */
++static int ioctl_dev_init(struct v4l2_int_device *s)
++{
++ struct mt9v113_decoder *decoder = s->priv;
++ int err;
++
++ printk("%s: %d\n", __func__, __LINE__);
++ err = mt9v113_detect(decoder);
++ if (err < 0) {
++ v4l_err(decoder->client,
++ "Unable to detect decoder\n");
++ return err;
++ }
++
++ v4l_info(decoder->client,
++ "chip version 0x%.2x detected\n", decoder->ver);
++
++ err |= mt9v113_configure(decoder);
++ err |= mt9v113_vga_mode(decoder);
++
++ return 0;
++}
++
++static struct v4l2_int_ioctl_desc mt9v113_ioctl_desc[] = {
++ {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*) ioctl_dev_init},
++ {vidioc_int_dev_exit_num, (v4l2_int_ioctl_func*) ioctl_dev_exit},
++ {vidioc_int_s_power_num, (v4l2_int_ioctl_func*) ioctl_s_power},
++ {vidioc_int_g_priv_num, (v4l2_int_ioctl_func*) ioctl_g_priv},
++ {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*) ioctl_g_ifparm},
++ {vidioc_int_init_num, (v4l2_int_ioctl_func*) ioctl_init},
++ {vidioc_int_enum_fmt_cap_num,
++ (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap},
++ {vidioc_int_try_fmt_cap_num,
++ (v4l2_int_ioctl_func *) ioctl_try_fmt_cap},
++ {vidioc_int_g_fmt_cap_num,
++ (v4l2_int_ioctl_func *) ioctl_g_fmt_cap},
++ {vidioc_int_s_fmt_cap_num,
++ (v4l2_int_ioctl_func *) ioctl_s_fmt_cap},
++ {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm},
++ {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm},
++ {vidioc_int_queryctrl_num,
++ (v4l2_int_ioctl_func *) ioctl_queryctrl},
++ {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl},
++ {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl},
++ {vidioc_int_querystd_num, (v4l2_int_ioctl_func *) ioctl_querystd},
++ {vidioc_int_s_std_num, (v4l2_int_ioctl_func *) ioctl_s_std},
++ {vidioc_int_s_video_routing_num,
++ (v4l2_int_ioctl_func *) ioctl_s_routing},
++};
++
++static struct v4l2_int_slave mt9v113_slave = {
++ .ioctls = mt9v113_ioctl_desc,
++ .num_ioctls = ARRAY_SIZE(mt9v113_ioctl_desc),
++};
++
++static struct mt9v113_decoder mt9v113_dev = {
++ .state = STATE_NOT_DETECTED,
++
++ .fmt_list = mt9v113_fmt_list,
++ .num_fmts = ARRAY_SIZE(mt9v113_fmt_list),
++
++ .pix = { /* Default to 8-bit YUV 422 */
++ .width = VGA_NUM_ACTIVE_PIXELS,
++ .height = VGA_NUM_ACTIVE_LINES,
++ .pixelformat = V4L2_PIX_FMT_UYVY,
++ .field = V4L2_FIELD_NONE,
++ .bytesperline = VGA_NUM_ACTIVE_PIXELS * 2,
++ .sizeimage =
++ VGA_NUM_ACTIVE_PIXELS * 2 * VGA_NUM_ACTIVE_LINES,
++ .colorspace = V4L2_COLORSPACE_SMPTE170M,
++ },
++
++ .current_std = MT9V113_STD_VGA,
++ .std_list = mt9v113_std_list,
++ .num_stds = ARRAY_SIZE(mt9v113_std_list),
++
++};
++
++static struct v4l2_int_device mt9v113_int_device = {
++ .module = THIS_MODULE,
++ .name = MT9V113_MODULE_NAME,
++ .priv = &mt9v113_dev,
++ .type = v4l2_int_type_slave,
++ .u = {
++ .slave = &mt9v113_slave,
++ },
++};
++
++/**
++ * mt9v113_probe - decoder driver i2c probe handler
++ * @client: i2c driver client device structure
++ *
++ * Register decoder as an i2c client device and V4L2
++ * device.
++ */
++static int
++mt9v113_probe(struct i2c_client *client, const struct i2c_device_id *id)
++{
++ struct mt9v113_decoder *decoder = &mt9v113_dev;
++ int err;
++
++ printk("%s: %d\n", __func__, __LINE__);
++ /* Check if the adapter supports the needed features */
++ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
++ return -EIO;
++
++ printk("%s: %d\n", __func__, __LINE__);
++ decoder->pdata = client->dev.platform_data;
++ if (!decoder->pdata) {
++ v4l_err(client, "No platform data!!\n");
++ return -ENODEV;
++ }
++ printk("%s: %d\n", __func__, __LINE__);
++ /*
++ * Fetch platform specific data, and configure the
++ * mt9v113_reg_list[] accordingly. Since this is one
++ * time configuration, no need to preserve.
++ */
++
++ /*mt9v113_reg_list[REG_OUTPUT_FORMATTER2].val |=
++ (decoder->pdata->clk_polarity << 1);
++ mt9v113_reg_list[REG_SYNC_CONTROL].val |=
++ ((decoder->pdata->hs_polarity << 2) |
++ (decoder->pdata->vs_polarity << 3));
++ */
++ /*
++ * Save the id data, required for power up sequence
++ */
++ decoder->id = (struct i2c_device_id *)id;
++ /* Attach to Master */
++ strcpy(mt9v113_int_device.u.slave->attach_to, decoder->pdata->master);
++ decoder->v4l2_int_device = &mt9v113_int_device;
++ decoder->client = client;
++ i2c_set_clientdata(client, decoder);
++
++ /* Register with V4L2 layer as slave device */
++ err = v4l2_int_device_register(decoder->v4l2_int_device);
++ if (err) {
++ i2c_set_clientdata(client, NULL);
++ v4l_err(client,
++ "Unable to register to v4l2. Err[%d]\n", err);
++
++ } else
++ v4l_info(client, "Registered to v4l2 master %s!!\n",
++ decoder->pdata->master);
++
++ return 0;
++}
++
++/**
++ * mt9v113_remove - decoder driver i2c remove handler
++ * @client: i2c driver client device structure
++ *
++ * Unregister decoder as an i2c client device and V4L2
++ * device. Complement of mt9v113_probe().
++ */
++static int __exit mt9v113_remove(struct i2c_client *client)
++{
++ struct mt9v113_decoder *decoder = i2c_get_clientdata(client);
++
++ if (!client->adapter)
++ return -ENODEV; /* our client isn't attached */
++
++ v4l2_int_device_unregister(decoder->v4l2_int_device);
++ i2c_set_clientdata(client, NULL);
++
++ return 0;
++}
++/*
++ * mt9v113 Init/Power on Sequence
++ */
++static const struct mt9v113_reg mt9v113m_init_reg_seq[] = {
++ {TOK_WRITE, REG_OPERATION_MODE, 0x01},
++ {TOK_WRITE, REG_OPERATION_MODE, 0x00},
++};
++static const struct mt9v113_init_seq mt9v113m_init = {
++ .no_regs = ARRAY_SIZE(mt9v113m_init_reg_seq),
++ .init_reg_seq = mt9v113m_init_reg_seq,
++};
++/*
++ * I2C Device Table -
++ *
++ * name - Name of the actual device/chip.
++ * driver_data - Driver data
++ */
++static const struct i2c_device_id mt9v113_id[] = {
++ {"mt9v113", (unsigned long)&mt9v113m_init},
++ {},
++};
++
++MODULE_DEVICE_TABLE(i2c, mt9v113_id);
++
++static struct i2c_driver mt9v113_i2c_driver = {
++ .driver = {
++ .name = MT9V113_MODULE_NAME,
++ .owner = THIS_MODULE,
++ },
++ .probe = mt9v113_probe,
++ .remove = __exit_p(mt9v113_remove),
++ .id_table = mt9v113_id,
++};
++
++/**
++ * mt9v113_init
++ *
++ * Module init function
++ */
++static int __init mt9v113_init(void)
++{
++ return i2c_add_driver(&mt9v113_i2c_driver);
++}
++
++/**
++ * mt9v113_cleanup
++ *
++ * Module exit function
++ */
++static void __exit mt9v113_cleanup(void)
++{
++ i2c_del_driver(&mt9v113_i2c_driver);
++}
++
++module_init(mt9v113_init);
++module_exit(mt9v113_cleanup);
++
++MODULE_AUTHOR("Texas Instruments");
++MODULE_DESCRIPTION("MT9V113 linux decoder driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/video/mt9v113_regs.h b/drivers/media/video/mt9v113_regs.h
+new file mode 100644
+index 0000000..64b065f
+--- /dev/null
++++ b/drivers/media/video/mt9v113_regs.h
+@@ -0,0 +1,294 @@
++/*
++ * drivers/media/video/mt9v113_regs.h
++ *
++ * Copyright (C) 2008 Texas Instruments Inc
++ * Author: Vaibhav Hiremath <hvaibhav@ti.com>
++ *
++ * Contributors:
++ * Sivaraj R <sivaraj@ti.com>
++ * Brijesh R Jadav <brijesh.j@ti.com>
++ * Hardik Shah <hardik.shah@ti.com>
++ * Manjunath Hadli <mrh@ti.com>
++ * Karicheri Muralidharan <m-karicheri2@ti.com>
++ *
++ * This package is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++#ifndef _MT9V113_REGS_H
++#define _MT9V113_REGS_H
++
++/*
++ * MT9V113 registers
++ */
++#define REG_CHIP_ID (0x00)
++
++/*
++ * MT9V113 registers
++ */
++#define REG_INPUT_SEL (0x00)
++#define REG_AFE_GAIN_CTRL (0x01)
++#define REG_VIDEO_STD (0x02)
++#define REG_OPERATION_MODE (0x03)
++#define REG_AUTOSWITCH_MASK (0x04)
++
++#define REG_COLOR_KILLER (0x05)
++#define REG_LUMA_CONTROL1 (0x06)
++#define REG_LUMA_CONTROL2 (0x07)
++#define REG_LUMA_CONTROL3 (0x08)
++
++#define REG_BRIGHTNESS (0x09)
++#define REG_CONTRAST (0x0A)
++#define REG_SATURATION (0x0B)
++#define REG_HUE (0x0C)
++
++#define REG_CHROMA_CONTROL1 (0x0D)
++#define REG_CHROMA_CONTROL2 (0x0E)
++
++/* 0x0F Reserved */
++
++#define REG_COMP_PR_SATURATION (0x10)
++#define REG_COMP_Y_CONTRAST (0x11)
++#define REG_COMP_PB_SATURATION (0x12)
++
++/* 0x13 Reserved */
++
++#define REG_COMP_Y_BRIGHTNESS (0x14)
++
++/* 0x15 Reserved */
++
++#define REG_AVID_START_PIXEL_LSB (0x16)
++#define REG_AVID_START_PIXEL_MSB (0x17)
++#define REG_AVID_STOP_PIXEL_LSB (0x18)
++#define REG_AVID_STOP_PIXEL_MSB (0x19)
++
++#define REG_HSYNC_START_PIXEL_LSB (0x1A)
++#define REG_HSYNC_START_PIXEL_MSB (0x1B)
++#define REG_HSYNC_STOP_PIXEL_LSB (0x1C)
++#define REG_HSYNC_STOP_PIXEL_MSB (0x1D)
++
++#define REG_VSYNC_START_LINE_LSB (0x1E)
++#define REG_VSYNC_START_LINE_MSB (0x1F)
++#define REG_VSYNC_STOP_LINE_LSB (0x20)
++#define REG_VSYNC_STOP_LINE_MSB (0x21)
++
++#define REG_VBLK_START_LINE_LSB (0x22)
++#define REG_VBLK_START_LINE_MSB (0x23)
++#define REG_VBLK_STOP_LINE_LSB (0x24)
++#define REG_VBLK_STOP_LINE_MSB (0x25)
++
++/* 0x26 - 0x27 Reserved */
++
++#define REG_FAST_SWTICH_CONTROL (0x28)
++
++/* 0x29 Reserved */
++
++#define REG_FAST_SWTICH_SCART_DELAY (0x2A)
++
++/* 0x2B Reserved */
++
++#define REG_SCART_DELAY (0x2C)
++#define REG_CTI_DELAY (0x2D)
++#define REG_CTI_CONTROL (0x2E)
++
++/* 0x2F - 0x31 Reserved */
++
++#define REG_SYNC_CONTROL (0x32)
++#define REG_OUTPUT_FORMATTER1 (0x33)
++#define REG_OUTPUT_FORMATTER2 (0x34)
++#define REG_OUTPUT_FORMATTER3 (0x35)
++#define REG_OUTPUT_FORMATTER4 (0x36)
++#define REG_OUTPUT_FORMATTER5 (0x37)
++#define REG_OUTPUT_FORMATTER6 (0x38)
++#define REG_CLEAR_LOST_LOCK (0x39)
++
++#define REG_STATUS1 (0x3A)
++#define REG_STATUS2 (0x3B)
++
++#define REG_AGC_GAIN_STATUS_LSB (0x3C)
++#define REG_AGC_GAIN_STATUS_MSB (0x3D)
++
++/* 0x3E Reserved */
++
++#define REG_VIDEO_STD_STATUS (0x3F)
++#define REG_GPIO_INPUT1 (0x40)
++#define REG_GPIO_INPUT2 (0x41)
++
++/* 0x42 - 0x45 Reserved */
++
++#define REG_AFE_COARSE_GAIN_CH1 (0x46)
++#define REG_AFE_COARSE_GAIN_CH2 (0x47)
++#define REG_AFE_COARSE_GAIN_CH3 (0x48)
++#define REG_AFE_COARSE_GAIN_CH4 (0x49)
++
++#define REG_AFE_FINE_GAIN_PB_B_LSB (0x4A)
++#define REG_AFE_FINE_GAIN_PB_B_MSB (0x4B)
++#define REG_AFE_FINE_GAIN_Y_G_CHROMA_LSB (0x4C)
++#define REG_AFE_FINE_GAIN_Y_G_CHROMA_MSB (0x4D)
++#define REG_AFE_FINE_GAIN_PR_R_LSB (0x4E)
++#define REG_AFE_FINE_GAIN_PR_R_MSB (0x4F)
++#define REG_AFE_FINE_GAIN_CVBS_LUMA_LSB (0x50)
++#define REG_AFE_FINE_GAIN_CVBS_LUMA_MSB (0x51)
++
++/* 0x52 - 0x68 Reserved */
++
++#define REG_FBIT_VBIT_CONTROL1 (0x69)
++
++/* 0x6A - 0x6B Reserved */
++
++#define REG_BACKEND_AGC_CONTROL (0x6C)
++
++/* 0x6D - 0x6E Reserved */
++
++#define REG_AGC_DECREMENT_SPEED_CONTROL (0x6F)
++#define REG_ROM_VERSION (0x70)
++
++/* 0x71 - 0x73 Reserved */
++
++#define REG_AGC_WHITE_PEAK_PROCESSING (0x74)
++#define REG_FBIT_VBIT_CONTROL2 (0x75)
++#define REG_VCR_TRICK_MODE_CONTROL (0x76)
++#define REG_HORIZONTAL_SHAKE_INCREMENT (0x77)
++#define REG_AGC_INCREMENT_SPEED (0x78)
++#define REG_AGC_INCREMENT_DELAY (0x79)
++
++/* 0x7A - 0x7F Reserved */
++
++#define REG_CHIP_ID_MSB (0x80)
++#define REG_CHIP_ID_LSB (0x81)
++
++/* 0x82 Reserved */
++
++#define REG_CPLL_SPEED_CONTROL (0x83)
++
++/* 0x84 - 0x96 Reserved */
++
++#define REG_STATUS_REQUEST (0x97)
++
++/* 0x98 - 0x99 Reserved */
++
++#define REG_VERTICAL_LINE_COUNT_LSB (0x9A)
++#define REG_VERTICAL_LINE_COUNT_MSB (0x9B)
++
++/* 0x9C - 0x9D Reserved */
++
++#define REG_AGC_DECREMENT_DELAY (0x9E)
++
++/* 0x9F - 0xB0 Reserved */
++
++#define REG_VDP_TTX_FILTER_1_MASK1 (0xB1)
++#define REG_VDP_TTX_FILTER_1_MASK2 (0xB2)
++#define REG_VDP_TTX_FILTER_1_MASK3 (0xB3)
++#define REG_VDP_TTX_FILTER_1_MASK4 (0xB4)
++#define REG_VDP_TTX_FILTER_1_MASK5 (0xB5)
++#define REG_VDP_TTX_FILTER_2_MASK1 (0xB6)
++#define REG_VDP_TTX_FILTER_2_MASK2 (0xB7)
++#define REG_VDP_TTX_FILTER_2_MASK3 (0xB8)
++#define REG_VDP_TTX_FILTER_2_MASK4 (0xB9)
++#define REG_VDP_TTX_FILTER_2_MASK5 (0xBA)
++#define REG_VDP_TTX_FILTER_CONTROL (0xBB)
++#define REG_VDP_FIFO_WORD_COUNT (0xBC)
++#define REG_VDP_FIFO_INTERRUPT_THRLD (0xBD)
++
++/* 0xBE Reserved */
++
++#define REG_VDP_FIFO_RESET (0xBF)
++#define REG_VDP_FIFO_OUTPUT_CONTROL (0xC0)
++#define REG_VDP_LINE_NUMBER_INTERRUPT (0xC1)
++#define REG_VDP_PIXEL_ALIGNMENT_LSB (0xC2)
++#define REG_VDP_PIXEL_ALIGNMENT_MSB (0xC3)
++
++/* 0xC4 - 0xD5 Reserved */
++
++#define REG_VDP_LINE_START (0xD6)
++#define REG_VDP_LINE_STOP (0xD7)
++#define REG_VDP_GLOBAL_LINE_MODE (0xD8)
++#define REG_VDP_FULL_FIELD_ENABLE (0xD9)
++#define REG_VDP_FULL_FIELD_MODE (0xDA)
++
++/* 0xDB - 0xDF Reserved */
++
++#define REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR (0xE0)
++#define REG_VBUS_DATA_ACCESS_VBUS_ADDR_INCR (0xE1)
++#define REG_FIFO_READ_DATA (0xE2)
++
++/* 0xE3 - 0xE7 Reserved */
++
++#define REG_VBUS_ADDRESS_ACCESS1 (0xE8)
++#define REG_VBUS_ADDRESS_ACCESS2 (0xE9)
++#define REG_VBUS_ADDRESS_ACCESS3 (0xEA)
++
++/* 0xEB - 0xEF Reserved */
++
++#define REG_INTERRUPT_RAW_STATUS0 (0xF0)
++#define REG_INTERRUPT_RAW_STATUS1 (0xF1)
++#define REG_INTERRUPT_STATUS0 (0xF2)
++#define REG_INTERRUPT_STATUS1 (0xF3)
++#define REG_INTERRUPT_MASK0 (0xF4)
++#define REG_INTERRUPT_MASK1 (0xF5)
++#define REG_INTERRUPT_CLEAR0 (0xF6)
++#define REG_INTERRUPT_CLEAR1 (0xF7)
++
++/* 0xF8 - 0xFF Reserved */
++
++/* The ID values we are looking for */
++#define MT9V113_CHIP_ID_MSB (0x51)
++
++#define MT9V113_IMAGE_STD_VGA (0x01)
++#define MT9V113_IMAGE_STD_QVGA (0x02)
++#define MT9V113_IMAGE_STD_INVALID (0xFF)
++
++/*
++ * Status bit
++ */
++#define STATUS_TV_VCR_BIT (1<<0)
++#define STATUS_HORZ_SYNC_LOCK_BIT (1<<1)
++#define STATUS_VIRT_SYNC_LOCK_BIT (1<<2)
++#define STATUS_CLR_SUBCAR_LOCK_BIT (1<<3)
++#define STATUS_LOST_LOCK_DETECT_BIT (1<<4)
++#define STATUS_FEILD_RATE_BIT (1<<5)
++#define STATUS_LINE_ALTERNATING_BIT (1<<6)
++#define STATUS_PEAK_WHITE_DETECT_BIT (1<<7)
++
++/* Tokens for register write */
++#define TOK_WRITE (0) /* token for write operation */
++#define TOK_TERM (1) /* terminating token */
++#define TOK_DELAY (2) /* delay token for reg list */
++#define TOK_SKIP (3) /* token to skip a register */
++/**
++ * struct mt9v113_reg - Structure for TVP5146/47 register initialization values
++ * @token - Token: TOK_WRITE, TOK_TERM etc..
++ * @reg - Register offset
++ * @val - Register Value for TOK_WRITE or delay in ms for TOK_DELAY
++ */
++struct mt9v113_reg {
++ unsigned short token;
++ unsigned short reg;
++ unsigned short val;
++};
++
++/**
++ * struct mt9v113_init_seq - Structure for TVP5146/47/46M2/47M1 power up
++ * Sequence.
++ * @ no_regs - Number of registers to write for power up sequence.
++ * @ init_reg_seq - Array of registers and respective value to write.
++ */
++struct mt9v113_init_seq {
++ unsigned int no_regs;
++ const struct mt9v113_reg *init_reg_seq;
++};
++
++#define MT9V113_CHIP_ID (0x2280)
++
++#endif /* ifndef _MT9V113_REGS_H */
+diff --git a/include/media/mt9v113.h b/include/media/mt9v113.h
+new file mode 100644
+index 0000000..c7ad362
+--- /dev/null
++++ b/include/media/mt9v113.h
+@@ -0,0 +1,83 @@
++/*
++ * drivers/media/video/mt9v113.h
++ *
++ * Copyright (C) 2008 Texas Instruments Inc
++ * Author: Vaibhav Hiremath <hvaibhav@ti.com>
++ *
++ * Contributors:
++ * Sivaraj R <sivaraj@ti.com>
++ * Brijesh R Jadav <brijesh.j@ti.com>
++ * Hardik Shah <hardik.shah@ti.com>
++ * Manjunath Hadli <mrh@ti.com>
++ * Karicheri Muralidharan <m-karicheri2@ti.com>
++ *
++ * This package is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++#ifndef _MT9V113_H
++#define _MT9V113_H
++
++/*
++ * Other macros
++ */
++#define MT9V113_MODULE_NAME "mt9v113"
++
++/* Number of pixels and number of lines per frame for different standards */
++#define VGA_NUM_ACTIVE_PIXELS (640*2)
++#define VGA_NUM_ACTIVE_LINES (480)
++#define QVGA_NUM_ACTIVE_PIXELS (320*2)
++#define QVGA_NUM_ACTIVE_LINES (240)
++
++/**
++ * struct mt9v113_platform_data - Platform data values and access functions.
++ * @power_set: Power state access function, zero is off, non-zero is on.
++ * @ifparm: Interface parameters access function.
++ * @priv_data_set: Device private data (pointer) access function.
++ * @clk_polarity: Clock polarity of the current interface.
++ * @ hs_polarity: HSYNC Polarity configuration for current interface.
++ * @ vs_polarity: VSYNC Polarity configuration for current interface.
++ */
++struct mt9v113_platform_data {
++ char *master;
++ int (*power_set) (struct v4l2_int_device *s, enum v4l2_power on);
++ int (*ifparm) (struct v4l2_ifparm *p);
++ int (*priv_data_set) (void *);
++ /* Interface control params */
++ bool clk_polarity;
++ bool hs_polarity;
++ bool vs_polarity;
++};
++
++// new
++
++/*i2c adress for MT9V113*/
++#define MT9V113_I2C_ADDR (0x78 >>1)
++
++#define I2C_ONE_BYTE_TRANSFER (1)
++#define I2C_TWO_BYTE_TRANSFER (2)
++#define I2C_THREE_BYTE_TRANSFER (3)
++#define I2C_FOUR_BYTE_TRANSFER (4)
++#define I2C_TXRX_DATA_MASK (0x00FF)
++#define I2C_TXRX_DATA_MASK_UPPER (0xFF00)
++#define I2C_TXRX_DATA_SHIFT (8)
++
++#define MT9V113_VGA_30FPS (1130)
++#define MT9V113_QVGA_30FPS (1131)
++
++#define MT9V113_CLK_MAX (54000000) /* 54MHz */
++#define MT9V113_CLK_MIN (6000000) /* 6Mhz */
++
++#endif /* ifndef _MT9V113_H */
++
+diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h
+index ce415ec..7827575 100644
+--- a/include/media/v4l2-int-device.h
++++ b/include/media/v4l2-int-device.h
+@@ -115,6 +115,7 @@ enum v4l2_if_type {
+ V4L2_IF_TYPE_BT656,
+ V4L2_IF_TYPE_YCbCr,
+ V4L2_IF_TYPE_RAW,
++ V4L2_IF_TYPE_PARALLEL,
+ };
+
+ enum v4l2_if_type_bt656_mode {
+@@ -215,12 +216,38 @@ struct v4l2_if_type_raw {
+ u32 clock_curr;
+ };
+
++struct v4l2_if_type_parallel {
++ /*
++ * 0: Frame begins when vsync is high.
++ * 1: Frame begins when vsync changes from low to high.
++ */
++ unsigned frame_start_on_rising_vs:1;
++ /* Swap every two adjacent image data elements. */
++ unsigned swap:1;
++ /* Inverted latch clock polarity from slave. */
++ unsigned latch_clk_inv:1;
++ /* Hs polarity. 0 is active high, 1 active low. */
++ unsigned no_hs_inv:1;
++ /* Vs polarity. 0 is active high, 1 active low. */
++ unsigned no_vs_inv:1;
++ /* Minimum accepted bus clock for slave (in Hz). */
++ u32 clock_min;
++ /* Maximum accepted bus clock for slave. */
++ u32 clock_max;
++ /*
++ * Current wish of the slave. May only change in response to
++ * ioctls that affect image capture.
++ */
++ u32 clock_curr;
++};
++
+ struct v4l2_ifparm {
+ enum v4l2_if_type if_type;
+ union {
+ struct v4l2_if_type_bt656 bt656;
+ struct v4l2_if_type_ycbcr ycbcr;
+ struct v4l2_if_type_raw raw;
++ struct v4l2_if_type_parallel parallel;
+ } u;
+ };
+
+--
+1.6.6.1
+