All of lore.kernel.org
 help / color / mirror / Atom feed
From: hvaibhav@ti.com
To: video4linux-list@redhat.com
Cc: davinci-linux-open-source-bounces@linux.davincidsp.com,
	Karicheri Muralidharan <m-karicheri2@ti.com>,
	linux-omap@vger.kernel.org
Subject: [PATCH 2/2] TVP514x Driver with Review comments fixed [V4]
Date: Tue,  2 Dec 2008 21:05:42 +0530	[thread overview]
Message-ID: <1228232142-11934-1-git-send-email-hvaibhav@ti.com> (raw)
In-Reply-To: <hvaibhav@ti.com>

From: Vaibhav Hiremath <hvaibhav@ti.com>

I have fixed all the review commentsreceived so far.
Here are the details -

FIXSES:
    Make use of i2c_smbus_read/write_byte API:
        Probe function now checks for SMBUS capability,
	and read/write functions make use of the above API.

    Error check for I2C Read/Write:
        Added error condition check for both read and write
	API.
	This has been added for completeness.

    input set/get ioctl:
        As we do have support for set and get routing ioctl,
	instead of adding new ioctl used them.

    enum_ioctl:
        After discussing with Hans verkuil, came to conclusion
	that as of now just remove support for enum_ioctl from
	decoder, since this has to handle at master driver level.

TODO LIST:
    OMAP Master capture driver:
        This should be completely aligned with the current
	discussion.

    Migration to sub_device framework:
        Immediately after all the above task, migrate both
	Master and slave driver to sub_device framework.

Signed-off-by: Brijesh Jadav <brijesh.j@ti.com>
Signed-off-by: Hardik Shah <hardik.shah@ti.com>
Signed-off-by: Manjunath Hadli <mrh@ti.com>
Signed-off-by: R Sivaraj <sivaraj@ti.com>
Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
Signed-off-by: Karicheri Muralidharan <m-karicheri2@ti.com>
---
 drivers/media/video/Kconfig        |   11 +
 drivers/media/video/Makefile       |    1 +
 drivers/media/video/tvp514x.c      | 1521 ++++++++++++++++++++++++++++++++++++
 drivers/media/video/tvp514x_regs.h |  292 +++++++
 include/media/tvp514x.h            |  232 ++++++
 5 files changed, 2057 insertions(+), 0 deletions(-)
 create mode 100755 drivers/media/video/tvp514x.c
 create mode 100755 drivers/media/video/tvp514x_regs.h
 create mode 100755 include/media/tvp514x.h

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 47102c2..2e5dc3e 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -361,6 +361,17 @@ config VIDEO_SAA7191
 	  To compile this driver as a module, choose M here: the
 	  module will be called saa7191.

+config VIDEO_TVP514X
+	tristate "Texas Instruments TVP514x video decoder"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	  This is a Video4Linux2 sensor-level driver for the TI TVP5146/47
+	  decoder. It is currently working with the TI OMAP3 camera
+	  controller.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called tvp514x.
+
 config VIDEO_TVP5150
 	tristate "Texas Instruments TVP5150 video decoder"
 	depends on VIDEO_V4L2 && I2C
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 16962f3..cdbbf38 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
 obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
 obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
 obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
+obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
 obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
 obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
 obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
new file mode 100755
index 0000000..c0834e4
--- /dev/null
+++ b/drivers/media/video/tvp514x.c
@@ -0,0 +1,1521 @@
+/*
+ * drivers/media/video/tvp514x.c
+ *
+ * TI TVP5146/47 decoder driver
+ *
+ * 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.
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-int-device.h>
+#include <media/tvp514x.h>
+
+#include "tvp514x_regs.h"
+
+#define MODULE_NAME	TVP514X_MODULE_NAME
+
+/* Debug functions */
+static int debug;
+module_param(debug, bool, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
+#define dump_reg(client, reg, val)				\
+	do {							\
+		val = tvp514x_read_reg(client, reg);		\
+		v4l_info(client, "Reg(0x%.2X): 0x%.2X\n", reg, val); \
+	} while (0)
+
+
+/* TVP514x default register values */
+static struct tvp514x_reg tvp514x_reg_list[] = {
+	{TOK_WRITE, REG_INPUT_SEL, 0x05},	/* Composite selected */
+	{TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F},
+	{TOK_WRITE, REG_VIDEO_STD, 0x00},	/* Auto mode */
+	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
+	{TOK_SKIP, REG_AUTOSWITCH_MASK, 0x3F},
+	{TOK_WRITE, REG_COLOR_KILLER, 0x10},
+	{TOK_WRITE, REG_LUMA_CONTROL1, 0x00},
+	{TOK_WRITE, REG_LUMA_CONTROL2, 0x00},
+	{TOK_WRITE, REG_LUMA_CONTROL3, 0x02},
+	{TOK_WRITE, REG_BRIGHTNESS, 0x80},
+	{TOK_WRITE, REG_CONTRAST, 0x80},
+	{TOK_WRITE, REG_SATURATION, 0x80},
+	{TOK_WRITE, REG_HUE, 0x00},
+	{TOK_WRITE, REG_CHROMA_CONTROL1, 0x00},
+	{TOK_WRITE, REG_CHROMA_CONTROL2, 0x0E},
+	{TOK_SKIP, 0x0F, 0x00},	/* Reserved */
+	{TOK_WRITE, REG_COMP_PR_SATURATION, 0x80},
+	{TOK_WRITE, REG_COMP_Y_CONTRAST, 0x80},
+	{TOK_WRITE, REG_COMP_PB_SATURATION, 0x80},
+	{TOK_SKIP, 0x13, 0x00},	/* Reserved */
+	{TOK_WRITE, REG_COMP_Y_BRIGHTNESS, 0x80},
+	{TOK_SKIP, 0x15, 0x00},	/* Reserved */
+	{TOK_SKIP, REG_AVID_START_PIXEL_LSB, 0x55},	/* NTSC timing */
+	{TOK_SKIP, REG_AVID_START_PIXEL_MSB, 0x00},
+	{TOK_SKIP, REG_AVID_STOP_PIXEL_LSB, 0x25},
+	{TOK_SKIP, REG_AVID_STOP_PIXEL_MSB, 0x03},
+	{TOK_SKIP, REG_HSYNC_START_PIXEL_LSB, 0x00},	/* NTSC timing */
+	{TOK_SKIP, REG_HSYNC_START_PIXEL_MSB, 0x00},
+	{TOK_SKIP, REG_HSYNC_STOP_PIXEL_LSB, 0x40},
+	{TOK_SKIP, REG_HSYNC_STOP_PIXEL_MSB, 0x00},
+	{TOK_SKIP, REG_VSYNC_START_LINE_LSB, 0x04},	/* NTSC timing */
+	{TOK_SKIP, REG_VSYNC_START_LINE_MSB, 0x00},
+	{TOK_SKIP, REG_VSYNC_STOP_LINE_LSB, 0x07},
+	{TOK_SKIP, REG_VSYNC_STOP_LINE_MSB, 0x00},
+	{TOK_SKIP, REG_VBLK_START_LINE_LSB, 0x01},	/* NTSC timing */
+	{TOK_SKIP, REG_VBLK_START_LINE_MSB, 0x00},
+	{TOK_SKIP, REG_VBLK_STOP_LINE_LSB, 0x15},
+	{TOK_SKIP, REG_VBLK_STOP_LINE_MSB, 0x00},
+	{TOK_SKIP, 0x26, 0x00},	/* Reserved */
+	{TOK_SKIP, 0x27, 0x00},	/* Reserved */
+	{TOK_SKIP, REG_FAST_SWTICH_CONTROL, 0xCC},
+	{TOK_SKIP, 0x29, 0x00},	/* Reserved */
+	{TOK_SKIP, REG_FAST_SWTICH_SCART_DELAY, 0x00},
+	{TOK_SKIP, 0x2B, 0x00},	/* Reserved */
+	{TOK_SKIP, REG_SCART_DELAY, 0x00},
+	{TOK_SKIP, REG_CTI_DELAY, 0x00},
+	{TOK_SKIP, REG_CTI_CONTROL, 0x00},
+	{TOK_SKIP, 0x2F, 0x00},	/* Reserved */
+	{TOK_SKIP, 0x30, 0x00},	/* Reserved */
+	{TOK_SKIP, 0x31, 0x00},	/* Reserved */
+	{TOK_WRITE, REG_SYNC_CONTROL, 0x00},	/* HS, VS active high */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER1, 0x00},	/* 10-bit BT.656 */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER2, 0x11},	/* Enable clk & data */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER3, 0xEE},	/* Enable AVID & FLD */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER4, 0xAF},	/* Enable VS & HS */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER5, 0xFF},
+	{TOK_WRITE, REG_OUTPUT_FORMATTER6, 0xFF},
+	{TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01},	/* Clear status */
+	{TOK_TERM, 0, 0},
+};
+
+/* List of image formats supported by TVP5146/47 decoder
+ * Currently we are using 8 bit mode only, but can be
+ * extended to 10/20 bit mode.
+ */
+static const struct v4l2_fmtdesc tvp514x_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,
+	},
+};
+
+#define TVP514X_NUM_FORMATS		ARRAY_SIZE(tvp514x_fmt_list)
+
+/*
+ * Supported standards -
+ *
+ * Currently supports two standards only, need to add support for rest of the
+ * modes, like SECAM, etc...
+ */
+static struct tvp514x_std_info tvp514x_std_list[] = {
+	/* Standard: STD_NTSC_MJ */
+	[STD_NTSC_MJ] = {
+	 .width = NTSC_NUM_ACTIVE_PIXELS,
+	 .height = NTSC_NUM_ACTIVE_LINES,
+	 .video_std = VIDEO_STD_NTSC_MJ_BIT,
+	 .standard = {
+		      .index = 0,
+		      .id = V4L2_STD_NTSC,
+		      .name = "NTSC",
+		      .frameperiod = {1001, 30000},
+		      .framelines = 525
+		     },
+	/* Standard: STD_PAL_BDGHIN */
+	},
+	[STD_PAL_BDGHIN] = {
+	 .width = PAL_NUM_ACTIVE_PIXELS,
+	 .height = PAL_NUM_ACTIVE_LINES,
+	 .video_std = VIDEO_STD_PAL_BDGHIN_BIT,
+	 .standard = {
+		      .index = 1,
+		      .id = V4L2_STD_PAL,
+		      .name = "PAL",
+		      .frameperiod = {1, 25},
+		      .framelines = 625
+		     },
+	},
+	/* Standard: need to add for additional standard */
+};
+
+#define TVP514X_NUM_STANDARDS		ARRAY_SIZE(tvp514x_std_list)
+
+/* Supported controls */
+static const struct tvp514x_ctrl_info tvp514x_ctrl_list[] = {
+	{
+	 .reg_address = REG_BRIGHTNESS,
+	 .query_ctrl = {
+			.id = V4L2_CID_BRIGHTNESS,
+			.name = "BRIGHTNESS",
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.minimum = 0,
+			.maximum = 255,
+			.step = 1,
+			.default_value = 128
+			},
+	}, {
+	 .reg_address = REG_CONTRAST,
+	 .query_ctrl = {
+			.id = V4L2_CID_CONTRAST,
+			.name = "CONTRAST",
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.minimum = 0,
+			.maximum = 255,
+			.step = 1,
+			.default_value = 128
+			},
+	}, {
+	 .reg_address = REG_SATURATION,
+	 .query_ctrl = {
+			.id = V4L2_CID_SATURATION,
+			.name = "SATURATION",
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.minimum = 0,
+			.maximum = 255,
+			.step = 1,
+			.default_value = 128
+			},
+	}, {
+	 .reg_address = REG_HUE,
+	 .query_ctrl = {
+			.id = V4L2_CID_HUE,
+			.name = "HUE",
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.minimum = -180,
+			.maximum = 180,
+			.step = 180,
+			.default_value = 0
+			},
+	}, {
+	 .reg_address = REG_AFE_GAIN_CTRL,
+	 .query_ctrl = {
+			.id = V4L2_CID_AUTOGAIN,
+			.name = "Automatic Gain Control",
+			.type = V4L2_CTRL_TYPE_BOOLEAN,
+			.minimum = 0,
+			.maximum = 1,
+			.step = 1,
+			.default_value = 1
+			},
+	 },
+};
+
+#define TVP514X_NUM_CONTROLS		ARRAY_SIZE(tvp514x_ctrl_list)
+
+/*
+ * Read a value from a register in an TVP5146/47 decoder device.
+ * Returns value read if successful, or non-zero (-1) otherwise.
+ */
+static int tvp514x_read_reg(struct i2c_client *client, u8 reg)
+{
+	int err;
+	int retry = 0;
+read_again:
+
+	err = i2c_smbus_read_byte_data(client, reg);
+	if (err == -1) {
+		if (retry <= I2C_RETRY_COUNT) {
+			v4l_warn(client, "Read: retry ... %d\n", retry);
+			retry++;
+			msleep_interruptible(10);
+			goto read_again;
+		}
+	}
+
+	return err;
+}
+
+/*
+ * Write a value to a register in an TVP5146/47 decoder device.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tvp514x_write_reg(struct i2c_client *client, u8 reg, u8 val)
+{
+	int err;
+	int retry = 0;
+write_again:
+
+	err = i2c_smbus_write_byte_data(client, reg, val);
+	if (err) {
+		if (retry <= I2C_RETRY_COUNT) {
+			v4l_warn(client, "Write: retry ... %d\n", retry);
+			retry++;
+			msleep_interruptible(10);
+			goto write_again;
+		}
+	}
+
+	return err;
+}
+
+/*
+ * tvp514x_write_regs : Initializes a list of TVP5146/47 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 tvp514x_write_regs(struct i2c_client *client,
+			      const struct tvp514x_reg reglist[])
+{
+	int err;
+	const struct tvp514x_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 = tvp514x_write_reg(client, next->reg, (u8) next->val);
+		if (err) {
+			v4l_err(client, "Write failed. Err[%d]\n", err);
+			return err;
+		}
+	}
+	return 0;
+}
+
+/*
+ * tvp514x_get_current_std:
+ * Returns the current standard detected by TVP5146/47
+ */
+static enum tvp514x_std tvp514x_get_current_std(struct tvp514x_decoder
+						*decoder)
+{
+	u8 std, std_status;
+
+	std = tvp514x_read_reg(decoder->client, REG_VIDEO_STD);
+	if ((std & VIDEO_STD_MASK) == VIDEO_STD_AUTO_SWITCH_BIT) {
+		/* use the standard status register */
+		std_status = tvp514x_read_reg(decoder->client,
+				REG_VIDEO_STD_STATUS);
+	} else
+		std_status = std;	/* use the standard register itself */
+
+	switch (std_status & VIDEO_STD_MASK) {
+	case VIDEO_STD_NTSC_MJ_BIT:
+		return STD_NTSC_MJ;
+
+	case VIDEO_STD_PAL_BDGHIN_BIT:
+		return STD_PAL_BDGHIN;
+
+	default:
+		return STD_INVALID;
+	}
+
+	return STD_INVALID;
+}
+
+/*
+ * TVP5146/47 register dump function
+ */
+void tvp514x_reg_dump(struct tvp514x_decoder *decoder)
+{
+	u8 value;
+
+	dump_reg(decoder->client, REG_INPUT_SEL, value);
+	dump_reg(decoder->client, REG_AFE_GAIN_CTRL, value);
+	dump_reg(decoder->client, REG_VIDEO_STD, value);
+	dump_reg(decoder->client, REG_OPERATION_MODE, value);
+	dump_reg(decoder->client, REG_COLOR_KILLER, value);
+	dump_reg(decoder->client, REG_LUMA_CONTROL1, value);
+	dump_reg(decoder->client, REG_LUMA_CONTROL2, value);
+	dump_reg(decoder->client, REG_LUMA_CONTROL3, value);
+	dump_reg(decoder->client, REG_BRIGHTNESS, value);
+	dump_reg(decoder->client, REG_CONTRAST, value);
+	dump_reg(decoder->client, REG_SATURATION, value);
+	dump_reg(decoder->client, REG_HUE, value);
+	dump_reg(decoder->client, REG_CHROMA_CONTROL1, value);
+	dump_reg(decoder->client, REG_CHROMA_CONTROL2, value);
+	dump_reg(decoder->client, REG_COMP_PR_SATURATION, value);
+	dump_reg(decoder->client, REG_COMP_Y_CONTRAST, value);
+	dump_reg(decoder->client, REG_COMP_PB_SATURATION, value);
+	dump_reg(decoder->client, REG_COMP_Y_BRIGHTNESS, value);
+	dump_reg(decoder->client, REG_AVID_START_PIXEL_LSB, value);
+	dump_reg(decoder->client, REG_AVID_START_PIXEL_MSB, value);
+	dump_reg(decoder->client, REG_AVID_STOP_PIXEL_LSB, value);
+	dump_reg(decoder->client, REG_AVID_STOP_PIXEL_MSB, value);
+	dump_reg(decoder->client, REG_HSYNC_START_PIXEL_LSB, value);
+	dump_reg(decoder->client, REG_HSYNC_START_PIXEL_MSB, value);
+	dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_LSB, value);
+	dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_MSB, value);
+	dump_reg(decoder->client, REG_VSYNC_START_LINE_LSB, value);
+	dump_reg(decoder->client, REG_VSYNC_START_LINE_MSB, value);
+	dump_reg(decoder->client, REG_VSYNC_STOP_LINE_LSB, value);
+	dump_reg(decoder->client, REG_VSYNC_STOP_LINE_MSB, value);
+	dump_reg(decoder->client, REG_VBLK_START_LINE_LSB, value);
+	dump_reg(decoder->client, REG_VBLK_START_LINE_MSB, value);
+	dump_reg(decoder->client, REG_VBLK_STOP_LINE_LSB, value);
+	dump_reg(decoder->client, REG_VBLK_STOP_LINE_MSB, value);
+	dump_reg(decoder->client, REG_SYNC_CONTROL, value);
+	dump_reg(decoder->client, REG_OUTPUT_FORMATTER1, value);
+	dump_reg(decoder->client, REG_OUTPUT_FORMATTER2, value);
+	dump_reg(decoder->client, REG_OUTPUT_FORMATTER3, value);
+	dump_reg(decoder->client, REG_OUTPUT_FORMATTER4, value);
+	dump_reg(decoder->client, REG_OUTPUT_FORMATTER5, value);
+	dump_reg(decoder->client, REG_OUTPUT_FORMATTER6, value);
+	dump_reg(decoder->client, REG_CLEAR_LOST_LOCK, value);
+}
+
+/*
+ * Configure the TVP5146/47 with the current register settings
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tvp514x_configure(struct tvp514x_decoder *decoder)
+{
+	int err;
+
+	/* common register initialization */
+	err =
+	    tvp514x_write_regs(decoder->client, tvp514x_reg_list);
+	if (err)
+		return err;
+
+	if (debug)
+		tvp514x_reg_dump(decoder);
+
+	return 0;
+}
+
+/*
+ * Detect if an tvp514x 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 tvp514x_detect(struct tvp514x_decoder *decoder)
+{
+	u8 chip_id_msb, chip_id_lsb, rom_ver;
+
+	chip_id_msb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_MSB);
+	chip_id_lsb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_LSB);
+	rom_ver = tvp514x_read_reg(decoder->client, REG_ROM_VERSION);
+
+	v4l_dbg(1, debug, decoder->client,
+		 "chip id detected msb:0x%x lsb:0x%x rom version:0x%x\n",
+		 chip_id_msb, chip_id_lsb, rom_ver);
+	if ((chip_id_msb != TVP514X_CHIP_ID_MSB)
+		|| ((chip_id_lsb != TVP5146_CHIP_ID_LSB)
+		&& (chip_id_lsb != TVP5147_CHIP_ID_LSB))) {
+		/* We didn't read the values we expected, so this must not be
+		 * an TVP5146/47.
+		 */
+		v4l_err(decoder->client,
+			"chip id mismatch msb:0x%x lsb:0x%x\n",
+			chip_id_msb, chip_id_lsb);
+		return -ENODEV;
+	}
+
+	decoder->ver = rom_ver;
+	decoder->state = STATE_DETECTED;
+
+	v4l_info(decoder->client,
+			"\n%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
+ * TVP5146/47 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 TVP5146/47. If no active input is
+ * detected, returns -EINVAL
+ */
+static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id)
+{
+	struct tvp514x_decoder *decoder = s->priv;
+	enum tvp514x_std current_std;
+	enum tvp514x_input input_sel;
+	u8 sync_lock_status, lock_mask;
+
+	if (std_id == NULL)
+		return -EINVAL;
+
+	/* get the current standard */
+	current_std = tvp514x_get_current_std(decoder);
+	if (current_std == STD_INVALID)
+		return -EINVAL;
+
+	input_sel = decoder->pdata->input_list[decoder->inputidx].input_sel;
+
+	switch (input_sel) {
+	case INPUT_CVBS_VI1A:
+	case INPUT_CVBS_VI1B:
+	case INPUT_CVBS_VI1C:
+	case INPUT_CVBS_VI2A:
+	case INPUT_CVBS_VI2B:
+	case INPUT_CVBS_VI2C:
+	case INPUT_CVBS_VI3A:
+	case INPUT_CVBS_VI3B:
+	case INPUT_CVBS_VI3C:
+	case INPUT_CVBS_VI4A:
+		lock_mask = STATUS_CLR_SUBCAR_LOCK_BIT |
+			STATUS_HORZ_SYNC_LOCK_BIT |
+			STATUS_VIRT_SYNC_LOCK_BIT;
+		break;
+
+	case INPUT_SVIDEO_VI2A_VI1A:
+	case INPUT_SVIDEO_VI2B_VI1B:
+	case INPUT_SVIDEO_VI2C_VI1C:
+	case INPUT_SVIDEO_VI2A_VI3A:
+	case INPUT_SVIDEO_VI2B_VI3B:
+	case INPUT_SVIDEO_VI2C_VI3C:
+	case INPUT_SVIDEO_VI4A_VI1A:
+	case INPUT_SVIDEO_VI4A_VI1B:
+	case INPUT_SVIDEO_VI4A_VI1C:
+	case INPUT_SVIDEO_VI4A_VI3A:
+	case INPUT_SVIDEO_VI4A_VI3B:
+	case INPUT_SVIDEO_VI4A_VI3C:
+		lock_mask = STATUS_HORZ_SYNC_LOCK_BIT |
+			STATUS_VIRT_SYNC_LOCK_BIT;
+		break;
+		/*Need to add other interfaces*/
+	default:
+		return -EINVAL;
+	}
+	/* check whether signal is locked */
+	sync_lock_status = tvp514x_read_reg(decoder->client, REG_STATUS1);
+	if (lock_mask != (sync_lock_status & lock_mask))
+		return -EINVAL;	/* No input detected */
+
+	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 tvp514x_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 == STD_INVALID))
+		return -EINVAL;
+
+	err = tvp514x_write_reg(decoder->client, REG_VIDEO_STD,
+				decoder->std_list[i].video_std);
+	if (err)
+		return err;
+
+	decoder->current_std = i;
+	tvp514x_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, int index)
+{
+	struct tvp514x_decoder *decoder = s->priv;
+	int err;
+	enum tvp514x_input input_sel;
+	enum tvp514x_std current_std = STD_INVALID;
+	u8 sync_lock_status, lock_mask;
+	int try_count = LOCK_RETRY_COUNT;
+
+	if ((index >= decoder->pdata->num_inputs) || (index < 0))
+		return -EINVAL;	/* Index out of bound */
+
+	/* Get the register value to be written to select the requested input */
+	input_sel = decoder->pdata->input_list[index].input_sel;
+	err = tvp514x_write_reg(decoder->client, REG_INPUT_SEL, input_sel);
+	if (err)
+		return err;
+
+	decoder->inputidx = index;
+	tvp514x_reg_list[REG_INPUT_SEL].val = input_sel;
+
+	/* Clear status */
+	msleep(LOCK_RETRY_DELAY);
+	err =
+	    tvp514x_write_reg(decoder->client, REG_CLEAR_LOST_LOCK, 0x01);
+	if (err)
+		return err;
+
+	switch (input_sel) {
+	case INPUT_CVBS_VI1A:
+	case INPUT_CVBS_VI1B:
+	case INPUT_CVBS_VI1C:
+	case INPUT_CVBS_VI2A:
+	case INPUT_CVBS_VI2B:
+	case INPUT_CVBS_VI2C:
+	case INPUT_CVBS_VI3A:
+	case INPUT_CVBS_VI3B:
+	case INPUT_CVBS_VI3C:
+	case INPUT_CVBS_VI4A:
+		lock_mask = STATUS_CLR_SUBCAR_LOCK_BIT |
+			STATUS_HORZ_SYNC_LOCK_BIT |
+			STATUS_VIRT_SYNC_LOCK_BIT;
+		break;
+
+	case INPUT_SVIDEO_VI2A_VI1A:
+	case INPUT_SVIDEO_VI2B_VI1B:
+	case INPUT_SVIDEO_VI2C_VI1C:
+	case INPUT_SVIDEO_VI2A_VI3A:
+	case INPUT_SVIDEO_VI2B_VI3B:
+	case INPUT_SVIDEO_VI2C_VI3C:
+	case INPUT_SVIDEO_VI4A_VI1A:
+	case INPUT_SVIDEO_VI4A_VI1B:
+	case INPUT_SVIDEO_VI4A_VI1C:
+	case INPUT_SVIDEO_VI4A_VI3A:
+	case INPUT_SVIDEO_VI4A_VI3B:
+	case INPUT_SVIDEO_VI4A_VI3C:
+		lock_mask = STATUS_HORZ_SYNC_LOCK_BIT |
+			STATUS_VIRT_SYNC_LOCK_BIT;
+		break;
+	/*Need to add other interfaces*/
+	default:
+		return -EINVAL;
+	}
+
+	while (try_count-- > 0) {
+		/* Allow decoder to sync up with new input */
+		msleep(LOCK_RETRY_DELAY);
+
+		/* get the current standard for future reference */
+		current_std = tvp514x_get_current_std(decoder);
+		if (current_std == STD_INVALID)
+			continue;
+
+		sync_lock_status = tvp514x_read_reg(decoder->client,
+				REG_STATUS1);
+		if (lock_mask == (sync_lock_status & lock_mask))
+			break;	/* Input detected */
+	}
+
+	if ((current_std == STD_INVALID) || (try_count < 0))
+		return -EINVAL;
+
+	decoder->current_std = current_std;
+
+	v4l_dbg(1, debug, decoder->client,
+			"Input set to: index - %d (%s)",
+			decoder->pdata->input_list[index].input.index,
+			decoder->pdata->input_list[index].input.name);
+	return 0;
+}
+
+/**
+ * ioctl_g_routing - V4L2 decoder interface handler for VIDIOC_G_INPUT ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @index: returns the current selected input
+ *
+ * Returns the current selected input. Returns -EINVAL if any error occurs
+ */
+static int ioctl_g_routing(struct v4l2_int_device *s, int *index)
+{
+	struct tvp514x_decoder *decoder = s->priv;
+	int err = -EINVAL, i, inputidx;
+
+	if (index == NULL)
+		return err;
+
+	/* Search through the input list for active inputs */
+	inputidx = decoder->inputidx;
+	for (i = 0; i < decoder->pdata->num_inputs; i++) {
+		inputidx++;	/* Move to next input */
+		if (inputidx >= decoder->pdata->num_inputs)
+			inputidx = 0;	/* fall back to first input */
+
+		err = ioctl_s_routing(s, inputidx);
+		if (!err) {
+			/* Active input found - select it and return success */
+			*index = inputidx;
+			return 0;
+		}
+	}
+
+	return err;
+}
+
+/**
+ * ioctl_queryctrl - V4L2 decoder interface handler for VIDIOC_QUERYCTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @qc: standard V4L2 VIDIOC_QUERYCTRL ioctl structure
+ *
+ * If the requested control is supported, returns the control information
+ * from the ctrl_list[] array. Otherwise, returns -EINVAL if the
+ * control is not supported.
+ */
+static int
+ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
+{
+	struct tvp514x_decoder *decoder = s->priv;
+	int id, index;
+	const struct tvp514x_ctrl_info *control = NULL;
+
+	if (qctrl == NULL)
+		return -EINVAL;
+
+	id = qctrl->id;
+	memset(qctrl, 0, sizeof(struct v4l2_queryctrl));
+	qctrl->id = id;
+
+	for (index = 0; index < decoder->num_ctrls; index++) {
+		control = &decoder->ctrl_list[index];
+		if (control->query_ctrl.id == qctrl->id)
+			break;	/* Match found */
+	}
+	if (index == decoder->num_ctrls)
+		return -EINVAL;	/* Index out of bound */
+
+	memcpy(qctrl, &control->query_ctrl, sizeof(struct v4l2_queryctrl));
+
+	v4l_dbg(1, debug, decoder->client,
+			"Query Control: %s : Min - %d, Max - %d, Def - %d",
+			control->query_ctrl.name,
+			control->query_ctrl.minimum,
+			control->query_ctrl.maximum,
+			control->query_ctrl.default_value);
+	return 0;
+}
+
+/**
+ * ioctl_g_ctrl - V4L2 decoder interface handler for VIDIOC_G_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_G_CTRL ioctl 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 tvp514x_decoder *decoder = s->priv;
+	int index, value;
+	const struct tvp514x_ctrl_info *control = NULL;
+
+	if (ctrl == NULL)
+		return -EINVAL;
+
+	for (index = 0; index < decoder->num_ctrls; index++) {
+		control = &decoder->ctrl_list[index];
+		if (control->query_ctrl.id == ctrl->id)
+			break;	/* Match found */
+	}
+	if (index == decoder->num_ctrls)
+		return -EINVAL;	/* Index out of bound */
+
+	value =
+	    tvp514x_read_reg(decoder->client, control->reg_address);
+
+	/* cross check */
+	if (value != tvp514x_reg_list[control->reg_address].val)
+		return -EINVAL;	/* Driver & TVP5146/47 setting mismatch */
+
+	if (V4L2_CID_AUTOGAIN == ctrl->id) {
+		if ((value & 0x3) == 3)
+			value = 1;
+		else
+			value = 0;
+	}
+
+	if (V4L2_CID_HUE == ctrl->id) {
+		if (value == 0x7F)
+			value = 180;
+		else if (value == 0x80)
+			value = -180;
+		else
+			value = 0;
+	}
+
+	ctrl->value = value;
+
+	v4l_dbg(1, debug, decoder->client,
+			"Get Cotrol: %s - %d",
+			control->query_ctrl.name, value);
+	return 0;
+}
+
+/**
+ * ioctl_s_ctrl - V4L2 decoder interface handler for VIDIOC_S_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_S_CTRL ioctl 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 tvp514x_decoder *decoder = s->priv;
+	int err, value, index;
+	const struct tvp514x_ctrl_info *control = NULL;
+
+	if (ctrl == NULL)
+		return -EINVAL;
+
+	value = (__s32) ctrl->value;
+	for (index = 0; index < decoder->num_ctrls; index++) {
+		control = &decoder->ctrl_list[index];
+		if (control->query_ctrl.id == ctrl->id)
+			break;	/* Match found */
+	}
+	if (index == decoder->num_ctrls)
+		return -EINVAL;	/* Index out of bound */
+
+	if (V4L2_CID_AUTOGAIN == ctrl->id) {
+		if (value == 1)
+			value = 0x0F;
+		else if (value == 0)
+			value = 0x0C;
+		else
+			return -ERANGE;
+	} else if (V4L2_CID_HUE == ctrl->id) {
+		if (value == 180)
+			value = 0x7F;
+		else if (value == -180)
+			value = 0x80;
+		else if (value == 0)
+			value = 0;
+		else
+			return -ERANGE;
+	} else {
+		if ((value < control->query_ctrl.minimum)
+			|| (value > control->query_ctrl.maximum))
+			return -ERANGE;
+	}
+
+	err =
+	    tvp514x_write_reg(decoder->client, control->reg_address,
+				value);
+	if (err)
+		return err;
+
+	tvp514x_reg_list[control->reg_address].val = value;
+
+	v4l_dbg(1, debug, decoder->client,
+			"Set Cotrol: %s - %d",
+			control->query_ctrl.name, 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 tvp514x_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 tvp514x_decoder *decoder = s->priv;
+	int ifmt;
+	struct v4l2_pix_format *pix;
+	enum tvp514x_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 = tvp514x_get_current_std(decoder);
+	if (current_std == 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_INTERLACED;
+	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 tvp514x_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;
+	else
+		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 tvp514x_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 tvp514x_decoder *decoder = s->priv;
+	struct v4l2_captureparm *cparm;
+	enum tvp514x_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 = tvp514x_get_current_std(decoder);
+	if (current_std == 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 tvp514x_decoder *decoder = s->priv;
+	struct v4l2_fract *timeperframe;
+	enum tvp514x_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 = tvp514x_get_current_std(decoder);
+	if (current_std == 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 tvp514x_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 = TVP514X_XCLK_BT656;
+
+	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 tvp514x_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 tvp514x_decoder *decoder = s->priv;
+	int err = 0;
+
+	switch (on) {
+	case V4L2_POWER_OFF:
+		/* Power Down Sequence */
+		err =
+		    tvp514x_write_reg(decoder->client, REG_OPERATION_MODE,
+					0x01);
+		/* Disable mux for TVP5146/47 decoder data path */
+		if (decoder->pdata->power_set)
+			err |= decoder->pdata->power_set(on);
+		decoder->state = STATE_NOT_DETECTED;
+		break;
+
+	case V4L2_POWER_STANDBY:
+		if (decoder->pdata->power_set)
+			err = decoder->pdata->power_set(on);
+		break;
+
+	case V4L2_POWER_ON:
+		/* Enable mux for TVP5146/47 decoder data path */
+		if ((decoder->pdata->power_set) &&
+				(decoder->state == STATE_NOT_DETECTED)) {
+			int i;
+			struct tvp514x_init_seq *int_seq =
+				(struct tvp514x_init_seq *)
+				decoder->id->driver_data;
+
+			err = decoder->pdata->power_set(on);
+
+			/* Power Up Sequence */
+			for (i = 0; i < int_seq->no_regs; i++) {
+				err |= tvp514x_write_reg(decoder->client,
+						int_seq->init_reg_seq[i].reg,
+						int_seq->init_reg_seq[i].val);
+			}
+			/* Detect the sensor is not already detected */
+			err |= tvp514x_detect(decoder);
+			if (err) {
+				v4l_err(decoder->client,
+						"Unable to detect decoder\n");
+				return err;
+			}
+		}
+		err |= tvp514x_configure(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 tvp514x_configure())
+ */
+static int ioctl_init(struct v4l2_int_device *s)
+{
+	struct tvp514x_decoder *decoder = s->priv;
+
+	/* Set default standard to auto */
+	tvp514x_reg_list[REG_VIDEO_STD].val =
+	    VIDEO_STD_AUTO_SWITCH_BIT;
+
+	return tvp514x_configure(decoder);
+}
+
+/**
+ * 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
+ * TVP5146/47 device could be found, otherwise returns appropriate error.
+ */
+static int ioctl_dev_init(struct v4l2_int_device *s)
+{
+	struct tvp514x_decoder *decoder = s->priv;
+	int err;
+
+	err = tvp514x_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);
+
+	return 0;
+}
+
+static struct v4l2_int_ioctl_desc tvp514x_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_g_video_routing_num,
+		(v4l2_int_ioctl_func *) ioctl_g_routing},
+	{vidioc_int_s_video_routing_num,
+		(v4l2_int_ioctl_func *) ioctl_s_routing},
+};
+
+static struct v4l2_int_slave tvp514x_slave = {
+	.ioctls = tvp514x_ioctl_desc,
+	.num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc),
+};
+
+static struct tvp514x_decoder tvp514x_dev = {
+	.state = STATE_NOT_DETECTED,
+
+	.num_fmts = TVP514X_NUM_FORMATS,
+	.fmt_list = tvp514x_fmt_list,
+
+	.pix = {		/* Default to NTSC 8-bit YUV 422 */
+		.width = NTSC_NUM_ACTIVE_PIXELS,
+		.height = NTSC_NUM_ACTIVE_LINES,
+		.pixelformat = V4L2_PIX_FMT_UYVY,
+		.field = V4L2_FIELD_INTERLACED,
+		.bytesperline = NTSC_NUM_ACTIVE_PIXELS * 2,
+		.sizeimage =
+		NTSC_NUM_ACTIVE_PIXELS * 2 * NTSC_NUM_ACTIVE_LINES,
+		.colorspace = V4L2_COLORSPACE_SMPTE170M,
+		},
+
+	.current_std = STD_NTSC_MJ,
+	.num_stds = TVP514X_NUM_STANDARDS,
+	.std_list = tvp514x_std_list,
+
+	.num_ctrls = TVP514X_NUM_CONTROLS,
+	.ctrl_list = tvp514x_ctrl_list,
+
+};
+
+static struct v4l2_int_device tvp514x_int_device = {
+	.module = THIS_MODULE,
+	.name = MODULE_NAME,
+	.priv = &tvp514x_dev,
+	.type = v4l2_int_type_slave,
+	.u = {
+	      .slave = &tvp514x_slave,
+	      },
+};
+
+/**
+ * tvp514x_probe - decoder driver i2c probe handler
+ * @client: i2c driver client device structure
+ *
+ * Register decoder as an i2c client device and V4L2
+ * device.
+ */
+static int
+tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	struct tvp514x_decoder *decoder = &tvp514x_dev;
+	int err;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	decoder->pdata = client->dev.platform_data;
+	if (!decoder->pdata) {
+		v4l_err(client, "No platform data\n!!");
+		return -ENODEV;
+	}
+	/*
+	 * Fetch platform specific data, and configure the
+	 * tvp514x_reg_list[] accordingly. Since this is one
+	 * time configuration, no need to preserve.
+	 */
+	decoder->inputidx = decoder->pdata->default_input;
+	tvp514x_reg_list[REG_OUTPUT_FORMATTER2].val |=
+			(decoder->pdata->clk_polarity << 1);
+	tvp514x_reg_list[REG_OUTPUT_FORMATTER1].val |=
+			decoder->pdata->fmt;
+	tvp514x_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(tvp514x_int_device.u.slave->attach_to, decoder->pdata->master);
+	decoder->v4l2_int_device = &tvp514x_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;
+}
+
+/**
+ * tvp514x_remove - decoder driver i2c remove handler
+ * @client: i2c driver client device structure
+ *
+ * Unregister decoder as an i2c client device and V4L2
+ * device. Complement of tvp514x_probe().
+ */
+static int __exit tvp514x_remove(struct i2c_client *client)
+{
+	struct tvp514x_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;
+}
+/*
+ * TVP5146 Init/Power on Sequence
+ */
+static struct tvp514x_reg tvp5146_init_reg_seq[] = {
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0x80},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
+	{TOK_WRITE, REG_OPERATION_MODE, 0x01},
+	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
+};
+static struct tvp514x_init_seq tvp5146_init = {
+	.no_regs = ARRAY_SIZE(tvp5146_init_reg_seq),
+	.init_reg_seq = tvp5146_init_reg_seq,
+};
+/*
+ * TVP5147 Init/Power on Sequence
+ */
+static struct tvp514x_reg tvp5147_init_reg_seq[] =	{
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0x80},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x16},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xA0},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x16},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
+	{TOK_WRITE, REG_OPERATION_MODE, 0x01},
+	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
+};
+static struct tvp514x_init_seq tvp5147_init = {
+	.no_regs = ARRAY_SIZE(tvp5147_init_reg_seq),
+	.init_reg_seq = tvp5147_init_reg_seq,
+};
+/*
+ * TVP5146M2/TVP5147M1 Init/Power on Sequence
+ */
+static struct tvp514x_reg tvp514xm_init_reg_seq[] = {
+	{TOK_WRITE, REG_OPERATION_MODE, 0x01},
+	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
+};
+static struct tvp514x_init_seq tvp514xm_init = {
+	.no_regs = ARRAY_SIZE(tvp514xm_init_reg_seq),
+	.init_reg_seq = tvp514xm_init_reg_seq,
+};
+/*
+ * I2C Device Table -
+ *
+ * name - Name of the actual device/chip.
+ * driver_data - Driver data
+ */
+static const struct i2c_device_id tvp514x_id[] = {
+	{"tvp5146", (unsigned int)&tvp5146_init},
+	{"tvp5146m2", (unsigned int)&tvp514xm_init},
+	{"tvp5147", (unsigned int)&tvp5147_init},
+	{"tvp5147m1", (unsigned int)&tvp514xm_init},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, tvp514x_id);
+
+static struct i2c_driver tvp514x_i2c_driver = {
+	.driver = {
+		   .name = MODULE_NAME,
+		   .owner = THIS_MODULE,
+		   },
+	.probe = tvp514x_probe,
+	.remove = __exit_p(tvp514x_remove),
+	.id_table = tvp514x_id,
+};
+
+/**
+ * tvp514x_init
+ *
+ * Module init function
+ */
+static int __init tvp514x_init(void)
+{
+	int err;
+
+	err = i2c_add_driver(&tvp514x_i2c_driver);
+	if (err) {
+		printk(KERN_ERR "Failed to register " MODULE_NAME ".\n");
+		return err;
+	}
+	return 0;
+}
+
+/**
+ * tvp514x_cleanup
+ *
+ * Module exit function
+ */
+static void __exit tvp514x_cleanup(void)
+{
+	i2c_del_driver(&tvp514x_i2c_driver);
+}
+
+module_init(tvp514x_init);
+module_exit(tvp514x_cleanup);
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("TVP514X linux decoder driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tvp514x_regs.h b/drivers/media/video/tvp514x_regs.h
new file mode 100755
index 0000000..003a3c1
--- /dev/null
+++ b/drivers/media/video/tvp514x_regs.h
@@ -0,0 +1,292 @@
+/*
+ * drivers/media/video/tvp514x_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 _TVP514X_REGS_H
+#define _TVP514X_REGS_H
+
+/*
+ * TVP5146/47 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 */
+
+/*
+ * Mask and bit definitions of TVP5146/47 registers
+ */
+/* The ID values we are looking for */
+#define TVP514X_CHIP_ID_MSB		(0x51)
+#define TVP5146_CHIP_ID_LSB		(0x46)
+#define TVP5147_CHIP_ID_LSB		(0x47)
+
+#define VIDEO_STD_MASK			(0x07)
+#define VIDEO_STD_AUTO_SWITCH_BIT	(0x00)
+#define VIDEO_STD_NTSC_MJ_BIT		(0x01)
+#define VIDEO_STD_PAL_BDGHIN_BIT	(0x02)
+#define VIDEO_STD_PAL_M_BIT		(0x03)
+#define VIDEO_STD_PAL_COMBINATION_N_BIT	(0x04)
+#define VIDEO_STD_NTSC_4_43_BIT		(0x05)
+#define VIDEO_STD_SECAM_BIT		(0x06)
+#define VIDEO_STD_PAL_60_BIT		(0x07)
+
+/*
+ * 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)
+
+/**
+ * struct tvp514x_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 tvp514x_reg {
+	u8 token;
+	u8 reg;
+	u32 val;
+};
+
+/**
+ * struct tvp514x_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 tvp514x_init_seq {
+	unsigned int no_regs;
+	struct tvp514x_reg *init_reg_seq;
+};
+#endif				/* ifndef _TVP514X_REGS_H */
diff --git a/include/media/tvp514x.h b/include/media/tvp514x.h
new file mode 100755
index 0000000..2fee5e7
--- /dev/null
+++ b/include/media/tvp514x.h
@@ -0,0 +1,232 @@
+/*
+ * drivers/media/video/tvp514x.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 _TVP514X_H
+#define _TVP514X_H
+
+/*
+ * Other macros
+ */
+#define TVP514X_MODULE_NAME		"tvp514x"
+#define TVP514X_I2C_DELAY		(3)
+#define I2C_RETRY_COUNT			(5)
+#define LOCK_RETRY_COUNT		(5)
+#define LOCK_RETRY_DELAY		(200)
+
+#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 */
+
+#define TVP514X_XCLK_BT656		(27000000)
+
+/* Number of pixels and number of lines per frame for different standards */
+#define NTSC_NUM_ACTIVE_PIXELS		(720)
+#define NTSC_NUM_ACTIVE_LINES		(480)
+#define PAL_NUM_ACTIVE_PIXELS		(720)
+#define PAL_NUM_ACTIVE_LINES		(576)
+
+/**
+ * enum tvp514x_std - enum for supported standards
+ */
+enum tvp514x_std {
+	STD_NTSC_MJ = 0,
+	STD_PAL_BDGHIN,
+	STD_INVALID
+};
+
+/**
+ * enum tvp514x_state - enum for different decoder states
+ */
+enum tvp514x_state {
+	STATE_NOT_DETECTED,
+	STATE_DETECTED
+};
+
+/**
+ * enum tvp514x_input - enum for different decoder input pin
+ *		configuration.
+ */
+enum tvp514x_input {
+	/*
+	 * CVBS input selection
+	 */
+	INPUT_CVBS_VI1A = 0x0,
+	INPUT_CVBS_VI1B,
+	INPUT_CVBS_VI1C,
+	INPUT_CVBS_VI2A = 0x04,
+	INPUT_CVBS_VI2B,
+	INPUT_CVBS_VI2C,
+	INPUT_CVBS_VI3A = 0x08,
+	INPUT_CVBS_VI3B,
+	INPUT_CVBS_VI3C,
+	INPUT_CVBS_VI4A = 0x0C,
+	/*
+	 * S-Video input selection
+	 */
+	INPUT_SVIDEO_VI2A_VI1A = 0x44,
+	INPUT_SVIDEO_VI2B_VI1B,
+	INPUT_SVIDEO_VI2C_VI1C,
+	INPUT_SVIDEO_VI2A_VI3A = 0x54,
+	INPUT_SVIDEO_VI2B_VI3B,
+	INPUT_SVIDEO_VI2C_VI3C,
+	INPUT_SVIDEO_VI4A_VI1A = 0x4C,
+	INPUT_SVIDEO_VI4A_VI1B,
+	INPUT_SVIDEO_VI4A_VI1C,
+	INPUT_SVIDEO_VI4A_VI3A = 0x5C,
+	INPUT_SVIDEO_VI4A_VI3B,
+	INPUT_SVIDEO_VI4A_VI3C
+
+	/* Need to add entries for
+	 * RGB, YPbPr and SCART.
+	 */
+};
+
+/**
+ * enum tvp514x_output_fmt - enum for output format
+ *			supported.
+ */
+enum tvp514x_output_fmt {
+	OUTPUT_10BIT_422_EMBEDDED_SYNC = 0,
+	OUTPUT_20BIT_422_SEPERATE_SYNC,
+	OUTPUT_10BIT_422_SEPERATE_SYNC = 3,
+	OUTPUT_INVALID
+};
+
+/**
+ * struct tvp514x_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 tvp514x_std_info {
+	unsigned long width;
+	unsigned long height;
+	u8 video_std;
+	struct v4l2_standard standard;
+};
+
+/**
+ * struct tvp514x_ctrl_info - Information regarding supported controls
+ * @reg_address: Register offset of control register
+ * @query_ctrl: v4l2 query control information
+ */
+struct tvp514x_ctrl_info {
+	u8 reg_address;
+	struct v4l2_queryctrl query_ctrl;
+};
+
+/**
+ * struct tvp514x_input_info - Information regarding supported inputs
+ * @input_sel: Input select register
+ * @lock_mask: lock mask - depends on Svideo/CVBS
+ * @input: v4l2 input information
+ */
+struct tvp514x_input_info {
+	enum tvp514x_input input_sel;
+	struct v4l2_input input;
+};
+
+/**
+ * struct tvp514x_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
+ * @reg_list: The board dependent driver should fill the default value for
+ *            required registers depending on board layout. The TVP5146/47
+ *            driver will update this register list for the registers
+ *            whose values should be maintained across open()/close() like
+ *            setting brightness as defined in V4L2.
+ *            The register list should be in the same order as defined in
+ *            TVP5146/47 datasheet including reserved registers. As of now
+ *            the driver expects the size of this list to be a minimum of
+ *            57 + 1 (upto regsiter REG_CLEAR_LOST_LOCK).
+ *            The last member should be of the list should be
+ *            {TOK_TERM, 0, 0} to indicate the end of register list.
+ * @num_inputs: Number of input connection in board
+ * @input_list: Input information list for num_inputs
+ */
+struct tvp514x_platform_data {
+	char *master;
+	int (*power_set) (enum v4l2_power on);
+	int (*ifparm) (struct v4l2_ifparm *p);
+	int (*priv_data_set) (void *);
+	/* Input params */
+	int num_inputs;
+	const struct tvp514x_input_info *input_list;
+	int default_input;
+	/* Interface control params */
+	enum tvp514x_output_fmt fmt;
+	bool clk_polarity;
+	bool hs_polarity;
+	bool vs_polarity;
+};
+
+/**
+ * struct tvp514x_decoded - TVP5146/47 decoder object
+ * @v4l2_int_device: Slave handle
+ * @pdata: Board specific
+ * @client: I2C client data
+ * @id: Entry from I2C table
+ * @ver: Chip version
+ * @state: TVP5146/47 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
+ * @num_ctrls: Number of controls
+ * @ctrl_list: Control list
+ */
+struct tvp514x_decoder {
+	struct v4l2_int_device *v4l2_int_device;
+	const struct tvp514x_platform_data *pdata;
+	struct i2c_client *client;
+
+	struct i2c_device_id *id;
+
+	int ver;
+	enum tvp514x_state state;
+
+	struct v4l2_pix_format pix;
+	int num_fmts;
+	const struct v4l2_fmtdesc *fmt_list;
+
+	enum tvp514x_std current_std;
+	int num_stds;
+	struct tvp514x_std_info *std_list;
+
+	int num_ctrls;
+	const struct tvp514x_ctrl_info *ctrl_list;
+
+	int inputidx;
+};
+
+#endif				/* ifndef _TVP514X_H */
--
1.5.6

--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request@redhat.com?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list

WARNING: multiple messages have this Message-ID (diff)
From: hvaibhav@ti.com
To: video4linux-list@redhat.com
Cc: linux-omap@vger.kernel.org,
	davinci-linux-open-source-bounces@linux.davincidsp.com,
	Vaibhav Hiremath <hvaibhav@ti.com>,
	Brijesh Jadav <brijesh.j@ti.com>,
	Hardik Shah <hardik.shah@ti.com>, Manjunath Hadli <mrh@ti.com>,
	R Sivaraj <sivaraj@ti.com>,
	Karicheri Muralidharan <m-karicheri2@ti.com>
Subject: [PATCH 2/2] TVP514x Driver with Review comments fixed [V4]
Date: Tue,  2 Dec 2008 21:05:42 +0530	[thread overview]
Message-ID: <1228232142-11934-1-git-send-email-hvaibhav@ti.com> (raw)
In-Reply-To: <hvaibhav@ti.com>

From: Vaibhav Hiremath <hvaibhav@ti.com>

I have fixed all the review commentsreceived so far.
Here are the details -

FIXSES:
    Make use of i2c_smbus_read/write_byte API:
        Probe function now checks for SMBUS capability,
	and read/write functions make use of the above API.

    Error check for I2C Read/Write:
        Added error condition check for both read and write
	API.
	This has been added for completeness.

    input set/get ioctl:
        As we do have support for set and get routing ioctl,
	instead of adding new ioctl used them.

    enum_ioctl:
        After discussing with Hans verkuil, came to conclusion
	that as of now just remove support for enum_ioctl from
	decoder, since this has to handle at master driver level.

TODO LIST:
    OMAP Master capture driver:
        This should be completely aligned with the current
	discussion.

    Migration to sub_device framework:
        Immediately after all the above task, migrate both
	Master and slave driver to sub_device framework.

Signed-off-by: Brijesh Jadav <brijesh.j@ti.com>
Signed-off-by: Hardik Shah <hardik.shah@ti.com>
Signed-off-by: Manjunath Hadli <mrh@ti.com>
Signed-off-by: R Sivaraj <sivaraj@ti.com>
Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
Signed-off-by: Karicheri Muralidharan <m-karicheri2@ti.com>
---
 drivers/media/video/Kconfig        |   11 +
 drivers/media/video/Makefile       |    1 +
 drivers/media/video/tvp514x.c      | 1521 ++++++++++++++++++++++++++++++++++++
 drivers/media/video/tvp514x_regs.h |  292 +++++++
 include/media/tvp514x.h            |  232 ++++++
 5 files changed, 2057 insertions(+), 0 deletions(-)
 create mode 100755 drivers/media/video/tvp514x.c
 create mode 100755 drivers/media/video/tvp514x_regs.h
 create mode 100755 include/media/tvp514x.h

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 47102c2..2e5dc3e 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -361,6 +361,17 @@ config VIDEO_SAA7191
 	  To compile this driver as a module, choose M here: the
 	  module will be called saa7191.

+config VIDEO_TVP514X
+	tristate "Texas Instruments TVP514x video decoder"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	  This is a Video4Linux2 sensor-level driver for the TI TVP5146/47
+	  decoder. It is currently working with the TI OMAP3 camera
+	  controller.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called tvp514x.
+
 config VIDEO_TVP5150
 	tristate "Texas Instruments TVP5150 video decoder"
 	depends on VIDEO_V4L2 && I2C
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 16962f3..cdbbf38 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
 obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
 obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
 obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
+obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
 obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
 obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
 obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
new file mode 100755
index 0000000..c0834e4
--- /dev/null
+++ b/drivers/media/video/tvp514x.c
@@ -0,0 +1,1521 @@
+/*
+ * drivers/media/video/tvp514x.c
+ *
+ * TI TVP5146/47 decoder driver
+ *
+ * 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.
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-int-device.h>
+#include <media/tvp514x.h>
+
+#include "tvp514x_regs.h"
+
+#define MODULE_NAME	TVP514X_MODULE_NAME
+
+/* Debug functions */
+static int debug;
+module_param(debug, bool, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
+#define dump_reg(client, reg, val)				\
+	do {							\
+		val = tvp514x_read_reg(client, reg);		\
+		v4l_info(client, "Reg(0x%.2X): 0x%.2X\n", reg, val); \
+	} while (0)
+
+
+/* TVP514x default register values */
+static struct tvp514x_reg tvp514x_reg_list[] = {
+	{TOK_WRITE, REG_INPUT_SEL, 0x05},	/* Composite selected */
+	{TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F},
+	{TOK_WRITE, REG_VIDEO_STD, 0x00},	/* Auto mode */
+	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
+	{TOK_SKIP, REG_AUTOSWITCH_MASK, 0x3F},
+	{TOK_WRITE, REG_COLOR_KILLER, 0x10},
+	{TOK_WRITE, REG_LUMA_CONTROL1, 0x00},
+	{TOK_WRITE, REG_LUMA_CONTROL2, 0x00},
+	{TOK_WRITE, REG_LUMA_CONTROL3, 0x02},
+	{TOK_WRITE, REG_BRIGHTNESS, 0x80},
+	{TOK_WRITE, REG_CONTRAST, 0x80},
+	{TOK_WRITE, REG_SATURATION, 0x80},
+	{TOK_WRITE, REG_HUE, 0x00},
+	{TOK_WRITE, REG_CHROMA_CONTROL1, 0x00},
+	{TOK_WRITE, REG_CHROMA_CONTROL2, 0x0E},
+	{TOK_SKIP, 0x0F, 0x00},	/* Reserved */
+	{TOK_WRITE, REG_COMP_PR_SATURATION, 0x80},
+	{TOK_WRITE, REG_COMP_Y_CONTRAST, 0x80},
+	{TOK_WRITE, REG_COMP_PB_SATURATION, 0x80},
+	{TOK_SKIP, 0x13, 0x00},	/* Reserved */
+	{TOK_WRITE, REG_COMP_Y_BRIGHTNESS, 0x80},
+	{TOK_SKIP, 0x15, 0x00},	/* Reserved */
+	{TOK_SKIP, REG_AVID_START_PIXEL_LSB, 0x55},	/* NTSC timing */
+	{TOK_SKIP, REG_AVID_START_PIXEL_MSB, 0x00},
+	{TOK_SKIP, REG_AVID_STOP_PIXEL_LSB, 0x25},
+	{TOK_SKIP, REG_AVID_STOP_PIXEL_MSB, 0x03},
+	{TOK_SKIP, REG_HSYNC_START_PIXEL_LSB, 0x00},	/* NTSC timing */
+	{TOK_SKIP, REG_HSYNC_START_PIXEL_MSB, 0x00},
+	{TOK_SKIP, REG_HSYNC_STOP_PIXEL_LSB, 0x40},
+	{TOK_SKIP, REG_HSYNC_STOP_PIXEL_MSB, 0x00},
+	{TOK_SKIP, REG_VSYNC_START_LINE_LSB, 0x04},	/* NTSC timing */
+	{TOK_SKIP, REG_VSYNC_START_LINE_MSB, 0x00},
+	{TOK_SKIP, REG_VSYNC_STOP_LINE_LSB, 0x07},
+	{TOK_SKIP, REG_VSYNC_STOP_LINE_MSB, 0x00},
+	{TOK_SKIP, REG_VBLK_START_LINE_LSB, 0x01},	/* NTSC timing */
+	{TOK_SKIP, REG_VBLK_START_LINE_MSB, 0x00},
+	{TOK_SKIP, REG_VBLK_STOP_LINE_LSB, 0x15},
+	{TOK_SKIP, REG_VBLK_STOP_LINE_MSB, 0x00},
+	{TOK_SKIP, 0x26, 0x00},	/* Reserved */
+	{TOK_SKIP, 0x27, 0x00},	/* Reserved */
+	{TOK_SKIP, REG_FAST_SWTICH_CONTROL, 0xCC},
+	{TOK_SKIP, 0x29, 0x00},	/* Reserved */
+	{TOK_SKIP, REG_FAST_SWTICH_SCART_DELAY, 0x00},
+	{TOK_SKIP, 0x2B, 0x00},	/* Reserved */
+	{TOK_SKIP, REG_SCART_DELAY, 0x00},
+	{TOK_SKIP, REG_CTI_DELAY, 0x00},
+	{TOK_SKIP, REG_CTI_CONTROL, 0x00},
+	{TOK_SKIP, 0x2F, 0x00},	/* Reserved */
+	{TOK_SKIP, 0x30, 0x00},	/* Reserved */
+	{TOK_SKIP, 0x31, 0x00},	/* Reserved */
+	{TOK_WRITE, REG_SYNC_CONTROL, 0x00},	/* HS, VS active high */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER1, 0x00},	/* 10-bit BT.656 */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER2, 0x11},	/* Enable clk & data */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER3, 0xEE},	/* Enable AVID & FLD */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER4, 0xAF},	/* Enable VS & HS */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER5, 0xFF},
+	{TOK_WRITE, REG_OUTPUT_FORMATTER6, 0xFF},
+	{TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01},	/* Clear status */
+	{TOK_TERM, 0, 0},
+};
+
+/* List of image formats supported by TVP5146/47 decoder
+ * Currently we are using 8 bit mode only, but can be
+ * extended to 10/20 bit mode.
+ */
+static const struct v4l2_fmtdesc tvp514x_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,
+	},
+};
+
+#define TVP514X_NUM_FORMATS		ARRAY_SIZE(tvp514x_fmt_list)
+
+/*
+ * Supported standards -
+ *
+ * Currently supports two standards only, need to add support for rest of the
+ * modes, like SECAM, etc...
+ */
+static struct tvp514x_std_info tvp514x_std_list[] = {
+	/* Standard: STD_NTSC_MJ */
+	[STD_NTSC_MJ] = {
+	 .width = NTSC_NUM_ACTIVE_PIXELS,
+	 .height = NTSC_NUM_ACTIVE_LINES,
+	 .video_std = VIDEO_STD_NTSC_MJ_BIT,
+	 .standard = {
+		      .index = 0,
+		      .id = V4L2_STD_NTSC,
+		      .name = "NTSC",
+		      .frameperiod = {1001, 30000},
+		      .framelines = 525
+		     },
+	/* Standard: STD_PAL_BDGHIN */
+	},
+	[STD_PAL_BDGHIN] = {
+	 .width = PAL_NUM_ACTIVE_PIXELS,
+	 .height = PAL_NUM_ACTIVE_LINES,
+	 .video_std = VIDEO_STD_PAL_BDGHIN_BIT,
+	 .standard = {
+		      .index = 1,
+		      .id = V4L2_STD_PAL,
+		      .name = "PAL",
+		      .frameperiod = {1, 25},
+		      .framelines = 625
+		     },
+	},
+	/* Standard: need to add for additional standard */
+};
+
+#define TVP514X_NUM_STANDARDS		ARRAY_SIZE(tvp514x_std_list)
+
+/* Supported controls */
+static const struct tvp514x_ctrl_info tvp514x_ctrl_list[] = {
+	{
+	 .reg_address = REG_BRIGHTNESS,
+	 .query_ctrl = {
+			.id = V4L2_CID_BRIGHTNESS,
+			.name = "BRIGHTNESS",
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.minimum = 0,
+			.maximum = 255,
+			.step = 1,
+			.default_value = 128
+			},
+	}, {
+	 .reg_address = REG_CONTRAST,
+	 .query_ctrl = {
+			.id = V4L2_CID_CONTRAST,
+			.name = "CONTRAST",
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.minimum = 0,
+			.maximum = 255,
+			.step = 1,
+			.default_value = 128
+			},
+	}, {
+	 .reg_address = REG_SATURATION,
+	 .query_ctrl = {
+			.id = V4L2_CID_SATURATION,
+			.name = "SATURATION",
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.minimum = 0,
+			.maximum = 255,
+			.step = 1,
+			.default_value = 128
+			},
+	}, {
+	 .reg_address = REG_HUE,
+	 .query_ctrl = {
+			.id = V4L2_CID_HUE,
+			.name = "HUE",
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.minimum = -180,
+			.maximum = 180,
+			.step = 180,
+			.default_value = 0
+			},
+	}, {
+	 .reg_address = REG_AFE_GAIN_CTRL,
+	 .query_ctrl = {
+			.id = V4L2_CID_AUTOGAIN,
+			.name = "Automatic Gain Control",
+			.type = V4L2_CTRL_TYPE_BOOLEAN,
+			.minimum = 0,
+			.maximum = 1,
+			.step = 1,
+			.default_value = 1
+			},
+	 },
+};
+
+#define TVP514X_NUM_CONTROLS		ARRAY_SIZE(tvp514x_ctrl_list)
+
+/*
+ * Read a value from a register in an TVP5146/47 decoder device.
+ * Returns value read if successful, or non-zero (-1) otherwise.
+ */
+static int tvp514x_read_reg(struct i2c_client *client, u8 reg)
+{
+	int err;
+	int retry = 0;
+read_again:
+
+	err = i2c_smbus_read_byte_data(client, reg);
+	if (err == -1) {
+		if (retry <= I2C_RETRY_COUNT) {
+			v4l_warn(client, "Read: retry ... %d\n", retry);
+			retry++;
+			msleep_interruptible(10);
+			goto read_again;
+		}
+	}
+
+	return err;
+}
+
+/*
+ * Write a value to a register in an TVP5146/47 decoder device.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tvp514x_write_reg(struct i2c_client *client, u8 reg, u8 val)
+{
+	int err;
+	int retry = 0;
+write_again:
+
+	err = i2c_smbus_write_byte_data(client, reg, val);
+	if (err) {
+		if (retry <= I2C_RETRY_COUNT) {
+			v4l_warn(client, "Write: retry ... %d\n", retry);
+			retry++;
+			msleep_interruptible(10);
+			goto write_again;
+		}
+	}
+
+	return err;
+}
+
+/*
+ * tvp514x_write_regs : Initializes a list of TVP5146/47 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 tvp514x_write_regs(struct i2c_client *client,
+			      const struct tvp514x_reg reglist[])
+{
+	int err;
+	const struct tvp514x_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 = tvp514x_write_reg(client, next->reg, (u8) next->val);
+		if (err) {
+			v4l_err(client, "Write failed. Err[%d]\n", err);
+			return err;
+		}
+	}
+	return 0;
+}
+
+/*
+ * tvp514x_get_current_std:
+ * Returns the current standard detected by TVP5146/47
+ */
+static enum tvp514x_std tvp514x_get_current_std(struct tvp514x_decoder
+						*decoder)
+{
+	u8 std, std_status;
+
+	std = tvp514x_read_reg(decoder->client, REG_VIDEO_STD);
+	if ((std & VIDEO_STD_MASK) == VIDEO_STD_AUTO_SWITCH_BIT) {
+		/* use the standard status register */
+		std_status = tvp514x_read_reg(decoder->client,
+				REG_VIDEO_STD_STATUS);
+	} else
+		std_status = std;	/* use the standard register itself */
+
+	switch (std_status & VIDEO_STD_MASK) {
+	case VIDEO_STD_NTSC_MJ_BIT:
+		return STD_NTSC_MJ;
+
+	case VIDEO_STD_PAL_BDGHIN_BIT:
+		return STD_PAL_BDGHIN;
+
+	default:
+		return STD_INVALID;
+	}
+
+	return STD_INVALID;
+}
+
+/*
+ * TVP5146/47 register dump function
+ */
+void tvp514x_reg_dump(struct tvp514x_decoder *decoder)
+{
+	u8 value;
+
+	dump_reg(decoder->client, REG_INPUT_SEL, value);
+	dump_reg(decoder->client, REG_AFE_GAIN_CTRL, value);
+	dump_reg(decoder->client, REG_VIDEO_STD, value);
+	dump_reg(decoder->client, REG_OPERATION_MODE, value);
+	dump_reg(decoder->client, REG_COLOR_KILLER, value);
+	dump_reg(decoder->client, REG_LUMA_CONTROL1, value);
+	dump_reg(decoder->client, REG_LUMA_CONTROL2, value);
+	dump_reg(decoder->client, REG_LUMA_CONTROL3, value);
+	dump_reg(decoder->client, REG_BRIGHTNESS, value);
+	dump_reg(decoder->client, REG_CONTRAST, value);
+	dump_reg(decoder->client, REG_SATURATION, value);
+	dump_reg(decoder->client, REG_HUE, value);
+	dump_reg(decoder->client, REG_CHROMA_CONTROL1, value);
+	dump_reg(decoder->client, REG_CHROMA_CONTROL2, value);
+	dump_reg(decoder->client, REG_COMP_PR_SATURATION, value);
+	dump_reg(decoder->client, REG_COMP_Y_CONTRAST, value);
+	dump_reg(decoder->client, REG_COMP_PB_SATURATION, value);
+	dump_reg(decoder->client, REG_COMP_Y_BRIGHTNESS, value);
+	dump_reg(decoder->client, REG_AVID_START_PIXEL_LSB, value);
+	dump_reg(decoder->client, REG_AVID_START_PIXEL_MSB, value);
+	dump_reg(decoder->client, REG_AVID_STOP_PIXEL_LSB, value);
+	dump_reg(decoder->client, REG_AVID_STOP_PIXEL_MSB, value);
+	dump_reg(decoder->client, REG_HSYNC_START_PIXEL_LSB, value);
+	dump_reg(decoder->client, REG_HSYNC_START_PIXEL_MSB, value);
+	dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_LSB, value);
+	dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_MSB, value);
+	dump_reg(decoder->client, REG_VSYNC_START_LINE_LSB, value);
+	dump_reg(decoder->client, REG_VSYNC_START_LINE_MSB, value);
+	dump_reg(decoder->client, REG_VSYNC_STOP_LINE_LSB, value);
+	dump_reg(decoder->client, REG_VSYNC_STOP_LINE_MSB, value);
+	dump_reg(decoder->client, REG_VBLK_START_LINE_LSB, value);
+	dump_reg(decoder->client, REG_VBLK_START_LINE_MSB, value);
+	dump_reg(decoder->client, REG_VBLK_STOP_LINE_LSB, value);
+	dump_reg(decoder->client, REG_VBLK_STOP_LINE_MSB, value);
+	dump_reg(decoder->client, REG_SYNC_CONTROL, value);
+	dump_reg(decoder->client, REG_OUTPUT_FORMATTER1, value);
+	dump_reg(decoder->client, REG_OUTPUT_FORMATTER2, value);
+	dump_reg(decoder->client, REG_OUTPUT_FORMATTER3, value);
+	dump_reg(decoder->client, REG_OUTPUT_FORMATTER4, value);
+	dump_reg(decoder->client, REG_OUTPUT_FORMATTER5, value);
+	dump_reg(decoder->client, REG_OUTPUT_FORMATTER6, value);
+	dump_reg(decoder->client, REG_CLEAR_LOST_LOCK, value);
+}
+
+/*
+ * Configure the TVP5146/47 with the current register settings
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tvp514x_configure(struct tvp514x_decoder *decoder)
+{
+	int err;
+
+	/* common register initialization */
+	err =
+	    tvp514x_write_regs(decoder->client, tvp514x_reg_list);
+	if (err)
+		return err;
+
+	if (debug)
+		tvp514x_reg_dump(decoder);
+
+	return 0;
+}
+
+/*
+ * Detect if an tvp514x 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 tvp514x_detect(struct tvp514x_decoder *decoder)
+{
+	u8 chip_id_msb, chip_id_lsb, rom_ver;
+
+	chip_id_msb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_MSB);
+	chip_id_lsb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_LSB);
+	rom_ver = tvp514x_read_reg(decoder->client, REG_ROM_VERSION);
+
+	v4l_dbg(1, debug, decoder->client,
+		 "chip id detected msb:0x%x lsb:0x%x rom version:0x%x\n",
+		 chip_id_msb, chip_id_lsb, rom_ver);
+	if ((chip_id_msb != TVP514X_CHIP_ID_MSB)
+		|| ((chip_id_lsb != TVP5146_CHIP_ID_LSB)
+		&& (chip_id_lsb != TVP5147_CHIP_ID_LSB))) {
+		/* We didn't read the values we expected, so this must not be
+		 * an TVP5146/47.
+		 */
+		v4l_err(decoder->client,
+			"chip id mismatch msb:0x%x lsb:0x%x\n",
+			chip_id_msb, chip_id_lsb);
+		return -ENODEV;
+	}
+
+	decoder->ver = rom_ver;
+	decoder->state = STATE_DETECTED;
+
+	v4l_info(decoder->client,
+			"\n%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
+ * TVP5146/47 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 TVP5146/47. If no active input is
+ * detected, returns -EINVAL
+ */
+static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id)
+{
+	struct tvp514x_decoder *decoder = s->priv;
+	enum tvp514x_std current_std;
+	enum tvp514x_input input_sel;
+	u8 sync_lock_status, lock_mask;
+
+	if (std_id == NULL)
+		return -EINVAL;
+
+	/* get the current standard */
+	current_std = tvp514x_get_current_std(decoder);
+	if (current_std == STD_INVALID)
+		return -EINVAL;
+
+	input_sel = decoder->pdata->input_list[decoder->inputidx].input_sel;
+
+	switch (input_sel) {
+	case INPUT_CVBS_VI1A:
+	case INPUT_CVBS_VI1B:
+	case INPUT_CVBS_VI1C:
+	case INPUT_CVBS_VI2A:
+	case INPUT_CVBS_VI2B:
+	case INPUT_CVBS_VI2C:
+	case INPUT_CVBS_VI3A:
+	case INPUT_CVBS_VI3B:
+	case INPUT_CVBS_VI3C:
+	case INPUT_CVBS_VI4A:
+		lock_mask = STATUS_CLR_SUBCAR_LOCK_BIT |
+			STATUS_HORZ_SYNC_LOCK_BIT |
+			STATUS_VIRT_SYNC_LOCK_BIT;
+		break;
+
+	case INPUT_SVIDEO_VI2A_VI1A:
+	case INPUT_SVIDEO_VI2B_VI1B:
+	case INPUT_SVIDEO_VI2C_VI1C:
+	case INPUT_SVIDEO_VI2A_VI3A:
+	case INPUT_SVIDEO_VI2B_VI3B:
+	case INPUT_SVIDEO_VI2C_VI3C:
+	case INPUT_SVIDEO_VI4A_VI1A:
+	case INPUT_SVIDEO_VI4A_VI1B:
+	case INPUT_SVIDEO_VI4A_VI1C:
+	case INPUT_SVIDEO_VI4A_VI3A:
+	case INPUT_SVIDEO_VI4A_VI3B:
+	case INPUT_SVIDEO_VI4A_VI3C:
+		lock_mask = STATUS_HORZ_SYNC_LOCK_BIT |
+			STATUS_VIRT_SYNC_LOCK_BIT;
+		break;
+		/*Need to add other interfaces*/
+	default:
+		return -EINVAL;
+	}
+	/* check whether signal is locked */
+	sync_lock_status = tvp514x_read_reg(decoder->client, REG_STATUS1);
+	if (lock_mask != (sync_lock_status & lock_mask))
+		return -EINVAL;	/* No input detected */
+
+	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 tvp514x_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 == STD_INVALID))
+		return -EINVAL;
+
+	err = tvp514x_write_reg(decoder->client, REG_VIDEO_STD,
+				decoder->std_list[i].video_std);
+	if (err)
+		return err;
+
+	decoder->current_std = i;
+	tvp514x_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, int index)
+{
+	struct tvp514x_decoder *decoder = s->priv;
+	int err;
+	enum tvp514x_input input_sel;
+	enum tvp514x_std current_std = STD_INVALID;
+	u8 sync_lock_status, lock_mask;
+	int try_count = LOCK_RETRY_COUNT;
+
+	if ((index >= decoder->pdata->num_inputs) || (index < 0))
+		return -EINVAL;	/* Index out of bound */
+
+	/* Get the register value to be written to select the requested input */
+	input_sel = decoder->pdata->input_list[index].input_sel;
+	err = tvp514x_write_reg(decoder->client, REG_INPUT_SEL, input_sel);
+	if (err)
+		return err;
+
+	decoder->inputidx = index;
+	tvp514x_reg_list[REG_INPUT_SEL].val = input_sel;
+
+	/* Clear status */
+	msleep(LOCK_RETRY_DELAY);
+	err =
+	    tvp514x_write_reg(decoder->client, REG_CLEAR_LOST_LOCK, 0x01);
+	if (err)
+		return err;
+
+	switch (input_sel) {
+	case INPUT_CVBS_VI1A:
+	case INPUT_CVBS_VI1B:
+	case INPUT_CVBS_VI1C:
+	case INPUT_CVBS_VI2A:
+	case INPUT_CVBS_VI2B:
+	case INPUT_CVBS_VI2C:
+	case INPUT_CVBS_VI3A:
+	case INPUT_CVBS_VI3B:
+	case INPUT_CVBS_VI3C:
+	case INPUT_CVBS_VI4A:
+		lock_mask = STATUS_CLR_SUBCAR_LOCK_BIT |
+			STATUS_HORZ_SYNC_LOCK_BIT |
+			STATUS_VIRT_SYNC_LOCK_BIT;
+		break;
+
+	case INPUT_SVIDEO_VI2A_VI1A:
+	case INPUT_SVIDEO_VI2B_VI1B:
+	case INPUT_SVIDEO_VI2C_VI1C:
+	case INPUT_SVIDEO_VI2A_VI3A:
+	case INPUT_SVIDEO_VI2B_VI3B:
+	case INPUT_SVIDEO_VI2C_VI3C:
+	case INPUT_SVIDEO_VI4A_VI1A:
+	case INPUT_SVIDEO_VI4A_VI1B:
+	case INPUT_SVIDEO_VI4A_VI1C:
+	case INPUT_SVIDEO_VI4A_VI3A:
+	case INPUT_SVIDEO_VI4A_VI3B:
+	case INPUT_SVIDEO_VI4A_VI3C:
+		lock_mask = STATUS_HORZ_SYNC_LOCK_BIT |
+			STATUS_VIRT_SYNC_LOCK_BIT;
+		break;
+	/*Need to add other interfaces*/
+	default:
+		return -EINVAL;
+	}
+
+	while (try_count-- > 0) {
+		/* Allow decoder to sync up with new input */
+		msleep(LOCK_RETRY_DELAY);
+
+		/* get the current standard for future reference */
+		current_std = tvp514x_get_current_std(decoder);
+		if (current_std == STD_INVALID)
+			continue;
+
+		sync_lock_status = tvp514x_read_reg(decoder->client,
+				REG_STATUS1);
+		if (lock_mask == (sync_lock_status & lock_mask))
+			break;	/* Input detected */
+	}
+
+	if ((current_std == STD_INVALID) || (try_count < 0))
+		return -EINVAL;
+
+	decoder->current_std = current_std;
+
+	v4l_dbg(1, debug, decoder->client,
+			"Input set to: index - %d (%s)",
+			decoder->pdata->input_list[index].input.index,
+			decoder->pdata->input_list[index].input.name);
+	return 0;
+}
+
+/**
+ * ioctl_g_routing - V4L2 decoder interface handler for VIDIOC_G_INPUT ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @index: returns the current selected input
+ *
+ * Returns the current selected input. Returns -EINVAL if any error occurs
+ */
+static int ioctl_g_routing(struct v4l2_int_device *s, int *index)
+{
+	struct tvp514x_decoder *decoder = s->priv;
+	int err = -EINVAL, i, inputidx;
+
+	if (index == NULL)
+		return err;
+
+	/* Search through the input list for active inputs */
+	inputidx = decoder->inputidx;
+	for (i = 0; i < decoder->pdata->num_inputs; i++) {
+		inputidx++;	/* Move to next input */
+		if (inputidx >= decoder->pdata->num_inputs)
+			inputidx = 0;	/* fall back to first input */
+
+		err = ioctl_s_routing(s, inputidx);
+		if (!err) {
+			/* Active input found - select it and return success */
+			*index = inputidx;
+			return 0;
+		}
+	}
+
+	return err;
+}
+
+/**
+ * ioctl_queryctrl - V4L2 decoder interface handler for VIDIOC_QUERYCTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @qc: standard V4L2 VIDIOC_QUERYCTRL ioctl structure
+ *
+ * If the requested control is supported, returns the control information
+ * from the ctrl_list[] array. Otherwise, returns -EINVAL if the
+ * control is not supported.
+ */
+static int
+ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
+{
+	struct tvp514x_decoder *decoder = s->priv;
+	int id, index;
+	const struct tvp514x_ctrl_info *control = NULL;
+
+	if (qctrl == NULL)
+		return -EINVAL;
+
+	id = qctrl->id;
+	memset(qctrl, 0, sizeof(struct v4l2_queryctrl));
+	qctrl->id = id;
+
+	for (index = 0; index < decoder->num_ctrls; index++) {
+		control = &decoder->ctrl_list[index];
+		if (control->query_ctrl.id == qctrl->id)
+			break;	/* Match found */
+	}
+	if (index == decoder->num_ctrls)
+		return -EINVAL;	/* Index out of bound */
+
+	memcpy(qctrl, &control->query_ctrl, sizeof(struct v4l2_queryctrl));
+
+	v4l_dbg(1, debug, decoder->client,
+			"Query Control: %s : Min - %d, Max - %d, Def - %d",
+			control->query_ctrl.name,
+			control->query_ctrl.minimum,
+			control->query_ctrl.maximum,
+			control->query_ctrl.default_value);
+	return 0;
+}
+
+/**
+ * ioctl_g_ctrl - V4L2 decoder interface handler for VIDIOC_G_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_G_CTRL ioctl 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 tvp514x_decoder *decoder = s->priv;
+	int index, value;
+	const struct tvp514x_ctrl_info *control = NULL;
+
+	if (ctrl == NULL)
+		return -EINVAL;
+
+	for (index = 0; index < decoder->num_ctrls; index++) {
+		control = &decoder->ctrl_list[index];
+		if (control->query_ctrl.id == ctrl->id)
+			break;	/* Match found */
+	}
+	if (index == decoder->num_ctrls)
+		return -EINVAL;	/* Index out of bound */
+
+	value =
+	    tvp514x_read_reg(decoder->client, control->reg_address);
+
+	/* cross check */
+	if (value != tvp514x_reg_list[control->reg_address].val)
+		return -EINVAL;	/* Driver & TVP5146/47 setting mismatch */
+
+	if (V4L2_CID_AUTOGAIN == ctrl->id) {
+		if ((value & 0x3) == 3)
+			value = 1;
+		else
+			value = 0;
+	}
+
+	if (V4L2_CID_HUE == ctrl->id) {
+		if (value == 0x7F)
+			value = 180;
+		else if (value == 0x80)
+			value = -180;
+		else
+			value = 0;
+	}
+
+	ctrl->value = value;
+
+	v4l_dbg(1, debug, decoder->client,
+			"Get Cotrol: %s - %d",
+			control->query_ctrl.name, value);
+	return 0;
+}
+
+/**
+ * ioctl_s_ctrl - V4L2 decoder interface handler for VIDIOC_S_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_S_CTRL ioctl 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 tvp514x_decoder *decoder = s->priv;
+	int err, value, index;
+	const struct tvp514x_ctrl_info *control = NULL;
+
+	if (ctrl == NULL)
+		return -EINVAL;
+
+	value = (__s32) ctrl->value;
+	for (index = 0; index < decoder->num_ctrls; index++) {
+		control = &decoder->ctrl_list[index];
+		if (control->query_ctrl.id == ctrl->id)
+			break;	/* Match found */
+	}
+	if (index == decoder->num_ctrls)
+		return -EINVAL;	/* Index out of bound */
+
+	if (V4L2_CID_AUTOGAIN == ctrl->id) {
+		if (value == 1)
+			value = 0x0F;
+		else if (value == 0)
+			value = 0x0C;
+		else
+			return -ERANGE;
+	} else if (V4L2_CID_HUE == ctrl->id) {
+		if (value == 180)
+			value = 0x7F;
+		else if (value == -180)
+			value = 0x80;
+		else if (value == 0)
+			value = 0;
+		else
+			return -ERANGE;
+	} else {
+		if ((value < control->query_ctrl.minimum)
+			|| (value > control->query_ctrl.maximum))
+			return -ERANGE;
+	}
+
+	err =
+	    tvp514x_write_reg(decoder->client, control->reg_address,
+				value);
+	if (err)
+		return err;
+
+	tvp514x_reg_list[control->reg_address].val = value;
+
+	v4l_dbg(1, debug, decoder->client,
+			"Set Cotrol: %s - %d",
+			control->query_ctrl.name, 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 tvp514x_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 tvp514x_decoder *decoder = s->priv;
+	int ifmt;
+	struct v4l2_pix_format *pix;
+	enum tvp514x_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 = tvp514x_get_current_std(decoder);
+	if (current_std == 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_INTERLACED;
+	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 tvp514x_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;
+	else
+		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 tvp514x_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 tvp514x_decoder *decoder = s->priv;
+	struct v4l2_captureparm *cparm;
+	enum tvp514x_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 = tvp514x_get_current_std(decoder);
+	if (current_std == 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 tvp514x_decoder *decoder = s->priv;
+	struct v4l2_fract *timeperframe;
+	enum tvp514x_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 = tvp514x_get_current_std(decoder);
+	if (current_std == 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 tvp514x_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 = TVP514X_XCLK_BT656;
+
+	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 tvp514x_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 tvp514x_decoder *decoder = s->priv;
+	int err = 0;
+
+	switch (on) {
+	case V4L2_POWER_OFF:
+		/* Power Down Sequence */
+		err =
+		    tvp514x_write_reg(decoder->client, REG_OPERATION_MODE,
+					0x01);
+		/* Disable mux for TVP5146/47 decoder data path */
+		if (decoder->pdata->power_set)
+			err |= decoder->pdata->power_set(on);
+		decoder->state = STATE_NOT_DETECTED;
+		break;
+
+	case V4L2_POWER_STANDBY:
+		if (decoder->pdata->power_set)
+			err = decoder->pdata->power_set(on);
+		break;
+
+	case V4L2_POWER_ON:
+		/* Enable mux for TVP5146/47 decoder data path */
+		if ((decoder->pdata->power_set) &&
+				(decoder->state == STATE_NOT_DETECTED)) {
+			int i;
+			struct tvp514x_init_seq *int_seq =
+				(struct tvp514x_init_seq *)
+				decoder->id->driver_data;
+
+			err = decoder->pdata->power_set(on);
+
+			/* Power Up Sequence */
+			for (i = 0; i < int_seq->no_regs; i++) {
+				err |= tvp514x_write_reg(decoder->client,
+						int_seq->init_reg_seq[i].reg,
+						int_seq->init_reg_seq[i].val);
+			}
+			/* Detect the sensor is not already detected */
+			err |= tvp514x_detect(decoder);
+			if (err) {
+				v4l_err(decoder->client,
+						"Unable to detect decoder\n");
+				return err;
+			}
+		}
+		err |= tvp514x_configure(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 tvp514x_configure())
+ */
+static int ioctl_init(struct v4l2_int_device *s)
+{
+	struct tvp514x_decoder *decoder = s->priv;
+
+	/* Set default standard to auto */
+	tvp514x_reg_list[REG_VIDEO_STD].val =
+	    VIDEO_STD_AUTO_SWITCH_BIT;
+
+	return tvp514x_configure(decoder);
+}
+
+/**
+ * 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
+ * TVP5146/47 device could be found, otherwise returns appropriate error.
+ */
+static int ioctl_dev_init(struct v4l2_int_device *s)
+{
+	struct tvp514x_decoder *decoder = s->priv;
+	int err;
+
+	err = tvp514x_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);
+
+	return 0;
+}
+
+static struct v4l2_int_ioctl_desc tvp514x_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_g_video_routing_num,
+		(v4l2_int_ioctl_func *) ioctl_g_routing},
+	{vidioc_int_s_video_routing_num,
+		(v4l2_int_ioctl_func *) ioctl_s_routing},
+};
+
+static struct v4l2_int_slave tvp514x_slave = {
+	.ioctls = tvp514x_ioctl_desc,
+	.num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc),
+};
+
+static struct tvp514x_decoder tvp514x_dev = {
+	.state = STATE_NOT_DETECTED,
+
+	.num_fmts = TVP514X_NUM_FORMATS,
+	.fmt_list = tvp514x_fmt_list,
+
+	.pix = {		/* Default to NTSC 8-bit YUV 422 */
+		.width = NTSC_NUM_ACTIVE_PIXELS,
+		.height = NTSC_NUM_ACTIVE_LINES,
+		.pixelformat = V4L2_PIX_FMT_UYVY,
+		.field = V4L2_FIELD_INTERLACED,
+		.bytesperline = NTSC_NUM_ACTIVE_PIXELS * 2,
+		.sizeimage =
+		NTSC_NUM_ACTIVE_PIXELS * 2 * NTSC_NUM_ACTIVE_LINES,
+		.colorspace = V4L2_COLORSPACE_SMPTE170M,
+		},
+
+	.current_std = STD_NTSC_MJ,
+	.num_stds = TVP514X_NUM_STANDARDS,
+	.std_list = tvp514x_std_list,
+
+	.num_ctrls = TVP514X_NUM_CONTROLS,
+	.ctrl_list = tvp514x_ctrl_list,
+
+};
+
+static struct v4l2_int_device tvp514x_int_device = {
+	.module = THIS_MODULE,
+	.name = MODULE_NAME,
+	.priv = &tvp514x_dev,
+	.type = v4l2_int_type_slave,
+	.u = {
+	      .slave = &tvp514x_slave,
+	      },
+};
+
+/**
+ * tvp514x_probe - decoder driver i2c probe handler
+ * @client: i2c driver client device structure
+ *
+ * Register decoder as an i2c client device and V4L2
+ * device.
+ */
+static int
+tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	struct tvp514x_decoder *decoder = &tvp514x_dev;
+	int err;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	decoder->pdata = client->dev.platform_data;
+	if (!decoder->pdata) {
+		v4l_err(client, "No platform data\n!!");
+		return -ENODEV;
+	}
+	/*
+	 * Fetch platform specific data, and configure the
+	 * tvp514x_reg_list[] accordingly. Since this is one
+	 * time configuration, no need to preserve.
+	 */
+	decoder->inputidx = decoder->pdata->default_input;
+	tvp514x_reg_list[REG_OUTPUT_FORMATTER2].val |=
+			(decoder->pdata->clk_polarity << 1);
+	tvp514x_reg_list[REG_OUTPUT_FORMATTER1].val |=
+			decoder->pdata->fmt;
+	tvp514x_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(tvp514x_int_device.u.slave->attach_to, decoder->pdata->master);
+	decoder->v4l2_int_device = &tvp514x_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;
+}
+
+/**
+ * tvp514x_remove - decoder driver i2c remove handler
+ * @client: i2c driver client device structure
+ *
+ * Unregister decoder as an i2c client device and V4L2
+ * device. Complement of tvp514x_probe().
+ */
+static int __exit tvp514x_remove(struct i2c_client *client)
+{
+	struct tvp514x_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;
+}
+/*
+ * TVP5146 Init/Power on Sequence
+ */
+static struct tvp514x_reg tvp5146_init_reg_seq[] = {
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0x80},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
+	{TOK_WRITE, REG_OPERATION_MODE, 0x01},
+	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
+};
+static struct tvp514x_init_seq tvp5146_init = {
+	.no_regs = ARRAY_SIZE(tvp5146_init_reg_seq),
+	.init_reg_seq = tvp5146_init_reg_seq,
+};
+/*
+ * TVP5147 Init/Power on Sequence
+ */
+static struct tvp514x_reg tvp5147_init_reg_seq[] =	{
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0x80},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x01},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x16},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xA0},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x16},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x60},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
+	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS3, 0xB0},
+	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
+	{TOK_WRITE, REG_OPERATION_MODE, 0x01},
+	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
+};
+static struct tvp514x_init_seq tvp5147_init = {
+	.no_regs = ARRAY_SIZE(tvp5147_init_reg_seq),
+	.init_reg_seq = tvp5147_init_reg_seq,
+};
+/*
+ * TVP5146M2/TVP5147M1 Init/Power on Sequence
+ */
+static struct tvp514x_reg tvp514xm_init_reg_seq[] = {
+	{TOK_WRITE, REG_OPERATION_MODE, 0x01},
+	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
+};
+static struct tvp514x_init_seq tvp514xm_init = {
+	.no_regs = ARRAY_SIZE(tvp514xm_init_reg_seq),
+	.init_reg_seq = tvp514xm_init_reg_seq,
+};
+/*
+ * I2C Device Table -
+ *
+ * name - Name of the actual device/chip.
+ * driver_data - Driver data
+ */
+static const struct i2c_device_id tvp514x_id[] = {
+	{"tvp5146", (unsigned int)&tvp5146_init},
+	{"tvp5146m2", (unsigned int)&tvp514xm_init},
+	{"tvp5147", (unsigned int)&tvp5147_init},
+	{"tvp5147m1", (unsigned int)&tvp514xm_init},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, tvp514x_id);
+
+static struct i2c_driver tvp514x_i2c_driver = {
+	.driver = {
+		   .name = MODULE_NAME,
+		   .owner = THIS_MODULE,
+		   },
+	.probe = tvp514x_probe,
+	.remove = __exit_p(tvp514x_remove),
+	.id_table = tvp514x_id,
+};
+
+/**
+ * tvp514x_init
+ *
+ * Module init function
+ */
+static int __init tvp514x_init(void)
+{
+	int err;
+
+	err = i2c_add_driver(&tvp514x_i2c_driver);
+	if (err) {
+		printk(KERN_ERR "Failed to register " MODULE_NAME ".\n");
+		return err;
+	}
+	return 0;
+}
+
+/**
+ * tvp514x_cleanup
+ *
+ * Module exit function
+ */
+static void __exit tvp514x_cleanup(void)
+{
+	i2c_del_driver(&tvp514x_i2c_driver);
+}
+
+module_init(tvp514x_init);
+module_exit(tvp514x_cleanup);
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("TVP514X linux decoder driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tvp514x_regs.h b/drivers/media/video/tvp514x_regs.h
new file mode 100755
index 0000000..003a3c1
--- /dev/null
+++ b/drivers/media/video/tvp514x_regs.h
@@ -0,0 +1,292 @@
+/*
+ * drivers/media/video/tvp514x_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 _TVP514X_REGS_H
+#define _TVP514X_REGS_H
+
+/*
+ * TVP5146/47 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 */
+
+/*
+ * Mask and bit definitions of TVP5146/47 registers
+ */
+/* The ID values we are looking for */
+#define TVP514X_CHIP_ID_MSB		(0x51)
+#define TVP5146_CHIP_ID_LSB		(0x46)
+#define TVP5147_CHIP_ID_LSB		(0x47)
+
+#define VIDEO_STD_MASK			(0x07)
+#define VIDEO_STD_AUTO_SWITCH_BIT	(0x00)
+#define VIDEO_STD_NTSC_MJ_BIT		(0x01)
+#define VIDEO_STD_PAL_BDGHIN_BIT	(0x02)
+#define VIDEO_STD_PAL_M_BIT		(0x03)
+#define VIDEO_STD_PAL_COMBINATION_N_BIT	(0x04)
+#define VIDEO_STD_NTSC_4_43_BIT		(0x05)
+#define VIDEO_STD_SECAM_BIT		(0x06)
+#define VIDEO_STD_PAL_60_BIT		(0x07)
+
+/*
+ * 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)
+
+/**
+ * struct tvp514x_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 tvp514x_reg {
+	u8 token;
+	u8 reg;
+	u32 val;
+};
+
+/**
+ * struct tvp514x_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 tvp514x_init_seq {
+	unsigned int no_regs;
+	struct tvp514x_reg *init_reg_seq;
+};
+#endif				/* ifndef _TVP514X_REGS_H */
diff --git a/include/media/tvp514x.h b/include/media/tvp514x.h
new file mode 100755
index 0000000..2fee5e7
--- /dev/null
+++ b/include/media/tvp514x.h
@@ -0,0 +1,232 @@
+/*
+ * drivers/media/video/tvp514x.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 _TVP514X_H
+#define _TVP514X_H
+
+/*
+ * Other macros
+ */
+#define TVP514X_MODULE_NAME		"tvp514x"
+#define TVP514X_I2C_DELAY		(3)
+#define I2C_RETRY_COUNT			(5)
+#define LOCK_RETRY_COUNT		(5)
+#define LOCK_RETRY_DELAY		(200)
+
+#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 */
+
+#define TVP514X_XCLK_BT656		(27000000)
+
+/* Number of pixels and number of lines per frame for different standards */
+#define NTSC_NUM_ACTIVE_PIXELS		(720)
+#define NTSC_NUM_ACTIVE_LINES		(480)
+#define PAL_NUM_ACTIVE_PIXELS		(720)
+#define PAL_NUM_ACTIVE_LINES		(576)
+
+/**
+ * enum tvp514x_std - enum for supported standards
+ */
+enum tvp514x_std {
+	STD_NTSC_MJ = 0,
+	STD_PAL_BDGHIN,
+	STD_INVALID
+};
+
+/**
+ * enum tvp514x_state - enum for different decoder states
+ */
+enum tvp514x_state {
+	STATE_NOT_DETECTED,
+	STATE_DETECTED
+};
+
+/**
+ * enum tvp514x_input - enum for different decoder input pin
+ *		configuration.
+ */
+enum tvp514x_input {
+	/*
+	 * CVBS input selection
+	 */
+	INPUT_CVBS_VI1A = 0x0,
+	INPUT_CVBS_VI1B,
+	INPUT_CVBS_VI1C,
+	INPUT_CVBS_VI2A = 0x04,
+	INPUT_CVBS_VI2B,
+	INPUT_CVBS_VI2C,
+	INPUT_CVBS_VI3A = 0x08,
+	INPUT_CVBS_VI3B,
+	INPUT_CVBS_VI3C,
+	INPUT_CVBS_VI4A = 0x0C,
+	/*
+	 * S-Video input selection
+	 */
+	INPUT_SVIDEO_VI2A_VI1A = 0x44,
+	INPUT_SVIDEO_VI2B_VI1B,
+	INPUT_SVIDEO_VI2C_VI1C,
+	INPUT_SVIDEO_VI2A_VI3A = 0x54,
+	INPUT_SVIDEO_VI2B_VI3B,
+	INPUT_SVIDEO_VI2C_VI3C,
+	INPUT_SVIDEO_VI4A_VI1A = 0x4C,
+	INPUT_SVIDEO_VI4A_VI1B,
+	INPUT_SVIDEO_VI4A_VI1C,
+	INPUT_SVIDEO_VI4A_VI3A = 0x5C,
+	INPUT_SVIDEO_VI4A_VI3B,
+	INPUT_SVIDEO_VI4A_VI3C
+
+	/* Need to add entries for
+	 * RGB, YPbPr and SCART.
+	 */
+};
+
+/**
+ * enum tvp514x_output_fmt - enum for output format
+ *			supported.
+ */
+enum tvp514x_output_fmt {
+	OUTPUT_10BIT_422_EMBEDDED_SYNC = 0,
+	OUTPUT_20BIT_422_SEPERATE_SYNC,
+	OUTPUT_10BIT_422_SEPERATE_SYNC = 3,
+	OUTPUT_INVALID
+};
+
+/**
+ * struct tvp514x_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 tvp514x_std_info {
+	unsigned long width;
+	unsigned long height;
+	u8 video_std;
+	struct v4l2_standard standard;
+};
+
+/**
+ * struct tvp514x_ctrl_info - Information regarding supported controls
+ * @reg_address: Register offset of control register
+ * @query_ctrl: v4l2 query control information
+ */
+struct tvp514x_ctrl_info {
+	u8 reg_address;
+	struct v4l2_queryctrl query_ctrl;
+};
+
+/**
+ * struct tvp514x_input_info - Information regarding supported inputs
+ * @input_sel: Input select register
+ * @lock_mask: lock mask - depends on Svideo/CVBS
+ * @input: v4l2 input information
+ */
+struct tvp514x_input_info {
+	enum tvp514x_input input_sel;
+	struct v4l2_input input;
+};
+
+/**
+ * struct tvp514x_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
+ * @reg_list: The board dependent driver should fill the default value for
+ *            required registers depending on board layout. The TVP5146/47
+ *            driver will update this register list for the registers
+ *            whose values should be maintained across open()/close() like
+ *            setting brightness as defined in V4L2.
+ *            The register list should be in the same order as defined in
+ *            TVP5146/47 datasheet including reserved registers. As of now
+ *            the driver expects the size of this list to be a minimum of
+ *            57 + 1 (upto regsiter REG_CLEAR_LOST_LOCK).
+ *            The last member should be of the list should be
+ *            {TOK_TERM, 0, 0} to indicate the end of register list.
+ * @num_inputs: Number of input connection in board
+ * @input_list: Input information list for num_inputs
+ */
+struct tvp514x_platform_data {
+	char *master;
+	int (*power_set) (enum v4l2_power on);
+	int (*ifparm) (struct v4l2_ifparm *p);
+	int (*priv_data_set) (void *);
+	/* Input params */
+	int num_inputs;
+	const struct tvp514x_input_info *input_list;
+	int default_input;
+	/* Interface control params */
+	enum tvp514x_output_fmt fmt;
+	bool clk_polarity;
+	bool hs_polarity;
+	bool vs_polarity;
+};
+
+/**
+ * struct tvp514x_decoded - TVP5146/47 decoder object
+ * @v4l2_int_device: Slave handle
+ * @pdata: Board specific
+ * @client: I2C client data
+ * @id: Entry from I2C table
+ * @ver: Chip version
+ * @state: TVP5146/47 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
+ * @num_ctrls: Number of controls
+ * @ctrl_list: Control list
+ */
+struct tvp514x_decoder {
+	struct v4l2_int_device *v4l2_int_device;
+	const struct tvp514x_platform_data *pdata;
+	struct i2c_client *client;
+
+	struct i2c_device_id *id;
+
+	int ver;
+	enum tvp514x_state state;
+
+	struct v4l2_pix_format pix;
+	int num_fmts;
+	const struct v4l2_fmtdesc *fmt_list;
+
+	enum tvp514x_std current_std;
+	int num_stds;
+	struct tvp514x_std_info *std_list;
+
+	int num_ctrls;
+	const struct tvp514x_ctrl_info *ctrl_list;
+
+	int inputidx;
+};
+
+#endif				/* ifndef _TVP514X_H */
--
1.5.6


         reply	other threads:[~2008-12-02 15:36 UTC|newest]

Thread overview: 263+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <hvaibhav@ti.com>
2008-11-21 15:22 ` [PATCH 2/2] TVP514x V4L int device driver support hvaibhav
2008-11-21 16:16   ` Hans Verkuil
2008-11-21 18:12   ` Trilok Soni
2008-11-21 18:12     ` Trilok Soni
2008-11-21 19:07     ` Hiremath, Vaibhav
2008-11-21 19:07       ` Hiremath, Vaibhav
2008-11-21 19:11     ` David Brownell
2008-11-23 22:00   ` Hans Verkuil
2008-11-23 22:04     ` Koen Kooi
2008-11-24  6:16     ` Trilok Soni
2008-11-24  6:16       ` Trilok Soni
2008-11-24  6:32       ` David Brownell
2008-11-24  7:53         ` Hans Verkuil
2008-11-24  8:53           ` Hiremath, Vaibhav
2008-11-24  8:53             ` Hiremath, Vaibhav
2008-11-24  8:04       ` Hans Verkuil
2008-11-24  8:04         ` Hans Verkuil
2008-11-24  8:43         ` Trilok Soni
2008-11-24  8:43           ` Trilok Soni
2008-11-24  8:59           ` Hiremath, Vaibhav
2008-11-24  8:59             ` Hiremath, Vaibhav
2008-11-24 10:06   ` David Brownell
2008-11-26 17:04 ` [PATCH 1/2] Add Input/Output related ioctl support hvaibhav
2008-11-26 17:15   ` Hans Verkuil
2008-11-26 17:15     ` Hans Verkuil
2008-11-26 17:05 ` [PATCH 2/2] TVP514x Driver with Review comments fixed hvaibhav
2008-11-26 17:05   ` hvaibhav
2008-11-26 17:48   ` Hans Verkuil
2008-12-02 15:35 ` hvaibhav [this message]
2008-12-02 15:35   ` [PATCH 2/2] TVP514x Driver with Review comments fixed [V4] hvaibhav
2008-12-02 17:20   ` Hans Verkuil
2008-12-03  3:58     ` Hiremath, Vaibhav
2008-12-03  3:58       ` Hiremath, Vaibhav
2008-12-03 13:43     ` V4L2 PIXEL buffer conversion Jonathan Lafontaine
2008-12-02 19:29   ` [PATCH 2/2] TVP514x Driver with Review comments fixed [V4] David Brownell
2008-12-02 19:44   ` David Brownell
2009-11-18  6:58 ` [U-Boot] [PATCH] OMAP3EVM: Added NAND support hvaibhav at ti.com
2009-11-18  7:30   ` Dirk Behme
2009-11-18  8:25     ` Hiremath, Vaibhav
2009-11-18 18:07   ` Nishanth Menon
2009-11-18 18:18     ` Scott Wood
2009-11-18 18:40     ` Hiremath, Vaibhav
2009-11-18  8:26 ` hvaibhav at ti.com
2009-11-18  8:36   ` Dirk Behme
2009-11-18 14:40     ` Hiremath, Vaibhav
2009-11-23 11:05 ` [U-Boot] [PATCH V4] " hvaibhav at ti.com
2009-11-27 15:51   ` Tom
2009-11-30 17:49     ` Hiremath, Vaibhav
2009-11-23 11:06 ` [U-Boot] [PATCH] omap3_mmc: Encapsulate twl4030 under option CONFIG_TWL4030_POWER hvaibhav at ti.com
2009-11-27 14:03   ` Tom
2009-11-30 17:43     ` Hiremath, Vaibhav
2009-11-23 11:06 ` [U-Boot] [PATCH 1/5] Introducing AM3517EVM support hvaibhav at ti.com
2009-11-23 19:43   ` Wolfgang Denk
2009-11-26  4:24     ` Hiremath, Vaibhav
2009-11-23 11:08 ` [U-Boot] [PATCH 0/5] Introducing TI's New SoC/board AM3517EVM hvaibhav at ti.com
2009-11-23 13:50   ` Paulraj, Sandeep
2009-11-23 14:16     ` Hiremath, Vaibhav
2009-11-23 20:03     ` Wolfgang Denk
2009-11-26  4:49       ` Hiremath, Vaibhav
2009-11-25 20:24   ` Tom
2009-11-23 11:08 ` [U-Boot] [PATCH 2/5] am3517_evm_config options added to Makfile hvaibhav at ti.com
2009-11-23 19:44   ` Wolfgang Denk
2009-11-26  4:25     ` Hiremath, Vaibhav
2009-11-23 11:08 ` [U-Boot] [PATCH 3/5] Added configuration file for AM3517EVM hvaibhav at ti.com
2009-11-23 19:46   ` Wolfgang Denk
2009-11-26  4:43     ` Hiremath, Vaibhav
2009-11-26 16:04       ` Tom
2009-11-30 17:01         ` Hiremath, Vaibhav
2009-12-05  0:20       ` Wolfgang Denk
2009-11-23 11:08 ` [U-Boot] [PATCH 4/5] AM3517EVM: Add mux configuration hvaibhav at ti.com
2009-11-23 19:49   ` Wolfgang Denk
2009-11-26  4:45     ` Hiremath, Vaibhav
2009-11-26 16:07       ` Tom
2009-12-05  0:23       ` Wolfgang Denk
2009-11-23 11:09 ` [U-Boot] [PATCH 5/5] AM3517: Add support for EMIF4 hvaibhav at ti.com
2009-11-23 19:50   ` Wolfgang Denk
2009-11-26  4:48     ` Hiremath, Vaibhav
2009-11-26 16:14       ` Tom
2009-11-30 17:03         ` Hiremath, Vaibhav
2010-01-30 10:16 ` [U-Boot] [PATCH 0/3] Add Support for AM3517EVM with EMIF4 hvaibhav at ti.com
2010-02-02 18:40   ` Hiremath, Vaibhav
2010-02-03 13:24     ` Tom
2010-02-03 13:26       ` Hiremath, Vaibhav
2010-01-30 10:16 ` [U-Boot] [PATCH 1/3] OMAP3: Consolidate SDRC related operations hvaibhav at ti.com
2010-02-07 16:13   ` Tom
2010-02-10  9:35     ` Hiremath, Vaibhav
2010-04-23 14:55 ` [U-Boot] [RESEND:PATCH-V4] OMAP3EVM: Added NAND support hvaibhav at ti.com
2010-05-05 20:01   ` Wolfgang Denk
2010-05-06  5:36     ` Hiremath, Vaibhav
2010-05-06 10:40       ` Nishanth Menon
2010-05-06 10:50         ` Wolfgang Denk
2010-05-06 10:54           ` Nishanth Menon
2010-05-06 11:03             ` Wolfgang Denk
2010-05-06 11:11               ` Nishanth Menon
2010-05-06 11:28                 ` Wolfgang Denk
2010-05-06 11:04           ` Hiremath, Vaibhav
2010-05-06 10:59       ` Wolfgang Denk
2010-04-23 14:55 ` [U-Boot] [PATCH-V2 2/4] omap3: Consolidate SDRC related operations hvaibhav at ti.com
2010-05-05 20:07   ` Wolfgang Denk
2010-05-06  6:49     ` Hiremath, Vaibhav
2010-05-06 10:55       ` Wolfgang Denk
2010-04-23 14:55 ` [U-Boot] [PATCH-V2 3/4] AM35x: Add support for AM3517EVM hvaibhav at ti.com
2010-05-05 20:12   ` Wolfgang Denk
2010-05-06  6:52     ` Hiremath, Vaibhav
2010-05-06 10:52       ` Wolfgang Denk
2010-04-23 14:55 ` [U-Boot] [PATCH-V2 4/4] AM35x: Add support for EMIF4 hvaibhav at ti.com
2010-05-05 20:14   ` Wolfgang Denk
2010-05-06  6:56     ` Hiremath, Vaibhav
2010-05-06 10:56       ` Wolfgang Denk
2010-05-06 17:19 ` [U-Boot] [PATCH-V5] OMAP3EVM: Added NAND support hvaibhav at ti.com
2010-05-11  4:59   ` Hiremath, Vaibhav
2010-05-11  8:59     ` Wolfgang Denk
2010-05-11  9:01       ` Hiremath, Vaibhav
2010-05-11 20:11       ` Scott Wood
2010-05-06 17:23 ` [U-Boot] [PATCH-V3 1/2] AM35x: Add support for AM3517EVM hvaibhav at ti.com
2010-05-11  5:00   ` Hiremath, Vaibhav
2010-05-31  9:40   ` Wolfgang Denk
2010-06-03 17:27     ` Hiremath, Vaibhav
2010-06-07  8:56     ` Hiremath, Vaibhav
2010-06-07 12:24       ` Wolfgang Denk
2010-06-07 14:23         ` Hiremath, Vaibhav
2010-05-06 17:23 ` [U-Boot] [PATCH-V3 2/2] AM35x: Add support for EMIF4 hvaibhav at ti.com
2010-05-31  9:43   ` Wolfgang Denk
2010-06-03 17:28     ` Hiremath, Vaibhav
2010-06-07 14:59 ` [U-Boot] [PATCH-V4 1/2] AM35x: Add support for AM3517EVM hvaibhav at ti.com
2010-06-07 21:20   ` Paulraj, Sandeep
2010-11-29 16:21 ` [U-Boot] [PATCH] AM3517:Fix for ARM Relocation support hvaibhav at ti.com
2010-11-29 16:24   ` Hiremath, Vaibhav
2010-11-29 16:32     ` Paulraj, Sandeep
2010-11-29 16:22 ` [U-Boot] [PATCH] AM3517:Build FIX: undef CONFIG_CMD_NFS support hvaibhav at ti.com
2010-11-29 21:36   ` Paulraj, Sandeep
2010-11-29 16:23 ` [U-Boot] [PATCH] AM3517:EMIF4: fix SDRAM size to 256Mb hvaibhav at ti.com
2010-11-29 21:36   ` Paulraj, Sandeep
2010-11-29 21:37   ` Paulraj, Sandeep
2011-08-01 14:21 ` [U-Boot] [PATCH] omap3evm: Use generic MMC driver hvaibhav at ti.com
2011-08-17  2:32   ` Andy Fleming
2011-08-01 14:21 ` [U-Boot] [PATCH] am3517evm: " hvaibhav at ti.com
2011-08-17  2:33   ` Andy Fleming
2013-03-15  7:11 ` [U-Boot] [PATCH] am335x: Enable DDR PHY dynamic power down bit for DDR3 boards Vaibhav Hiremath
2013-03-15 15:05   ` Tom Rini
2013-03-15 15:56     ` Lars Poeschel
2013-03-26 14:53   ` [U-Boot] " Tom Rini
2013-03-04 11:35 [RFC PATCH 3/3] ARM: OMAP2+: Add command line parameter for debugSS module control hvaibhav
2013-03-04 11:35 ` hvaibhav at ti.com
2013-04-08 17:29 ` Tony Lindgren
2013-04-08 17:29   ` Tony Lindgren
2013-04-09  8:07   ` Hiremath, Vaibhav
2013-04-09  8:07     ` Hiremath, Vaibhav
2013-04-09 16:34     ` Tony Lindgren
2013-04-09 16:34       ` Tony Lindgren
2013-04-10  5:11       ` Hiremath, Vaibhav
2013-04-10  5:11         ` Hiremath, Vaibhav
2013-04-10 17:07         ` Tony Lindgren
2013-04-10 17:07           ` Tony Lindgren
  -- strict thread matches above, loose matches on Subject: below --
2013-03-04 11:35 [RFC PATCH 1/3] ARM: AM33XX: clock: Add debugSS clock nodes to clock tree hvaibhav
2013-03-04 11:35 ` hvaibhav at ti.com
2013-05-29 19:07 ` Paul Walmsley
2013-05-29 19:07   ` Paul Walmsley
2013-03-04 11:35 [RFC PATCH 0/3] ARM: OMAP2+: Add command line parameter for debugSS module control hvaibhav
2013-03-04 11:35 ` hvaibhav at ti.com
2013-03-14 11:29 ` Hiremath, Vaibhav
2013-03-14 11:29   ` Hiremath, Vaibhav
2013-04-08 17:30   ` Tony Lindgren
2013-04-08 17:30     ` Tony Lindgren
2013-04-09  8:11     ` Hiremath, Vaibhav
2013-04-09  8:11       ` Hiremath, Vaibhav
2011-12-02  6:43 [PATCH-V5 2/3] arm:omap:am33xx: Add AM335XEVM machine support hvaibhav
2011-12-02  6:43 ` hvaibhav at ti.com
2012-05-02  9:23 ` Paul Walmsley
2012-05-02  9:23   ` Paul Walmsley
2012-05-02  9:34   ` Hiremath, Vaibhav
2012-05-02  9:34     ` Hiremath, Vaibhav
2012-05-03 15:57     ` Tony Lindgren
2012-05-03 15:57       ` Tony Lindgren
2012-05-03 16:41       ` Hiremath, Vaibhav
2012-05-03 16:41         ` Hiremath, Vaibhav
2012-05-03 19:37         ` Tony Lindgren
2012-05-03 19:37           ` Tony Lindgren
2012-05-04  6:14           ` Hiremath, Vaibhav
2012-05-04  6:14             ` Hiremath, Vaibhav
2012-05-03 21:17         ` Kevin Hilman
2012-05-03 21:17           ` Kevin Hilman
2012-05-04  6:00           ` Hiremath, Vaibhav
2012-05-04  6:00             ` Hiremath, Vaibhav
2012-05-04 20:05             ` Tony Lindgren
2012-05-04 20:05               ` Tony Lindgren
2012-05-07 14:38               ` Hiremath, Vaibhav
2012-05-07 14:38                 ` Hiremath, Vaibhav
2012-05-07 17:32                 ` Tony Lindgren
2012-05-07 17:32                   ` Tony Lindgren
2012-05-07 18:55                   ` Hiremath, Vaibhav
2012-05-07 18:55                     ` Hiremath, Vaibhav
2012-05-08 19:06                     ` Tony Lindgren
2012-05-08 19:06                       ` Tony Lindgren
2012-05-08 19:57                       ` Hiremath, Vaibhav
2012-05-08 19:57                         ` Hiremath, Vaibhav
2012-05-04  6:28       ` Hiremath, Vaibhav
2012-05-04  6:28         ` Hiremath, Vaibhav
2012-05-04 20:00         ` Tony Lindgren
2012-05-04 20:00           ` Tony Lindgren
2011-12-02  6:43 [PATCH-V5 1/3] arm:omap:am33xx: Update common OMAP machine specific sources hvaibhav
2011-12-02  6:43 ` hvaibhav at ti.com
2011-12-07 21:09 ` Tony Lindgren
2011-12-07 21:09   ` Tony Lindgren
2011-12-02  6:43 [PATCH-V5 0/3] Introducing TI's New SoC/board AM335XEVM hvaibhav
2011-12-02  6:43 ` hvaibhav at ti.com
2011-12-07  0:24 ` Kevin Hilman
2011-12-07  0:24   ` Kevin Hilman
2011-12-07 21:10   ` Tony Lindgren
2011-12-07 21:10     ` Tony Lindgren
2011-12-08 13:45     ` Hiremath, Vaibhav
2011-12-08 13:45       ` Hiremath, Vaibhav
2011-12-08 17:18       ` Tony Lindgren
2011-12-08 17:18         ` Tony Lindgren
2012-02-01  6:53         ` Hiremath, Vaibhav
2012-02-01  6:53           ` Hiremath, Vaibhav
2012-01-18  8:47     ` Hiremath, Vaibhav
2012-01-18  8:47       ` Hiremath, Vaibhav
2011-09-20 14:32 [PATCH-V3 4/4] arm:omap:am33xx: Add low level debugging support hvaibhav
2011-09-20 14:32 ` hvaibhav at ti.com
2011-10-06 23:09 ` Tony Lindgren
2011-10-06 23:09   ` Tony Lindgren
2011-11-07 15:17   ` Hiremath, Vaibhav
2011-11-07 15:17     ` Hiremath, Vaibhav
2011-11-07 18:16     ` Tony Lindgren
2011-11-07 18:16       ` Tony Lindgren
2011-09-20 14:32 [PATCH-V3 3/4] arm:omap:am33xx: Create board support and enable build for AM335XEVM hvaibhav
2011-09-20 14:32 ` hvaibhav at ti.com
2011-10-06 23:07 ` Tony Lindgren
2011-10-06 23:07   ` Tony Lindgren
2011-09-20 14:32 [PATCH-V3 2/4] arm:omap:am33xx: Update common OMAP machine specific sources hvaibhav
2011-09-20 14:32 ` hvaibhav at ti.com
2011-09-26 18:45 ` Kevin Hilman
2011-09-26 18:45   ` Kevin Hilman
2011-09-30 12:09   ` Premi, Sanjeev
2011-09-30 12:09     ` Premi, Sanjeev
2011-09-30 17:09     ` Kevin Hilman
2011-09-30 17:09       ` Kevin Hilman
2011-10-06 23:03       ` Tony Lindgren
2011-10-06 23:03         ` Tony Lindgren
2011-11-03 13:48         ` Hiremath, Vaibhav
2011-11-03 13:48           ` Hiremath, Vaibhav
2011-11-05  9:41 ` Hiremath, Vaibhav
2011-11-05  9:41   ` Hiremath, Vaibhav
2011-11-05 10:29   ` Hiremath, Vaibhav
2011-11-05 10:29     ` Hiremath, Vaibhav
2011-09-20 14:32 [PATCH-V3 1/4] arm:omap:am33xx: Update common omap platform files hvaibhav
2011-09-20 14:32 ` hvaibhav at ti.com
2011-10-06 23:03 ` Tony Lindgren
2011-10-06 23:03   ` Tony Lindgren
2011-08-29 12:46 [RFC PATCH-V2 0/4] Introducing TI's New SoC/board AM335XEVM hvaibhav
2011-08-29 12:46 ` hvaibhav at ti.com
2011-09-15  0:32 ` Tony Lindgren
2011-09-15  0:32   ` Tony Lindgren
2011-09-15  7:13   ` Hiremath, Vaibhav
2011-09-15  7:13     ` Hiremath, Vaibhav
2009-05-06 18:31 [PATCH (V2)] TVP514x: Migration to sub-device framework hvaibhav
2009-06-14 10:14 ` Hans Verkuil
2009-06-14 12:44   ` Hans Verkuil
2009-06-14 14:32     ` tcm825x.c: migrating to sub-device framework? (was: TVP514x: Migration to sub-device framework) Hans Verkuil
2009-06-15  8:45       ` tcm825x.c: migrating to sub-device framework? Sakari Ailus
2009-06-14 19:50   ` [PATCH (V2)] TVP514x: Migration to sub-device framework David Brownell
2009-06-14 19:50     ` David Brownell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1228232142-11934-1-git-send-email-hvaibhav@ti.com \
    --to=hvaibhav@ti.com \
    --cc=davinci-linux-open-source-bounces@linux.davincidsp.com \
    --cc=linux-omap@vger.kernel.org \
    --cc=m-karicheri2@ti.com \
    --cc=video4linux-list@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.