All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/1] Add driver support for ITE IT9135 device
@ 2011-08-05 10:24 jasondong
  2011-08-06  9:51 ` [PATCH 1/2] IT9135 Add support for KWORLD_UB499_2T_T09 (id 1b80:e409) Malcolm Priestley
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: jasondong @ 2011-08-05 10:24 UTC (permalink / raw)
  To: linux-media

This is DVB USB Linux driver for ITEtech IT9135 base USB TV module.
It supported the IT9135 AX and BX chip versions.

Signed-off-by: jasondong <jason.dong@ite.com.tw>
---
 Documentation/dvb/get_dvb_firmware      |   17 +-
 drivers/media/dvb/dvb-usb/Kconfig       |    6 +
 drivers/media/dvb/dvb-usb/Makefile      |    3 +
 drivers/media/dvb/dvb-usb/dvb-usb-ids.h |    4 +
 drivers/media/dvb/dvb-usb/it9135-fe.c   | 4743 +++++++++++++++++++++++++++++++
 drivers/media/dvb/dvb-usb/it9135-fe.h   | 1632 +++++++++++
 drivers/media/dvb/dvb-usb/it9135.c      | 2492 ++++++++++++++++
 drivers/media/dvb/dvb-usb/it9135.h      |  155 +
 8 files changed, 9051 insertions(+), 1 deletions(-)
 mode change 100644 => 100755 Documentation/dvb/get_dvb_firmware
 create mode 100644 drivers/media/dvb/dvb-usb/it9135-fe.c
 create mode 100644 drivers/media/dvb/dvb-usb/it9135-fe.h
 create mode 100644 drivers/media/dvb/dvb-usb/it9135.c
 create mode 100644 drivers/media/dvb/dvb-usb/it9135.h

diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
old mode 100644
new mode 100755
index 3348d31..1b30198
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -27,7 +27,7 @@ use IO::Handle;
 		"or51211", "or51132_qam", "or51132_vsb", "bluebird",
 		"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
 		"af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395",
-		"lme2510c_s7395_old");
+		"lme2510c_s7395_old", "it9135");
 
 # Check args
 syntax() if (scalar(@ARGV) != 1);
@@ -634,6 +634,21 @@ sub lme2510c_s7395_old {
     $outfile;
 }
 
+sub it9135 {
+	my $sourcefile = "dvb-usb-it9135.zip";
+	my $url = "http://www.ite.com.tw/uploads/firmware/v3.6.0.0/$sourcefile";
+	my $hash = "1e55f6c8833f1d0ae067c2bb2953e6a9";
+	my $outfile = "dvb-usb-it9135.fw";
+
+	checkstandard();
+
+	wgetfile($sourcefile, $url);
+	unzip($sourcefile, "");
+	verify("$outfile", $hash);
+
+	$outfile;
+}
+
 # ---------------------------------------------------------------
 # Utilities
 
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index e85304c..468fe8e 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -373,3 +373,9 @@ config DVB_USB_TECHNISAT_USB2
 	select DVB_STV6110x if !DVB_FE_CUSTOMISE
 	help
 	  Say Y here to support the Technisat USB2 DVB-S/S2 device
+
+config DVB_USB_IT9135
+	tristate "ITEtech IT9135 DVB-T USB2.0 support"
+	depends on DVB_USB
+	help
+	  Say Y here to support the ITE IT9135 based DVB-T USB2.0 receiver
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 4bac13d..466b23c 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -94,6 +94,9 @@ obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
 dvb-usb-technisat-usb2-objs = technisat-usb2.o
 obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
 
+dvb-usb-it9135-objs := it9135.o it9135-fe.o
+obj-$(CONFIG_DVB_USB_IT9135) += dvb-usb-it9135.o
+
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
 # due to tuner-xc3028
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 21b1549..ffeb338 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -67,6 +67,7 @@
 #define USB_VID_EVOLUTEPC			0x1e59
 #define USB_VID_AZUREWAVE			0x13d3
 #define USB_VID_TECHNISAT			0x14f7
+#define USB_VID_ITETECH				0x048d
 
 /* Product IDs */
 #define USB_PID_ADSTECH_USB2_COLD			0xa333
@@ -320,4 +321,7 @@
 #define USB_PID_TECHNISAT_USB2_HDCI_V2			0x0002
 #define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2		0x0004
 #define USB_PID_TECHNISAT_USB2_DVB_S2			0x0500
+#define USB_PID_ITETECH_IT9135				0x9135
+#define USB_PID_ITETECH_IT9135_9005			0x9005
+#define USB_PID_ITETECH_IT9135_9006			0x9006
 #endif
diff --git a/drivers/media/dvb/dvb-usb/it9135-fe.c b/drivers/media/dvb/dvb-usb/it9135-fe.c
new file mode 100644
index 0000000..e3ddbf3
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/it9135-fe.c
@@ -0,0 +1,4743 @@
+/*
+ * DVB USB Linux driver for IT9135 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2011 ITE Technologies, INC.
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ */
+
+#include <linux/delay.h>
+
+#include "it9135.h"
+
+static unsigned long it9135_enter_mutex(struct it9135_data *data)
+{
+	/*
+	 *  ToDo:  Add code here
+	 */
+	return ERROR_NO_ERROR;
+}
+
+static unsigned long it9135_leave_mutex(struct it9135_data *data)
+{
+	/*
+	 *  ToDo:  Add code here
+	 */
+	return ERROR_NO_ERROR;
+}
+
+/*
+ * IT9135 command functions
+ */
+#define IT9135_MAX_CMD_SIZE		63
+
+static unsigned long it9135_cmd_add_checksum(struct it9135_data *data,
+					     unsigned long *buff_len,
+					     unsigned char *buffer)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned long loop = (*buff_len - 1) / 2;
+	unsigned long remain = (*buff_len - 1) % 2;
+	unsigned long i;
+	unsigned short checksum = 0;
+
+	for (i = 0; i < loop; i++)
+		checksum +=
+		    (unsigned short)(buffer[2 * i + 1] << 8) +
+		    (unsigned short)(buffer[2 * i + 2]);
+	if (remain)
+		checksum += (unsigned short)(buffer[*buff_len - 1] << 8);
+
+	checksum = ~checksum;
+	buffer[*buff_len] = (unsigned char)((checksum & 0xFF00) >> 8);
+	buffer[*buff_len + 1] = (unsigned char)(checksum & 0x00FF);
+	buffer[0] = (unsigned char)(*buff_len + 1);
+	*buff_len += 2;
+
+	return error;
+}
+
+static unsigned long it9135_cmd_remove_checksum(struct it9135_data *data,
+						unsigned long *buff_len,
+						unsigned char *buffer)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned long loop = (*buff_len - 3) / 2;
+	unsigned long remain = (*buff_len - 3) % 2;
+	unsigned long i;
+	unsigned short checksum = 0;
+
+	for (i = 0; i < loop; i++)
+		checksum +=
+		    (unsigned short)(buffer[2 * i + 1] << 8) +
+		    (unsigned short)(buffer[2 * i + 2]);
+	if (remain)
+		checksum += (unsigned short)(buffer[*buff_len - 3] << 8);
+
+	checksum = ~checksum;
+	if (((unsigned short)(buffer[*buff_len - 2] << 8) +
+	     (unsigned short)(buffer[*buff_len - 1])) != checksum) {
+		error = ERROR_WRONG_CHECKSUM;
+		goto exit;
+	}
+	if (buffer[2])
+		error = ERROR_FIRMWARE_STATUS | buffer[2];
+
+	buffer[0] = (unsigned char)(*buff_len - 3);
+	*buff_len -= 2;
+
+exit:
+	return error;
+}
+
+#define IT9135_USB_BULK_TIMEOUT		2000
+
+static unsigned long it9135_cmd_bus_tx(struct it9135_data *data,
+				       unsigned long buff_len,
+				       unsigned char *buffer)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	int act_len, ret;
+
+	ret = usb_bulk_msg(usb_get_dev(data->driver),
+			   usb_sndbulkpipe(usb_get_dev(data->driver), 0x02),
+			   buffer, buff_len, &act_len, IT9135_USB_BULK_TIMEOUT);
+
+	if (ret) {
+		error = ERROR_USB_WRITE_FAIL;
+		err(" it9135_cmd_bus_tx fail : %d!", ret);
+	}
+
+	return error;
+}
+
+static unsigned long it9135_cmd_bus_rx(struct it9135_data *data,
+				       unsigned long buff_len,
+				       unsigned char *buffer)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	int act_len, ret;
+
+	ret = usb_bulk_msg(usb_get_dev(data->driver),
+			   usb_rcvbulkpipe(usb_get_dev(data->driver), 129),
+			   buffer, 125, &act_len, IT9135_USB_BULK_TIMEOUT);
+
+	if (ret) {
+		error = ERROR_USB_WRITE_FAIL;
+		err(" it9135_cmd_bus_rx fail: %d!", ret);
+	}
+
+	return error;
+}
+
+static unsigned long it9135_cmd_loadfirmware(struct it9135_data *data,
+					     unsigned long length,
+					     unsigned char *firmware)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned short command;
+	unsigned long loop;
+	unsigned long remain;
+	unsigned long i, j, k;
+	unsigned char buffer[255];
+	unsigned long payloadLength;
+	unsigned long buff_len;
+	unsigned long remain_len;
+	unsigned long send_len;
+
+	it9135_enter_mutex(data);
+
+	payloadLength = (IT9135_MAX_CMD_SIZE - 6);
+	loop = length / payloadLength;
+	remain = length % payloadLength;
+
+	k = 0;
+	command = it9135_build_command(CMD_FW_DOWNLOAD, PROCESSOR_LINK, 0);
+	for (i = 0; i < loop; i++) {
+		buffer[1] = (unsigned char)(command >> 8);
+		buffer[2] = (unsigned char)command;
+		buffer[3] = (unsigned char)data->cmd_seq++;
+
+		for (j = 0; j < payloadLength; j++)
+			buffer[4 + j] = firmware[j + i * payloadLength];
+
+		buff_len = 4 + payloadLength;
+		error = it9135_cmd_add_checksum(data, &buff_len, buffer);
+		if (error)
+			goto exit;
+
+		send_len = 0;
+		remain_len = IT9135_MAX_CMD_SIZE;
+		while (remain_len > 0) {
+			k = (remain_len >
+			     IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
+			    : (remain_len);
+			error = it9135_cmd_bus_tx(data, k, &buffer[send_len]);
+			if (error)
+				goto exit;
+
+			send_len += k;
+			remain_len -= k;
+		}
+	}
+
+	if (remain) {
+		buffer[1] = (unsigned char)(command >> 8);
+		buffer[2] = (unsigned char)command;
+		buffer[3] = (unsigned char)data->cmd_seq++;
+
+		for (j = 0; j < remain; j++)
+			buffer[4 + j] = firmware[j + i * payloadLength];
+
+		buff_len = 4 + remain;
+		error = it9135_cmd_add_checksum(data, &buff_len, buffer);
+		if (error)
+			goto exit;
+
+		send_len = 0;
+		remain_len = buff_len;
+		while (remain_len > 0) {
+			k = (remain_len >
+			     IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
+			    : (remain_len);
+			error = it9135_cmd_bus_tx(data, k, &buffer[send_len]);
+			if (error)
+				goto exit;
+
+			send_len += k;
+			remain_len -= k;
+		}
+	}
+
+exit:
+	it9135_leave_mutex(data);
+	return error;
+}
+
+static unsigned long it9135_cmd_reboot(struct it9135_data *data,
+				       unsigned char chip)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned short command;
+	unsigned char buffer[255];
+	unsigned long buff_len;
+
+	it9135_enter_mutex(data);
+
+	command = it9135_build_command(CMD_REBOOT, PROCESSOR_LINK, chip);
+	buffer[1] = (unsigned char)(command >> 8);
+	buffer[2] = (unsigned char)command;
+	buffer[3] = (unsigned char)data->cmd_seq++;
+	buff_len = 4;
+	error = it9135_cmd_add_checksum(data, &buff_len, buffer);
+	if (error)
+		goto exit;
+
+	error = it9135_cmd_bus_tx(data, buff_len, buffer);
+	if (error)
+		goto exit;
+
+exit:
+	it9135_leave_mutex(data);
+	return error;
+}
+
+/*
+ * Send the command to device.
+ *
+ * @param struct it9135_data the handle of IT9135.
+ * @param command the command to be send.
+ * @param chip The index of IT9135. The possible values are 0~7.
+ * @param processor The processor of specified register. Because each chip
+ *        has two processor so user have to specify the processor. The
+ *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
+ * @param w_buff_len the number of registers to be write.
+ * @param w_buff a unsigned char array which is used to store values to be write.
+ * @param r_buff_len the number of registers to be read.
+ * @param r_buff a unsigned char array which is used to store values to be read.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+static unsigned long it9135_cmd_sendcommand(struct it9135_data *data,
+					    unsigned short command,
+					    unsigned char chip,
+					    unsigned char processor,
+					    unsigned long w_buff_len,
+					    unsigned char *w_buff,
+					    unsigned long r_buff_len,
+					    unsigned char *r_buff)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char buffer[255];
+	unsigned long buff_len;
+	unsigned long remain_len;
+	unsigned long send_len;
+	unsigned long i, k;
+
+	it9135_enter_mutex(data);
+
+	if ((w_buff_len + 6) > IT9135_MAX_CMD_SIZE) {
+		error = ERROR_INVALID_DATA_LENGTH;
+		goto exit;
+	}
+
+	if ((r_buff_len + 5) > IT9135_MAX_PKT_SIZE) {
+		error = ERROR_INVALID_DATA_LENGTH;
+		goto exit;
+	}
+
+	if ((r_buff_len + 5) > IT9135_MAX_CMD_SIZE) {
+		error = ERROR_INVALID_DATA_LENGTH;
+		goto exit;
+	}
+
+	if (w_buff_len == 0) {
+		command = it9135_build_command(command, processor, chip);
+		buffer[1] = (unsigned char)(command >> 8);
+		buffer[2] = (unsigned char)command;
+		buffer[3] = (unsigned char)data->cmd_seq++;
+		buff_len = 4;
+		error = it9135_cmd_add_checksum(data, &buff_len, buffer);
+		if (error)
+			goto exit;
+
+		/* send command packet */
+		i = 0;
+		send_len = 0;
+		remain_len = buff_len;
+		while (remain_len > 0) {
+			i = (remain_len >
+			     IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
+			    : (remain_len);
+			error = it9135_cmd_bus_tx(data, i, &buffer[send_len]);
+			if (error)
+				goto exit;
+
+			send_len += i;
+			remain_len -= i;
+		}
+	} else {
+		command = it9135_build_command(command, processor, chip);
+		buffer[1] = (unsigned char)(command >> 8);
+		buffer[2] = (unsigned char)command;
+		buffer[3] = (unsigned char)data->cmd_seq++;
+		for (k = 0; k < w_buff_len; k++)
+			buffer[k + 4] = w_buff[k];
+
+		buff_len = 4 + w_buff_len;
+		error = it9135_cmd_add_checksum(data, &buff_len, buffer);
+		if (error)
+			goto exit;
+
+		/* send command */
+		i = 0;
+		send_len = 0;
+		remain_len = buff_len;
+		while (remain_len > 0) {
+			i = (remain_len >
+			     IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
+			    : (remain_len);
+			error = it9135_cmd_bus_tx(data, i, &buffer[send_len]);
+			if (error)
+				goto exit;
+
+			send_len += i;
+			remain_len -= i;
+		}
+	}
+
+	buff_len = 5 + r_buff_len;
+
+	error = it9135_cmd_bus_rx(data, buff_len, buffer);
+	if (error)
+		goto exit;
+
+	error = it9135_cmd_remove_checksum(data, &buff_len, buffer);
+	if (error)
+		goto exit;
+
+	if (r_buff_len) {
+		for (k = 0; k < r_buff_len; k++)
+			r_buff[k] = buffer[k + 3];
+	}
+
+exit:
+	it9135_leave_mutex(data);
+	return error;
+}
+
+/*
+ * IT9135 tuner functions
+ */
+
+static unsigned int it9135_tuner_get_nv(unsigned int nc)
+{
+	unsigned int nv;
+
+	switch (nc) {
+	case 0:
+		nv = 48;
+		break;
+	case 1:
+		nv = 32;
+		break;
+	case 2:
+		nv = 24;
+		break;
+	case 3:
+		nv = 16;
+		break;
+	case 4:
+		nv = 12;
+		break;
+	case 5:
+		nv = 8;
+		break;
+	case 6:
+		nv = 6;
+		break;
+	case 7:
+		nv = 4;
+		break;
+	case 8:		/* L-band */
+		nv = 2;
+		break;
+	default:
+		nv = 2;
+		break;
+	}
+
+	return nv;
+}
+
+static unsigned int it9135_fn_min[] = {
+	53000, 74000, 111000, 148000, 222000, 296000, 445000, 573000, 950000
+};
+
+static unsigned long it9135_tuner_init(struct it9135_data *data,
+				       unsigned char chip)
+{
+	unsigned long error = 0;
+	unsigned char buf[4], val;
+	unsigned int m_bdry, nc, nv;
+	unsigned long tmp_numer, tmp_denom;
+	unsigned int cnt;
+
+#define OMEGA_TUNER_INIT_POLL_INTERVAL	2
+#define OMEGA_TUNER_INIT_POLL_COUNTS	50
+
+	/* ----- read ----- */
+	/* p_reg_p_tsm_init_clock_mode */
+	error = it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xEC86, 1, buf);
+	if (error)
+		goto exit;
+	/* p_reg_p_fbc_n_code */
+	error =
+	    it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xED03, 1, &buf[1]);
+	if (error)
+		goto exit;
+	/* r_reg_r_fbc_m_bdry_7_0 */
+	error =
+	    it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xED23, 2, &buf[2]);
+	if (error)
+		goto exit;
+
+	/* ----- set_clock_mode ----- */
+	data->clock_mode = buf[0];
+
+	/* ----- set_fref_kHz & m_cal ----- */
+	switch (data->clock_mode) {
+	case 0:		/* 12.00MHz, 12000/18 = 2000/3 */
+		data->fxtal_khz = 2000;
+		data->fdiv = 3;
+		val = 16;
+		break;
+	case 1:		/* 20.48MHz, 20480/32 = 640/1 */
+		data->fxtal_khz = 640;
+		data->fdiv = 1;
+		val = 6;
+		break;
+	default:		/* 20.48MHz, 20480/32 = 640/1 */
+		data->fxtal_khz = 640;
+		data->fdiv = 1;
+		val = 6;
+		break;
+	}
+
+	/* ----- set_fbdry ----- */
+	nc = buf[1];
+	nv = it9135_tuner_get_nv(nc);
+	m_bdry = (buf[3] << 8) + buf[2];	/* m_bdry = m_bdry_15_8 << 8 + m_bdry_7_0 */
+
+	/* ----- patch to wait for fbc done ----- */
+	cnt = 1;
+	while (m_bdry == 0 && cnt < OMEGA_TUNER_INIT_POLL_COUNTS) {
+		mdelay(OMEGA_TUNER_INIT_POLL_INTERVAL);
+		/* r_reg_r_fbc_m_bdry_7_0 */
+		error =
+		    it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xED23, 2,
+				     &buf[2]);
+		if (error)
+			goto exit;
+		m_bdry = (buf[3] << 8) + buf[2];	/* m_bdry = m_bdry_15_8 << 8 + m_bdry_7_0 */
+		cnt++;
+	}
+
+	if (m_bdry == 0) {
+		error = ERROR_TUNER_INIT_FAIL;
+		goto exit;
+	}
+
+	tmp_numer = (unsigned long)data->fxtal_khz * (unsigned long)m_bdry;
+	tmp_denom = (unsigned long)data->fdiv * (unsigned long)nv;
+	it9135_fn_min[7] = (unsigned int)(tmp_numer / tmp_denom);
+
+	/* ----- patch to wait for all cal done, borrow p_reg_p_tsm_init_mode ----- */
+	cnt = 1;
+
+	if (data->chip_type == 0x9135 && data->chip_ver == 2) {
+		mdelay(50);	/* for omega2 */
+	} else {
+		/* p_reg_p_tsm_init_mode */
+		error =
+		    it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xEC82, 1,
+				     buf);
+		if (error)
+			goto exit;
+
+		while (buf[0] == 0 && cnt < OMEGA_TUNER_INIT_POLL_COUNTS) {
+			mdelay(OMEGA_TUNER_INIT_POLL_INTERVAL);
+			/* p_reg_p_tsm_init_mode */
+			error =
+			    it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xEC82,
+					     1, buf);
+			if (error)
+				goto exit;
+			cnt++;
+		}
+		if (buf[0] == 0) {
+			error = ERROR_TUNER_INIT_FAIL;
+			goto exit;
+		}
+	}
+
+	/* p_reg_p_iqik_m_cal */
+	error = it9135_write_regs(data, chip, PROCESSOR_OFDM, 0xED81, 1, &val);
+
+exit:
+	return error;
+}
+
+static unsigned int it9135_tuner_get_nc(unsigned int rf_freq_khz)
+{
+	unsigned int nc;
+
+	if ((rf_freq_khz <= it9135_fn_min[1])) {	/* 74 */
+		nc = 0;
+	} else if ((rf_freq_khz > it9135_fn_min[1]) && (rf_freq_khz <= it9135_fn_min[2])) {	/* 74 111 */
+		nc = 1;
+	} else if ((rf_freq_khz > it9135_fn_min[2]) && (rf_freq_khz <= it9135_fn_min[3])) {	/* 111 148 */
+		nc = 2;
+	} else if ((rf_freq_khz > it9135_fn_min[3]) && (rf_freq_khz <= it9135_fn_min[4])) {	/* 148 222 */
+		nc = 3;
+	} else if ((rf_freq_khz > it9135_fn_min[4]) && (rf_freq_khz <= it9135_fn_min[5])) {	/* 222 296 */
+		nc = 4;
+	} else if ((rf_freq_khz > it9135_fn_min[5]) && (rf_freq_khz <= it9135_fn_min[6])) {	/* 296 445 */
+		nc = 5;
+	} else if ((rf_freq_khz > it9135_fn_min[6]) && (rf_freq_khz <= it9135_fn_min[7])) {	/* 445 573 */
+		nc = 6;
+	} else if ((rf_freq_khz > it9135_fn_min[7]) && (rf_freq_khz <= it9135_fn_min[8])) {	/* 573 890 */
+		nc = 7;
+	} else {		/* L-band */
+		nc = 8;
+	}
+
+	return nc;
+}
+
+static unsigned int it9135_tuner_get_freq_code(struct it9135_data *data,
+					       unsigned int rf_freq_khz,
+					       unsigned int *nc,
+					       unsigned int *nv,
+					       unsigned int *mv)
+{
+	unsigned int freq_code;
+	unsigned long tmp_tg, tmp_cal, tmp_m;
+
+	*nc = it9135_tuner_get_nc(rf_freq_khz);
+	*nv = it9135_tuner_get_nv(*nc);
+	tmp_tg =
+	    (unsigned long)rf_freq_khz * (unsigned long)(*nv) *
+	    (unsigned long)data->fdiv;
+	tmp_m = (tmp_tg / (unsigned long)data->fxtal_khz);
+	tmp_cal = tmp_m * (unsigned long)data->fxtal_khz;
+
+	if ((tmp_tg - tmp_cal) >= (data->fxtal_khz >> 1))
+		tmp_m = tmp_m + 1;
+
+	*mv = (unsigned int)(tmp_m);
+
+	freq_code = (((*nc) & 0x07) << 13) + (*mv);
+
+	return freq_code;
+}
+
+static unsigned int it9135_tuner_get_freq_iqik(struct it9135_data *data,
+					       unsigned int rf_freq_khz,
+					       unsigned char iqik_m_cal)
+{
+	unsigned int nc, nv, mv, cal_freq;
+
+#define OMEGA_IQIK_M_CAL_MAX	64
+#define OMEGA_IQIK_M_CAL_MID	32
+
+	cal_freq = it9135_tuner_get_freq_code(data, rf_freq_khz, &nc, &nv, &mv);
+	if (data->clock_mode == 0 && (iqik_m_cal < OMEGA_IQIK_M_CAL_MID)) {
+		mv = mv + ((((unsigned int)iqik_m_cal) * nv * 9) >> 5);
+	} else if (data->clock_mode == 0
+		   && (iqik_m_cal >= OMEGA_IQIK_M_CAL_MID)) {
+		iqik_m_cal = OMEGA_IQIK_M_CAL_MAX - iqik_m_cal;
+		mv = mv - ((((unsigned int)iqik_m_cal) * nv * 9) >> 5);
+	} else if (data->clock_mode == 1 && (iqik_m_cal < OMEGA_IQIK_M_CAL_MID)) {
+		mv = mv + ((((unsigned int)iqik_m_cal) * nv) >> 1);
+	} else {		/* (data->clock_mode==1 && (iqik_m_cal >= OMEGA_IQIK_M_CAL_MID)) */
+		iqik_m_cal = OMEGA_IQIK_M_CAL_MAX - iqik_m_cal;
+		mv = mv - ((((unsigned int)iqik_m_cal) * nv) >> 1);
+	}
+	cal_freq = ((nc & 0x07) << 13) + mv;
+
+	return cal_freq;
+}
+
+/* the reason to use 392000(but not 400000) because cal_rssi will use 400000-8000= 392000; */
+static unsigned int it9135_lna_fband_min[] = {
+	392000, 440000, 484000, 533000, 587000, 645000, 710000, 782000, 860000,
+	1450000, 1492000, 1660000, 1685000
+};
+
+static unsigned char it9135_tuner_get_lna_cap_sel(unsigned int rf_freq_khz)
+{
+	unsigned char lna_cap_sel;
+
+	if (rf_freq_khz <= it9135_lna_fband_min[1]) {	/* <=440 */
+		lna_cap_sel = 0;
+	} else if (rf_freq_khz > it9135_lna_fband_min[1] && rf_freq_khz <= it9135_lna_fband_min[2]) {	/* 440 484 */
+		lna_cap_sel = 1;
+	} else if (rf_freq_khz > it9135_lna_fband_min[2] && rf_freq_khz <= it9135_lna_fband_min[3]) {	/* 484 533 */
+		lna_cap_sel = 2;
+	} else if (rf_freq_khz > it9135_lna_fband_min[3] && rf_freq_khz <= it9135_lna_fband_min[4]) {	/* 533 587 */
+		lna_cap_sel = 3;
+	} else if (rf_freq_khz > it9135_lna_fband_min[4] && rf_freq_khz <= it9135_lna_fband_min[5]) {	/* 587 645 */
+		lna_cap_sel = 4;
+	} else if (rf_freq_khz > it9135_lna_fband_min[5] && rf_freq_khz <= it9135_lna_fband_min[6]) {	/* 645 710 */
+		lna_cap_sel = 5;
+	} else if (rf_freq_khz > it9135_lna_fband_min[6] && rf_freq_khz <= it9135_lna_fband_min[7]) {	/* 710 782 */
+		lna_cap_sel = 6;
+	} else {		/* >782 */
+		lna_cap_sel = 7;
+	}
+
+	return lna_cap_sel;
+}
+
+static unsigned int it9135_tuner_get_lo_freq(struct it9135_data *data,
+					     unsigned int rf_freq_khz)
+{
+	unsigned int nc, nv, mv, lo_freq;
+
+	lo_freq = it9135_tuner_get_freq_code(data, rf_freq_khz, &nc, &nv, &mv);
+
+	return lo_freq;
+}
+
+static unsigned char it9135_tuner_get_lpf_bw(unsigned int bw_khz)
+{
+	unsigned char lpf_bw;
+
+	switch (bw_khz) {	/*5.0MHz */
+	case 5000:
+		lpf_bw = 0;
+		break;
+	case 5500:		/*5.5MHz */
+		lpf_bw = 1;
+		break;
+	case 6000:		/*6.0MHz */
+		lpf_bw = 2;
+		break;
+	case 6500:		/*6.5MHz */
+		lpf_bw = 3;
+		break;
+	case 7000:		/*7.0MHz */
+		lpf_bw = 4;
+		break;
+	case 7500:		/*7.5MHz */
+		lpf_bw = 5;
+		break;
+	case 8000:		/*8.0MHz */
+		lpf_bw = 6;
+		break;
+	case 8500:		/*8.5MHz */
+		lpf_bw = 7;
+		break;
+	default:		/*default: 8MHz */
+		lpf_bw = 6;
+		break;
+	}
+
+	return lpf_bw;
+}
+
+static unsigned long it9135_tuner_set_freq(struct it9135_data *data,
+					   unsigned char chip,
+					   unsigned int bw_khz,
+					   unsigned int rf_freq_khz)
+{
+	unsigned long error = 0;
+	unsigned char val[7];
+	unsigned char buf[2];
+	unsigned int tmp;
+
+#define IT9135_CAP_FREQ_UHF_MIN		392000
+
+	/* p_reg_t_ctrl */
+	error = it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xEC4C, 1, buf);
+	if (error)
+		goto exit;
+	/* p_reg_p_iqik_m_cal */
+	error =
+	    it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xED81, 1, &buf[1]);
+	if (error)
+		goto exit;
+
+	val[0] = it9135_tuner_get_lna_cap_sel(rf_freq_khz);
+	val[1] = it9135_tuner_get_lpf_bw(bw_khz);
+
+	/* ----- set_rf_mode ----- */
+	if (rf_freq_khz < IT9135_CAP_FREQ_UHF_MIN)
+		val[2] = buf[0] & 0xE7;	/* ctrl<4:3>=0b00 for VHF */
+	else
+		val[2] = (buf[0] & 0xE7) | 0x08;	/* ctrl<4:3>=0b01 for UHF */
+
+	/* ----- set_cal_freq ----- */
+	tmp = it9135_tuner_get_freq_iqik(data, rf_freq_khz, buf[1]);
+	val[3] = (unsigned char)(tmp & 0xFF);
+	val[4] = (unsigned char)((tmp >> 8) & 0xFF);
+	/* ----- set_lo_freq ----- */
+	tmp = it9135_tuner_get_lo_freq(data, rf_freq_khz);
+	val[5] = (unsigned char)(tmp & 0xFF);
+	val[6] = (unsigned char)((tmp >> 8) & 0xFF);
+	/* ----- write ----- */
+	error =
+	    it9135_write_regs(data, chip, PROCESSOR_OFDM, var_pre_lna_cap_sel,
+			      1, val);
+	if (error)
+		goto exit;
+	/* p_reg_t_lpf_bw */
+	error =
+	    it9135_write_regs(data, chip, PROCESSOR_OFDM, 0xEC56, 1, &val[1]);
+	if (error)
+		goto exit;
+	/* p_reg_t_ctrl */
+	error =
+	    it9135_write_regs(data, chip, PROCESSOR_OFDM, 0xEC4C, 1, &val[2]);
+	if (error)
+		goto exit;
+	/*----- the writing sequence is important for cal_freq and lo_freq, thus separate ----- */
+	/* p_reg_t_cal_freq_7_0 */
+	error =
+	    it9135_write_regs(data, chip, PROCESSOR_OFDM, 0xEC4D, 1, &val[3]);
+	if (error)
+		goto exit;
+	/* p_reg_t_cal_freq_15_8 */
+	error =
+	    it9135_write_regs(data, chip, PROCESSOR_OFDM, 0xEC4E, 1, &val[4]);
+	if (error)
+		goto exit;
+
+	error =
+	    it9135_write_regs(data, chip, PROCESSOR_OFDM, var_pre_lo_freq_7_0,
+			      1, &val[5]);
+	if (error)
+		goto exit;
+
+	error =
+	    it9135_write_regs(data, chip, PROCESSOR_OFDM, var_pre_lo_freq_15_8,
+			      1, &val[6]);
+
+exit:
+	return error;
+}
+
+/*
+ * Demodular functions
+ */
+
+static unsigned long it9135_divider(struct it9135_data *data, unsigned long a,
+				    unsigned long b, unsigned long x)
+{
+	unsigned long answer = 0;
+	unsigned long c = 0;
+	unsigned long i = 0;
+
+	if (a > b) {
+		c = a / b;
+		a = a - c * b;
+	}
+
+	for (i = 0; i < x; i++) {
+		if (a >= b) {
+			answer += 1;
+			a -= b;
+		}
+		a <<= 1;
+		answer <<= 1;
+	}
+
+	answer = (c << (long)x) + answer;
+
+	return answer;
+}
+
+/* @param crystal_Freq: Crystal frequency (Hz) */
+static unsigned long it9135_compute_crystal(struct it9135_data *data,
+					    long crystal_frequency,
+					    unsigned long *crystal)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	*crystal =
+	    (long)it9135_divider(data, (unsigned long)crystal_frequency,
+				 1000000ul, 19ul);
+
+	return error;
+}
+
+/* @param adcFrequency: ADC frequency (Hz) */
+static unsigned long it9135_compute_adc(struct it9135_data *data, long adc_freq,
+					unsigned long *adc)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	*adc =
+	    (long)it9135_divider(data, (unsigned long)adc_freq, 1000000ul,
+				 19ul);
+
+	return error;
+}
+
+/*
+ * @param adcFrequency: ADC frequency (Hz)
+ * @param ifFrequency:  IF frequency (Hz)
+ * @param inversion:    RF spectrum inversion
+ */
+static unsigned long it9135_compute_fcw(struct it9135_data *data,
+					long adc_frequency, long if_frequency,
+					int inversion, unsigned long *fcw)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	long if_freq;
+	long adc_freq;
+	long adc_freq_half;
+	long adc_freq_sample;
+	long inv_bfs;
+	long ctrl_word;
+	unsigned char adc_multiplier;
+
+	adc_freq = adc_frequency;
+	if_freq = if_frequency;
+	adc_freq_half = adc_freq / 2;
+
+	if (inversion)
+		if_freq = -1 * if_freq;
+
+	adc_freq_sample = if_freq;
+
+	if (adc_freq_sample >= 0) {
+		inv_bfs = 1;
+	} else {
+		inv_bfs = -1;
+		adc_freq_sample = adc_freq_sample * -1;
+	}
+
+	while (adc_freq_sample > adc_freq_half)
+		adc_freq_sample = adc_freq_sample - adc_freq;
+
+	/* Sample, spectrum at positive frequency */
+	if (adc_freq_sample >= 0) {
+		inv_bfs = inv_bfs * -1;
+	} else {
+		inv_bfs = inv_bfs * 1;
+		adc_freq_sample = adc_freq_sample * (-1);	/* Absolute value */
+	}
+
+	ctrl_word =
+	    (long)it9135_divider(data, (unsigned long)adc_freq_sample,
+				 (unsigned long)adc_freq, 23ul);
+
+	if (inv_bfs == -1)
+		ctrl_word *= -1;
+
+	/* Get ADC multiplier */
+	error =
+	    it9135_read_reg(data, 0, PROCESSOR_OFDM, adcx2, &adc_multiplier);
+	if (error)
+		goto exit;
+
+	if (adc_multiplier == 1)
+		ctrl_word /= 2;
+
+	*fcw = ctrl_word & 0x7FFFFF;
+
+exit:
+	return error;
+}
+
+static unsigned long it9135_mask_dca_output(struct it9135_data *data)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char i;
+
+	if ((data->chip_num > 1)
+	    && (data->architecture == ARCHITECTURE_DCA)) {
+		for (i = 0; i < data->chip_num; i++) {
+			error =
+			    it9135_write_reg_bits(data, i,
+						  PROCESSOR_OFDM,
+						  p_reg_dca_upper_out_en,
+						  reg_dca_upper_out_en_pos,
+						  reg_dca_upper_out_en_len, 0);
+			if (error)
+				goto exit;
+		}
+		mdelay(5);
+	}
+
+exit:
+	return error;
+}
+
+static struct it9135_coeff_param coeff_tab[] = {
+	/* adc_freq 20156250 */
+	{20156250, 5000, 0x02449b5c, 0x01224dae, 0x00912b60, 0x009126d7,
+	 0x0091224e, 0x01224dae, 0x009126d7, 0x0048936b, 0x0387, 0x0122},
+	{20156250, 6000, 0x02b8ba6e, 0x015c5d37, 0x00ae340d, 0x00ae2e9b,
+	 0x00ae292a, 0x015c5d37, 0x00ae2e9b, 0x0057174e, 0x02f1, 0x015c},
+	{20156250, 7000, 0x032cd980, 0x01966cc0, 0x00cb3cba, 0x00cb3660,
+	 0x00cb3007, 0x01966cc0, 0x00cb3660, 0x00659b30, 0x0285, 0x0196},
+	{20156250, 8000, 0x03a0f893, 0x01d07c49, 0x00e84567, 0x00e83e25,
+	 0x00e836e3, 0x01d07c49, 0x00e83e25, 0x00741f12, 0x0234, 0x01d0},
+	/* adc_freq 20187500 */
+	{20187500, 5000, 0x0243b546, 0x0121daa3, 0x0090f1d9, 0x0090ed51,
+	 0x0090e8ca, 0x0121daa3, 0x0090ed51, 0x004876a9, 0x0388, 0x0122},
+	{20187500, 6000, 0x02b7a654, 0x015bd32a, 0x00adef04, 0x00ade995,
+	 0x00ade426, 0x015bd32a, 0x00ade995, 0x0056f4ca, 0x02f2, 0x015c},
+	{20187500, 7000, 0x032b9761, 0x0195cbb1, 0x00caec30, 0x00cae5d8,
+	 0x00cadf81, 0x0195cbb1, 0x00cae5d8, 0x006572ec, 0x0286, 0x0196},
+	{20187500, 8000, 0x039f886f, 0x01cfc438, 0x00e7e95b, 0x00e7e21c,
+	 0x00e7dadd, 0x01cfc438, 0x00e7e21c, 0x0073f10e, 0x0235, 0x01d0},
+	/* adc_freq 20250000 */
+	{20250000, 5000, 0x0241eb3b, 0x0120f59e, 0x00907f53, 0x00907acf,
+	 0x0090764b, 0x0120f59e, 0x00907acf, 0x00483d67, 0x038b, 0x0121},
+	{20250000, 6000, 0x02b580ad, 0x015ac057, 0x00ad6597, 0x00ad602b,
+	 0x00ad5ac1, 0x015ac057, 0x00ad602b, 0x0056b016, 0x02f4, 0x015b},
+	{20250000, 7000, 0x03291620, 0x01948b10, 0x00ca4bda, 0x00ca4588,
+	 0x00ca3f36, 0x01948b10, 0x00ca4588, 0x006522c4, 0x0288, 0x0195},
+	{20250000, 8000, 0x039cab92, 0x01ce55c9, 0x00e7321e, 0x00e72ae4,
+	 0x00e723ab, 0x01ce55c9, 0x00e72ae4, 0x00739572, 0x0237, 0x01ce},
+	/* adc_freq 20583333 */
+	{20583333, 5000, 0x02388f54, 0x011c47aa, 0x008e2846, 0x008e23d5,
+	 0x008e1f64, 0x011c47aa, 0x008e23d5, 0x004711ea, 0x039a, 0x011c},
+	{20583333, 6000, 0x02aa4598, 0x015522cc, 0x00aa96bb, 0x00aa9166,
+	 0x00aa8c12, 0x015522cc, 0x00aa9166, 0x005548b3, 0x0300, 0x0155},
+	{20583333, 7000, 0x031bfbdc, 0x018dfdee, 0x00c7052f, 0x00c6fef7,
+	 0x00c6f8bf, 0x018dfdee, 0x00c6fef7, 0x00637f7b, 0x0293, 0x018e},
+	{20583333, 8000, 0x038db21f, 0x01c6d910, 0x00e373a3, 0x00e36c88,
+	 0x00e3656d, 0x01c6d910, 0x00e36c88, 0x0071b644, 0x0240, 0x01c7},
+	/* adc_freq 20416667 */
+	{20416667, 5000, 0x023d337f, 0x011e99c0, 0x008f515a, 0x008f4ce0,
+	 0x008f4865, 0x011e99c0, 0x008f4ce0, 0x0047a670, 0x0393, 0x011f},
+	{20416667, 6000, 0x02afd765, 0x0157ebb3, 0x00abfb39, 0x00abf5d9,
+	 0x00abf07a, 0x0157ebb3, 0x00abf5d9, 0x0055faed, 0x02fa, 0x0158},
+	{20416667, 7000, 0x03227b4b, 0x01913da6, 0x00c8a518, 0x00c89ed3,
+	 0x00c8988e, 0x01913da6, 0x00c89ed3, 0x00644f69, 0x028d, 0x0191},
+	{20416667, 8000, 0x03951f32, 0x01ca8f99, 0x00e54ef7, 0x00e547cc,
+	 0x00e540a2, 0x01ca8f99, 0x00e547cc, 0x0072a3e6, 0x023c, 0x01cb},
+	/* adc_freq 20480000 */
+	{20480000, 5000, 0x023b6db7, 0x011db6db, 0x008edfe5, 0x008edb6e,
+	 0x008ed6f7, 0x011db6db, 0x008edb6e, 0x00476db7, 0x0396, 0x011e},
+	{20480000, 6000, 0x02adb6db, 0x0156db6e, 0x00ab7312, 0x00ab6db7,
+	 0x00ab685c, 0x0156db6e, 0x00ab6db7, 0x0055b6db, 0x02fd, 0x0157},
+	{20480000, 7000, 0x03200000, 0x01900000, 0x00c80640, 0x00c80000,
+	 0x00c7f9c0, 0x01900000, 0x00c80000, 0x00640000, 0x028f, 0x0190},
+	{20480000, 8000, 0x03924925, 0x01c92492, 0x00e4996e, 0x00e49249,
+	 0x00e48b25, 0x01c92492, 0x00e49249, 0x00724925, 0x023d, 0x01c9},
+	/* adc_freq 20500000 */
+	{20500000, 5000, 0x023adeff, 0x011d6f80, 0x008ebc36, 0x008eb7c0,
+	 0x008eb34a, 0x011d6f80, 0x008eb7c0, 0x00475be0, 0x0396, 0x011d},
+	{20500000, 6000, 0x02ad0b99, 0x015685cc, 0x00ab4840, 0x00ab42e6,
+	 0x00ab3d8c, 0x015685cc, 0x00ab42e6, 0x0055a173, 0x02fd, 0x0157},
+	{20500000, 7000, 0x031f3832, 0x018f9c19, 0x00c7d44b, 0x00c7ce0c,
+	 0x00c7c7ce, 0x018f9c19, 0x00c7ce0c, 0x0063e706, 0x0290, 0x0190},
+	{20500000, 8000, 0x039164cb, 0x01c8b266, 0x00e46056, 0x00e45933,
+	 0x00e45210, 0x01c8b266, 0x00e45933, 0x00722c99, 0x023e, 0x01c9},
+	/* adc_freq 20625000 */
+	{20625000, 5000, 0x02376948, 0x011bb4a4, 0x008ddec1, 0x008dda52,
+	 0x008dd5e3, 0x011bb4a4, 0x008dda52, 0x0046ed29, 0x039c, 0x011c},
+	{20625000, 6000, 0x02a8e4bd, 0x0154725e, 0x00aa3e81, 0x00aa392f,
+	 0x00aa33de, 0x0154725e, 0x00aa392f, 0x00551c98, 0x0302, 0x0154},
+	{20625000, 7000, 0x031a6032, 0x018d3019, 0x00c69e41, 0x00c6980c,
+	 0x00c691d8, 0x018d3019, 0x00c6980c, 0x00634c06, 0x0294, 0x018d},
+	{20625000, 8000, 0x038bdba6, 0x01c5edd3, 0x00e2fe02, 0x00e2f6ea,
+	 0x00e2efd2, 0x01c5edd3, 0x00e2f6ea, 0x00717b75, 0x0242, 0x01c6}
+};
+
+static int it915_coeff_tab_count = ARRAY_SIZE(coeff_tab);
+
+static unsigned long it9135_get_coeff_param(struct it9135_coeff_param *coeff)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	int i;
+
+	deb_info("it9135_get_coeff_param - %ld, %d\n", coeff->adc_freq,
+		 coeff->bandwidth);
+
+	for (i = 0; i < it915_coeff_tab_count; i++) {
+		if ((coeff->adc_freq == coeff_tab[i].adc_freq)
+		    && (coeff->bandwidth == coeff_tab[i].bandwidth)) {
+			memcpy(coeff, &coeff_tab[i], sizeof(*coeff));
+			deb_info("find coeff table - %ld, %d\n",
+				 coeff->adc_freq, coeff->bandwidth);
+			break;
+		}
+	}
+
+	if (i == it915_coeff_tab_count)
+		error = ERROR_INVALID_BW;
+
+	return error;
+}
+
+/*
+ * Program the bandwidth related parameters to IT9135.
+ *
+ * @param struct it9135_data the handle of IT9135.
+ * @param chip The index of IT9135. The possible values are 0~7.
+ *        NOTE: When the architecture is set to ARCHITECTURE_DCA
+ *        this parameter is regard as don't care.
+ * @param bandwidth DVB channel bandwidth in KHz. The possible values
+ *        are 5000, 6000, 7000, and 8000 (KHz).
+ * @param adc_freq The value of desire internal ADC frequency (Hz) ex: 20480000.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+static unsigned long it9135_select_bandwidth(struct it9135_data *data,
+					     unsigned char chip,
+					     unsigned short bandwidth,
+					     unsigned long adc_freq)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	struct it9135_coeff_param coeff;
+	unsigned char temp0;
+	unsigned char temp1;
+	unsigned char temp2;
+	unsigned char temp3;
+	unsigned char buffer[36];
+	unsigned char bw;
+	unsigned char adc_multiplier;
+
+	switch (bandwidth) {
+	case 5000:
+		bw = 3;
+		break;
+	case 6000:
+		bw = 0;
+		break;
+	case 7000:
+		bw = 1;
+		break;
+	case 8000:
+		bw = 2;
+		break;
+	default:
+		error = ERROR_INVALID_BW;
+		goto exit;
+	}
+
+	error =
+	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM, g_reg_bw,
+				  reg_bw_pos, reg_bw_len, bw);
+	if (error)
+		goto exit;
+
+	/* Program CFOE */
+	coeff.adc_freq = adc_freq;
+	coeff.bandwidth = bandwidth;
+	error = it9135_get_coeff_param(&coeff);
+	if (error)
+		goto exit;
+
+	/* Get ADC multiplier */
+	error =
+	    it9135_read_reg(data, 0, PROCESSOR_OFDM, adcx2, &adc_multiplier);
+	if (error)
+		goto exit;
+
+	if (adc_multiplier == 1) {
+		coeff.coeff1_2048Nu /= 2;
+		coeff.coeff1_4096Nu /= 2;
+		coeff.coeff1_8191Nu /= 2;
+		coeff.coeff1_8192Nu /= 2;
+		coeff.coeff1_8193Nu /= 2;
+		coeff.coeff2_2k /= 2;
+		coeff.coeff2_4k /= 2;
+		coeff.coeff2_8k /= 2;
+	}
+
+	/* Write coeff1_2048Nu */
+	/* Get unsigned char0 */
+	temp0 = (unsigned char)(coeff.coeff1_2048Nu & 0x000000FF);
+	/* Get unsigned char1 */
+	temp1 = (unsigned char)((coeff.coeff1_2048Nu & 0x0000FF00) >> 8);
+	/* Get unsigned char2 */
+	temp2 = (unsigned char)((coeff.coeff1_2048Nu & 0x00FF0000) >> 16);
+	/* Get unsigned char3 */
+	temp3 = (unsigned char)((coeff.coeff1_2048Nu & 0x03000000) >> 24);
+
+	/* Big endian to make 8051 happy */
+	buffer[cfoe_NS_2048_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
+	buffer[cfoe_NS_2048_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
+	buffer[cfoe_NS_2048_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
+	buffer[cfoe_NS_2048_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
+
+	/* Write coeff2_2k */
+	/* Get unsigned char0 */
+	temp0 = (unsigned char)((coeff.coeff2_2k & 0x000000FF));
+	/* Get unsigned char1 */
+	temp1 = (unsigned char)((coeff.coeff2_2k & 0x0000FF00) >> 8);
+	/* Get unsigned char2 */
+	temp2 = (unsigned char)((coeff.coeff2_2k & 0x00FF0000) >> 16);
+	/* Get unsigned char3 */
+	temp3 = (unsigned char)((coeff.coeff2_2k & 0x01000000) >> 24);
+
+	/* Big endian to make 8051 happy */
+	buffer[cfoe_NS_2k_coeff2_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
+	buffer[cfoe_NS_2k_coeff2_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
+	buffer[cfoe_NS_2k_coeff2_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
+	buffer[cfoe_NS_2k_coeff2_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
+
+	/* Write coeff1_8191Nu */
+	/* Get unsigned char0 */
+	temp0 = (unsigned char)((coeff.coeff1_8191Nu & 0x000000FF));
+	/* Get unsigned char1 */
+	temp1 = (unsigned char)((coeff.coeff1_8191Nu & 0x0000FF00) >> 8);
+	/* Get unsigned char2 */
+	temp2 = (unsigned char)((coeff.coeff1_8191Nu & 0x00FFC000) >> 16);
+	/* Get unsigned char3 */
+	temp3 = (unsigned char)((coeff.coeff1_8191Nu & 0x03000000) >> 24);
+
+	/* Big endian to make 8051 happy */
+	buffer[cfoe_NS_8191_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
+	buffer[cfoe_NS_8191_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
+	buffer[cfoe_NS_8191_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
+	buffer[cfoe_NS_8191_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
+
+	/* Write coeff1_8192Nu */
+	/* Get unsigned char0 */
+	temp0 = (unsigned char)(coeff.coeff1_8192Nu & 0x000000FF);
+	/* Get unsigned char1 */
+	temp1 = (unsigned char)((coeff.coeff1_8192Nu & 0x0000FF00) >> 8);
+	/* Get unsigned char2 */
+	temp2 = (unsigned char)((coeff.coeff1_8192Nu & 0x00FFC000) >> 16);
+	/* Get unsigned char3 */
+	temp3 = (unsigned char)((coeff.coeff1_8192Nu & 0x03000000) >> 24);
+
+	/* Big endian to make 8051 happy */
+	buffer[cfoe_NS_8192_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
+	buffer[cfoe_NS_8192_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
+	buffer[cfoe_NS_8192_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
+	buffer[cfoe_NS_8192_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
+
+	/* Write coeff1_8193Nu */
+	/* Get unsigned char0 */
+	temp0 = (unsigned char)((coeff.coeff1_8193Nu & 0x000000FF));
+	/* Get unsigned char1 */
+	temp1 = (unsigned char)((coeff.coeff1_8193Nu & 0x0000FF00) >> 8);
+	/* Get unsigned char2 */
+	temp2 = (unsigned char)((coeff.coeff1_8193Nu & 0x00FFC000) >> 16);
+	/* Get unsigned char3 */
+	temp3 = (unsigned char)((coeff.coeff1_8193Nu & 0x03000000) >> 24);
+
+	/* Big endian to make 8051 happy */
+	buffer[cfoe_NS_8193_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
+	buffer[cfoe_NS_8193_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
+	buffer[cfoe_NS_8193_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
+	buffer[cfoe_NS_8193_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
+
+	/* Write coeff2_8k */
+	/* Get unsigned char0 */
+	temp0 = (unsigned char)((coeff.coeff2_8k & 0x000000FF));
+	/* Get unsigned char1 */
+	temp1 = (unsigned char)((coeff.coeff2_8k & 0x0000FF00) >> 8);
+	/* Get unsigned char2 */
+	temp2 = (unsigned char)((coeff.coeff2_8k & 0x00FF0000) >> 16);
+	/* Get unsigned char3 */
+	temp3 = (unsigned char)((coeff.coeff2_8k & 0x01000000) >> 24);
+
+	/* Big endian to make 8051 happy */
+	buffer[cfoe_NS_8k_coeff2_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
+	buffer[cfoe_NS_8k_coeff2_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
+	buffer[cfoe_NS_8k_coeff2_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
+	buffer[cfoe_NS_8k_coeff2_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
+
+	/* Write coeff1_4096Nu */
+	/* Get unsigned char0 */
+	temp0 = (unsigned char)(coeff.coeff1_4096Nu & 0x000000FF);
+	/* Get unsigned char1 */
+	temp1 = (unsigned char)((coeff.coeff1_4096Nu & 0x0000FF00) >> 8);
+	/* Get unsigned char2 */
+	temp2 = (unsigned char)((coeff.coeff1_4096Nu & 0x00FF0000) >> 16);
+	/* Get unsigned char3[1:0] */
+	/* Bit[7:2] will be written soon and so don't have to care them */
+	temp3 = (unsigned char)((coeff.coeff1_4096Nu & 0x03000000) >> 24);
+
+	/* Big endian to make 8051 happy */
+	buffer[cfoe_NS_4096_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
+	buffer[cfoe_NS_4096_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
+	buffer[cfoe_NS_4096_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
+	buffer[cfoe_NS_4096_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
+
+	/* Write coeff2_4k */
+	/* Get unsigned char0 */
+	temp0 = (unsigned char)((coeff.coeff2_4k & 0x000000FF));
+	/* Get unsigned char1 */
+	temp1 = (unsigned char)((coeff.coeff2_4k & 0x0000FF00) >> 8);
+	/* Get unsigned char2 */
+	temp2 = (unsigned char)((coeff.coeff2_4k & 0x00FF0000) >> 16);
+	/* Get unsigned char3 */
+	temp3 = (unsigned char)((coeff.coeff2_4k & 0x01000000) >> 24);
+
+	/* Big endian to make 8051 happy */
+	buffer[cfoe_NS_4k_coeff2_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
+	buffer[cfoe_NS_4k_coeff2_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
+	buffer[cfoe_NS_4k_coeff2_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
+	buffer[cfoe_NS_4k_coeff2_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
+
+	/* Get unsigned char0 */
+	temp0 = (unsigned char)(coeff.bfsfcw_fftindex_ratio & 0x00FF);
+	/* Get unsigned char1 */
+	temp1 = (unsigned char)((coeff.bfsfcw_fftindex_ratio & 0xFF00) >> 8);
+
+	/* Big endian to make 8051 happy */
+	buffer[bfsfcw_fftindex_ratio_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
+	buffer[bfsfcw_fftindex_ratio_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
+
+	/* Get unsigned char0 */
+	temp0 = (unsigned char)(coeff.fftindex_bfsfcw_ratio & 0x00FF);
+	/* Get unsigned char1 */
+	temp1 = (unsigned char)((coeff.fftindex_bfsfcw_ratio & 0xFF00) >> 8);
+
+	/* Big endian to make 8051 happy */
+	buffer[fftindex_bfsfcw_ratio_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
+	buffer[fftindex_bfsfcw_ratio_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
+
+	error =
+	    it9135_write_regs(data, chip, PROCESSOR_OFDM,
+			      cfoe_NS_2048_coeff1_25_24, 36, buffer);
+	if (error)
+		goto exit;
+
+exit:
+	return error;
+}
+
+/*
+ * The type defination of band table.
+ */
+struct it9135_freq_band {
+	unsigned long mini;	/* The minimum frequency of this band */
+	unsigned long max;	/* The maximum frequency of this band */
+};
+
+static struct it9135_freq_band it9135_freq_band_tab[] = {
+	{30000, 300000},	/* VHF 30MHz ~ 300MHz */
+	{300000, 1000000},	/* UHF 300MHz ~ 1000MHz */
+	{1670000, 1680000}	/* L-BAND */
+};
+
+static int it915_freq_band_tab_count = ARRAY_SIZE(it9135_freq_band_tab);
+
+/*
+ * Set frequency.
+ *
+ * @param struct it9135_data the handle of IT9135.
+ * @param chip The index of IT9135. The possible values are 0~7.
+ * @param frequency The desired frequency.
+ * @return ERROR_NO_ERROR: successful, other non-zero error code otherwise.
+ */
+static unsigned long it9135_set_frequency(struct it9135_data *data,
+					  unsigned char chip,
+					  unsigned long frequency)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned long freq = frequency;
+	unsigned char band;
+	unsigned char i;
+
+	/* Clear easy mode flag first */
+	error =
+	    it9135_write_reg(data, chip, PROCESSOR_OFDM, Training_Mode, 0x00);
+	if (error)
+		goto exit;
+
+	/* Clear empty_channel_status lock flag */
+	error =
+	    it9135_write_reg(data, chip, PROCESSOR_OFDM, empty_channel_status,
+			     0x00);
+	if (error)
+		goto exit;
+
+	/* Clear MPEG2 lock flag */
+	error =
+	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
+				  r_mp2if_sync_byte_locked,
+				  mp2if_sync_byte_locked_pos,
+				  mp2if_sync_byte_locked_len, 0x00);
+	if (error)
+		goto exit;
+
+	/* Determine frequency band */
+	band = 0xFF;
+	for (i = 0; i < it915_freq_band_tab_count; i++) {
+		if ((frequency >= it9135_freq_band_tab[i].mini)
+		    && (frequency <= it9135_freq_band_tab[i].max)) {
+			band = i;
+			break;
+		}
+	}
+	error = it9135_write_reg(data, chip, PROCESSOR_OFDM, FreBand, band);
+	if (error)
+		goto exit;
+
+	if (data->chip_num > 1 && chip == 0)
+		freq += 100;
+	else if (data->chip_num > 1 && chip == 1)
+		freq -= 100;
+
+	error =
+	    it9135_tuner_set_freq(data, chip, data->bandwidth[chip], frequency);
+	if (error)
+		goto exit;
+
+	/* Trigger ofsm */
+	error = it9135_write_reg(data, chip, PROCESSOR_OFDM, trigger_ofsm, 0);
+	if (error)
+		goto exit;
+
+	data->frequency[chip] = frequency;
+
+exit:
+	return error;
+}
+
+/*
+ * Load firmware to device
+ *
+ * @param struct it9135_data the handle of IT9135.
+ * @fw_codes pointer to fw binary.
+ * @fw_segs pointer to fw segments.
+ * @fw_parts pointer to fw partition.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+static unsigned long it9135_load_firmware(struct it9135_data *data,
+					  unsigned char *fw_codes,
+					  struct it9135_segment *fw_segs,
+					  unsigned char *fw_parts)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned long beginPartition = 0;
+	unsigned long endPartition = 0;
+	unsigned long version;
+	unsigned long firmwareLength;
+	unsigned char *firmwareCodesPointer;
+	unsigned short command;
+	unsigned long i;
+
+/* Define I2C master speed, the default value 0x07 means 366KHz (1000000000 / (24.4 * 16 * User_I2C_SPEED)). */
+#define User_I2C_SPEED              0x07
+
+	/* Set I2C master clock speed. */
+	error =
+	    it9135_write_reg(data, 0, PROCESSOR_LINK,
+			     p_reg_one_cycle_counter_tuner, User_I2C_SPEED);
+	if (error)
+		goto exit;
+
+	firmwareCodesPointer = fw_codes;
+
+	beginPartition = 0;
+	endPartition = fw_parts[0];
+
+	for (i = beginPartition; i < endPartition; i++) {
+		firmwareLength = fw_segs[i].length;
+		if (fw_segs[i].type == 0) {
+			/* Dwonload firmware */
+			error =
+			    it9135_cmd_sendcommand(data, CMD_FW_DOWNLOAD_BEGIN,
+						   0, PROCESSOR_LINK, 0, NULL,
+						   0, NULL);
+			if (error)
+				goto exit;
+			error =
+			    it9135_cmd_loadfirmware(data, firmwareLength,
+						    firmwareCodesPointer);
+			if (error)
+				goto exit;
+			error =
+			    it9135_cmd_sendcommand(data, CMD_FW_DOWNLOAD_END, 0,
+						   PROCESSOR_LINK, 0, NULL, 0,
+						   NULL);
+			if (error)
+				goto exit;
+		} else if (fw_segs[i].type == 1) {
+			/* Copy firmware */
+			error =
+			    it9135_cmd_sendcommand(data,
+						   CMD_SCATTER_WRITE, 0,
+						   PROCESSOR_LINK,
+						   firmwareLength,
+						   firmwareCodesPointer, 0,
+						   NULL);
+			if (error)
+				goto exit;
+		} else {
+			/* Direct write firmware */
+			command =
+			    (unsigned short)(firmwareCodesPointer[0] << 8) +
+			    (unsigned short)firmwareCodesPointer[1];
+			error =
+			    it9135_cmd_sendcommand(data, command, 0,
+						   PROCESSOR_LINK,
+						   firmwareLength - 2,
+						   firmwareCodesPointer + 2, 0,
+						   NULL);
+			if (error)
+				goto exit;
+		}
+		firmwareCodesPointer += firmwareLength;
+	}
+
+	/* Boot */
+	error =
+	    it9135_cmd_sendcommand(data, CMD_BOOT, 0, PROCESSOR_LINK, 0, NULL,
+				   0, NULL);
+	if (error)
+		goto exit;
+
+	mdelay(10);
+
+	/* Check if firmware is running */
+	version = 0;
+	error = it9135_get_fw_ver(data, PROCESSOR_LINK, &version);
+	if (error)
+		goto exit;
+	if (version == 0)
+		error = ERROR_BOOT_FAIL;
+
+exit:
+	return error;
+}
+
+/*
+ * Load initial script to device
+ *
+ * @param struct it9135_data the handle of IT9135.
+ * @script_sets pointer to script_sets.
+ * @scripts pointer to fw scripts.
+ * @tuner_script_sets pointer to tunerScriptSets.
+ * @tuner_scripts pointer to tunerScripts.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+static unsigned long it9135_load_script(struct it9135_data *data,
+					unsigned short *script_sets,
+					struct it9135_val_set *scripts,
+					unsigned short *tuner_script_sets,
+					struct it9135_val_set *tuner_scripts)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned short beginScript;
+	unsigned short endScript;
+	unsigned char i, value1 = 0, prechip_version = 0, supportRelay =
+	    0, chip_num = 0, bufferLens = 1;
+	unsigned short j;
+	unsigned char buffer[20] = { 0 };
+	unsigned long tunerAddr, tunerAddrTemp;
+
+	/* Querry SupportRelayCommandWrite */
+	error = it9135_read_reg(data, 0, PROCESSOR_OFDM, 0x004D, &supportRelay);
+	if (error)
+		goto exit;
+
+	if (supportRelay && data->chip_num == 2)
+		chip_num = 1;
+	else
+		chip_num = data->chip_num;
+
+	/* Enable RelayCommandWrite */
+	if (supportRelay) {
+		error = it9135_write_reg(data, 0, PROCESSOR_OFDM, 0x004E, 1);
+		if (error)
+			goto exit;
+	}
+
+	if ((script_sets[0] != 0) && (scripts != NULL)) {
+		beginScript = 0;
+		endScript = script_sets[0];
+
+		for (i = 0; i < chip_num; i++) {
+			/* Load OFSM init script */
+			for (j = beginScript; j < endScript; j++) {
+				tunerAddr = tunerAddrTemp = scripts[j].address;
+				buffer[0] = scripts[j].value;
+
+				while (j < endScript && bufferLens < 20) {
+					tunerAddrTemp += 1;
+					if (tunerAddrTemp !=
+					    scripts[j + 1].address)
+						break;
+
+					buffer[bufferLens] =
+					    scripts[j + 1].value;
+					bufferLens++;
+					j++;
+				}
+
+				error =
+				    it9135_write_regs(data, i, PROCESSOR_OFDM,
+						      tunerAddr, bufferLens,
+						      buffer);
+				if (error)
+					goto exit;
+				bufferLens = 1;
+			}
+		}
+	}
+
+	/* Distinguish chip type */
+	error =
+	    it9135_read_reg(data, 0, PROCESSOR_LINK, chip_version_7_0, &value1);
+	if (error)
+		goto exit;
+
+	error =
+	    it9135_read_reg(data, 0, PROCESSOR_LINK, prechip_version_7_0,
+			    &prechip_version);
+	if (error)
+		goto exit;
+
+	if ((tuner_script_sets[0] != 0) && (tuner_scripts != NULL)) {
+		if (tuner_script_sets[1] == tuner_script_sets[0]
+		    && !(data->chip_ver == 0xF8 && prechip_version == 0xEA)) {
+			/* New version */
+			beginScript = tuner_script_sets[0];
+			endScript = tuner_script_sets[0] + tuner_script_sets[1];
+		} else {
+			/* Old version */
+			beginScript = 0;
+			endScript = tuner_script_sets[0];
+		}
+
+		for (i = 0; i < chip_num; i++) {
+			/* Load tuner init script */
+			for (j = beginScript; j < endScript; j++) {
+				tunerAddr = tunerAddrTemp =
+				    tuner_scripts[j].address;
+				buffer[0] = tuner_scripts[j].value;
+
+				while (j < endScript && bufferLens < 20) {
+					tunerAddrTemp += 1;
+					if (tunerAddrTemp !=
+					    tuner_scripts[j + 1].address)
+						break;
+
+					buffer[bufferLens] =
+					    tuner_scripts[j + 1].value;
+					bufferLens++;
+					j++;
+				}
+
+				error =
+				    it9135_write_regs(data, i, PROCESSOR_OFDM,
+						      tunerAddr, bufferLens,
+						      buffer);
+				if (error)
+					goto exit;
+				bufferLens = 1;
+			}
+		}
+	}
+
+	/* Disable RelayCommandWrite */
+	if (supportRelay) {
+		error = it9135_write_reg(data, 0, PROCESSOR_OFDM, 0x004E, 0);
+		if (error)
+			goto exit;
+	}
+
+exit:
+	return error;
+}
+
+/* end of local functions */
+
+unsigned long it9135_write_regs(struct it9135_data *data, unsigned char chip,
+				unsigned char processor, unsigned long reg_addr,
+				unsigned long w_buff_len, unsigned char *w_buff)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned short command;
+	unsigned char buffer[255];
+	unsigned long buff_len;
+	unsigned long remain_len;
+	unsigned long send_len;
+	unsigned long i;
+	unsigned char reg_addr_len = 2;
+
+	it9135_enter_mutex(data);
+
+	if (w_buff_len == 0)
+		goto exit;
+	if (reg_addr_len > 4) {
+		error = ERROR_PROTOCOL_FORMAT_INVALID;
+		goto exit;
+	}
+
+	if ((w_buff_len + 12) > IT9135_MAX_CMD_SIZE) {
+		error = ERROR_INVALID_DATA_LENGTH;
+		goto exit;
+	}
+
+	/* add frame header */
+	command = it9135_build_command(CMD_REG_DEMOD_WRITE, processor, chip);
+	buffer[1] = (unsigned char)(command >> 8);
+	buffer[2] = (unsigned char)command;
+	buffer[3] = (unsigned char)data->cmd_seq++;
+	buffer[4] = (unsigned char)w_buff_len;
+	buffer[5] = (unsigned char)reg_addr_len;
+	buffer[6] = (unsigned char)((reg_addr) >> 24);	/* Get first unsigned char of reg. address  */
+	buffer[7] = (unsigned char)((reg_addr) >> 16);	/* Get second unsigned char of reg. address */
+	buffer[8] = (unsigned char)((reg_addr) >> 8);	/* Get third unsigned char of reg. address  */
+	buffer[9] = (unsigned char)(reg_addr);	/* Get fourth unsigned char of reg. address */
+
+	/* add frame data */
+	for (i = 0; i < w_buff_len; i++)
+		buffer[10 + i] = w_buff[i];
+
+	/* add frame check-sum */
+	buff_len = 10 + w_buff_len;
+	error = it9135_cmd_add_checksum(data, &buff_len, buffer);
+	if (error)
+		goto exit;
+
+	/* send frame */
+	i = 0;
+	send_len = 0;
+	remain_len = buff_len;
+	while (remain_len > 0) {
+		i = (remain_len > IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
+		    : (remain_len);
+		error = it9135_cmd_bus_tx(data, i, &buffer[send_len]);
+		if (error)
+			goto exit;
+
+		send_len += i;
+		remain_len -= i;
+	}
+
+	/* get reply frame */
+	buff_len = 5;
+	error = it9135_cmd_bus_rx(data, buff_len, buffer);
+	if (error)
+		goto exit;
+
+	/* remove check-sum from reply frame */
+	error = it9135_cmd_remove_checksum(data, &buff_len, buffer);
+	if (error)
+		goto exit;
+
+exit:
+	it9135_leave_mutex(data);
+	return error;
+}
+
+unsigned long it9135_write_gen_regs(struct it9135_data *data,
+				    unsigned char chip,
+				    unsigned char interfaceIndex,
+				    unsigned char slaveAddress,
+				    unsigned char buff_len,
+				    unsigned char *buffer)
+{
+	unsigned char w_buff[256];
+	unsigned char i;
+
+	w_buff[0] = buff_len;
+	w_buff[1] = interfaceIndex;
+	w_buff[2] = slaveAddress;
+
+	for (i = 0; i < buff_len; i++)
+		w_buff[3 + i] = buffer[i];
+
+	return it9135_cmd_sendcommand(data, CMD_GENERIC_WRITE, chip,
+				      PROCESSOR_LINK, buff_len + 3, w_buff, 0,
+				      NULL);
+}
+
+unsigned long it9135_write_reg(struct it9135_data *data, unsigned char chip,
+			       unsigned char processor, unsigned long reg_addr,
+			       unsigned char value)
+{
+	return it9135_write_regs(data, chip, processor, reg_addr, 1, &value);
+}
+
+unsigned long it9135_write_ee_vals(struct it9135_data *data, unsigned char chip,
+				   unsigned short reg_addr,
+				   unsigned char w_buff_len,
+				   unsigned char *w_buff)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned short command;
+	unsigned char buffer[255];
+	unsigned long buff_len;
+	unsigned long remain_len;
+	unsigned long send_len;
+	unsigned long i;
+	unsigned char eeprom_addr = 1;
+	unsigned char reg_addr_len = 1;
+
+	it9135_enter_mutex(data);
+
+	if (w_buff_len == 0)
+		goto exit;
+
+	if ((unsigned long)(w_buff_len + 11) > IT9135_MAX_CMD_SIZE) {
+		error = ERROR_INVALID_DATA_LENGTH;
+		goto exit;
+	}
+
+	/* add frame header */
+	command =
+	    it9135_build_command(CMD_REG_EEPROM_WRITE, PROCESSOR_LINK, chip);
+	buffer[1] = (unsigned char)(command >> 8);
+	buffer[2] = (unsigned char)command;
+	buffer[3] = (unsigned char)data->cmd_seq++;
+	buffer[4] = (unsigned char)w_buff_len;
+	buffer[5] = (unsigned char)eeprom_addr;
+	buffer[6] = (unsigned char)reg_addr_len;
+	buffer[7] = (unsigned char)(reg_addr >> 8);	/* Get high unsigned char of reg. address */
+	buffer[8] = (unsigned char)reg_addr;	/* Get low unsigned char of reg. address  */
+
+	/* add frame data */
+	for (i = 0; i < w_buff_len; i++)
+		buffer[9 + i] = w_buff[i];
+
+	/* add frame check-sum */
+	buff_len = 9 + w_buff_len;
+	error = it9135_cmd_add_checksum(data, &buff_len, buffer);
+	if (error)
+		goto exit;
+
+	/* send frame */
+	i = 0;
+	send_len = 0;
+	remain_len = buff_len;
+	while (remain_len > 0) {
+		i = (remain_len > IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
+		    : (remain_len);
+		error = it9135_cmd_bus_tx(data, i, &buffer[send_len]);
+		if (error)
+			goto exit;
+
+		send_len += i;
+		remain_len -= i;
+	}
+
+	/* get reply frame */
+	buff_len = 5;
+	error = it9135_cmd_bus_rx(data, buff_len, buffer);
+	if (error)
+		goto exit;
+
+	/* remove check-sum from reply frame */
+	error = it9135_cmd_remove_checksum(data, &buff_len, buffer);
+	if (error)
+		goto exit;
+
+exit:
+	it9135_leave_mutex(data);
+	return error;
+}
+
+static unsigned char it9135_reg_bit_mask[8] = {
+	0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF
+};
+
+unsigned long it9135_write_reg_bits(struct it9135_data *data,
+				    unsigned char chip, unsigned char processor,
+				    unsigned long reg_addr,
+				    unsigned char position,
+				    unsigned char length, unsigned char value)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char temp;
+
+	if (length == 8) {
+		error =
+		    it9135_write_regs(data, chip, processor, reg_addr, 1,
+				      &value);
+	} else {
+		error =
+		    it9135_read_regs(data, chip, processor, reg_addr, 1, &temp);
+		if (error)
+			goto exit;
+
+		temp =
+		    REG_CREATE(it9135_reg_bit_mask, value, temp, position,
+			       length);
+
+		error =
+		    it9135_write_regs(data, chip, processor, reg_addr, 1,
+				      &temp);
+	}
+
+exit:
+	return error;
+}
+
+unsigned long it9135_read_reg(struct it9135_data *data, unsigned char chip,
+			      unsigned char processor, unsigned long reg_addr,
+			      unsigned char *value)
+{
+	return it9135_read_regs(data, chip, processor, reg_addr, 1, value);
+}
+
+unsigned long it9135_read_regs(struct it9135_data *data, unsigned char chip,
+			       unsigned char processor, unsigned long reg_addr,
+			       unsigned long r_buff_len, unsigned char *r_buff)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned short command;
+	unsigned char buffer[255];
+	unsigned long buff_len;
+	unsigned long send_len;
+	unsigned long remain_len;
+	unsigned long i, k;
+	unsigned char reg_addr_len = 2;
+
+	it9135_enter_mutex(data);
+
+	if (r_buff_len == 0)
+		goto exit;
+	if (reg_addr_len > 4) {
+		error = ERROR_PROTOCOL_FORMAT_INVALID;
+		goto exit;
+	}
+
+	if ((r_buff_len + 5) > IT9135_MAX_PKT_SIZE) {
+		error = ERROR_INVALID_DATA_LENGTH;
+		goto exit;
+	}
+
+	if ((r_buff_len + 5) > IT9135_MAX_CMD_SIZE) {
+		error = ERROR_INVALID_DATA_LENGTH;
+		goto exit;
+	}
+
+	/* add frame header */
+	command = it9135_build_command(CMD_REG_DEMOD_READ, processor, chip);
+	buffer[1] = (unsigned char)(command >> 8);
+	buffer[2] = (unsigned char)command;
+	buffer[3] = (unsigned char)data->cmd_seq++;
+	buffer[4] = (unsigned char)r_buff_len;
+	buffer[5] = (unsigned char)reg_addr_len;
+	buffer[6] = (unsigned char)(reg_addr >> 24);	/* Get first unsigned char of reg. address  */
+	buffer[7] = (unsigned char)(reg_addr >> 16);	/* Get second unsigned char of reg. address */
+	buffer[8] = (unsigned char)(reg_addr >> 8);	/* Get third unsigned char of reg. address  */
+	buffer[9] = (unsigned char)(reg_addr);	/* Get fourth unsigned char of reg. address */
+
+	/* add frame check-sum */
+	buff_len = 10;
+	error = it9135_cmd_add_checksum(data, &buff_len, buffer);
+	if (error)
+		goto exit;
+
+	/* send frame */
+	i = 0;
+	send_len = 0;
+	remain_len = buff_len;
+	while (remain_len > 0) {
+		i = (remain_len > IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
+		    : (remain_len);
+		error = it9135_cmd_bus_tx(data, i, &buffer[send_len]);
+		if (error)
+			goto exit;
+
+		send_len += i;
+		remain_len -= i;
+	}
+
+	/* get reply frame */
+	buff_len = 5 + r_buff_len;
+	error = it9135_cmd_bus_rx(data, buff_len, buffer);
+	if (error)
+		goto exit;
+
+	/* remove check-sum from reply frame */
+	error = it9135_cmd_remove_checksum(data, &buff_len, buffer);
+	if (error)
+		goto exit;
+
+	for (k = 0; k < r_buff_len; k++)
+		r_buff[k] = buffer[k + 3];
+
+exit:
+	it9135_leave_mutex(data);
+	return error;
+}
+
+unsigned long it9135_read_gen_regs(struct it9135_data *data, unsigned char chip,
+				   unsigned char interfaceIndex,
+				   unsigned char slaveAddress,
+				   unsigned char buff_len,
+				   unsigned char *buffer)
+{
+	unsigned char w_buff[3];
+
+	w_buff[0] = buff_len;
+	w_buff[1] = interfaceIndex;
+	w_buff[2] = slaveAddress;
+
+	return it9135_cmd_sendcommand(data, CMD_GENERIC_READ, chip,
+				      PROCESSOR_LINK, 3, w_buff, buff_len,
+				      buffer);
+}
+
+unsigned long it9135_read_ee_vals(struct it9135_data *data, unsigned char chip,
+				  unsigned short reg_addr,
+				  unsigned char r_buff_len,
+				  unsigned char *r_buff)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned short command;
+	unsigned char buffer[255];
+	unsigned long buff_len;
+	unsigned long remain_len;
+	unsigned long send_len;
+	unsigned long i, k;
+	unsigned char eeprom_addr = 1;
+	unsigned char reg_addr_len = 1;
+
+	it9135_enter_mutex(data);
+
+	if (r_buff_len == 0)
+		goto exit;
+
+	if ((unsigned long)(r_buff_len + 5) > IT9135_MAX_PKT_SIZE) {
+		error = ERROR_INVALID_DATA_LENGTH;
+		goto exit;
+	}
+
+	if ((unsigned long)(r_buff_len + 5) > IT9135_MAX_CMD_SIZE) {
+		error = ERROR_INVALID_DATA_LENGTH;
+		goto exit;
+	}
+
+	/* add command header */
+	command =
+	    it9135_build_command(CMD_REG_EEPROM_READ, PROCESSOR_LINK, chip);
+	buffer[1] = (unsigned char)(command >> 8);
+	buffer[2] = (unsigned char)command;
+	buffer[3] = (unsigned char)data->cmd_seq++;
+	buffer[4] = (unsigned char)r_buff_len;
+	buffer[5] = (unsigned char)eeprom_addr;
+	buffer[6] = (unsigned char)reg_addr_len;
+	buffer[7] = (unsigned char)(reg_addr >> 8);	/* Get high unsigned char of reg. address */
+	buffer[8] = (unsigned char)reg_addr;	/* Get low unsigned char of reg. address  */
+
+	/* add frame check-sum */
+	buff_len = 9;
+	error = it9135_cmd_add_checksum(data, &buff_len, buffer);
+	if (error)
+		goto exit;
+
+	/* send frame */
+	i = 0;
+	send_len = 0;
+	remain_len = buff_len;
+	while (remain_len > 0) {
+		i = (remain_len > IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
+		    : (remain_len);
+		error = it9135_cmd_bus_tx(data, i, &buffer[send_len]);
+		if (error)
+			goto exit;
+
+		send_len += i;
+		remain_len -= i;
+	}
+
+	/* get reply frame */
+	buff_len = 5 + r_buff_len;
+	error = it9135_cmd_bus_rx(data, buff_len, buffer);
+	if (error)
+		goto exit;
+
+	/* remove frame check-sum */
+	error = it9135_cmd_remove_checksum(data, &buff_len, buffer);
+	if (error)
+		goto exit;
+
+	for (k = 0; k < r_buff_len; k++)
+		r_buff[k] = buffer[k + 3];
+
+exit:
+	it9135_leave_mutex(data);
+	return error;
+}
+
+unsigned long it9135_read_reg_bits(struct it9135_data *data,
+				   unsigned char chip, unsigned char processor,
+				   unsigned long reg_addr,
+				   unsigned char position, unsigned char length,
+				   unsigned char *value)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char temp = 0;
+
+	error = it9135_read_regs(data, chip, processor, reg_addr, 1, &temp);
+	if (error)
+		goto exit;
+
+	if (length == 8) {
+		*value = temp;
+	} else {
+		temp = REG_GET(it9135_reg_bit_mask, temp, position, length);
+		*value = temp;
+	}
+
+exit:
+	return error;
+}
+
+unsigned long it9135_get_fw_ver(struct it9135_data *data,
+				unsigned char processor, unsigned long *version)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char w_buff[1] = { 1 };
+	unsigned char r_buff[4] = { 0, 0, 0, 0 };
+
+	error =
+	    it9135_cmd_sendcommand(data, CMD_QUERYINFO, 0, processor, 1, w_buff,
+				   4, r_buff);
+	if (error)
+		goto exit;
+
+	*version =
+	    (unsigned long)(((unsigned long)r_buff[0] << 24) +
+			    ((unsigned long)r_buff[1] << 16) +
+			    ((unsigned long)r_buff[2] << 8) +
+			    (unsigned long)r_buff[3]);
+
+exit:
+	return error;
+}
+
+/*
+ * Set the counting range for Post-Viterbi and Post-Viterbi.
+ *
+ * @param struct it9135_data the handle of IT9135.
+ * @param chip The index of IT9135. The possible values are 0~7.
+ *        NOTE: When the architecture is set to ARCHITECTURE_DCA
+ *        this parameter is regard as don't care.
+ * @param post_err_cnt the number of super frame for Pre-Viterbi (24 bits).
+ * @param post_bit_cnt the number of packet unit for Post-Viterbi (16 bits).
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_get_post_vitber(struct it9135_data *data,
+				     unsigned char chip,
+				     unsigned long *post_err_cnt,
+				     unsigned long *post_bit_cnt,
+				     unsigned short *abort_cnt)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned long err_cnt;
+	unsigned long bit_cnt;
+	unsigned char buffer[7];
+	unsigned short abort;
+
+	*post_err_cnt = 0;
+	*post_bit_cnt = 0;
+
+	error =
+	    it9135_read_regs(data, chip, PROCESSOR_OFDM,
+			     rsd_abort_packet_cnt_7_0,
+			     r_rsd_packet_unit_15_8 - rsd_abort_packet_cnt_7_0 +
+			     1, buffer);
+	if (error)
+		goto exit;
+
+	abort = ((unsigned short)
+		 buffer[rsd_abort_packet_cnt_15_8 - rsd_abort_packet_cnt_7_0]
+		 << 8) + buffer[rsd_abort_packet_cnt_7_0 -
+				rsd_abort_packet_cnt_7_0];
+	err_cnt = ((unsigned long)
+		   buffer[rsd_bit_err_cnt_23_16 -
+			  rsd_abort_packet_cnt_7_0] << 16) + ((unsigned long)
+							      buffer
+							      [rsd_bit_err_cnt_15_8
+							       -
+							       rsd_abort_packet_cnt_7_0]
+							      << 8) +
+	    buffer[rsd_bit_err_cnt_7_0 - rsd_abort_packet_cnt_7_0];
+	bit_cnt = ((unsigned long)
+		   buffer[r_rsd_packet_unit_15_8 -
+			  rsd_abort_packet_cnt_7_0] << 8) +
+	    buffer[r_rsd_packet_unit_7_0 - rsd_abort_packet_cnt_7_0];
+
+	if (bit_cnt == 0) {
+		/*error = ERROR_RSD_PKT_CNT_0; */
+		*post_err_cnt = 1;
+		*post_bit_cnt = 2;
+		*abort_cnt = 1000;
+		goto exit;
+	}
+
+	*abort_cnt = abort;
+	bit_cnt = bit_cnt - (unsigned long)abort;
+	if (bit_cnt == 0) {
+		*post_err_cnt = 1;
+		*post_bit_cnt = 2;
+	} else {
+		*post_err_cnt = err_cnt - (unsigned long)abort * 8 * 8;
+		*post_bit_cnt = bit_cnt * 204 * 8;
+	}
+
+exit:
+	return error;
+}
+
+/* NorDig 3.4.4.6 & Table 3.4 */
+static int it9135_Pref_values[3][5] = {
+	{-93, -91, -90, -89, -88},	/* QPSK    CodeRate 1/2 ~ 7/8 Pref Values */
+	{-87, -85, -84, -83, -82},	/* 16QAM   CodeRate 1/2 ~ 7/8 Pref Values */
+	{-82, -80, -78, -77, -76},	/* 64QAM   CodeRate 1/2 ~ 7/8 Pref Values */
+};
+
+/*
+ * Get siganl quality.
+ *
+ * @param struct it9135_data the handle of IT9135.
+ * @param chip The index of IT9135. The possible values are 0~7.
+ *        NOTE: When the architecture is set to ARCHITECTURE_DCA
+ *        this parameter is regard as don't care.
+ * @param quality The value of signal quality.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_get_signal_quality(struct it9135_data *data,
+					unsigned char chip,
+					unsigned char *quality)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	error = it9135_read_reg(data, chip, PROCESSOR_OFDM, signal_quality, quality);
+	
+	return (error);
+}
+
+unsigned long it9135_get_strength(struct it9135_data *data, unsigned char chip,
+				  unsigned char *strength)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char temp, lna_gain_offset;
+	struct it9135_ch_modulation ch_modulation;
+	int Prec, Pref, Prel;
+
+	error =
+	    it9135_read_reg(data, chip, PROCESSOR_OFDM, var_p_inband, &temp);
+	if (error)
+		goto exit;
+
+	error = it9135_get_ch_modulation(data, chip, &ch_modulation);
+	if (error)
+		goto exit;
+
+	if (ch_modulation.frequency < 300000)
+		lna_gain_offset = 7;	/* VHF */
+	else
+		lna_gain_offset = 14;	/* UHF */
+
+	Prec = (temp - 100) - lna_gain_offset;
+
+	if (ch_modulation.priority == PRIORITY_HIGH)
+		Pref = it9135_Pref_values[ch_modulation.constellation]
+		    [ch_modulation.h_code_rate];
+	else
+		Pref = it9135_Pref_values[ch_modulation.constellation]
+		    [ch_modulation.l_code_rate];
+
+	Prel = Prec - Pref;
+
+	if (Prel < -15)
+		*strength = 0;
+	else if ((-15 <= Prel) && (Prel < 0))
+		*strength = (unsigned char)((2 * (Prel + 15)) / 3);
+	else if ((0 <= Prel) && (Prel < 20))
+		*strength = (unsigned char)(4 * Prel + 10);
+	else if ((20 <= Prel) && (Prel < 35))
+		*strength = ((unsigned char)(2 * (Prel - 20)) / 3 + 90);
+	else if (Prel >= 35)
+		*strength = 100;
+
+exit:
+	return error;
+}
+
+/* @param strength_dbm: DBm */
+unsigned long it9135_get_strength_dbm(struct it9135_data *data,
+				      unsigned char chip, long *strength_dbm)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char temp;
+
+	error =
+	    it9135_read_reg(data, chip, PROCESSOR_OFDM, var_p_inband, &temp);
+	if (error)
+		goto exit;
+
+	*strength_dbm = (long)(temp - 100);
+
+exit:
+	return error;
+}
+
+unsigned long it9135_load_ir_tab(struct it9135_data *data,
+				 unsigned short tab_len, unsigned char *table)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char base_high;
+	unsigned char base_low;
+	unsigned short reg_base;
+	unsigned short i;
+
+	error =
+	    it9135_read_reg(data, 0, PROCESSOR_LINK, ir_table_start_15_8,
+			    &base_high);
+	if (error)
+		goto exit;
+	error =
+	    it9135_read_reg(data, 0, PROCESSOR_LINK, ir_table_start_7_0,
+			    &base_low);
+	if (error)
+		goto exit;
+
+	reg_base = (unsigned short)(base_high << 8) + (unsigned short)base_low;
+
+	if (reg_base) {
+		for (i = 0; i < tab_len; i++) {
+			error =
+			    it9135_write_reg(data, 0, PROCESSOR_LINK,
+					     reg_base + i, table[i]);
+			if (error)
+				goto exit;
+		}
+	}
+
+exit:
+	return error;
+}
+
+static struct it9135_freq_clk it9135_freq_clk_tab[2] = {
+	{12000, 20250000},
+	{20480, 20480000}
+};
+
+unsigned long it9135_dev_init(struct it9135_data *data, unsigned char chip_num,
+			      unsigned short saw_band, unsigned char streamType,
+			      unsigned char architecture)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned long crystal = 0;
+	unsigned long adc = 0;
+	unsigned long fcw = 0;
+	unsigned char buffer[4];
+	unsigned long version = 0;
+	unsigned short *tuner_script_sets = NULL;
+	struct it9135_val_set *tuner_scripts = NULL;
+	unsigned char i;
+	unsigned char var[2];
+
+#define IT9135_IF_FREQUENCY				0
+#define IT9135_IF_INVERSION				0
+/* Define I2C address of secondary chip when Diversity mode or PIP mode is active. */
+#define IT9135_CHIP2_I2C_ADDR      0x3A
+
+	data->chip_num = chip_num;
+	data->fcw = 0x00000000;
+	data->frequency[0] = 642000;
+	data->frequency[1] = 642000;
+	data->inited = 0;
+	data->host_if[0] = 0;
+	data->cmd_seq = 0;
+	data->pid_info.pid_init = 0;
+
+	error =
+	    it9135_read_reg(data, 0, PROCESSOR_LINK, chip_version_7_0,
+			    &data->chip_ver);
+	if (error)
+		goto exit;
+	error =
+	    it9135_read_regs(data, 0, PROCESSOR_LINK, chip_version_7_0 + 1, 2,
+			     var);
+	if (error)
+		goto exit;
+	data->chip_type = var[1] << 8 | var[0];
+
+	if (data->busId == 0xFFFF || data->tuner_desc.id == 0xFFFF)
+		goto exit;
+
+	error = it9135_get_fw_ver(data, PROCESSOR_LINK, &version);
+	if (error)
+		goto exit;
+	if (version != 0)
+		data->booted = 1;
+	else
+		data->booted = 0;
+
+	/*if (data->chip_type == 0x9135 && data->chip_ver == 2) {
+	   data->fw_codes = FirmwareV2_codes;
+	   data->fw_segs = FirmwareV2_segments;
+	   data->fw_parts = FirmwareV2_partitions;
+	   data->script_sets = FirmwareV2_scriptSets;
+	   data->scripts = FirmwareV2_scripts;
+	   } else {
+	   data->fw_codes = Firmware_codes;
+	   data->fw_segs = Firmware_segments;
+	   data->fw_parts = Firmware_partitions;
+	   data->script_sets = Firmware_scriptSets;
+	   data->scripts = Firmware_scripts;
+	   } */
+	tuner_script_sets = data->tuner_desc.script_sets;
+	tuner_scripts = data->tuner_desc.scripts;
+
+	error =
+	    it9135_read_reg_bits(data, 0, PROCESSOR_LINK,
+				 r_io_mux_pwron_clk_strap,
+				 io_mux_pwron_clk_strap_pos,
+				 io_mux_pwron_clk_strap_len, &i);
+	if (error)
+		goto exit;
+
+	data->crystal_Freq = it9135_freq_clk_tab[0].crystal_Freq;
+	data->adc_freq = it9135_freq_clk_tab[0].adc_freq;
+
+	/* Write secondary I2C address to device */
+	/* Enable or disable clock for 2nd chip power saving */
+	if (data->chip_num > 1) {
+		error =
+		    it9135_write_reg(data, 0, PROCESSOR_LINK,
+				     second_i2c_address, IT9135_CHIP2_I2C_ADDR);
+		if (error)
+			goto exit;
+
+		error =
+		    it9135_write_reg(data, 0, PROCESSOR_LINK, p_reg_top_clkoen,
+				     1);
+		if (error)
+			goto exit;
+
+	} else {
+		error =
+		    it9135_write_reg(data, 0, PROCESSOR_LINK,
+				     second_i2c_address, 0x00);
+		if (error)
+			goto exit;
+
+		error =
+		    it9135_write_reg(data, 0, PROCESSOR_LINK, p_reg_top_clkoen,
+				     0);
+		if (error)
+			goto exit;
+	}
+
+	/* Load firmware */
+	if (data->fw_codes != NULL) {
+		if (!data->booted) {
+			error =
+			    it9135_load_firmware(data,
+						 data->fw_codes, data->fw_segs,
+						 &data->fw_parts);
+			if (error)
+				goto exit;
+			data->booted = 1;
+		}
+	}
+
+	/* Set I2C master clock 100k in order to support tuner I2C. */
+	error =
+	    it9135_write_reg(data, 0, PROCESSOR_LINK,
+			     p_reg_one_cycle_counter_tuner, 0x1a);
+	if (error)
+		goto exit;
+
+	for (i = 0; i < data->chip_num; i++) {
+		error = it9135_write_reg(data, i, PROCESSOR_OFDM, 0xEC4C, 0x68);
+		if (error)
+			goto exit;
+		mdelay(10);
+	}
+
+	if (data->chip_type == 0x9135 && data->chip_ver == 1) {
+		/* Open tuner */
+		for (i = 0; i < data->chip_num; i++) {
+
+			/* Set 0xD827 to 0 as open drain for tuner i2c */
+			error =
+			    it9135_write_reg(data, i, PROCESSOR_LINK,
+					     p_reg_top_padodpu, 0);
+			if (error)
+				goto exit;
+
+			/* Set 0xD829 to 0 as push pull for tuner AGC */
+			error =
+			    it9135_write_reg(data, i, PROCESSOR_LINK,
+					     p_reg_top_agc_od, 0);
+			if (error)
+				goto exit;
+		}
+
+		for (i = 0; i < data->chip_num; i++) {
+			error = it9135_tuner_init(data, i);
+			if (error)
+				goto exit;
+		}
+	}
+
+	for (i = 0; i < data->chip_num; i++) {
+		/* Tell firmware the type of tuner. */
+		error =
+		    it9135_write_reg(data, i, PROCESSOR_LINK,
+				     p_reg_link_ofsm_dummy_15_8,
+				     (unsigned char)data->tuner_desc.id);
+		if (error)
+			goto exit;
+	}
+
+	/* Initialize OFDM */
+	if (data->booted) {
+		for (i = 0; i < data->chip_num; i++) {
+			/* Set read-update bit to 1 for constellation */
+			error =
+			    it9135_write_reg_bits(data, i,
+						  PROCESSOR_OFDM,
+						  p_reg_feq_read_update,
+						  reg_feq_read_update_pos,
+						  reg_feq_read_update_len, 1);
+			if (error)
+				goto exit;
+
+			/* Enable FEC Monitor */
+			error =
+			    it9135_write_reg_bits(data, i,
+						  PROCESSOR_OFDM,
+						  p_fec_vtb_rsd_mon_en,
+						  fec_vtb_rsd_mon_en_pos,
+						  fec_vtb_rsd_mon_en_len, 1);
+			if (error)
+				goto exit;
+		}
+
+		/* Compute ADC and load them to device */
+		error =
+		    it9135_compute_crystal(data,
+					   (long)data->crystal_Freq * 1000,
+					   &crystal);
+		if (error)
+			goto exit;
+
+		buffer[0] = (unsigned char)(crystal & 0x000000FF);
+		buffer[1] = (unsigned char)((crystal & 0x0000FF00) >> 8);
+		buffer[2] = (unsigned char)((crystal & 0x00FF0000) >> 16);
+		buffer[3] = (unsigned char)((crystal & 0xFF000000) >> 24);
+		for (i = 0; i < data->chip_num; i++) {
+			error =
+			    it9135_write_regs(data, i, PROCESSOR_OFDM,
+					      crystal_clk_7_0, 4, buffer);
+			if (error)
+				goto exit;
+		}
+
+		/* Compute ADC and load them to device */
+		error = it9135_compute_adc(data, (long)data->adc_freq, &adc);
+		if (error)
+			goto exit;
+
+		buffer[0] = (unsigned char)(adc & 0x000000FF);
+		buffer[1] = (unsigned char)((adc & 0x0000FF00) >> 8);
+		buffer[2] = (unsigned char)((adc & 0x00FF0000) >> 16);
+		for (i = 0; i < data->chip_num; i++) {
+			error =
+			    it9135_write_regs(data, i, PROCESSOR_OFDM,
+					      p_reg_f_adc_7_0, 3, buffer);
+			if (error)
+				goto exit;
+		}
+
+		/* Compute FCW and load them to device */
+		error =
+		    it9135_compute_fcw(data,
+				       (long)data->adc_freq,
+				       (long)IT9135_IF_FREQUENCY,
+				       IT9135_IF_INVERSION, &fcw);
+		if (error)
+			goto exit;
+		data->fcw = fcw;
+
+		buffer[0] = (unsigned char)(fcw & 0x000000FF);
+		buffer[1] = (unsigned char)((fcw & 0x0000FF00) >> 8);
+		buffer[2] = (unsigned char)((fcw & 0x007F0000) >> 16);
+		for (i = 0; i < data->chip_num; i++) {
+			error =
+			    it9135_write_regs(data, i,
+					      PROCESSOR_OFDM, bfs_fcw_7_0,
+					      bfs_fcw_22_16 - bfs_fcw_7_0 + 1,
+					      buffer);
+			if (error)
+				goto exit;
+		}
+	}
+
+	/* Load script */
+	if (data->scripts != NULL) {
+		error =
+		    it9135_load_script(data, data->script_sets,
+				       data->scripts, tuner_script_sets,
+				       tuner_scripts);
+		if (error)
+			goto exit;
+	}
+
+	if ((data->chip_type == 0x9135 && data->chip_ver == 2)
+	    || data->chip_type == 0x9175) {
+		for (i = 0; i < data->chip_num; i++) {
+			error =
+			    it9135_write_reg(data, i, PROCESSOR_OFDM,
+					     trigger_ofsm, 0x01);
+			if (error)
+				goto exit;
+		}
+
+		/* Open tuner */
+		for (i = 0; i < data->chip_num; i++) {
+
+			/* Set 0xD827 to 0 as open drain for tuner i2c */
+			error =
+			    it9135_write_reg(data, i, PROCESSOR_LINK,
+					     p_reg_top_padodpu, 0);
+			if (error)
+				goto exit;
+
+			/* Set 0xD829 to 0 as push pull for tuner AGC */
+			error =
+			    it9135_write_reg(data, i, PROCESSOR_LINK,
+					     p_reg_top_agc_od, 0);
+			if (error)
+				goto exit;
+		}
+
+		for (i = 0; i < data->chip_num; i++) {
+			error = it9135_tuner_init(data, i);
+			if (error)
+				goto exit;
+		}
+	}
+
+	/* Set the desired stream type */
+	error = it9135_set_stream_type(data, streamType);
+	if (error)
+		goto exit;
+
+	/* Set the desired architecture type */
+	error = it9135_set_arch(data, architecture);
+	if (error)
+		goto exit;
+
+	for (i = 0; i < data->chip_num; i++) {
+		/* Set H/W MPEG2 locked detection */
+		error =
+		    it9135_write_reg(data, i, PROCESSOR_LINK,
+				     p_reg_top_lock3_out, 1);
+		if (error)
+			goto exit;
+		error =
+		    it9135_write_reg(data, i, PROCESSOR_LINK,
+				     p_reg_top_padmiscdrsr, 1);
+		if (error)
+			goto exit;
+		/* Set registers for driving power 0xD830 */
+		error =
+		    it9135_write_reg(data, i, PROCESSOR_LINK,
+				     p_reg_top_padmiscdr2, 0);
+		if (error)
+			goto exit;
+		/* enhance the performance while using DIP crystals */
+		error = it9135_write_reg(data, i, PROCESSOR_OFDM, 0xEC57, 0);
+		if (error)
+			goto exit;
+		error = it9135_write_reg(data, i, PROCESSOR_OFDM, 0xEC58, 0);
+		if (error)
+			goto exit;
+		/* Set ADC frequency multiplier */
+		error = it9135_set_multiplier(data, Multiplier_2X);
+		if (error)
+			goto exit;
+		/* Set registers for driving power 0xD831 */
+		error =
+		    it9135_write_reg(data, i, PROCESSOR_LINK,
+				     p_reg_top_padmiscdr4, 0);
+		if (error)
+			goto exit;
+		/* Set registers for driving power 0xD832 */
+		error =
+		    it9135_write_reg(data, i, PROCESSOR_LINK,
+				     p_reg_top_padmiscdr8, 0);
+		if (error)
+			goto exit;
+	}
+
+	data->inited = 1;
+
+exit:
+	return error;
+}
+
+unsigned long it9135_tps_locked(struct it9135_data *data, unsigned char chip,
+				int *locked)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char temp;
+
+	*locked = 0;
+
+	error =
+	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM, p_fd_tpsd_lock,
+				 fd_tpsd_lock_pos, fd_tpsd_lock_len, &temp);
+	if (error)
+		goto exit;
+	if (temp)
+		*locked = 1;
+
+exit:
+	return error;
+}
+
+unsigned long it9135_mp2_locked(struct it9135_data *data, unsigned char chip,
+				int *locked)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char temp;
+
+	*locked = 0;
+
+	error =
+	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM,
+				 r_mp2if_sync_byte_locked,
+				 mp2if_sync_byte_locked_pos,
+				 mp2if_sync_byte_locked_len, &temp);
+	if (error)
+		goto exit;
+
+	if (temp)
+		*locked = 1;
+
+exit:
+	return error;
+}
+
+unsigned long it9135_freq_locked(struct it9135_data *data, unsigned char chip,
+				 int *locked)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned short empty_loop = 0;
+	unsigned short tps_loop = 0;
+	unsigned short mpeg2_loop = 0;
+	unsigned char channels[2];
+	unsigned char begin;
+	unsigned char end;
+	unsigned char i;
+	unsigned char empty_ch = 1;
+	unsigned char tps_locked = 0;
+	int retry = 1;
+
+check_lock:
+	*locked = 0;
+
+	if (data->architecture == ARCHITECTURE_DCA) {
+		begin = 0;
+		end = data->chip_num;
+	} else {
+		begin = chip;
+		end = begin + 1;
+	}
+
+	for (i = begin; i < end; i++) {
+		data->statistic[i].presented = 0;
+		data->statistic[i].locked = 0;
+		data->statistic[i].quality = 0;
+		data->statistic[i].strength = 0;
+	}
+
+	channels[0] = 2;
+	channels[1] = 2;
+	while (empty_loop < 40) {
+		for (i = begin; i < end; i++) {
+			error =
+			    it9135_read_reg(data, i, PROCESSOR_OFDM,
+					    empty_channel_status, &channels[i]);
+			if (error)
+				goto exit;
+		}
+		if ((channels[0] == 1) || (channels[1] == 1)) {
+			empty_ch = 0;
+			break;
+		}
+		if ((channels[0] == 2) && (channels[1] == 2)) {
+			empty_ch = 1;
+			goto exit;
+		}
+		mdelay(25);
+		empty_loop++;
+	}
+
+	if (empty_ch == 1)
+		goto exit;
+
+	while (tps_loop < 50) {
+		for (i = begin; i < end; i++) {
+			/* TPS check */
+			error =
+			    it9135_tps_locked(data, i,
+					      &data->statistic[i].presented);
+			if (error)
+				goto exit;
+			if (data->statistic[i].presented) {
+				tps_locked = 1;
+				break;
+			}
+		}
+
+		if (tps_locked == 1)
+			break;
+
+		mdelay(25);
+		tps_loop++;
+	}
+
+	if (tps_locked == 0)
+		goto exit;
+
+	while (mpeg2_loop < 40) {
+		if (data->architecture == ARCHITECTURE_DCA) {
+			error =
+			    it9135_mp2_locked(data, 0,
+					      &data->statistic[0].locked);
+			if (error)
+				goto exit;
+			if (data->statistic[0].locked) {
+				for (i = begin; i < end; i++) {
+					data->statistic[i].quality = 80;
+					data->statistic[i].strength = 80;
+				}
+				*locked = 1;
+				break;
+			}
+		} else {
+			error =
+			    it9135_mp2_locked(data, chip,
+					      &data->statistic[chip].locked);
+			if (error)
+				goto exit;
+			if (data->statistic[chip].locked) {
+				data->statistic[chip].quality = 80;
+				data->statistic[chip].strength = 80;
+				*locked = 1;
+				break;
+			}
+		}
+		mdelay(25);
+		mpeg2_loop++;
+	}
+	for (i = begin; i < end; i++) {
+		data->statistic[i].quality = 0;
+		data->statistic[i].strength = 20;
+	}
+
+exit:
+	if (*locked == 0 && retry == 1) {
+		retry = 0;
+		mpeg2_loop = 0;
+		tps_loop = 0;
+		empty_loop = 0;
+		empty_ch = 1;
+		tps_locked = 0;
+		/* Clear empty_channel_status lock flag */
+		error =
+		    it9135_write_reg(data, chip, PROCESSOR_OFDM,
+				     empty_channel_status, 0x00);
+		if (error)
+			goto exit;
+
+		/* Trigger ofsm */
+		error =
+		    it9135_write_reg(data, chip, PROCESSOR_OFDM, trigger_ofsm,
+				     0);
+		if (error)
+			goto exit;
+
+		goto check_lock;
+	}
+
+	return error;
+}
+
+unsigned long it9135_get_ch_modulation(struct it9135_data *data,
+				       unsigned char chip,
+				       struct it9135_ch_modulation
+				       *ch_modulation)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char temp;
+
+	/* Get constellation type */
+	error =
+	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM,
+				 g_reg_tpsd_const, reg_tpsd_const_pos,
+				 reg_tpsd_const_len, &temp);
+	if (error)
+		goto exit;
+	ch_modulation->constellation = temp;
+
+	/* Get TPS hierachy and alpha value */
+	error =
+	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM,
+				 g_reg_tpsd_hier, reg_tpsd_hier_pos,
+				 reg_tpsd_hier_len, &temp);
+	if (error)
+		goto exit;
+	ch_modulation->hierarchy = temp;
+
+	/* Get high/low priority */
+	error =
+	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM, g_reg_dec_pri,
+				 reg_dec_pri_pos, reg_dec_pri_len, &temp);
+	if (error)
+		goto exit;
+	if (temp)
+		ch_modulation->priority = PRIORITY_HIGH;
+	else
+		ch_modulation->priority = PRIORITY_LOW;
+
+	/* Get high code rate */
+	error =
+	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM,
+				 g_reg_tpsd_hpcr, reg_tpsd_hpcr_pos,
+				 reg_tpsd_hpcr_len, &temp);
+	if (error)
+		goto exit;
+	ch_modulation->h_code_rate = temp;
+
+	/* Get low code rate */
+	error =
+	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM,
+				 g_reg_tpsd_lpcr, reg_tpsd_lpcr_pos,
+				 reg_tpsd_lpcr_len, &temp);
+	if (error)
+		goto exit;
+	ch_modulation->l_code_rate = temp;
+
+	/* Get guard interval */
+	error =
+	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM, g_reg_tpsd_gi,
+				 reg_tpsd_gi_pos, reg_tpsd_gi_len, &temp);
+	if (error)
+		goto exit;
+	ch_modulation->interval = temp;
+
+	/* Get FFT mode */
+	error =
+	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM,
+				 g_reg_tpsd_txmod, reg_tpsd_txmod_pos,
+				 reg_tpsd_txmod_len, &temp);
+	if (error)
+		goto exit;
+	ch_modulation->trans_mode = temp;
+
+	/* Get bandwidth */
+	error =
+	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM, g_reg_bw,
+				 reg_bw_pos, reg_bw_len, &temp);
+	if (error)
+		goto exit;
+	ch_modulation->bandwidth = temp;
+
+	/* Get frequency */
+	ch_modulation->frequency = data->frequency[chip];
+
+exit:
+	return error;
+}
+
+unsigned long it9135_acquire_ch(struct it9135_data *data, unsigned char chip,
+				unsigned short bandwidth,
+				unsigned long frequency)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char begin;
+	unsigned char end;
+	unsigned char i;
+
+	if (data->architecture == ARCHITECTURE_DCA) {
+		begin = 0;
+		end = data->chip_num;
+	} else {
+		begin = chip;
+		end = begin + 1;
+	}
+
+	for (i = begin; i < end; i++) {
+		error =
+		    it9135_select_bandwidth(data, i, bandwidth, data->adc_freq);
+		if (error)
+			goto exit;
+		data->bandwidth[i] = bandwidth;
+	}
+
+	error = it9135_mask_dca_output(data);
+	if (error)
+		goto exit;
+
+	/* Set frequency */
+	for (i = begin; i < end; i++) {
+		error = it9135_set_frequency(data, i, frequency);
+		if (error)
+			goto exit;
+	}
+
+exit:
+	return error;
+}
+
+unsigned long it9135_set_stream_type(struct it9135_data *data,
+				     unsigned char streamType)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char i;
+
+	for (i = 0; i < data->chip_num; i++) {
+		error =
+		    it9135_write_reg_bits(data, i, PROCESSOR_OFDM,
+					  p_reg_mpeg_full_speed,
+					  reg_mpeg_full_speed_pos,
+					  reg_mpeg_full_speed_len, 0);
+		if (error)
+			goto exit;
+	}
+
+	/* Enable DVB-T mode */
+	for (i = 0; i < data->chip_num; i++) {
+		error =
+		    it9135_write_reg_bits(data, i, PROCESSOR_LINK,
+					  p_reg_dvbt_en, reg_dvbt_en_pos,
+					  reg_dvbt_en_len, 1);
+		if (error)
+			goto exit;
+	}
+
+	/* Pictor & Orion & Omega & Omega_LNA */
+	if (data->tuner_desc.id == 0x35
+	    || data->tuner_desc.id == 0x39
+	    || data->tuner_desc.id == 0x3A || data->chip_type == 0x9135
+	    || data->chip_type == 0x9175) {
+		/* Enter sub mode */
+		error =
+		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+					  p_mp2if_mpeg_ser_mode,
+					  mp2if_mpeg_ser_mode_pos,
+					  mp2if_mpeg_ser_mode_len, 0);
+		if (error)
+			goto exit;
+		error =
+		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+					  p_mp2if_mpeg_par_mode,
+					  mp2if_mpeg_par_mode_pos,
+					  mp2if_mpeg_par_mode_len, 0);
+		if (error)
+			goto exit;
+		/* Fix current leakage */
+		error =
+		    it9135_write_reg_bits(data, 0, PROCESSOR_LINK,
+					  p_reg_top_hostb_mpeg_ser_mode,
+					  reg_top_hostb_mpeg_ser_mode_pos,
+					  reg_top_hostb_mpeg_ser_mode_len, 0);
+		if (error)
+			goto exit;
+		error =
+		    it9135_write_reg_bits(data, 0, PROCESSOR_LINK,
+					  p_reg_top_hostb_mpeg_par_mode,
+					  reg_top_hostb_mpeg_par_mode_pos,
+					  reg_top_hostb_mpeg_par_mode_len, 0);
+		if (error)
+			goto exit;
+	} else {
+		/* Enter sub mode */
+		error =
+		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+					  p_mp2if_mpeg_ser_mode,
+					  mp2if_mpeg_ser_mode_pos,
+					  mp2if_mpeg_ser_mode_len, 0);
+		if (error)
+			goto exit;
+		error =
+		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+					  p_mp2if_mpeg_par_mode,
+					  mp2if_mpeg_par_mode_pos,
+					  mp2if_mpeg_par_mode_len, 0);
+		if (error)
+			goto exit;
+		/* Fix current leakage */
+		if (data->chip_num > 1) {
+			if (data->host_if[0]) {
+				error =
+				    it9135_write_reg_bits(data, 0,
+							  PROCESSOR_LINK,
+							  p_reg_top_hostb_mpeg_ser_mode,
+							  reg_top_hostb_mpeg_ser_mode_pos,
+							  reg_top_hostb_mpeg_ser_mode_len,
+							  0);
+				if (error)
+					goto exit;
+				error =
+				    it9135_write_reg_bits(data, 0,
+							  PROCESSOR_LINK,
+							  p_reg_top_hostb_mpeg_par_mode,
+							  reg_top_hostb_mpeg_par_mode_pos,
+							  reg_top_hostb_mpeg_par_mode_len,
+							  1);
+				if (error)
+					goto exit;
+			} else {
+				error =
+				    it9135_write_reg_bits(data, 0,
+							  PROCESSOR_LINK,
+							  p_reg_top_hosta_mpeg_ser_mode,
+							  reg_top_hosta_mpeg_ser_mode_pos,
+							  reg_top_hosta_mpeg_ser_mode_len,
+							  0);
+				if (error)
+					goto exit;
+				error =
+				    it9135_write_reg_bits(data, 0,
+							  PROCESSOR_LINK,
+							  p_reg_top_hosta_mpeg_par_mode,
+							  reg_top_hosta_mpeg_par_mode_pos,
+							  reg_top_hosta_mpeg_par_mode_len,
+							  1);
+				if (error)
+					goto exit;
+			}
+		} else {
+			error =
+			    it9135_write_reg_bits(data, 0,
+						  PROCESSOR_LINK,
+						  p_reg_top_hosta_mpeg_ser_mode,
+						  reg_top_hosta_mpeg_ser_mode_pos,
+						  reg_top_hosta_mpeg_ser_mode_len,
+						  0);
+			if (error)
+				goto exit;
+			error =
+			    it9135_write_reg_bits(data, 0,
+						  PROCESSOR_LINK,
+						  p_reg_top_hosta_mpeg_par_mode,
+						  reg_top_hosta_mpeg_par_mode_pos,
+						  reg_top_hosta_mpeg_par_mode_len,
+						  1);
+			if (error)
+				goto exit;
+			error =
+			    it9135_write_reg_bits(data, 0,
+						  PROCESSOR_LINK,
+						  p_reg_top_hostb_mpeg_ser_mode,
+						  reg_top_hostb_mpeg_ser_mode_pos,
+						  reg_top_hostb_mpeg_ser_mode_len,
+						  0);
+			if (error)
+				goto exit;
+			error =
+			    it9135_write_reg_bits(data, 0,
+						  PROCESSOR_LINK,
+						  p_reg_top_hostb_mpeg_par_mode,
+						  reg_top_hostb_mpeg_par_mode_pos,
+						  reg_top_hostb_mpeg_par_mode_len,
+						  1);
+			if (error)
+				goto exit;
+		}
+	}
+
+exit:
+	return error;
+}
+
+unsigned long it9135_set_arch(struct it9135_data *data,
+			      unsigned char architecture)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned short frame_sz;
+	unsigned char packet_sz;
+	unsigned char buffer[2];
+	unsigned char standalone[2];
+	unsigned char upper_chip[2];
+	unsigned char upper_host[2];
+	unsigned char lower_chip[2];
+	unsigned char lower_host[2];
+	unsigned char dca_en[2];
+	unsigned char phase_latch[2];
+	unsigned char fpga_latch[2];
+	unsigned char i;
+	int pip_valid = 0;
+
+/* Define USB frame size */
+#define IT9135_USB20_MAX_PACKET_SIZE      512
+#ifdef DVB_USB_ADAP_NEED_PID_FILTER
+#define IT9135_USB20_FRAME_SIZE           (188 * 21)
+#else
+#define IT9135_USB20_FRAME_SIZE           (188 * 348)
+#endif
+#define IT9135_USB20_FRAME_SIZE_DW        (IT9135_USB20_FRAME_SIZE / 4)
+#define IT9135_USB11_MAX_PACKET_SIZE      64
+#define IT9135_USB11_FRAME_SIZE           (188 * 21)
+#define IT9135_USB11_FRAME_SIZE_DW        (IT9135_USB11_FRAME_SIZE / 4)
+
+	if (architecture == ARCHITECTURE_DCA) {
+		for (i = 0; i < data->chip_num; i++) {
+			standalone[i] = 0;
+			upper_chip[i] = 0;
+			upper_host[i] = 0;
+			lower_chip[i] = 0;
+			lower_host[i] = 0;
+			dca_en[i] = 1;
+			phase_latch[i] = 0;
+			fpga_latch[i] = 0;
+		}
+
+		if (data->chip_num == 1) {
+			standalone[0] = 1;
+			dca_en[0] = 0;
+		} else {
+			/* Pictor & Orion & Omega */
+			if (data->tuner_desc.id == 0x35
+			    || data->tuner_desc.id == 0x39
+			    || data->tuner_desc.id == 0x3A) {
+				upper_chip[data->chip_num - 1] = 1;
+				upper_host[0] = 1;
+				lower_chip[0] = 1;
+				lower_host[data->chip_num - 1] = 1;
+				phase_latch[0] = 0;
+				phase_latch[data->chip_num - 1] = 0;
+				fpga_latch[0] = 0;
+				fpga_latch[data->chip_num - 1] = 0;
+			} else if (data->chip_type == 0x9135
+				   || data->chip_type == 0x9175) {
+				upper_chip[data->chip_num - 1] = 1;
+				upper_host[0] = 1;
+
+				lower_chip[0] = 1;
+				lower_host[data->chip_num - 1] = 1;
+
+				phase_latch[0] = 1;
+				phase_latch[data->chip_num - 1] = 1;
+
+				fpga_latch[0] = 0x44;
+				fpga_latch[data->chip_num - 1] = 0x44;
+			} else {
+				upper_chip[data->chip_num - 1] = 1;
+				upper_host[0] = 1;
+				lower_chip[0] = 1;
+				lower_host[data->chip_num - 1] = 1;
+				phase_latch[0] = 1;
+				phase_latch[data->chip_num - 1] = 1;
+				fpga_latch[0] = 0x77;
+				fpga_latch[data->chip_num - 1] = 0x77;
+			}
+		}
+	} else {
+		for (i = 0; i < data->chip_num; i++) {
+			standalone[i] = 1;
+			upper_chip[i] = 0;
+			upper_host[i] = 0;
+			lower_chip[i] = 0;
+			lower_host[i] = 0;
+			dca_en[i] = 0;
+			phase_latch[i] = 0;
+			fpga_latch[i] = 0;
+		}
+	}
+
+	if (data->inited) {
+		error = it9135_mask_dca_output(data);
+		if (error)
+			goto exit;
+	}
+
+	/* Pictor & Orion & Omega & Omega_LNA */
+	if (data->tuner_desc.id == 0x35
+	    || data->tuner_desc.id == 0x39
+	    || data->tuner_desc.id == 0x3A || data->chip_type == 0x9135
+	    || data->chip_type == 0x9175) {
+		for (i = data->chip_num; i > 0; i--) {
+			/* Set dca_upper_chip */
+			error =
+			    it9135_write_reg_bits(data, i - 1,
+						  PROCESSOR_OFDM,
+						  p_reg_dca_upper_chip,
+						  reg_dca_upper_chip_pos,
+						  reg_dca_upper_chip_len,
+						  upper_chip[i - 1]);
+			if (error)
+				goto exit;
+			error =
+			    it9135_write_reg_bits(data, i - 1,
+						  PROCESSOR_LINK,
+						  p_reg_top_hostb_dca_upper,
+						  reg_top_hostb_dca_upper_pos,
+						  reg_top_hostb_dca_upper_len,
+						  upper_host[i - 1]);
+			if (error)
+				goto exit;
+
+			/* Set dca_lower_chip */
+			error =
+			    it9135_write_reg_bits(data, i - 1,
+						  PROCESSOR_OFDM,
+						  p_reg_dca_lower_chip,
+						  reg_dca_lower_chip_pos,
+						  reg_dca_lower_chip_len,
+						  lower_chip[i - 1]);
+			if (error)
+				goto exit;
+			error =
+			    it9135_write_reg_bits(data, i - 1,
+						  PROCESSOR_LINK,
+						  p_reg_top_hostb_dca_lower,
+						  reg_top_hostb_dca_lower_pos,
+						  reg_top_hostb_dca_lower_len,
+						  lower_host[i - 1]);
+			if (error)
+				goto exit;
+
+			/* Set phase latch */
+			error =
+			    it9135_write_reg_bits(data, i - 1,
+						  PROCESSOR_OFDM,
+						  p_reg_dca_platch,
+						  reg_dca_platch_pos,
+						  reg_dca_platch_len,
+						  phase_latch[i - 1]);
+			if (error)
+				goto exit;
+
+			/* Set fpga latch */
+			error =
+			    it9135_write_reg_bits(data, i - 1, PROCESSOR_OFDM,
+						  p_reg_dca_fpga_latch,
+						  reg_dca_fpga_latch_pos,
+						  reg_dca_fpga_latch_len,
+						  fpga_latch[i - 1]);
+			if (error)
+				goto exit;
+		}
+	} else {
+		/* Set upper chip first in order to avoid I/O conflict */
+		for (i = data->chip_num; i > 0; i--) {
+			/* Set dca_upper_chip */
+			error =
+			    it9135_write_reg_bits(data, i - 1,
+						  PROCESSOR_OFDM,
+						  p_reg_dca_upper_chip,
+						  reg_dca_upper_chip_pos,
+						  reg_dca_upper_chip_len,
+						  upper_chip[i - 1]);
+			if (error)
+				goto exit;
+			if (i == 1) {
+				if (data->host_if[0]) {
+					error =
+					    it9135_write_reg_bits
+					    (data, i - 1, PROCESSOR_LINK,
+					     p_reg_top_hosta_dca_upper,
+					     reg_top_hosta_dca_upper_pos,
+					     reg_top_hosta_dca_upper_len,
+					     upper_host[i - 1]);
+					if (error)
+						goto exit;
+					error =
+					    it9135_write_reg_bits
+					    (data, i - 1, PROCESSOR_LINK,
+					     p_reg_top_hostb_dca_upper,
+					     reg_top_hostb_dca_upper_pos,
+					     reg_top_hostb_dca_upper_len, 0);
+					if (error)
+						goto exit;
+				} else {
+					error =
+					    it9135_write_reg_bits
+					    (data, i - 1, PROCESSOR_LINK,
+					     p_reg_top_hostb_dca_upper,
+					     reg_top_hostb_dca_upper_pos,
+					     reg_top_hostb_dca_upper_len,
+					     upper_host[i - 1]);
+					if (error)
+						goto exit;
+					error =
+					    it9135_write_reg_bits
+					    (data, i - 1, PROCESSOR_LINK,
+					     p_reg_top_hosta_dca_upper,
+					     reg_top_hosta_dca_upper_pos,
+					     reg_top_hosta_dca_upper_len, 0);
+					if (error)
+						goto exit;
+				}
+			} else {
+				error =
+				    it9135_write_reg_bits(data,
+							  i - 1,
+							  PROCESSOR_LINK,
+							  p_reg_top_hostb_dca_upper,
+							  reg_top_hostb_dca_upper_pos,
+							  reg_top_hostb_dca_upper_len,
+							  upper_host[i - 1]);
+				if (error)
+					goto exit;
+				error =
+				    it9135_write_reg_bits(data,
+							  i - 1,
+							  PROCESSOR_LINK,
+							  p_reg_top_hosta_dca_upper,
+							  reg_top_hosta_dca_upper_pos,
+							  reg_top_hosta_dca_upper_len,
+							  0);
+				if (error)
+					goto exit;
+			}
+
+			/* Set dca_lower_chip */
+			error =
+			    it9135_write_reg_bits(data, i - 1,
+						  PROCESSOR_OFDM,
+						  p_reg_dca_lower_chip,
+						  reg_dca_lower_chip_pos,
+						  reg_dca_lower_chip_len,
+						  lower_chip[i - 1]);
+			if (error)
+				goto exit;
+			if (i == 1) {
+				if (data->host_if[0]) {
+					error =
+					    it9135_write_reg_bits
+					    (data, i - 1, PROCESSOR_LINK,
+					     p_reg_top_hosta_dca_lower,
+					     reg_top_hosta_dca_lower_pos,
+					     reg_top_hosta_dca_lower_len,
+					     lower_host[i - 1]);
+					if (error)
+						goto exit;
+					error =
+					    it9135_write_reg_bits
+					    (data, i - 1, PROCESSOR_LINK,
+					     p_reg_top_hostb_dca_lower,
+					     reg_top_hostb_dca_lower_pos,
+					     reg_top_hostb_dca_lower_len, 0);
+					if (error)
+						goto exit;
+				} else {
+					error =
+					    it9135_write_reg_bits
+					    (data, i - 1, PROCESSOR_LINK,
+					     p_reg_top_hostb_dca_lower,
+					     reg_top_hostb_dca_lower_pos,
+					     reg_top_hostb_dca_lower_len,
+					     lower_host[i - 1]);
+					if (error)
+						goto exit;
+					error =
+					    it9135_write_reg_bits
+					    (data, i - 1, PROCESSOR_LINK,
+					     p_reg_top_hosta_dca_lower,
+					     reg_top_hosta_dca_lower_pos,
+					     reg_top_hosta_dca_lower_len, 0);
+					if (error)
+						goto exit;
+				}
+			} else {
+				error =
+				    it9135_write_reg_bits(data,
+							  i - 1,
+							  PROCESSOR_LINK,
+							  p_reg_top_hostb_dca_lower,
+							  reg_top_hostb_dca_lower_pos,
+							  reg_top_hostb_dca_lower_len,
+							  lower_host[i - 1]);
+				if (error)
+					goto exit;
+				error =
+				    it9135_write_reg_bits(data,
+							  i - 1,
+							  PROCESSOR_LINK,
+							  p_reg_top_hosta_dca_lower,
+							  reg_top_hosta_dca_lower_pos,
+							  reg_top_hosta_dca_lower_len,
+							  0);
+				if (error)
+					goto exit;
+			}
+
+			/* Set phase latch */
+			error =
+			    it9135_write_reg_bits(data, i - 1,
+						  PROCESSOR_OFDM,
+						  p_reg_dca_platch,
+						  reg_dca_platch_pos,
+						  reg_dca_platch_len,
+						  phase_latch[i - 1]);
+			if (error)
+				goto exit;
+
+			/* Set fpga latch */
+			error =
+			    it9135_write_reg_bits(data, i - 1,
+						  PROCESSOR_OFDM,
+						  p_reg_dca_fpga_latch,
+						  reg_dca_fpga_latch_pos,
+						  reg_dca_fpga_latch_len,
+						  fpga_latch[i - 1]);
+			if (error)
+				goto exit;
+		}
+	}
+
+	for (i = 0; i < data->chip_num; i++) {
+		/* Set stand alone */
+		error =
+		    it9135_write_reg_bits(data, i, PROCESSOR_OFDM,
+					  p_reg_dca_stand_alone,
+					  reg_dca_stand_alone_pos,
+					  reg_dca_stand_alone_len,
+					  standalone[i]);
+		if (error)
+			goto exit;
+
+		/* Set DCA enable */
+		error =
+		    it9135_write_reg_bits(data, i, PROCESSOR_OFDM,
+					  p_reg_dca_en, reg_dca_en_pos,
+					  reg_dca_en_len, dca_en[i]);
+		if (error)
+			goto exit;
+	}
+
+	if (data->inited) {
+		for (i = 0; i < data->chip_num; i++) {
+			error =
+			    it9135_write_reg(data, i, PROCESSOR_OFDM,
+					     trigger_ofsm, 0);
+			if (error)
+				goto exit;
+		}
+	}
+
+	frame_sz = IT9135_USB20_FRAME_SIZE_DW;
+	packet_sz = (unsigned char)(IT9135_USB20_MAX_PACKET_SIZE / 4);
+
+	if (data->busId == IT9135_BUS_USB11) {
+		frame_sz = IT9135_USB11_FRAME_SIZE_DW;
+		packet_sz = (unsigned char)(IT9135_USB11_MAX_PACKET_SIZE / 4);
+	}
+
+	if ((data->chip_num > 1) && (architecture == ARCHITECTURE_PIP))
+		pip_valid = 1;
+
+	/* Reset EP4 */
+	error =
+	    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM, p_reg_mp2_sw_rst,
+				  reg_mp2_sw_rst_pos, reg_mp2_sw_rst_len, 1);
+	if (error)
+		goto exit;
+
+	/* Reset EP5 */
+	error =
+	    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+				  p_reg_mp2if2_sw_rst, reg_mp2if2_sw_rst_pos,
+				  reg_mp2if2_sw_rst_len, 1);
+	if (error)
+		goto exit;
+
+	/* Disable EP4 */
+	error =
+	    it9135_write_reg_bits(data, 0, PROCESSOR_LINK, p_reg_ep4_tx_en,
+				  reg_ep4_tx_en_pos, reg_ep4_tx_en_len, 0);
+	if (error)
+		goto exit;
+
+	/* Disable EP5 */
+	error =
+	    it9135_write_reg_bits(data, 0, PROCESSOR_LINK, p_reg_ep5_tx_en,
+				  reg_ep5_tx_en_pos, reg_ep5_tx_en_len, 0);
+	if (error)
+		goto exit;
+
+	/* Disable EP4 NAK */
+	error =
+	    it9135_write_reg_bits(data, 0, PROCESSOR_LINK, p_reg_ep4_tx_nak,
+				  reg_ep4_tx_nak_pos, reg_ep4_tx_nak_len, 0);
+	if (error)
+		goto exit;
+
+	/* Disable EP5 NAK */
+	error =
+	    it9135_write_reg_bits(data, 0, PROCESSOR_LINK, p_reg_ep5_tx_nak,
+				  reg_ep5_tx_nak_pos, reg_ep5_tx_nak_len, 0);
+	if (error)
+		goto exit;
+
+	/* Enable EP4 */
+	error =
+	    it9135_write_reg_bits(data, 0, PROCESSOR_LINK, p_reg_ep4_tx_en,
+				  reg_ep4_tx_en_pos, reg_ep4_tx_en_len, 1);
+	if (error)
+		goto exit;
+
+	/* Set EP4 transfer length */
+	buffer[p_reg_ep4_tx_len_7_0 - p_reg_ep4_tx_len_7_0] =
+	    (unsigned char)frame_sz;
+	buffer[p_reg_ep4_tx_len_15_8 - p_reg_ep4_tx_len_7_0] =
+	    (unsigned char)(frame_sz >> 8);
+	error =
+	    it9135_write_regs(data, 0, PROCESSOR_LINK, p_reg_ep4_tx_len_7_0, 2,
+			      buffer);
+
+	/* Set EP4 packet size */
+	error =
+	    it9135_write_reg(data, 0, PROCESSOR_LINK, p_reg_ep4_max_pkt,
+			     packet_sz);
+	if (error)
+		goto exit;
+
+	if (pip_valid) {
+		/* Enable EP5 */
+		error =
+		    it9135_write_reg_bits(data, 0, PROCESSOR_LINK,
+					  p_reg_ep5_tx_en, reg_ep5_tx_en_pos,
+					  reg_ep5_tx_en_len, 1);
+		if (error)
+			goto exit;
+
+		/* Set EP5 transfer length */
+		buffer[p_reg_ep5_tx_len_7_0 - p_reg_ep5_tx_len_7_0] =
+		    (unsigned char)frame_sz;
+		buffer[p_reg_ep5_tx_len_15_8 - p_reg_ep5_tx_len_7_0] =
+		    (unsigned char)(frame_sz >> 8);
+		error =
+		    it9135_write_regs(data, 0, PROCESSOR_LINK,
+				      p_reg_ep5_tx_len_7_0, 2, buffer);
+
+		/* Set EP5 packet size */
+		error =
+		    it9135_write_reg(data, 0, PROCESSOR_LINK, p_reg_ep5_max_pkt,
+				     packet_sz);
+		if (error)
+			goto exit;
+	}
+
+	/* Disable 15 SER/PAR mode */
+	error =
+	    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+				  p_mp2if_mpeg_ser_mode,
+				  mp2if_mpeg_ser_mode_pos,
+				  mp2if_mpeg_ser_mode_len, 0);
+	if (error)
+		goto exit;
+	error =
+	    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+				  p_mp2if_mpeg_par_mode,
+				  mp2if_mpeg_par_mode_pos,
+				  mp2if_mpeg_par_mode_len, 0);
+	if (error)
+		goto exit;
+
+	if (pip_valid) {
+		/* Enable mp2if2 */
+		error =
+		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+					  p_reg_mp2if2_en, reg_mp2if2_en_pos,
+					  reg_mp2if2_en_len, 1);
+		if (error)
+			goto exit;
+
+		for (i = 1; i < data->chip_num; i++) {
+			/* Enable serial mode */
+			error =
+			    it9135_write_reg_bits(data, i,
+						  PROCESSOR_OFDM,
+						  p_mp2if_mpeg_ser_mode,
+						  mp2if_mpeg_ser_mode_pos,
+						  mp2if_mpeg_ser_mode_len, 1);
+			if (error)
+				goto exit;
+
+			/* Enable HostB serial */
+			error =
+			    it9135_write_reg_bits(data, i,
+						  PROCESSOR_LINK,
+						  p_reg_top_hostb_mpeg_ser_mode,
+						  reg_top_hostb_mpeg_ser_mode_pos,
+						  reg_top_hostb_mpeg_ser_mode_len,
+						  1);
+			if (error)
+				goto exit;
+		}
+
+		/* Enable tsis */
+		error =
+		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+					  p_reg_tsis_en, reg_tsis_en_pos,
+					  reg_tsis_en_len, 1);
+		if (error)
+			goto exit;
+	} else {
+		/* Disable mp2if2 */
+		error =
+		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+					  p_reg_mp2if2_en, reg_mp2if2_en_pos,
+					  reg_mp2if2_en_len, 0);
+		if (error)
+			goto exit;
+
+		for (i = 1; i < data->chip_num; i++) {
+			/* Disable serial mode */
+			error =
+			    it9135_write_reg_bits(data, i,
+						  PROCESSOR_OFDM,
+						  p_mp2if_mpeg_ser_mode,
+						  mp2if_mpeg_ser_mode_pos,
+						  mp2if_mpeg_ser_mode_len, 0);
+			if (error)
+				goto exit;
+
+			/* Disable HostB serial */
+			error =
+			    it9135_write_reg_bits(data, i,
+						  PROCESSOR_LINK,
+						  p_reg_top_hostb_mpeg_ser_mode,
+						  reg_top_hostb_mpeg_ser_mode_pos,
+						  reg_top_hostb_mpeg_ser_mode_len,
+						  0);
+			if (error)
+				goto exit;
+		}
+
+		/* Disable tsis */
+		error =
+		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+					  p_reg_tsis_en, reg_tsis_en_pos,
+					  reg_tsis_en_len, 0);
+		if (error)
+			goto exit;
+	}
+
+	/* Negate EP4 reset */
+	error =
+	    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM, p_reg_mp2_sw_rst,
+				  reg_mp2_sw_rst_pos, reg_mp2_sw_rst_len, 0);
+	if (error)
+		goto exit;
+
+	/* Negate EP5 reset */
+	error =
+	    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+				  p_reg_mp2if2_sw_rst, reg_mp2if2_sw_rst_pos,
+				  reg_mp2if2_sw_rst_len, 0);
+	if (error)
+		goto exit;
+
+	if (pip_valid) {
+		/* Split 15 PSB to 1K + 1K and enable flow control */
+		error =
+		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+					  p_reg_mp2if2_half_psb,
+					  reg_mp2if2_half_psb_pos,
+					  reg_mp2if2_half_psb_len, 0);
+		if (error)
+			goto exit;
+		error =
+		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
+					  p_reg_mp2if_stop_en,
+					  reg_mp2if_stop_en_pos,
+					  reg_mp2if_stop_en_len, 1);
+		if (error)
+			goto exit;
+
+		for (i = 1; i < data->chip_num; i++) {
+			error =
+			    it9135_write_reg_bits(data, i, PROCESSOR_OFDM,
+						  p_reg_mpeg_full_speed,
+						  reg_mpeg_full_speed_pos,
+						  reg_mpeg_full_speed_len, 1);
+			if (error)
+				goto exit;
+			error =
+			    it9135_write_reg_bits(data, i,
+						  PROCESSOR_OFDM,
+						  p_reg_mp2if_stop_en,
+						  reg_mp2if_stop_en_pos,
+						  reg_mp2if_stop_en_len, 0);
+			if (error)
+				goto exit;
+		}
+	}
+
+	data->architecture = architecture;
+
+exit:
+	return error;
+}
+
+unsigned long it9135_get_statistic(struct it9135_data *data, unsigned char chip,
+				   struct it9135_statistic *statistic)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char quality = 0;
+	unsigned char strength;
+	unsigned char buffer[2];
+
+	/* Get statistic by stream type */
+	error =
+	    it9135_read_regs(data, chip, PROCESSOR_OFDM, tpsd_lock,
+			     mpeg_lock - tpsd_lock + 1, buffer);
+	if (error)
+		goto exit;
+
+	if (buffer[tpsd_lock - tpsd_lock])
+		data->statistic[chip].presented = 1;
+	else
+		data->statistic[chip].presented = 0;
+
+	if (buffer[mpeg_lock - tpsd_lock])
+		data->statistic[chip].locked = 1;
+	else
+		data->statistic[chip].locked = 0;
+
+	error = it9135_get_signal_quality(data, chip, &quality);
+	if (error)
+		goto exit;
+
+	data->statistic[chip].quality = quality;
+	error = it9135_get_strength(data, chip, &strength);
+	if (error)
+		goto exit;
+
+	data->statistic[chip].strength = strength;
+
+	*statistic = data->statistic[chip];
+
+exit:
+	return error;
+}
+
+/* get ir raw code (4 unsigned chars) */
+unsigned long it9135_get_ir_code(struct it9135_data *data, unsigned long *code)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char r_buff[4];
+
+	error =
+	    it9135_cmd_sendcommand(data, CMD_IR_GET, 0, PROCESSOR_LINK, 0, NULL,
+				   4, r_buff);
+	if (error)
+		goto exit;
+
+	*code =
+	    (unsigned long)((r_buff[0] << 24) + (r_buff[1] << 16) +
+			    (r_buff[2] << 8) + r_buff[3]);
+
+exit:
+	return error;
+}
+
+unsigned long it9135_dev_reboot(struct it9135_data *data)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned long version;
+	unsigned char i;
+
+	error = it9135_get_fw_ver(data, PROCESSOR_LINK, &version);
+	if (error)
+		goto exit;
+	if (version == 0xFFFFFFFF)
+		goto exit;	/* I2M and I2U */
+	if (version != 0) {
+		for (i = data->chip_num; i > 0; i--) {
+			error = it9135_cmd_reboot(data, i - 1);
+			mdelay(1);
+			if (error)
+				goto exit;
+		}
+	}
+
+	data->booted = 0;
+
+exit:
+	return error;
+}
+
+unsigned long it9135_ctrl_pw_saving(struct it9135_data *data,
+				    unsigned char chip, unsigned char control)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char temp;
+	unsigned char j;
+
+	if (control) {
+		/* Power up case */
+		error =
+		    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
+					  p_reg_afe_mem0, 3, 1, 0);
+		if (error)
+			goto exit;
+		error =
+		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_dyn0_clk,
+				     0);
+		if (error)
+			goto exit;
+
+		/* Fixed current leakage */
+		if ((data->chip_num > 1) && (chip > 0)) {
+			/* Pictor & Orion & Omega & Omega_LNA */
+			if (data->tuner_desc.id == 0x35
+			    || data->tuner_desc.id == 0x39) {
+				/* Disable HostB parallel */
+				error =
+				    it9135_write_reg_bits
+				    (data, chip, PROCESSOR_LINK,
+				     p_reg_top_hostb_mpeg_ser_mode,
+				     reg_top_hostb_mpeg_ser_mode_pos,
+				     reg_top_hostb_mpeg_ser_mode_len, 0);
+				if (error)
+					goto exit;
+				error =
+				    it9135_write_reg_bits
+				    (data, chip, PROCESSOR_LINK,
+				     p_reg_top_hostb_mpeg_par_mode,
+				     reg_top_hostb_mpeg_par_mode_pos,
+				     reg_top_hostb_mpeg_par_mode_len, 0);
+				if (error)
+					goto exit;
+			} else if (data->chip_type == 0x9135
+				   || data->chip_type == 0x9175) {
+				/* Enable HostB serial */
+				if ((data->architecture == ARCHITECTURE_PIP))
+					error =
+					    it9135_write_reg_bits
+					    (data, chip,
+					     PROCESSOR_LINK,
+					     p_reg_top_hostb_mpeg_ser_mode,
+					     reg_top_hostb_mpeg_ser_mode_pos,
+					     reg_top_hostb_mpeg_ser_mode_len,
+					     1);
+				else
+					error =
+					    it9135_write_reg_bits
+					    (data, chip,
+					     PROCESSOR_LINK,
+					     p_reg_top_hostb_mpeg_ser_mode,
+					     reg_top_hostb_mpeg_ser_mode_pos,
+					     reg_top_hostb_mpeg_ser_mode_len,
+					     0);
+				if (error)
+					goto exit;
+				/* Disable HostB parallel */
+				error =
+				    it9135_write_reg_bits
+				    (data, chip, PROCESSOR_LINK,
+				     p_reg_top_hostb_mpeg_par_mode,
+				     reg_top_hostb_mpeg_par_mode_pos,
+				     reg_top_hostb_mpeg_par_mode_len, 0);
+				if (error)
+					goto exit;
+			}
+		}
+	} else {
+		/* Power down case */
+		error =
+		    it9135_write_reg(data, chip, PROCESSOR_OFDM, suspend_flag,
+				     1);
+		if (error)
+			goto exit;
+		error =
+		    it9135_write_reg(data, chip, PROCESSOR_OFDM, trigger_ofsm,
+				     0);
+		if (error)
+			goto exit;
+
+		for (j = 0; j < 150; j++) {
+			error =
+			    it9135_read_reg(data, chip, PROCESSOR_OFDM,
+					    suspend_flag, &temp);
+			if (error)
+				goto exit;
+			if (!temp)
+				break;
+			mdelay(10);
+		}
+		/* power down demod adc */
+		error =
+		    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
+					  p_reg_afe_mem0, 3, 1, 1);
+		if (error)
+			goto exit;
+
+		/* Fixed current leakage */
+		if ((data->chip_num > 1) && (chip > 0)) {
+			/* Pictor & Orion & Omega */
+			if (data->tuner_desc.id ==
+			    0x35
+			    || data->tuner_desc.id ==
+			    0x39 || data->chip_type == 0x9135
+			    || data->chip_type == 0x9175) {
+				/* Enable HostB parallel */
+				error =
+				    it9135_write_reg_bits
+				    (data, chip, PROCESSOR_LINK,
+				     p_reg_top_hostb_mpeg_ser_mode,
+				     reg_top_hostb_mpeg_ser_mode_pos,
+				     reg_top_hostb_mpeg_ser_mode_len, 0);
+				if (error)
+					goto exit;
+				error =
+				    it9135_write_reg_bits
+				    (data, chip, PROCESSOR_LINK,
+				     p_reg_top_hostb_mpeg_par_mode,
+				     reg_top_hostb_mpeg_par_mode_pos,
+				     reg_top_hostb_mpeg_par_mode_len, 1);
+				if (error)
+					goto exit;
+			}
+		}
+	}
+
+exit:
+	return error;
+}
+
+unsigned long it9135_ctrl_tuner_leakage(struct it9135_data *data,
+					unsigned char chip,
+					unsigned char control)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char value[15] = { 0 };
+
+	if (control) {
+		/* Power up case */
+		error =
+		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_p_if_en,
+				     1);
+		if (error)
+			goto exit;
+	} else {
+		/* Fixed tuner current leakage */
+		error =
+		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_dyn0_clk,
+				     0);
+		if (error)
+			goto exit;
+		/* 0xec40 */
+		error =
+		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_p_if_en,
+				     0);
+		if (error)
+			goto exit;
+
+		value[1] = 0x0c;
+
+		error =
+		    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_reg_pd_a,
+				      15, value);
+		if (error)
+			goto exit;
+
+		value[1] = 0;
+
+		/* 0xec12~0xec15 */
+		error =
+		    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_reg_lna_g,
+				      4, value);
+		if (error)
+			goto exit;
+		/* oxec17~0xec1f */
+		error =
+		    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_reg_pgc, 9,
+				      value);
+		if (error)
+			goto exit;
+		/* 0xec22~0xec2b */
+		error =
+		    it9135_write_regs(data, chip, PROCESSOR_OFDM,
+				      p_reg_clk_del_sel, 10, value);
+		if (error)
+			goto exit;
+		/* 0xec20 */
+		error = it9135_write_reg(data, chip, PROCESSOR_OFDM, 0xec20, 0);
+		if (error)
+			goto exit;
+		/* 0xec3f */
+		error = it9135_write_reg(data, chip, PROCESSOR_OFDM, 0xec3F, 1);
+		if (error)
+			goto exit;
+	}
+
+exit:
+	return error;
+}
+
+unsigned long it9135_ctrl_tuner_pw_saving(struct it9135_data *data,
+					  unsigned char chip,
+					  unsigned char control)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char value[15] = { 0 };
+
+	if (control) {
+		/* Power up case */
+		error =
+		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_p_if_en,
+				     1);
+		if (error)
+			goto exit;
+	} else {
+		/* tuner power down */
+		error =
+		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_dyn0_clk,
+				     0);
+		if (error)
+			goto exit;
+		/* 0xec40 */
+		error =
+		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_p_if_en,
+				     0);
+		if (error)
+			goto exit;
+
+		value[0] = 0x3F;	/* 0xec02 */
+		value[1] = 0x1F;	/* 0xec03 */
+		value[2] = 0x3F;	/* 0xec04 */
+		value[3] = 0x3E;	/* 0xec05 */
+
+		error =
+		    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_reg_pd_a,
+				      15, value);
+		if (error)
+			goto exit;
+
+		value[0] = 0;
+		value[1] = 0;
+		value[2] = 0;
+		value[3] = 0;
+
+		/* 0xec12~0xec15 */
+		error =
+		    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_reg_lna_g,
+				      4, value);
+		if (error)
+			goto exit;
+		/* oxec17~0xec1f */
+		error =
+		    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_reg_pgc, 9,
+				      value);
+		if (error)
+			goto exit;
+		/* 0xec22~0xec2b */
+		error =
+		    it9135_write_regs(data, chip, PROCESSOR_OFDM,
+				      p_reg_clk_del_sel, 10, value);
+		if (error)
+			goto exit;
+		/* 0xec20 */
+		error = it9135_write_reg(data, chip, PROCESSOR_OFDM, 0xec20, 0);
+		if (error)
+			goto exit;
+		/* 0xec3f */
+		error = it9135_write_reg(data, chip, PROCESSOR_OFDM, 0xec3F, 1);
+		if (error)
+			goto exit;
+	}
+
+exit:
+	return error;
+}
+
+unsigned long it9135_ctrl_pid_filter(struct it9135_data *data,
+				     unsigned char chip, unsigned char control)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	error =
+	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
+				  p_mp2if_pid_en, mp2if_pid_en_pos,
+				  mp2if_pid_en_len, control);
+
+	return error;
+}
+
+unsigned long it9135_reset_pid_filter(struct it9135_data *data,
+				      unsigned char chip)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	error =
+	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM, p_mp2if_pid_rst,
+				  mp2if_pid_rst_pos, mp2if_pid_rst_len, 1);
+	if (error)
+		goto exit;
+
+exit:
+	return error;
+}
+
+unsigned long it9135_add_pid_filter(struct it9135_data *data,
+				    unsigned char chip, unsigned char index,
+				    unsigned short pid)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char w_buff[2];
+
+	/* Enable pid filter */
+	error =
+	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM, p_mp2if_pid_en,
+				  mp2if_pid_en_pos, mp2if_pid_en_len, 1);
+	if (error)
+		goto exit;
+
+	w_buff[0] = (unsigned char)pid;
+	w_buff[1] = (unsigned char)(pid >> 8);
+
+	error =
+	    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_mp2if_pid_dat_l, 2,
+			      w_buff);
+	if (error)
+		goto exit;
+
+	error =
+	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
+				  p_mp2if_pid_index_en, mp2if_pid_index_en_pos,
+				  mp2if_pid_index_en_len, 1);
+	if (error)
+		goto exit;
+
+	error =
+	    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_mp2if_pid_index,
+			     index);
+	if (error)
+		goto exit;
+
+exit:
+	return error;
+}
+
+unsigned long it9135_get_snr(struct it9135_data *data, unsigned char chip,
+			     unsigned char *snr)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	struct it9135_ch_modulation ch_modulation;
+	unsigned long snr_value;
+
+	error = it9135_get_ch_modulation(data, chip, &ch_modulation);
+	if (error)
+		goto exit;
+
+	error = it9135_get_snr_val(data, chip, &snr_value);
+	if (error)
+		goto exit;
+
+	if (ch_modulation.trans_mode == TransmissionMode_2K)
+		snr_value = snr_value * 4;
+	else if (ch_modulation.trans_mode == TransmissionMode_4K)
+		snr_value = snr_value * 2;
+	else
+		snr_value = snr_value * 1;
+
+	if (ch_modulation.constellation == 0) {	/* CONSTELLATION_QPSK */
+		if (snr_value < 0xB4771)
+			*snr = 0;
+		else if (snr_value < 0xC1AED)
+			*snr = 1;
+		else if (snr_value < 0xD0D27)
+			*snr = 2;
+		else if (snr_value < 0xE4D19)
+			*snr = 3;
+		else if (snr_value < 0xE5DA8)
+			*snr = 4;
+		else if (snr_value < 0x107097)
+			*snr = 5;
+		else if (snr_value < 0x116975)
+			*snr = 6;
+		else if (snr_value < 0x1252D9)
+			*snr = 7;
+		else if (snr_value < 0x131FA4)
+			*snr = 8;
+		else if (snr_value < 0x13D5E1)
+			*snr = 9;
+		else if (snr_value < 0x148E53)
+			*snr = 10;
+		else if (snr_value < 0x15358B)
+			*snr = 11;
+		else if (snr_value < 0x15DD29)
+			*snr = 12;
+		else if (snr_value < 0x168112)
+			*snr = 13;
+		else if (snr_value < 0x170B61)
+			*snr = 14;
+		else if (snr_value < 0x17A532)
+			*snr = 15;
+		else if (snr_value < 0x180F94)
+			*snr = 16;
+		else if (snr_value < 0x186ED2)
+			*snr = 17;
+		else if (snr_value < 0x18B271)
+			*snr = 18;
+		else if (snr_value < 0x18E118)
+			*snr = 19;
+		else if (snr_value < 0x18FF4B)
+			*snr = 20;
+		else if (snr_value < 0x190AF1)
+			*snr = 21;
+		else if (snr_value < 0x191451)
+			*snr = 22;
+		else
+			*snr = 23;
+	} else if (ch_modulation.constellation == 1) {	/* CONSTELLATION_16QAM */
+		if (snr_value < 0x4F0D5)
+			*snr = 0;
+		else if (snr_value < 0x5387A)
+			*snr = 1;
+		else if (snr_value < 0x573A4)
+			*snr = 2;
+		else if (snr_value < 0x5A99E)
+			*snr = 3;
+		else if (snr_value < 0x5CC80)
+			*snr = 4;
+		else if (snr_value < 0x5EB62)
+			*snr = 5;
+		else if (snr_value < 0x5FECF)
+			*snr = 6;
+		else if (snr_value < 0x60B80)
+			*snr = 7;
+		else if (snr_value < 0x62501)
+			*snr = 8;
+		else if (snr_value < 0x64865)
+			*snr = 9;
+		else if (snr_value < 0x69604)
+			*snr = 10;
+		else if (snr_value < 0x6F356)
+			*snr = 11;
+		else if (snr_value < 0x7706A)
+			*snr = 12;
+		else if (snr_value < 0x804D3)
+			*snr = 13;
+		else if (snr_value < 0x89D1A)
+			*snr = 14;
+		else if (snr_value < 0x93E3D)
+			*snr = 15;
+		else if (snr_value < 0x9E35D)
+			*snr = 16;
+		else if (snr_value < 0xA7C3C)
+			*snr = 17;
+		else if (snr_value < 0xAFAF8)
+			*snr = 18;
+		else if (snr_value < 0xB719D)
+			*snr = 19;
+		else if (snr_value < 0xBDA6A)
+			*snr = 20;
+		else if (snr_value < 0xC0C75)
+			*snr = 21;
+		else if (snr_value < 0xC3F7D)
+			*snr = 22;
+		else if (snr_value < 0xC5E62)
+			*snr = 23;
+		else if (snr_value < 0xC6C31)
+			*snr = 24;
+		else if (snr_value < 0xC7925)
+			*snr = 25;
+		else
+			*snr = 26;
+	} else if (ch_modulation.constellation == 2) {	/* CONSTELLATION_64QAM */
+		if (snr_value < 0x256D0)
+			*snr = 0;
+		else if (snr_value < 0x27A65)
+			*snr = 1;
+		else if (snr_value < 0x29873)
+			*snr = 2;
+		else if (snr_value < 0x2B7FE)
+			*snr = 3;
+		else if (snr_value < 0x2CF1E)
+			*snr = 4;
+		else if (snr_value < 0x2E234)
+			*snr = 5;
+		else if (snr_value < 0x2F409)
+			*snr = 6;
+		else if (snr_value < 0x30046)
+			*snr = 7;
+		else if (snr_value < 0x30844)
+			*snr = 8;
+		else if (snr_value < 0x30A02)
+			*snr = 9;
+		else if (snr_value < 0x30CDE)
+			*snr = 10;
+		else if (snr_value < 0x31031)
+			*snr = 11;
+		else if (snr_value < 0x3144C)
+			*snr = 12;
+		else if (snr_value < 0x315DD)
+			*snr = 13;
+		else if (snr_value < 0x31920)
+			*snr = 14;
+		else if (snr_value < 0x322D0)
+			*snr = 15;
+		else if (snr_value < 0x339FC)
+			*snr = 16;
+		else if (snr_value < 0x364A1)
+			*snr = 17;
+		else if (snr_value < 0x38BCC)
+			*snr = 18;
+		else if (snr_value < 0x3C7D3)
+			*snr = 19;
+		else if (snr_value < 0x408CC)
+			*snr = 20;
+		else if (snr_value < 0x43BED)
+			*snr = 21;
+		else if (snr_value < 0x48061)
+			*snr = 22;
+		else if (snr_value < 0x4BE95)
+			*snr = 23;
+		else if (snr_value < 0x4FA7D)
+			*snr = 24;
+		else if (snr_value < 0x52405)
+			*snr = 25;
+		else if (snr_value < 0x5570D)
+			*snr = 26;
+		else if (snr_value < 0x59FEB)
+			*snr = 27;
+		else if (snr_value < 0x5BF38)
+			*snr = 28;
+		else if (snr_value < 0x5F78F)
+			*snr = 29;
+		else if (snr_value < 0x612C3)
+			*snr = 30;
+		else if (snr_value < 0x626BE)
+			*snr = 31;
+		else
+			*snr = 32;
+	} else
+		goto exit;
+
+exit:
+	return error;
+}
+
+unsigned long it9135_get_snr_val(struct it9135_data *data, unsigned char chip,
+				 unsigned long *snr_value)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char super_frame_num = 0;
+	unsigned char snr_reg[3];
+
+	error = it9135_read_regs(data, chip, PROCESSOR_OFDM, 0x2c, 3, snr_reg);
+	if (error)
+		goto exit;
+
+	*snr_value = (snr_reg[2] << 16) + (snr_reg[1] << 8) + snr_reg[0];
+
+	/* gets superFrame num */
+	error =
+	    it9135_read_reg(data, chip, PROCESSOR_OFDM, 0xF78b,
+			    (unsigned char *)&super_frame_num);
+	if (error)
+		goto exit;
+
+	if (super_frame_num)
+		*snr_value /= super_frame_num;
+
+exit:
+	return error;
+}
+
+unsigned long it9135_set_multiplier(struct it9135_data *data,
+				    unsigned char multiplier)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char new_adc_mul = 0;
+	unsigned char buffer[3];
+	long ctl_word;
+	unsigned char i;
+
+	if (multiplier == Multiplier_1X)
+		new_adc_mul = 0;
+	else
+		new_adc_mul = 1;
+
+	for (i = 0; i < data->chip_num; i++) {
+		/* Write ADC multiplier factor to firmware. */
+		error =
+		    it9135_write_reg(data, i, PROCESSOR_OFDM, adcx2,
+				     new_adc_mul);
+		if (error)
+			goto exit;
+	}
+
+	/* Compute FCW and load them to device */
+	if (data->fcw >= 0x00400000)
+		ctl_word = data->fcw - 0x00800000;
+	else
+		ctl_word = data->fcw;
+
+	if (new_adc_mul == 1)
+		ctl_word /= 2;
+	else
+		ctl_word *= 2;
+
+	data->fcw = 0x7FFFFF & ctl_word;
+
+	buffer[0] = (unsigned char)(data->fcw & 0x000000FF);
+	buffer[1] = (unsigned char)((data->fcw & 0x0000FF00) >> 8);
+	buffer[2] = (unsigned char)((data->fcw & 0x007F0000) >> 16);
+	for (i = 0; i < data->chip_num; i++)
+		error =
+		    it9135_write_regs(data, i, PROCESSOR_OFDM, bfs_fcw_7_0,
+				      bfs_fcw_22_16 - bfs_fcw_7_0 + 1, buffer);
+
+exit:
+	return error;
+}
+
+unsigned long it9135_reset_pid(struct it9135_data *data, unsigned char chip)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char i;
+
+	for (i = 0; i < 32; i++)
+		data->pid_info.pid_tab[chip].pid[i] = 0xFFFF;
+
+	error =
+	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM, p_mp2if_pid_rst,
+				  mp2if_pid_rst_pos, mp2if_pid_rst_len, 1);
+	if (error)
+		goto exit;
+
+	data->pid_info.pid_cnt = 0;
+
+exit:
+	return error;
+}
+
+unsigned long it9135_remove_pid_at(struct it9135_data *data, unsigned char chip,
+				   unsigned char index, unsigned short pid)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	error =
+	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
+				  p_mp2if_pid_index_en, mp2if_pid_index_en_pos,
+				  mp2if_pid_index_en_len, 0);
+	if (error)
+		goto exit;
+
+	error =
+	    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_mp2if_pid_index,
+			     index);
+	if (error)
+		goto exit;
+
+exit:
+	return error;
+}
+
+unsigned long it9135_get_ch_statistic(struct it9135_data *data,
+				      unsigned char chip,
+				      struct it9135_ch_statistic *ch_statistic)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned long post_err_cnt;
+	unsigned long post_bit_cnt;
+	unsigned short rsd_abort_cnt;
+
+	/* Get BER if couter is ready, error = ERROR_RSD_COUNTER_NOT_READY if counter is not ready */
+	if (data->architecture == ARCHITECTURE_PIP) {
+		error =
+		    it9135_get_post_vitber(data, chip, &post_err_cnt,
+					   &post_bit_cnt, &rsd_abort_cnt);
+		if (error == ERROR_NO_ERROR) {
+			data->ch_statistic[chip].post_vit_err_cnt =
+			    post_err_cnt;
+			data->ch_statistic[chip].post_vitbit_cnt = post_bit_cnt;
+			data->ch_statistic[chip].abort_cnt = rsd_abort_cnt;
+		}
+	} else {
+		error =
+		    it9135_get_post_vitber(data, 0, &post_err_cnt,
+					   &post_bit_cnt, &rsd_abort_cnt);
+		if (error == ERROR_NO_ERROR) {
+			data->ch_statistic[chip].post_vit_err_cnt =
+			    post_err_cnt;
+			data->ch_statistic[chip].post_vitbit_cnt = post_bit_cnt;
+			data->ch_statistic[chip].abort_cnt = rsd_abort_cnt;
+		}
+	}
+
+	*ch_statistic = data->ch_statistic[chip];
+
+	return error;
+}
+
+static struct it9135_tuner_desc tuner_def_desc = {
+	NULL,
+	NULL,
+	0x38,			/* tuner id */
+};
+
+unsigned long it9135_set_bus_tuner(struct it9135_data *data,
+				   unsigned short busId,
+				   unsigned short tuner_id)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char support_type = OMEGA_NORMAL;
+
+	data->busId = busId;
+	memcpy(&data->tuner_desc, &tuner_def_desc, sizeof(data->tuner_desc));
+
+	switch (tuner_id) {
+	case IT9135_TUNER_ID:
+		support_type = OMEGA_NORMAL;
+		break;
+	case IT9135_TUNER_ID_LNA_CONFIG1:
+		support_type = OMEGA_LNA_CONFIG1;
+		break;
+	case IT9135_TUNER_ID_LNA_CONFIG2:
+		support_type = OMEGA_LNA_CONFIG2;
+		break;
+	case IT9135_TUNER_ID_V2:
+		support_type = OMEGA_NORMAL;
+		break;
+	case IT9135_TUNER_ID_V2_LNA_CONFIG1:
+		support_type = OMEGA_LNA_CONFIG1;
+		break;
+	case IT9135_TUNER_ID_V2_LNA_CONFIG2:
+		support_type = OMEGA_LNA_CONFIG2;
+		break;
+	default:
+		error = ERROR_INVALID_TUNER_TYPE;
+		goto exit;
+	}
+
+	if (data->chip_type == 0x9135 && data->chip_ver == 2) {
+		switch (support_type) {
+		case OMEGA_NORMAL:
+			data->tuner_desc.scripts = data->tuner_script_normal;
+			data->tuner_desc.script_sets =
+			    &data->tuner_script_sets_normal;
+			data->tuner_desc.id = IT9135_TUNER_ID_V2;
+			error = ERROR_NO_ERROR;
+			break;
+		case OMEGA_LNA_CONFIG1:
+			data->tuner_desc.scripts = data->tuner_script_lna1;
+			data->tuner_desc.script_sets =
+			    &data->tuner_script_sets_lna1;
+			data->tuner_desc.id = IT9135_TUNER_ID_V2_LNA_CONFIG1;
+			error = ERROR_NO_ERROR;
+			break;
+		case OMEGA_LNA_CONFIG2:
+			data->tuner_desc.scripts = data->tuner_script_lna2;
+			data->tuner_desc.script_sets =
+			    &data->tuner_script_sets_lna2;
+			data->tuner_desc.id = IT9135_TUNER_ID_V2_LNA_CONFIG2;
+			error = ERROR_NO_ERROR;
+			break;
+		default:
+			break;
+		}
+	} else {
+		switch (support_type) {
+		case OMEGA_NORMAL:
+			data->tuner_desc.scripts = data->tuner_script_normal;
+			data->tuner_desc.script_sets =
+			    &data->tuner_script_sets_normal;
+			data->tuner_desc.id = IT9135_TUNER_ID;
+			error = ERROR_NO_ERROR;
+			break;
+		case OMEGA_LNA_CONFIG1:
+			data->tuner_desc.scripts = data->tuner_script_lna1;
+			data->tuner_desc.script_sets =
+			    &data->tuner_script_sets_lna1;
+			data->tuner_desc.id = IT9135_TUNER_ID_LNA_CONFIG1;
+			error = ERROR_NO_ERROR;
+			break;
+		case OMEGA_LNA_CONFIG2:
+			data->tuner_desc.scripts = data->tuner_script_lna2;
+			data->tuner_desc.script_sets =
+			    &data->tuner_script_sets_lna2;
+			data->tuner_desc.id = IT9135_TUNER_ID_LNA_CONFIG2;
+			error = ERROR_NO_ERROR;
+			break;
+		default:
+
+			break;
+		}
+	}
+
+	if (data->tuner_desc.scripts == NULL) {
+		data->tuner_desc.scripts = NULL;
+		data->tuner_desc.script_sets = NULL;
+	}
+
+exit:
+	return error;
+}
+
+unsigned long it9135_add_pid(struct it9135_data *data, unsigned char chip,
+			     unsigned short pid)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char w_buff[2];
+	unsigned char i, j;
+	int found = 0;
+
+	if (!data->pid_info.pid_init) {
+		for (i = 0; i < data->chip_num; i++) {
+			for (j = 0; j < 32; j++)
+				data->pid_info.pid_tab[i].pid[j] = 0xFFFF;
+		}
+		data->pid_info.pid_init = 1;
+	}
+
+	/* Enable pid filter */
+	if (data->pid_info.pid_cnt == 0) {
+		error =
+		    it9135_write_reg_bits(data, chip,
+					  PROCESSOR_OFDM, p_mp2if_pid_en,
+					  mp2if_pid_en_pos, mp2if_pid_en_len,
+					  1);
+		if (error)
+			goto exit;
+	} else {
+		for (i = 0; i < 32; i++) {
+			if (data->pid_info.pid_tab[chip].pid[i] == pid) {
+				found = 1;
+				break;
+			}
+		}
+		if (found)
+			goto exit;
+	}
+
+	for (i = 0; i < 32; i++) {
+		if (data->pid_info.pid_tab[chip].pid[i] == 0xFFFF)
+			break;
+	}
+	if (i == 32) {
+		error = ERROR_PID_FILTER_FULL;
+		goto exit;
+	}
+
+	w_buff[0] = (unsigned char)pid;
+	w_buff[1] = (unsigned char)(pid >> 8);
+
+	error =
+	    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_mp2if_pid_dat_l, 2,
+			      w_buff);
+	if (error)
+		goto exit;
+
+	error =
+	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
+				  p_mp2if_pid_index_en, mp2if_pid_index_en_pos,
+				  mp2if_pid_index_en_len, 1);
+	if (error)
+		goto exit;
+
+	error =
+	    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_mp2if_pid_index, i);
+	if (error)
+		goto exit;
+
+	data->pid_info.pid_tab[chip].pid[i] = pid;
+	data->pid_info.pid_cnt++;
+
+exit:
+	return error;
+}
+
+unsigned long it9135_add_pid_at(struct it9135_data *data, unsigned char chip,
+				unsigned char index, unsigned short pid)
+{
+	return it9135_add_pid_filter(data, chip, index, pid);
+}
+
+unsigned long it9135_remove_pid(struct it9135_data *data, unsigned char chip,
+				unsigned short pid)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char i;
+	int found = 0;
+
+	for (i = 0; i < 32; i++) {
+		if (data->pid_info.pid_tab[chip].pid[i] == pid) {
+			found = 1;
+			break;
+		}
+	}
+	if (!found)
+		goto exit;
+
+	error =
+	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
+				  p_mp2if_pid_index_en, mp2if_pid_index_en_pos,
+				  mp2if_pid_index_en_len, 0);
+	if (error)
+		goto exit;
+
+	error =
+	    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_mp2if_pid_index, i);
+	if (error)
+		goto exit;
+
+	data->pid_info.pid_tab[chip].pid[i] = 0xFFFF;
+
+	/* Disable pid filter */
+	if (data->pid_info.pid_cnt == 1) {
+		error =
+		    it9135_write_reg_bits(data, chip,
+					  PROCESSOR_OFDM, p_mp2if_pid_en,
+					  mp2if_pid_en_pos, mp2if_pid_en_len,
+					  0);
+	}
+
+	data->pid_info.pid_cnt--;
+
+exit:
+	return error;
+}
diff --git a/drivers/media/dvb/dvb-usb/it9135-fe.h b/drivers/media/dvb/dvb-usb/it9135-fe.h
new file mode 100644
index 0000000..1744ba4
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/it9135-fe.h
@@ -0,0 +1,1632 @@
+/*
+ * DVB USB Linux driver for IT9135 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2011 ITE Technologies, INC.
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ */
+
+#ifndef __IT9135_FE_H__
+#define __IT9135_FE_H__
+
+#define IT9135_API_VER_NUM	0x0203
+#define IT9135_API_DATE		0x20110426
+#define IT9135_API_BUILD	0x00
+
+/*
+ * Hardware register define
+ */
+#define    p_reg_pd_a				0xEC02
+#define	reg_pd_a_pos 0
+#define	reg_pd_a_len 6
+#define	reg_pd_a_lsb 0
+#define    p_reg_pd_c				0xEC04
+#define	reg_pd_c_pos 0
+#define	reg_pd_c_len 6
+#define	reg_pd_c_lsb 0
+#define    p_reg_pd_d				0xEC05
+#define	reg_pd_d_pos 0
+#define	reg_pd_d_len 6
+#define	reg_pd_d_lsb 0
+#define    p_reg_tst_a				0xEC06
+#define	reg_tst_a_pos 0
+#define	reg_tst_a_len 6
+#define	reg_tst_a_lsb 0
+#define    p_reg_tst_b				0xEC07
+#define	reg_tst_b_pos 0
+#define	reg_tst_b_len 2
+#define	reg_tst_b_lsb 0
+#define    p_reg_ctrl_a				0xEC08
+#define	reg_ctrl_a_pos 0
+#define	reg_ctrl_a_len 6
+#define	reg_ctrl_a_lsb 0
+#define    p_reg_ctrl_b				0xEC09
+#define	reg_ctrl_b_pos 0
+#define	reg_ctrl_b_len 2
+#define	reg_ctrl_b_lsb 0
+#define    p_reg_cal_freq_a			0xEC0A
+#define	reg_cal_freq_a_pos 0
+#define	reg_cal_freq_a_len 6
+#define	reg_cal_freq_a_lsb 0
+#define    p_reg_cal_freq_b			0xEC0B
+#define	reg_cal_freq_b_pos 0
+#define	reg_cal_freq_b_len 6
+#define	reg_cal_freq_b_lsb 0
+#define    p_reg_cal_freq_c			0xEC0C
+#define	reg_cal_freq_c_pos 0
+#define	reg_cal_freq_c_len 4
+#define	reg_cal_freq_c_lsb 0
+#define    p_reg_lo_freq_a			0xEC0D
+#define	reg_lo_freq_a_pos 0
+#define	reg_lo_freq_a_len 6
+#define	reg_lo_freq_a_lsb 0
+#define    p_reg_lo_freq_b			0xEC0E
+#define	reg_lo_freq_b_pos 0
+#define	reg_lo_freq_b_len 6
+#define	reg_lo_freq_b_lsb 0
+#define    p_reg_lo_freq_c			0xEC0F
+#define	reg_lo_freq_c_pos 0
+#define	reg_lo_freq_c_len 4
+#define	reg_lo_freq_c_lsb 0
+#define    p_reg_lo_cap				0xEC10
+#define	reg_lo_cap_pos 0
+#define	reg_lo_cap_len 6
+#define	reg_lo_cap_lsb 0
+#define    p_reg_clk02_select			0xEC11
+#define	reg_clk02_select_pos 0
+#define	reg_clk02_select_len 3
+#define	reg_clk02_select_lsb 0
+#define    p_reg_clk01_select			0xEC11
+#define	reg_clk01_select_pos 3
+#define	reg_clk01_select_len 3
+#define	reg_clk01_select_lsb 0
+#define    p_reg_lna_cap			0xEC13
+#define	reg_lna_cap_pos 0
+#define	reg_lna_cap_len 6
+#define	reg_lna_cap_lsb 0
+#define    p_reg_lna_g				0xEC12
+#define	reg_lna_g_pos 0
+#define	reg_lna_g_len 3
+#define	reg_lna_g_lsb 0
+#define    p_reg_lna_band			0xEC14
+#define	reg_lna_band_pos 0
+#define	reg_lna_band_len 3
+#define	reg_lna_band_lsb 0
+#define    p_reg_pga				0xEC15
+#define	reg_pga_pos 0
+#define	reg_pga_len 6
+#define	reg_pga_lsb 0
+#define    p_reg_pgc				0xEC17
+#define	reg_pgc_pos 0
+#define	reg_pgc_len 3
+#define	reg_pgc_lsb 0
+#define    p_reg_lpf_cap			0xEC18
+#define	reg_lpf_cap_pos 0
+#define	reg_lpf_cap_len 5
+#define	reg_lpf_cap_lsb 0
+#define    p_reg_lpf_bw				0xEC19
+#define	reg_lpf_bw_pos 0
+#define	reg_lpf_bw_len 3
+#define	reg_lpf_bw_lsb 0
+#define    p_reg_ofsi				0xEC1A
+#define	reg_ofsi_pos 0
+#define	reg_ofsi_len 6
+#define	reg_ofsi_lsb 0
+#define    p_reg_ofsq				0xEC1B
+#define	reg_ofsq_pos 0
+#define	reg_ofsq_len 6
+#define	reg_ofsq_lsb 0
+#define    p_reg_dcxo_a				0xEC1C
+#define	reg_dcxo_a_pos 0
+#define	reg_dcxo_a_len 6
+#define	reg_dcxo_a_lsb 0
+#define    p_reg_dcxo_b				0xEC1D
+#define	reg_dcxo_b_pos 0
+#define	reg_dcxo_b_len 4
+#define	reg_dcxo_b_lsb 0
+#define    p_reg_tddo				0xEC1E
+#define	reg_tddo_pos 0
+#define	reg_tddo_len 6
+#define	reg_tddo_lsb 0
+#define    p_reg_strength_setting		0xEC1F
+#define	reg_strength_setting_pos 0
+#define	reg_strength_setting_len 6
+#define	reg_strength_setting_lsb 0
+#define    p_reg_gi				0xEC22
+#define	reg_gi_pos 0
+#define	reg_gi_len 2
+#define	reg_gi_lsb 0
+#define    p_reg_clk_del_sel			0xEC22
+#define	reg_clk_del_sel_pos 2
+#define	reg_clk_del_sel_len 2
+#define	reg_clk_del_sel_lsb 0
+#define    p_reg_p2s_ck_sel			0xEC22
+#define	reg_p2s_ck_sel_pos 4
+#define	reg_p2s_ck_sel_len 1
+#define	reg_p2s_ck_sel_lsb 0
+#define    p_reg_rssi_sel			0xEC22
+#define	reg_rssi_sel_pos 5
+#define	reg_rssi_sel_len 1
+#define	reg_rssi_sel_lsb 0
+#define    p_reg_tst_sel			0xEC23
+#define	reg_tst_sel_pos 4
+#define	reg_tst_sel_len 2
+#define	reg_tst_sel_lsb 0
+#define    p_reg_ctrl_c				0xEC24
+#define	reg_ctrl_c_pos 0
+#define	reg_ctrl_c_len 6
+#define	reg_ctrl_c_lsb 0
+#define    p_reg_ctrl_d				0xEC25
+#define	reg_ctrl_d_pos 0
+#define	reg_ctrl_d_len 6
+#define	reg_ctrl_d_lsb 0
+#define    p_reg_ctrl_e				0xEC26
+#define	reg_ctrl_e_pos 0
+#define	reg_ctrl_e_len 6
+#define	reg_ctrl_e_lsb 0
+#define    p_reg_ctrl_f				0xEC27
+#define	reg_ctrl_f_pos 0
+#define	reg_ctrl_f_len 6
+#define	reg_ctrl_f_lsb 0
+#define    p_reg_lo_bias			0xEC28
+#define	reg_lo_bias_pos 0
+#define	reg_lo_bias_len 3
+#define	reg_lo_bias_lsb 0
+#define    p_reg_ext_lna_en			0xEC29
+#define	reg_ext_lna_en_pos 0
+#define	reg_ext_lna_en_len 1
+#define	reg_ext_lna_en_lsb 0
+#define    p_reg_pga_bak			0xEC2A
+#define	reg_pga_bak_pos 0
+#define	reg_pga_bak_len 3
+#define	reg_pga_bak_lsb 0
+#define    p_reg_cpll_cap			0xEC2B
+#define	reg_cpll_cap_pos 0
+#define	reg_cpll_cap_len 6
+#define	reg_cpll_cap_lsb 0
+#define    p_reg_p_if_en			0xEC40
+#define	reg_p_if_en_pos 0
+#define	reg_p_if_en_len 2
+#define	reg_p_if_en_lsb 0
+#define    p_reg_one_cycle_counter_tuner	0xF103
+#define	reg_one_cycle_counter_tuner_pos 0
+#define	reg_one_cycle_counter_tuner_len 8
+#define	reg_one_cycle_counter_tuner_lsb 0
+#define    p_reg_f_adc_7_0			0xF1CD
+#define	reg_f_adc_7_0_pos 0
+#define	reg_f_adc_7_0_len 8
+#define	reg_f_adc_7_0_lsb 0
+#define    p_reg_dvbt_en			0xF41A
+#define	reg_dvbt_en_pos 0
+#define	reg_dvbt_en_len 1
+#define	reg_dvbt_en_lsb 0
+#define    p_fd_tpsd_lock			0xF5A9
+#define	fd_tpsd_lock_pos 0
+#define	fd_tpsd_lock_len 1
+#define	fd_tpsd_lock_lsb 0
+#define    p_reg_feq_read_update		0xF5CA
+#define	reg_feq_read_update_pos 0
+#define	reg_feq_read_update_len 1
+#define	reg_feq_read_update_lsb 0
+#define    p_reg_link_ofsm_dummy_15_8		0xF641
+#define	reg_link_ofsm_dummy_15_8_pos 0
+#define	reg_link_ofsm_dummy_15_8_len 8
+#define	reg_link_ofsm_dummy_15_8_lsb 8
+#define    p_fec_vtb_rsd_mon_en			0xF715
+#define	fec_vtb_rsd_mon_en_pos 0
+#define	fec_vtb_rsd_mon_en_len 1
+#define	fec_vtb_rsd_mon_en_lsb 0
+#define    p_reg_dca_platch			0xF730
+#define	reg_dca_platch_pos 0
+#define	reg_dca_platch_len 1
+#define	reg_dca_platch_lsb 0
+#define    p_reg_dca_upper_chip			0xF731
+#define	reg_dca_upper_chip_pos 0
+#define	reg_dca_upper_chip_len 1
+#define	reg_dca_upper_chip_lsb 0
+#define    p_reg_dca_lower_chip			0xF732
+#define	reg_dca_lower_chip_pos 0
+#define	reg_dca_lower_chip_len 1
+#define	reg_dca_lower_chip_lsb 0
+#define    p_reg_dca_stand_alone		0xF73C
+#define	reg_dca_stand_alone_pos 0
+#define	reg_dca_stand_alone_len 1
+#define	reg_dca_stand_alone_lsb 0
+#define    p_reg_dca_upper_out_en		0xF73D
+#define	reg_dca_upper_out_en_pos 0
+#define	reg_dca_upper_out_en_len 1
+#define	reg_dca_upper_out_en_lsb 0
+#define    p_reg_dca_en				0xF776
+#define	reg_dca_en_pos 0
+#define	reg_dca_en_len 1
+#define	reg_dca_en_lsb 0
+#define    p_reg_dca_fpga_latch			0xF778
+#define	reg_dca_fpga_latch_pos 0
+#define	reg_dca_fpga_latch_len 8
+#define	reg_dca_fpga_latch_lsb 0
+#define    g_reg_tpsd_txmod			0xF900
+#define	reg_tpsd_txmod_pos 0
+#define	reg_tpsd_txmod_len 2
+#define	reg_tpsd_txmod_lsb 0
+#define    g_reg_tpsd_gi			0xF901
+#define	reg_tpsd_gi_pos 0
+#define	reg_tpsd_gi_len 2
+#define	reg_tpsd_gi_lsb 0
+#define    g_reg_tpsd_hier			0xF902
+#define	reg_tpsd_hier_pos 0
+#define	reg_tpsd_hier_len 3
+#define	reg_tpsd_hier_lsb 0
+#define    g_reg_tpsd_const			0xF903
+#define	reg_tpsd_const_pos 0
+#define	reg_tpsd_const_len 2
+#define	reg_tpsd_const_lsb 0
+#define    g_reg_bw				0xF904
+#define	reg_bw_pos 0
+#define	reg_bw_len 2
+#define	reg_bw_lsb 0
+#define    g_reg_dec_pri			0xF905
+#define	reg_dec_pri_pos 0
+#define	reg_dec_pri_len 1
+#define	reg_dec_pri_lsb 0
+#define    g_reg_tpsd_hpcr			0xF906
+#define	reg_tpsd_hpcr_pos 0
+#define	reg_tpsd_hpcr_len 3
+#define	reg_tpsd_hpcr_lsb 0
+#define    g_reg_tpsd_lpcr			0xF907
+#define	reg_tpsd_lpcr_pos 0
+#define	reg_tpsd_lpcr_len 3
+#define	reg_tpsd_lpcr_lsb 0
+#define    p_mp2if_mpeg_ser_mode		0xF985
+#define	mp2if_mpeg_ser_mode_pos 0
+#define	mp2if_mpeg_ser_mode_len 1
+#define	mp2if_mpeg_ser_mode_lsb 0
+#define    p_mp2if_mpeg_par_mode		0xF986
+#define	mp2if_mpeg_par_mode_pos 0
+#define	mp2if_mpeg_par_mode_len 1
+#define	mp2if_mpeg_par_mode_lsb 0
+#define    p_reg_mpeg_full_speed		0xF990
+#define	reg_mpeg_full_speed_pos 0
+#define	reg_mpeg_full_speed_len 1
+#define	reg_mpeg_full_speed_lsb 0
+#define    p_mp2if_pid_rst			0xF992
+#define	mp2if_pid_rst_pos 0
+#define	mp2if_pid_rst_len 1
+#define	mp2if_pid_rst_lsb 0
+#define    p_mp2if_pid_en			0xF993
+#define	mp2if_pid_en_pos 0
+#define	mp2if_pid_en_len 1
+#define	mp2if_pid_en_lsb 0
+#define    p_mp2if_pid_index_en			0xF994
+#define	mp2if_pid_index_en_pos 0
+#define	mp2if_pid_index_en_len 1
+#define	mp2if_pid_index_en_lsb 0
+#define    p_mp2if_pid_index			0xF995
+#define	mp2if_pid_index_pos 0
+#define	mp2if_pid_index_len 5
+#define	mp2if_pid_index_lsb 0
+#define    p_mp2if_pid_dat_l			0xF996
+#define	mp2if_pid_dat_l_pos 0
+#define	mp2if_pid_dat_l_len 8
+#define	mp2if_pid_dat_l_lsb 0
+#define    r_mp2if_sync_byte_locked		0xF999
+#define	mp2if_sync_byte_locked_pos 0
+#define	mp2if_sync_byte_locked_len 1
+#define	mp2if_sync_byte_locked_lsb 0
+#define    p_reg_mp2_sw_rst			0xF99D
+#define	reg_mp2_sw_rst_pos 0
+#define	reg_mp2_sw_rst_len 1
+#define	reg_mp2_sw_rst_lsb 0
+#define    p_reg_mp2if2_en			0xF9A3
+#define	reg_mp2if2_en_pos 0
+#define	reg_mp2if2_en_len 1
+#define	reg_mp2if2_en_lsb 0
+#define    p_reg_mp2if2_sw_rst			0xF9A4
+#define	reg_mp2if2_sw_rst_pos 0
+#define	reg_mp2if2_sw_rst_len 1
+#define	reg_mp2if2_sw_rst_lsb 0
+#define    p_reg_mp2if2_half_psb		0xF9A5
+#define	reg_mp2if2_half_psb_pos 0
+#define	reg_mp2if2_half_psb_len 1
+#define	reg_mp2if2_half_psb_lsb 0
+#define    p_reg_mp2if_stop_en			0xF9B5
+#define	reg_mp2if_stop_en_pos 0
+#define	reg_mp2if_stop_en_len 1
+#define	reg_mp2if_stop_en_lsb 0
+#define    p_reg_tsis_en			0xF9CD
+#define	reg_tsis_en_pos 0
+#define	reg_tsis_en_len 1
+#define	reg_tsis_en_lsb 0
+#define    p_reg_afe_mem0			0xFB24
+#define	reg_afe_mem0_pos 0
+#define	reg_afe_mem0_len 8
+#define	reg_afe_mem0_lsb 0
+#define    p_reg_dyn0_clk			0xFBA8
+#define	reg_dyn0_clk_pos 0
+#define	reg_dyn0_clk_len 1
+#define	reg_dyn0_clk_lsb 0
+#define    r_io_mux_pwron_clk_strap		0xD800
+#define	io_mux_pwron_clk_strap_pos 0
+#define	io_mux_pwron_clk_strap_len 4
+#define	io_mux_pwron_clk_strap_lsb 0
+#define    p_reg_top_pwrdw_hwen			0xD809
+#define	reg_top_pwrdw_hwen_pos 0
+#define	reg_top_pwrdw_hwen_len 1
+#define	reg_top_pwrdw_hwen_lsb 0
+#define    p_reg_top_pwrdw			0xD80B
+#define	reg_top_pwrdw_pos 0
+#define	reg_top_pwrdw_len 1
+#define	reg_top_pwrdw_lsb 0
+#define    p_reg_top_padodpu			0xD827
+#define	reg_top_padodpu_pos 0
+#define	reg_top_padodpu_len 1
+#define	reg_top_padodpu_lsb 0
+#define    p_reg_top_agc_od			0xD829
+#define	reg_top_agc_od_pos 0
+#define	reg_top_agc_od_len 1
+#define	reg_top_agc_od_lsb 0
+#define    p_reg_top_padmiscdr2			0xD830
+#define	reg_top_padmiscdr2_pos 0
+#define	reg_top_padmiscdr2_len 1
+#define	reg_top_padmiscdr2_lsb 0
+#define    p_reg_top_padmiscdr4			0xD831
+#define	reg_top_padmiscdr4_pos 0
+#define	reg_top_padmiscdr4_len 1
+#define	reg_top_padmiscdr4_lsb 0
+#define    p_reg_top_padmiscdr8			0xD832
+#define	reg_top_padmiscdr8_pos 0
+#define	reg_top_padmiscdr8_len 1
+#define	reg_top_padmiscdr8_lsb 0
+#define    p_reg_top_padmiscdrsr		0xD833
+#define	reg_top_padmiscdrsr_pos 0
+#define	reg_top_padmiscdrsr_len 1
+#define	reg_top_padmiscdrsr_lsb 0
+#define    p_reg_top_gpioh1_o			0xD8AF
+#define	reg_top_gpioh1_o_pos 0
+#define	reg_top_gpioh1_o_len 1
+#define	reg_top_gpioh1_o_lsb 0
+#define    p_reg_top_gpioh1_en			0xD8B0
+#define	reg_top_gpioh1_en_pos 0
+#define	reg_top_gpioh1_en_len 1
+#define	reg_top_gpioh1_en_lsb 0
+#define    p_reg_top_gpioh1_on			0xD8B1
+#define	reg_top_gpioh1_on_pos 0
+#define	reg_top_gpioh1_on_len 1
+#define	reg_top_gpioh1_on_lsb 0
+#define    p_reg_top_gpioh3_o			0xD8B3
+#define	reg_top_gpioh3_o_pos 0
+#define	reg_top_gpioh3_o_len 1
+#define	reg_top_gpioh3_o_lsb 0
+#define    p_reg_top_gpioh3_en			0xD8B4
+#define	reg_top_gpioh3_en_pos 0
+#define	reg_top_gpioh3_en_len 1
+#define	reg_top_gpioh3_en_lsb 0
+#define    p_reg_top_gpioh3_on			0xD8B5
+#define	reg_top_gpioh3_on_pos 0
+#define	reg_top_gpioh3_on_len 1
+#define	reg_top_gpioh3_on_lsb 0
+#define    p_reg_top_gpioh5_o			0xD8BB
+#define	reg_top_gpioh5_o_pos 0
+#define	reg_top_gpioh5_o_len 1
+#define	reg_top_gpioh5_o_lsb 0
+#define    p_reg_top_gpioh5_en			0xD8BC
+#define	reg_top_gpioh5_en_pos 0
+#define	reg_top_gpioh5_en_len 1
+#define	reg_top_gpioh5_en_lsb 0
+#define    p_reg_top_gpioh5_on			0xD8BD
+#define	reg_top_gpioh5_on_pos 0
+#define	reg_top_gpioh5_on_len 1
+#define	reg_top_gpioh5_on_lsb 0
+#define    p_reg_top_gpioh7_en			0xD8C4
+#define	reg_top_gpioh7_en_pos 0
+#define	reg_top_gpioh7_en_len 1
+#define	reg_top_gpioh7_en_lsb 0
+#define    p_reg_top_gpioh7_on			0xD8C5
+#define	reg_top_gpioh7_on_pos 0
+#define	reg_top_gpioh7_on_len 1
+#define	reg_top_gpioh7_on_lsb 0
+#define    p_reg_top_lock3_out			0xD8FD
+#define	reg_top_lock3_out_pos 0
+#define	reg_top_lock3_out_len 1
+#define	reg_top_lock3_out_lsb 0
+#define    p_reg_top_hostb_mpeg_par_mode	0xD91B
+#define	reg_top_hostb_mpeg_par_mode_pos 0
+#define	reg_top_hostb_mpeg_par_mode_len 1
+#define	reg_top_hostb_mpeg_par_mode_lsb 0
+#define    p_reg_top_hostb_mpeg_ser_mode	0xD91C
+#define	reg_top_hostb_mpeg_ser_mode_pos 0
+#define	reg_top_hostb_mpeg_ser_mode_len 1
+#define	reg_top_hostb_mpeg_ser_mode_lsb 0
+#define    p_reg_top_hostb_dca_upper		0xD91E
+#define	reg_top_hostb_dca_upper_pos 0
+#define	reg_top_hostb_dca_upper_len 1
+#define	reg_top_hostb_dca_upper_lsb 0
+#define    p_reg_top_hostb_dca_lower		0xD91F
+#define	reg_top_hostb_dca_lower_pos 0
+#define	reg_top_hostb_dca_lower_len 1
+#define	reg_top_hostb_dca_lower_lsb 0
+#define    p_reg_ep4_max_pkt			0xDD0C
+#define	reg_ep4_max_pkt_pos 0
+#define	reg_ep4_max_pkt_len 8
+#define	reg_ep4_max_pkt_lsb 0
+#define    p_reg_ep5_max_pkt			0xDD0D
+#define	reg_ep5_max_pkt_pos 0
+#define	reg_ep5_max_pkt_len 8
+#define	reg_ep5_max_pkt_lsb 0
+#define    p_reg_ep4_tx_en			0xDD11
+#define	reg_ep4_tx_en_pos 5
+#define	reg_ep4_tx_en_len 1
+#define	reg_ep4_tx_en_lsb 0
+#define    p_reg_ep5_tx_en			0xDD11
+#define	reg_ep5_tx_en_pos 6
+#define	reg_ep5_tx_en_len 1
+#define	reg_ep5_tx_en_lsb 0
+#define    p_reg_ep4_tx_nak			0xDD13
+#define	reg_ep4_tx_nak_pos 5
+#define	reg_ep4_tx_nak_len 1
+#define	reg_ep4_tx_nak_lsb 0
+#define    p_reg_ep5_tx_nak			0xDD13
+#define	reg_ep5_tx_nak_pos 6
+#define	reg_ep5_tx_nak_len 1
+#define	reg_ep5_tx_nak_lsb 0
+#define    p_reg_ep4_tx_len_7_0			0xDD88
+#define	reg_ep4_tx_len_7_0_pos 0
+#define	reg_ep4_tx_len_7_0_len 8
+#define	reg_ep4_tx_len_7_0_lsb 0
+#define    p_reg_ep4_tx_len_15_8		0xDD89
+#define	reg_ep4_tx_len_15_8_pos 0
+#define	reg_ep4_tx_len_15_8_len 8
+#define	reg_ep4_tx_len_15_8_lsb 8
+#define    p_reg_ep5_tx_len_7_0			0xDD8A
+#define	reg_ep5_tx_len_7_0_pos 0
+#define	reg_ep5_tx_len_7_0_len 8
+#define	reg_ep5_tx_len_7_0_lsb 0
+#define    p_reg_ep5_tx_len_15_8		0xDD8B
+#define	reg_ep5_tx_len_15_8_pos 0
+#define	reg_ep5_tx_len_15_8_len 8
+#define	reg_ep5_tx_len_15_8_lsb 8
+#define    r_reg_aagc_rf_gain			0xCFFF
+#define	reg_aagc_rf_gain_pos 0
+#define	reg_aagc_rf_gain_len 8
+#define	reg_aagc_rf_gain_lsb 0
+#define    r_reg_aagc_if_gain			0xCFFF
+#define	reg_aagc_if_gain_pos 0
+#define	reg_aagc_if_gain_len 8
+#define	reg_aagc_if_gain_lsb 0
+#define    p_reg_top_clkoen			0xCFFF
+#define reg_top_clkoen_pos 0
+#define reg_top_clkoen_len 1
+#define reg_top_clkoen_lsb 0
+#define    p_reg_top_hosta_mpeg_ser_mode	0xCFFF
+#define reg_top_hosta_mpeg_ser_mode_pos 0
+#define reg_top_hosta_mpeg_ser_mode_len 1
+#define reg_top_hosta_mpeg_ser_mode_lsb 0
+#define    p_reg_top_hosta_mpeg_par_mode	0xCFFF
+#define reg_top_hosta_mpeg_par_mode_pos 0
+#define reg_top_hosta_mpeg_par_mode_len 1
+#define reg_top_hosta_mpeg_par_mode_lsb 0
+#define    p_reg_top_hosta_dca_upper		0xCFFF
+#define reg_top_hosta_dca_upper_pos 0
+#define reg_top_hosta_dca_upper_len 1
+#define reg_top_hosta_dca_upper_lsb 0
+#define    p_reg_top_hosta_dca_lower		0xCFFF
+#define reg_top_hosta_dca_lower_pos 0
+#define reg_top_hosta_dca_lower_len 1
+#define reg_top_hosta_dca_lower_lsb 0
+
+/*
+ * IT9135 variable defines
+ */
+/* ----- LL variables ----- */
+#define OVA_BASE			0x4C00	/* omega variable address base */
+#define OVA_LINK_VERSION		(OVA_BASE-4)	/* 4 bytes */
+#define OVA_LINK_VERSION_31_24		(OVA_LINK_VERSION+0)
+#define OVA_LINK_VERSION_23_16		(OVA_LINK_VERSION+1)
+#define OVA_LINK_VERSION_15_8		(OVA_LINK_VERSION+2)
+#define OVA_LINK_VERSION_7_0		(OVA_LINK_VERSION+3)
+#define OVA_SECOND_DEMOD_I2C_ADDR	(OVA_BASE-5)
+#define OVA_EEPROM_CFG			(OVA_BASE-620)	/* 256 bytes */
+#define OVA_IR_TABLE_ADDR		(OVA_BASE-363)	/* 2 bytes pointer point to IR_TABLE */
+#define OVA_IR_TABLE_ADDR_15_18		(OVA_IR_TABLE_ADDR+0)
+#define OVA_IR_TABLE_ADDR_7_0		(OVA_IR_TABLE_ADDR+1)
+
+/* For API variable name, not use in firmware */
+#define second_i2c_address		OVA_SECOND_DEMOD_I2C_ADDR
+#define ir_table_start_15_8		OVA_IR_TABLE_ADDR_15_18
+#define ir_table_start_7_0		OVA_IR_TABLE_ADDR_7_0
+#define prechip_version_7_0		0x384F
+#define chip_version_7_0		0x1222
+#define link_version_31_24		OVA_LINK_VERSION_31_24
+#define link_version_23_16		OVA_LINK_VERSION_23_16
+#define link_version_15_8		OVA_LINK_VERSION_15_8
+#define link_version_7_0		OVA_LINK_VERSION_7_0
+
+/* ----- OFDM variables ----- */
+/* 2k */
+#define var_addr_base			0x418b
+#define log_addr_base			0x418d
+#define log_data_base			0x418f
+#define LowerLocalRetra			0x43bb
+
+#define trigger_ofsm			0x0000
+#define cfoe_NS_2048_coeff1_25_24	0x0001
+#define cfoe_NS_2048_coeff1_23_16	0x0002
+#define cfoe_NS_2048_coeff1_15_8	0x0003
+#define cfoe_NS_2048_coeff1_7_0		0x0004
+#define cfoe_NS_2k_coeff2_24		0x0005
+#define cfoe_NS_2k_coeff2_23_16		0x0006
+#define cfoe_NS_2k_coeff2_15_8		0x0007
+#define cfoe_NS_2k_coeff2_7_0		0x0008
+
+/* 8k */
+#define cfoe_NS_8191_coeff1_25_24	0x0009
+#define cfoe_NS_8191_coeff1_23_16	0x000a
+#define cfoe_NS_8191_coeff1_15_8	0x000b
+#define cfoe_NS_8191_coeff1_7_0		0x000c
+#define cfoe_NS_8192_coeff1_25_24	0x000d
+#define cfoe_NS_8192_coeff1_23_16	0x000e
+#define cfoe_NS_8192_coeff1_15_8	0x000f
+#define cfoe_NS_8192_coeff1_7_0		0x0010
+#define cfoe_NS_8193_coeff1_25_24	0x0011
+#define cfoe_NS_8193_coeff1_23_16	0x0012
+#define cfoe_NS_8193_coeff1_15_8	0x0013
+#define cfoe_NS_8193_coeff1_7_0		0x0014
+
+#define cfoe_NS_8k_coeff2_24		0x0015
+#define cfoe_NS_8k_coeff2_23_16		0x0016
+#define cfoe_NS_8k_coeff2_15_8		0x0017
+#define cfoe_NS_8k_coeff2_7_0		0x0018
+
+/* 4k */
+#define cfoe_NS_4096_coeff1_25_24	0x0019
+#define cfoe_NS_4096_coeff1_23_16	0x001a
+#define cfoe_NS_4096_coeff1_15_8	0x001b
+#define cfoe_NS_4096_coeff1_7_0		0x001c
+#define cfoe_NS_4k_coeff2_24		0x001d
+#define cfoe_NS_4k_coeff2_23_16		0x001e
+#define cfoe_NS_4k_coeff2_15_8		0x001f
+#define cfoe_NS_4k_coeff2_7_0		0x0020
+
+#define bfsfcw_fftindex_ratio_7_0	0x0021
+#define bfsfcw_fftindex_ratio_15_8	0x0022
+#define fftindex_bfsfcw_ratio_7_0	0x0023
+#define fftindex_bfsfcw_ratio_15_8	0x0024
+
+#define crystal_clk_7_0			0x0025
+#define crystal_clk_15_8		0x0026
+#define crystal_clk_23_16		0x0027
+#define crystal_clk_31_24		0x0028
+
+#define bfs_fcw_7_0			0x0029
+#define bfs_fcw_15_8			0x002a
+#define bfs_fcw_22_16			0x002b
+
+#define rsd_abort_packet_cnt_7_0	0x0032
+#define rsd_abort_packet_cnt_15_8	0x0033
+#define rsd_bit_err_cnt_7_0		0x0034
+#define rsd_bit_err_cnt_15_8		0x0035
+#define rsd_bit_err_cnt_23_16		0x0036
+#define r_rsd_packet_unit_7_0		0x0037
+#define r_rsd_packet_unit_15_8		0x0038
+
+#define tpsd_lock			0x003c
+#define mpeg_lock			0x003d
+
+#define Training_Mode			0x0040
+
+#define adcx2				0x0045
+
+#define empty_channel_status		0x0047
+#define signal_quality			0x0049
+
+#define FreBand				0x004b
+#define suspend_flag			0x004c
+
+#define var_p_inband			0x00f7
+
+#define var_pre_lo_freq_7_0		0x011e
+#define var_pre_lo_freq_15_8		0x011f
+#define var_pre_lna_cap_sel		0x0120
+
+#define ofdm_version_31_24		0x4191
+#define ofdm_version_23_16		0x4192
+#define ofdm_version_15_8		0x4193
+#define ofdm_version_7_0		0x4194
+
+/*
+ * Error code
+ */
+enum it9135_err_code {
+	ERROR_NO_ERROR = 0x00000000ul,
+	ERROR_RESET_TIMEOUT = 0x00000001ul,
+	ERROR_WRITE_REG_TIMEOUT = 0x00000002ul,
+	ERROR_WRITE_TUNER_TIMEOUT = 0x00000003ul,
+	ERROR_WRITE_TUNER_FAIL = 0x00000004ul,
+	ERROR_RSD_COUNTER_NOT_READY = 0x00000005ul,
+	ERROR_VTB_COUNTER_NOT_READY = 0x00000006ul,
+	ERROR_FEC_MON_NOT_ENABLED = 0x00000007ul,
+	ERROR_INVALID_DEV_TYPE = 0x00000008ul,
+	ERROR_INVALID_TUNER_TYPE = 0x00000009ul,
+	ERROR_OPEN_FILE_FAIL = 0x0000000Aul,
+	ERROR_WRITEFILE_FAIL = 0x0000000Bul,
+	ERROR_READFILE_FAIL = 0x0000000Cul,
+	ERROR_CREATEFILE_FAIL = 0x0000000Dul,
+	ERROR_MALLOC_FAIL = 0x0000000Eul,
+	ERROR_INVALID_FILE_SIZE = 0x0000000Ful,
+	ERROR_INVALID_READ_SIZE = 0x00000010ul,
+	ERROR_LOAD_FW_DONE_BUT_FAIL = 0x00000011ul,
+	ERROR_NOT_IMPLEMENTED = 0x00000012ul,
+	ERROR_NOT_SUPPORT = 0x00000013ul,
+	ERROR_WRITE_MBX_TUNER_TIMEOUT = 0x00000014ul,
+	ERROR_DIV_MORE_THAN_8_CHIPS = 0x00000015ul,
+	ERROR_DIV_NO_CHIPS = 0x00000016ul,
+	ERROR_SUPER_FRAME_CNT_0 = 0x00000017ul,
+	ERROR_INVALID_FFT_MODE = 0x00000018ul,
+	ERROR_INVALID_CONSTELLATION_MODE = 0x00000019ul,
+	ERROR_RSD_PKT_CNT_0 = 0x0000001Aul,
+	ERROR_FFT_SHIFT_TIMEOUT = 0x0000001Bul,
+	ERROR_WAIT_TPS_TIMEOUT = 0x0000001Cul,
+	ERROR_INVALID_BW = 0x0000001Dul,
+	ERROR_INVALID_BUF_LEN = 0x0000001Eul,
+	ERROR_NULL_PTR = 0x0000001Ful,
+	ERROR_INVALID_AGC_VOLT = 0x00000020ul,
+	ERROR_MT_OPEN_FAIL = 0x00000021ul,
+	ERROR_MT_TUNE_FAIL = 0x00000022ul,
+	ERROR_CMD_NOT_SUPPORTED = 0x00000023ul,
+	ERROR_CE_NOT_READY = 0x00000024ul,
+	ERROR_EMBX_INT_NOT_CLEARED = 0x00000025ul,
+	ERROR_INV_PULLUP_VOLT = 0x00000026ul,
+	ERROR_FREQ_OUT_OF_RANGE = 0x00000027ul,
+	ERROR_INDEX_OUT_OF_RANGE = 0x00000028ul,
+	ERROR_NULL_SETTUNER_PTR = 0x00000029ul,
+	ERROR_NULL_INITSCRIPT_PTR = 0x0000002Aul,
+	ERROR_INVALID_INITSCRIPT_LEN = 0x0000002Bul,
+	ERROR_INVALID_POS = 0x0000002Cul,
+	ERROR_BACK_TO_BOOTCODE_FAIL = 0x0000002Dul,
+	ERROR_GET_BUFFER_VALUE_FAIL = 0x0000002Eul,
+	ERROR_INVALID_REG_VALUE = 0x0000002Ful,
+	ERROR_INVALID_INDEX = 0x00000030ul,
+	ERROR_READ_TUNER_TIMEOUT = 0x00000031ul,
+	ERROR_READ_TUNER_FAIL = 0x00000032ul,
+	ERROR_UNDEFINED_SAW_BW = 0x00000033ul,
+	ERROR_MT_NOT_AVAILABLE = 0x00000034ul,
+	ERROR_NO_SUCH_TABLE = 0x00000035ul,
+	ERROR_WRONG_CHECKSUM = 0x00000036ul,
+	ERROR_INVALID_XTAL_FREQ = 0x00000037ul,
+	ERROR_COUNTER_NOT_AVAILABLE = 0x00000038ul,
+	ERROR_INVALID_DATA_LENGTH = 0x00000039ul,
+	ERROR_BOOT_FAIL = 0x0000003Aul,
+	ERROR_BUFFER_INSUFFICIENT = 0x0000003Bul,
+	ERROR_NOT_READY = 0x0000003Cul,
+	ERROR_DRIVER_INVALID = 0x0000003Dul,
+	ERROR_INTERFACE_FAIL = 0x0000003Eul,
+	ERROR_PID_FILTER_FULL = 0x0000003Ful,
+	ERROR_OPERATION_TIMEOUT = 0x00000040ul,
+	ERROR_LOADFIRMWARE_SKIPPED = 0x00000041ul,
+	ERROR_REBOOT_FAIL = 0x00000042ul,
+	ERROR_PROTOCOL_FORMAT_INVALID = 0x00000043ul,
+	ERROR_ACTIVESYNC_ERROR = 0x00000044ul,
+	ERROR_CE_READWRITEBUS_ERROR = 0x00000045ul,
+	ERROR_CE_NODATA_ERROR = 0x00000046ul,
+	ERROR_NULL_FW_SCRIPT = 0x00000047ul,
+	ERROR_NULL_TUNER_SCRIPT = 0x00000048ul,
+	ERROR_INVALID_CHIP_TYPE = 0x00000049ul,
+	ERROR_TUNER_TYPE_NOT_COMPATIBLE = 0x0000004Aul,
+	/* Error Code of Gemini System */
+	ERROR_INVALID_INDICATOR_TYPE = 0x00000101ul,
+	ERROR_INVALID_SC_NUMBER = 0x00000102ul,
+	ERROR_INVALID_SC_INFO = 0x00000103ul,
+	ERROR_FIGBYPASS_FAIL = 0x00000104ul,
+	/* Error Code of Firmware */
+	ERROR_FIRMWARE_STATUS = 0x01000000ul,
+	/* Error Code of I2C Module */
+	ERROR_I2C_DATA_HIGH_FAIL = 0x02001000ul,
+	ERROR_I2C_CLK_HIGH_FAIL = 0x02002000ul,
+	ERROR_I2C_WRITE_NO_ACK = 0x02003000ul,
+	ERROR_I2C_DATA_LOW_FAIL = 0x02004000ul,
+	/* Error Code of USB Module */
+	ERROR_USB_NULL_HANDLE = 0x03010001ul,
+	ERROR_USB_WRITEFILE_FAIL = 0x03000002ul,
+	ERROR_USB_READFILE_FAIL = 0x03000003ul,
+	ERROR_USB_INVALID_READ_SIZE = 0x03000004ul,
+	ERROR_USB_INVALID_STATUS = 0x03000005ul,
+	ERROR_USB_INVALID_SN = 0x03000006ul,
+	ERROR_USB_INVALID_PKT_SIZE = 0x03000007ul,
+	ERROR_USB_INVALID_HEADER = 0x03000008ul,
+	ERROR_USB_NO_IR_PKT = 0x03000009ul,
+	ERROR_USB_INVALID_IR_PKT = 0x0300000Aul,
+	ERROR_USB_INVALID_DATA_LEN = 0x0300000Bul,
+	ERROR_USB_EP4_READFILE_FAIL = 0x0300000Cul,
+	ERROR_USB_EP$_INVALID_READ_SIZE = 0x0300000Dul,
+	ERROR_USB_BOOT_INVALID_PKT_TYPE = 0x0300000Eul,
+	ERROR_USB_BOOT_BAD_CONFIG_HEADER = 0x0300000Ful,
+	ERROR_USB_BOOT_BAD_CONFIG_SIZE = 0x03000010ul,
+	ERROR_USB_BOOT_BAD_CONFIG_SN = 0x03000011ul,
+	ERROR_USB_BOOT_BAD_CONFIG_SUBTYPE = 0x03000012ul,
+	ERROR_USB_BOOT_BAD_CONFIG_VALUE = 0x03000013ul,
+	ERROR_USB_BOOT_BAD_CONFIG_CHKSUM = 0x03000014ul,
+	ERROR_USB_BOOT_BAD_CONFIRM_HEADER = 0x03000015ul,
+	ERROR_USB_BOOT_BAD_CONFIRM_SIZE = 0x03000016ul,
+	ERROR_USB_BOOT_BAD_CONFIRM_SN = 0x03000017ul,
+	ERROR_USB_BOOT_BAD_CONFIRM_SUBTYPE = 0x03000018ul,
+	ERROR_USB_BOOT_BAD_CONFIRM_VALUE = 0x03000019ul,
+	ERROR_USB_BOOT_BAD_CONFIRM_CHKSUM = 0x03000020ul,
+	ERROR_USB_BOOT_BAD_BOOT_HEADER = 0x03000021ul,
+	ERROR_USB_BOOT_BAD_BOOT_SIZE = 0x03000022ul,
+	ERROR_USB_BOOT_BAD_BOOT_SN = 0x03000023ul,
+	ERROR_USB_BOOT_BAD_BOOT_PATTERN_01 = 0x03000024ul,
+	ERROR_USB_BOOT_BAD_BOOT_PATTERN_10 = 0x03000025ul,
+	ERROR_USB_BOOT_BAD_BOOT_CHKSUM = 0x03000026ul,
+	ERROR_USB_INVALID_BOOT_PKT_TYPE = 0x03000027ul,
+	ERROR_USB_BOOT_BAD_CONFIG_VAlUE = 0x03000028ul,
+	ERROR_USB_COINITIALIZEEX_FAIL = 0x03000029ul,
+	ERROR_USB_COCREATEINSTANCE_FAIL = 0x0300003Aul,
+	ERROR_USB_COCREATCLSEENUMERATOR_FAIL = 0x0300002Bul,
+	ERROR_USB_QUERY_INTERFACE_FAIL = 0x0300002Cul,
+	ERROR_USB_PKSCTRL_NULL = 0x0300002Dul,
+	ERROR_USB_INVALID_REGMODE = 0x0300002Eul,
+	ERROR_USB_INVALID_REG_COUNT = 0x0300002Ful,
+	ERROR_USB_INVALID_HANDLE = 0x03000100ul,
+	ERROR_USB_WRITE_FAIL = 0x03000200ul,
+	ERROR_USB_UNEXPECTED_WRITE_LEN = 0x03000300ul,
+	ERROR_USB_READ_FAIL = 0x03000400ul,
+	/* Error code of Omega */
+	ERROR_TUNER_INIT_FAIL = 0x05000000ul
+};
+
+enum it9135_tuner_id {
+	/* 0x50~0x5f reserved for OMEGA use */
+	IT9135_TUNER_ID = 0x38,
+	IT9135_TUNER_ID_LNA_CONFIG1 = 0x51,
+	IT9135_TUNER_ID_LNA_CONFIG2 = 0x52,
+	/* 0x60~0x6f reserved for OMEGA V2 use */
+	IT9135_TUNER_ID_V2 = 0x60,
+	IT9135_TUNER_ID_V2_LNA_CONFIG1 = 0x61,
+	IT9135_TUNER_ID_V2_LNA_CONFIG2 = 0x62
+};
+
+enum it9135_tuner_lna {
+	OMEGA_NORMAL = 0x00,
+	OMEGA_LNA_CONFIG1 = 0x01,
+	OMEGA_LNA_CONFIG2 = 0x02,
+};
+
+struct it9135_val_set {
+	unsigned long address;	/* The address of target register */
+	unsigned char value;	/* The value of target register   */
+};
+
+struct it9135_tuner_desc {
+	struct it9135_val_set *scripts;
+	unsigned short *script_sets;
+	unsigned short id;
+};
+
+/*
+ * The type defination of clock table.
+ */
+struct it9135_freq_clk {
+	unsigned long crystal_Freq;	/* The frequency of crystal. */
+	unsigned long adc_freq;	/* The frequency of ADC.     */
+};
+
+#define IT9135_MAX_PKT_SIZE	255
+
+/* Define commands */
+enum it9135_cmd {
+	CMD_REG_DEMOD_READ = 0x0000,
+	CMD_REG_DEMOD_WRITE = 0x0001,
+	CMD_REG_EEPROM_READ = 0x0004,
+	CMD_REG_EEPROM_WRITE = 0x0005,
+	CMD_IR_GET = 0x0018,
+	CMD_FW_DOWNLOAD = 0x0021,
+	CMD_QUERYINFO = 0x0022,
+	CMD_BOOT = 0x0023,
+	CMD_REBOOT = 0x0023,
+	CMD_FW_DOWNLOAD_BEGIN = 0x0024,
+	CMD_FW_DOWNLOAD_END = 0x0025,
+	CMD_SCATTER_WRITE = 0x0029,
+	CMD_GENERIC_READ = 0x002A,
+	CMD_GENERIC_WRITE = 0x002B
+};
+
+#define it9135_build_command(command, processor, chip) \
+		(command + (unsigned short) (processor << 12) + (unsigned short) (chip << 12))
+
+/*
+ * The type defination of channel Statistic.
+ */
+struct it9135_ch_statistic {
+	unsigned short abort_cnt;
+	unsigned long post_vitbit_cnt;
+	unsigned long post_vit_err_cnt;
+};
+
+/*
+ * The type defination of Segment
+ */
+struct it9135_segment {
+	unsigned char type;	/* 0:Firmware download 1:Rom copy 2:Direct command */
+	unsigned long length;
+};
+
+/*
+ * The type defination of TransmissionMode.
+ */
+enum it9135_transmission_modes {
+	TransmissionMode_2K = 0,	/* OFDM frame consists of 2048 different carriers (2K FFT mode) */
+	TransmissionMode_8K,	/* OFDM frame consists of 8192 different carriers (8K FFT mode) */
+	TransmissionMode_4K	/* OFDM frame consists of 4096 different carriers (4K FFT mode) */
+};
+
+/*
+ * The type defination of Priority.
+ */
+enum it9135_priority {
+	PRIORITY_HIGH = 0,	/* DVB-T and DVB-H - identifies high-priority stream */
+	PRIORITY_LOW		/* DVB-T and DVB-H - identifies low-priority stream  */
+};
+
+/*
+ * The type defination of CodeRate.
+ */
+enum it9135_code_rate {
+	CodeRate_1_OVER_2 = 0,	/* Signal uses FEC coding ratio of 1/2 */
+	CodeRate_2_OVER_3,	/* Signal uses FEC coding ratio of 2/3 */
+	CodeRate_3_OVER_4,	/* Signal uses FEC coding ratio of 3/4 */
+	CodeRate_5_OVER_6,	/* Signal uses FEC coding ratio of 5/6 */
+	CodeRate_7_OVER_8,	/* Signal uses FEC coding ratio of 7/8 */
+	CodeRate_NONE		/* None, NXT doesn't have this one     */
+};
+
+/*
+ * TPS Hierarchy and Alpha value.
+ */
+enum it9135_hierarchy {
+	Hierarchy_NONE = 0,	/* Signal is non-hierarchical        */
+	Hierarchy_ALPHA_1,	/* Signalling format uses alpha of 1 */
+	Hierarchy_ALPHA_2,	/* Signalling format uses alpha of 2 */
+	Hierarchy_ALPHA_4	/* Signalling format uses alpha of 4 */
+};
+
+/*
+ * The type defination of Multiplier.
+ */
+enum it9135_multiplier {
+	Multiplier_1X = 0,
+	Multiplier_2X
+};
+
+/*
+ * The type defination of StreamType.
+ */
+enum it9135_stream_type {
+	STREAM_TYPE_NONE = 0,	/* Invalid (Null) StreamType                */
+	STREAM_TYPE_DVBT_DATAGRAM = 3,	/* DVB-T mode, store data in device buffer  */
+	STREAM_TYPE_DVBT_PARALLEL,	/* DVB-T mode, output via paralle interface */
+	STREAM_TYPE_DVBT_SERIAL,	/* DVB-T mode, output via serial interface  */
+};
+
+/*
+ * The type defination of Architecture.
+ */
+enum it9135_architecture {
+	ARCHITECTURE_NONE = 0,	/* Inavalid (Null) Architecture.                                    */
+	ARCHITECTURE_DCA,	/* Diversity combine architecture. Only valid when chip number > 1. */
+	ARCHITECTURE_PIP	/* Picture in picture. Only valid when chip number > 1.             */
+};
+
+/*
+ * The type defination of processor.
+ */
+enum it9135_processor {
+	PROCESSOR_LINK = 0,
+	PROCESSOR_OFDM = 8
+};
+
+/*
+ * The type defination of Constellation.
+ */
+enum Constellation {
+	CONSTELLATION_QPSK = 0,	/* Signal uses QPSK constellation  */
+	CONSTELLATION_16QAM,	/* Signal uses 16QAM constellation */
+	CONSTELLATION_64QAM	/* Signal uses 64QAM constellation */
+};
+
+/*
+ * The defination of ChannelModulation.
+ */
+struct it9135_ch_modulation {
+	unsigned long frequency;	/* Channel frequency in KHz.                                */
+	unsigned char trans_mode;	/* Number of carriers used for OFDM signal                  */
+	unsigned char constellation;	/* Constellation scheme (FFT mode) in use           */
+	unsigned char interval;	/* Fraction of symbol length used as guard (Guard Interval) */
+	unsigned char priority;	/* The priority of stream                                   */
+	unsigned char h_code_rate;	/* FEC coding ratio of high-priority stream                 */
+	unsigned char l_code_rate;	/* FEC coding ratio of low-priority stream                  */
+	unsigned char hierarchy;	/* Hierarchy levels of OFDM signal                          */
+	unsigned char bandwidth;
+};
+
+/*
+ * The type defination of Statistic.
+ */
+struct it9135_statistic {
+	int presented;		/* Signal is presented.                           */
+	int locked;		/* Signal is locked.                              */
+	unsigned char quality;	/* Signal quality, from 0 (poor) to 100 (good).   */
+	unsigned char strength;	/* Signal strength from 0 (weak) to 100 (strong). */
+};
+
+/*
+ * The type defination of PidTable
+ */
+struct it9135_pid_tab {
+	unsigned short pid[32];
+};
+
+struct it9135_pid_info {
+	struct it9135_pid_tab pid_tab[2];
+	unsigned char pid_cnt;
+	int pid_init;
+};
+
+/*
+ * The data structure of IT9135
+ */
+struct it9135_data {
+	/* Basic structure */
+	void *driver;
+
+/* Bus types */
+#define IT9135_BUS_USB20	2
+#define IT9135_BUS_USB11           5
+	unsigned short busId;
+
+	unsigned short tuner_id;
+	struct it9135_tuner_desc tuner_desc;
+
+	unsigned char *fw_codes;
+	struct it9135_segment *fw_segs;	/* FW seqments */
+	unsigned char fw_parts;	/* FW partitions */
+	unsigned short *script_sets;
+	struct it9135_val_set *scripts;
+	unsigned short *tuner_script_sets;
+	struct it9135_val_set *tuner_scripts;
+
+	const struct firmware *it9135_fw;
+	unsigned char chip_ver;
+	unsigned long chip_type;
+	unsigned char chip_num;
+	unsigned char streamType;
+	unsigned char architecture;
+	unsigned long crystal_Freq;
+	unsigned long adc_freq;
+	unsigned short bandwidth[2];
+	unsigned long frequency[2];
+	unsigned long fcw;
+	struct it9135_statistic statistic[2];
+	struct it9135_ch_statistic ch_statistic[2];	/* releaseExternalRemove */
+	unsigned char host_if[2];	/* Host Interface */
+	unsigned char cmd_seq;	/* command sequence */
+	struct it9135_pid_info pid_info;
+	unsigned char pre_sqi;
+
+	int booted;
+	int inited;
+
+	unsigned char clock_mode;
+	unsigned int fxtal_khz;
+	unsigned int fdiv;
+
+	/* for linux kernel driver */
+	struct it9135_val_set *tuner_script_normal;
+	unsigned short tuner_script_sets_normal;
+	struct it9135_val_set *tuner_script_lna1;
+	unsigned short tuner_script_sets_lna1;
+	struct it9135_val_set *tuner_script_lna2;
+	unsigned short tuner_script_sets_lna2;
+};
+
+#define REG_MASK(mask, pos, len)		(mask[len-1] << pos)
+#define REG_CLEAR(mask, temp, pos, len)		(temp & (~REG_MASK(mask, pos, len)))
+#define REG_CREATE(mask, val, temp, pos, len)	((val << pos) | (REG_CLEAR(mask, temp, pos, len)))
+#define REG_GET(mask, value, pos, len)		((value & REG_MASK(mask, pos, len)) >> pos)
+#define LOWBYTE(w)				((unsigned char)((w) & 0xff))
+#define HIGHBYTE(w)				((unsigned char)((w >> 8) & 0xff))
+
+struct it9135_coeff_param {
+	unsigned long adc_freq;
+	unsigned short bandwidth;
+	unsigned long coeff1_2048Nu;
+	unsigned long coeff1_4096Nu;
+	unsigned long coeff1_8191Nu;
+	unsigned long coeff1_8192Nu;
+	unsigned long coeff1_8193Nu;
+	unsigned long coeff2_2k;
+	unsigned long coeff2_4k;
+	unsigned long coeff2_8k;
+	unsigned short bfsfcw_fftindex_ratio;
+	unsigned short fftindex_bfsfcw_ratio;
+};
+
+/*
+ * Write one unsigned char (8 bits) to a specific register in IT9135.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param processor: The processor of specified register. Because each chip
+ *        has two processor so user have to specify the processor. The
+ *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
+ * @param reg_addr: the address of the register to be written.
+ * @param value: the value to be written.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_write_reg(struct it9135_data *data, unsigned char chip,
+			       unsigned char processor, unsigned long reg_addr,
+			       unsigned char value);
+
+/*
+ * Write a sequence of unsigned chars to the contiguous registers in IT9135.
+ * The maximum burst size is restricted by the capacity of bus. If bus
+ * could transfer N unsigned chars in one cycle, then the maximum value of
+ * post_err_cnt would be N - 5.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param processor: The processor of specified register. Because each chip
+ *        has two processor so user have to specify the processor. The
+ *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
+ * @param reg_addr: the start address of the registers to be written.
+ * @param post_err_cnt: the number of registers to be written.
+ * @param buffer: a unsigned char array which is used to store values to be written.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_write_regs(struct it9135_data *data, unsigned char chip,
+				unsigned char processor, unsigned long reg_addr,
+				unsigned long w_buff_len,
+				unsigned char *w_buff);
+
+/*
+ * Write a sequence of unsigned chars to the contiguous registers in slave device
+ * through specified interface (1, 2, 3).
+ * The maximum burst size is restricted by the capacity of bus. If bus
+ * could transfer N unsigned chars in one cycle, then the maximum value of
+ * post_err_cnt would be N - 6 (one more unsigned char to specify tuner address).
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param interfaceIndex: the index of interface. The possible values are 1~3.
+ * @param slaveAddress: the I2c address of slave device.
+ * @param post_err_cnt: the number of registers to be read.
+ * @param buffer: a unsigned char array which is used to store values to be read.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_write_gen_regs(struct it9135_data *data,
+				    unsigned char chip,
+				    unsigned char interfaceIndex,
+				    unsigned char slaveAddress,
+				    unsigned char post_err_cnt,
+				    unsigned char *buffer);
+
+/*
+ * Write a sequence of unsigned chars to the contiguous cells in the EEPROM.
+ * The maximum burst size is restricted by the capacity of bus. If bus
+ * could transfer N unsigned chars in one cycle, then the maximum value of
+ * post_err_cnt would be N - 5 (firmware will detect EEPROM address).
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param reg_addr: the start address of the cells to be written.
+ * @param post_err_cnt: the number of cells to be written.
+ * @param buffer: a unsigned char array which is used to store values to be written.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_write_ee_vals(struct it9135_data *data, unsigned char chip,
+				   unsigned short reg_addr,
+				   unsigned char w_buff_len,
+				   unsigned char *w_buff);
+
+/*
+ * Modify bits in the specific register.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param processor: The processor of specified register. Because each chip
+ *        has two processor so user have to specify the processor. The
+ *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
+ * @param reg_addr: the address of the register to be written.
+ * @param position: the start position of bits to be modified (0 means the
+ *        LSB of the specifyed register).
+ * @param length: the length of bits.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_write_reg_bits(struct it9135_data *data,
+				    unsigned char chip, unsigned char processor,
+				    unsigned long reg_addr,
+				    unsigned char position,
+				    unsigned char length, unsigned char value);
+
+/*
+ * Read one unsigned char (8 bits) from a specific register in IT9135.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param processor: The processor of specified register. Because each chip
+ *        has two processor so user have to specify the processor. The
+ *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
+ * @param reg_addr: the address of the register to be read.
+ * @param value: the pointer used to store the value read from IT9135 register.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_read_reg(struct it9135_data *data, unsigned char chip,
+			      unsigned char processor, unsigned long reg_addr,
+			      unsigned char *value);
+
+/*
+ * Read a sequence of unsigned chars from the contiguous registers in IT9135.
+ * The maximum burst size is restricted by the capacity of bus. If bus
+ * could transfer N unsigned chars in one cycle, then the maximum value of
+ * post_err_cnt would be N - 5.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param processor: The processor of specified register. Because each chip
+ *        has two processor so user have to specify the processor. The
+ *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
+ * @param reg_addr: the address of the register to be read.
+ * @param post_err_cnt: the number of registers to be read.
+ * @param buffer: a unsigned char array which is used to store values to be read.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_read_regs(struct it9135_data *data, unsigned char chip,
+			       unsigned char processor, unsigned long reg_addr,
+			       unsigned long r_buff_len, unsigned char *r_buff);
+
+/*
+ * Read a sequence of unsigned chars from the contiguous registers in slave device
+ * through specified interface (1, 2, 3).
+ * The maximum burst size is restricted by the capacity of bus. If bus
+ * could transfer N unsigned chars in one cycle, then the maximum value of
+ * post_err_cnt would be N - 6 (one more unsigned char to specify tuner address).
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param interfaceIndex: the index of interface. The possible values are 1~3.
+ * @param slaveAddress: the I2c address of slave device.
+ * @param post_err_cnt: the number of registers to be read.
+ * @param buffer: a unsigned char array which is used to store values to be read.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_read_gen_regs(struct it9135_data *data,
+				   unsigned char chip,
+				   unsigned char interfaceIndex,
+				   unsigned char slaveAddress,
+				   unsigned char post_err_cnt,
+				   unsigned char *buffer);
+
+/*
+ * Read a sequence of unsigned chars from the contiguous cells in the EEPROM.
+ * The maximum burst size is restricted by the capacity of bus. If bus
+ * could transfer N unsigned chars in one cycle, then the maximum value of
+ * post_err_cnt would be N - 5 (firmware will detect EEPROM address).
+ *
+ * @param struct it9135_data the handle of IT9135.
+ * @param chip The index of IT9135. The possible values are 0~7.
+ * @param reg_addr the start address of the cells to be read.
+ * @param registerAddressLength the valid unsigned chars of reg_addr.
+ * @param post_err_cnt the number of cells to be read.
+ * @param buffer a unsigned char array which is used to store values to be read.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_read_ee_vals(struct it9135_data *data, unsigned char chip,
+				  unsigned short reg_addr,
+				  unsigned char r_buff_len,
+				  unsigned char *r_buff);
+
+/*
+ * Read bits of the specified register.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param processor: The processor of specified register. Because each chip
+ *        has two processor so user have to specify the processor. The
+ *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
+ * @param reg_addr: the address of the register to be read.
+ * @param position: the start position of bits to be read (0 means the
+ *        LSB of the specifyed register).
+ * @param length: the length of bits.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_read_reg_bits(struct it9135_data *data,
+				   unsigned char chip, unsigned char processor,
+				   unsigned long reg_addr,
+				   unsigned char position, unsigned char length,
+				   unsigned char *value);
+
+/*
+ * Get the version of firmware.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param version: the version of firmware.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_get_fw_ver(struct it9135_data *data,
+				unsigned char processor,
+				unsigned long *version);
+
+/*
+ * Get siganl strength Indication.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ *        NOTE: When the architecture is set to ARCHITECTURE_DCA
+ *        this parameter is regard as don't care.
+ * @param strength: The value of signal strength that calculations of "score mapping" from the signal strength (dBm) to the "0-100" scoring.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_get_strength(struct it9135_data *data, unsigned char chip,
+				  unsigned char *strength);
+
+/*
+ * Get signal strength in dbm
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param rfpullUpVolt_X10: the pullup voltag of RF multiply 10.
+ * @param ifpullUpVolt_X10: the pullup voltag of IF multiply 10.
+ * @param strengthDbm: The value of signal strength in DBm.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_get_strength_dbm(struct it9135_data *data,
+				      unsigned char chip, long *strength_dbm);
+
+/*
+ * Load the IR table for USB device.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param tab_len: The length of IR table.
+ * @param table: The content of IR table.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_load_ir_tab(struct it9135_data *data,
+				 unsigned short tab_len, unsigned char *table);
+
+/*
+ * First, download firmware from host to IT9135. Actually, firmware is
+ * put in firmware.h as a part of source code. Therefore, in order to
+ * update firmware the host have to re-compile the source code.
+ * Second, setting all parameters which will be need at the beginning.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip_num: The total number of IT9135s.
+ * @param saw_band: SAW filter bandwidth in MHz. The possible values
+ *        are 6000, 7000, and 8000 (KHz).
+ * @param streamType: The format of output stream.
+ * @param architecture: the architecture of IT9135.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_dev_init(struct it9135_data *data, unsigned char chip_num,
+			      unsigned short saw_band, unsigned char streamType,
+			      unsigned char architecture);
+
+/*
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ * @example <pre>
+ * </pre>
+ */
+unsigned long it9135_tps_locked(struct it9135_data *data, unsigned char chip,
+				int *locked);
+
+/*
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ * @example <pre>
+ * </pre>
+ */
+unsigned long it9135_mp2_locked(struct it9135_data *data, unsigned char chip,
+				int *locked);
+
+/*
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ *        NOTE: When the architecture is set to ARCHITECTURE_DCA
+ *        this parameter is regard as don't care.
+ * @param locked: the result of frequency tuning. 1 if there is
+ *        IT9135 can lock signal, 0 otherwise.
+ * @example <pre>
+ * </pre>
+ */
+unsigned long it9135_freq_locked(struct it9135_data *data, unsigned char chip,
+				 int *locked);
+
+/*
+ * Get channel modulation related information.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param ch_modul: The modulation of channel.
+ * @return ERROR_NO_ERROR: successful, other non-zero error code otherwise.
+ */
+unsigned long it9135_get_ch_modulation(struct it9135_data *data,
+				       unsigned char chip,
+				       struct it9135_ch_modulation *ch_modul);
+
+/*
+ * Specify the bandwidth of channel and tune the channel to the specific
+ * frequency. Afterwards, host could use output parameter dvbH to determine
+ * if there is a DVB-H signal.
+ * In DVB-T mode, after calling this function the output parameter dvbH
+ * should return 0 and host could use output parameter "locked" to check
+ * if the channel has correct TS output.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ *        NOTE: When the architecture is set to ARCHITECTURE_DCA
+ *        this parameter is regard as don't care.
+ * @param bandwidth: The channel bandwidth.
+ *        DVB-T: 5000, 6000, 7000, and 8000 (KHz).
+ * @param frequency: the channel frequency in KHz.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_acquire_ch(struct it9135_data *data, unsigned char chip,
+				unsigned short bandwidth,
+				unsigned long frequency);
+
+/*
+ * Set the output stream type of chip. Because the device could output in
+ * many stream type, therefore host have to choose one type before receive data.
+ *
+ * Note: Please refer to the example of Standard_acquireChannel when host want
+ *       to detect the available channels.
+ * Note: After host know all the available channels, and want to change to
+ *       specific channel, host have to choose output mode before receive
+ *       data. Please refer the example of it9135_set_stream_type.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param streamType: the possible values are
+ *        DVB-T:    STREAM_TYPE_DVBT_DATAGRAM
+ *                  STREAM_TYPE_DVBT_PARALLEL
+ *                  STREAM_TYPE_DVBT_SERIAL
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_set_stream_type(struct it9135_data *data,
+				     unsigned char streamType);
+
+/*
+ * Set the architecture of chip. When two of our device are using, they could
+ * be operated in Diversity Combine Architecture (DCA) or (PIP). Therefore,
+ * host could decide which mode to be operated.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param architecture: the possible values are
+ *        ARCHITECTURE_DCA
+ *        ARCHITECTURE_PIP
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_set_arch(struct it9135_data *data,
+			      unsigned char architecture);
+
+/*
+ * Get the statistic values of IT9135, it includes Pre-Viterbi BER,
+ * Post-Viterbi BER, Abort Count, Signal Presented Flag, Signal Locked Flag,
+ * Signal Quality, Signal Strength, Delta-T for DVB-H time slicing.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param statistic: the structure that store all statistic values.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_get_statistic(struct it9135_data *data, unsigned char chip,
+				   struct it9135_statistic *statistic);
+
+/*
+ * @param it9135_data: the handle of IT9135.
+ * @param code: the value of IR raw code, the size should be 4 or 6,
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ * @example <pre>
+ * </pre>
+ */
+unsigned long it9135_get_ir_code(struct it9135_data *data, unsigned long *code);
+
+/*
+ * Return to boot code
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ * @example <pre>
+ * </pre>
+ */
+unsigned long it9135_dev_reboot(struct it9135_data *data);
+
+/*
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param contorl: 1: Power up, 0: Power down;
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ * @example <pre>
+ * </pre>
+ */
+unsigned long it9135_ctrl_pw_saving(struct it9135_data *data,
+				    unsigned char chip, unsigned char control);
+
+/*
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param contorl: 1: Power up, 0: Power down;
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ * @example <pre>
+ * </pre>
+ */
+unsigned long it9135_ctrl_tuner_leakage(struct it9135_data *data,
+					unsigned char chip,
+					unsigned char control);
+
+/*
+ * @param it9135_data: the handle of IT9135.
+ * @param contorl: 1: Power up, 0: Power down;
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ * @example <pre>
+ * </pre>
+ */
+unsigned long it9135_ctrl_tuner_pw_saving(struct it9135_data *data,
+					  unsigned char chip,
+					  unsigned char control);
+
+/*
+ * Control PID fileter
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param contorl: 0: Disable, 1: Enable.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ * @example <pre>
+ * </pre>
+ */
+unsigned long it9135_ctrl_pid_filter(struct it9135_data *data,
+				     unsigned char chip, unsigned char control);
+
+/*
+ * Reset PID filter.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_reset_pid_filter(struct it9135_data *data,
+				      unsigned char chip);
+
+/*
+ * Add PID to PID filter.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param pid: the PID that will be add to PID filter.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_add_pid_filter(struct it9135_data *data,
+				    unsigned char chip, unsigned char index,
+				    unsigned short pid);
+
+/*
+ * get SNR .
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param snr (db).
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_get_snr(struct it9135_data *data, unsigned char chip,
+			     unsigned char *snr);
+
+/*
+ * get SNR data .
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param snr_value (hex).
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_get_snr_val(struct it9135_data *IT9135, unsigned char chip,
+				 unsigned long *snr_value);
+
+/*
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param multiplier: ADC frequency multiplier;
+ * @return ERROR_NO_ERROR: successful, other non-zero error code otherwise.
+ * @example <pre>
+ * </pre>
+ */
+unsigned long it9135_set_multiplier(struct it9135_data *data,
+				    unsigned char multiplier);
+
+/*
+ * Reset PID filter.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_reset_pid(struct it9135_data *data, unsigned char chip);
+
+/*
+ * Remove PID from PID filter by index.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param index: the index of PID filter.
+ * @param pid: the PID that will be remove from PID filter.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_remove_pid_at(struct it9135_data *data, unsigned char chip,
+				   unsigned char index, unsigned short pid);
+
+/*
+ * Get the statistic values of IT9135, it includes Pre-Viterbi BER,
+ * Post-Viterbi BER, Abort Count, Signal Presented Flag, Signal Locked Flag,
+ * Signal Quality, Signal Strength, Delta-T for DVB-H time slicing.
+ *
+ * @param struct it9135_data the handle of IT9135.
+ * @param chip The index of IT9135. The possible values are 0~7.
+ * @param statistic the structure that store all statistic values.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_get_ch_statistic(struct it9135_data *data,
+				      unsigned char chip,
+				      struct it9135_ch_statistic *ch_statistic);
+
+/*
+ * Set control bus and tuner.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param busId: The ID of bus.
+ * @param tuner_id: The ID of tuner.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_set_bus_tuner(struct it9135_data *data,
+				   unsigned short busId,
+				   unsigned short tuner_id);
+
+/*
+ * Add PID to PID filter.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param pid: the PID that will be add to PID filter.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_add_pid(struct it9135_data *data, unsigned char chip,
+			     unsigned short pid);
+
+/*
+ * Add PID to PID filter by index.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param index: the index of PID filter.
+ * @param pid: the PID that will be add to PID filter.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_add_pid_at(struct it9135_data *data, unsigned char chip,
+				unsigned char index, unsigned short pid);
+
+/*
+ * Remove PID from PID filter.
+ *
+ * @param it9135_data: the handle of IT9135.
+ * @param chip: The index of IT9135. The possible values are 0~7.
+ * @param pid: the PID that will be remove from PID filter.
+ * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
+ */
+unsigned long it9135_remove_pid(struct it9135_data *data, unsigned char chip,
+				unsigned short pid);
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/it9135.c b/drivers/media/dvb/dvb-usb/it9135.c
new file mode 100644
index 0000000..7fa21c7
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/it9135.c
@@ -0,0 +1,2492 @@
+/*
+ * DVB USB Linux driver for IT9135 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2011 ITE Technologies, INC.
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ */
+
+#include "it9135.h"
+
+int dvb_usb_it9135_debug;
+module_param_named(debug, dvb_usb_it9135_debug, int, 0644);
+MODULE_PARM_DESC(debug,
+		 "set debugging level.(func=1,info=2,warning=4)"
+		 DVB_USB_DEBUG_STATUS);
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct dvb_usb_device_properties it9135_properties[];
+
+static unsigned long it9135_drv_nim_reset(struct it9135_dev_ctx *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	deb_func("Enter %s Function\n", __func__);
+
+	/* Set AF0350 GPIOH1 to 0 to reset AF0351 */
+	error =
+	    it9135_write_reg_bits(&dev->data, 0,
+				  PROCESSOR_LINK, p_reg_top_gpioh1_en,
+				  reg_top_gpioh1_en_pos, reg_top_gpioh1_en_len,
+				  1);
+	error =
+	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
+				  p_reg_top_gpioh1_on, reg_top_gpioh1_on_pos,
+				  reg_top_gpioh1_on_len, 1);
+
+	error =
+	    it9135_write_reg_bits(&dev->data, 0,
+				  PROCESSOR_LINK, p_reg_top_gpioh1_o,
+				  reg_top_gpioh1_o_pos, reg_top_gpioh1_o_len,
+				  1);
+	mdelay(50);
+	error =
+	    it9135_write_reg_bits(&dev->data, 0,
+				  PROCESSOR_LINK, p_reg_top_gpioh1_o,
+				  reg_top_gpioh1_o_pos, reg_top_gpioh1_o_len,
+				  0);
+	mdelay(50);
+	error =
+	    it9135_write_reg_bits(&dev->data, 0,
+				  PROCESSOR_LINK, p_reg_top_gpioh1_o,
+				  reg_top_gpioh1_o_pos, reg_top_gpioh1_o_len,
+				  1);
+
+	return error;
+}
+
+/* Write NIMSuspend Register */
+static unsigned long it9135_drv_init_nim_suspend_regs(struct it9135_dev_ctx
+						      *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	deb_func("Enter %s Function\n", __func__);
+
+	error =
+	    it9135_write_reg_bits(&dev->data, 0,
+				  PROCESSOR_LINK, p_reg_top_gpioh5_en,
+				  reg_top_gpioh5_en_pos, reg_top_gpioh5_en_len,
+				  1);
+	error =
+	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
+				  p_reg_top_gpioh5_on, reg_top_gpioh5_on_pos,
+				  reg_top_gpioh5_on_len, 1);
+	error =
+	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
+				  p_reg_top_gpioh5_o, reg_top_gpioh5_o_pos,
+				  reg_top_gpioh5_o_len, 0);
+	mdelay(10);
+	error =
+	    it9135_write_reg_bits(&dev->data, 1, PROCESSOR_LINK,
+				  p_reg_top_pwrdw, reg_top_pwrdw_pos,
+				  reg_top_pwrdw_len, 1);
+	error =
+	    it9135_write_reg_bits(&dev->data, 1, PROCESSOR_LINK,
+				  p_reg_top_pwrdw_hwen, reg_top_pwrdw_hwen_pos,
+				  reg_top_pwrdw_hwen_len, 1);
+
+	return error;
+}
+
+/* Get OFDM /LINK Firmware version */
+static unsigned long it9135_drv_get_firmware_version_from_file(struct
+							       it9135_dev_ctx
+							       *dev,
+							       unsigned char
+							       processor,
+							       unsigned long
+							       *version)
+{
+	if (processor == PROCESSOR_OFDM) {
+		*version = dev->ofdm_ver;
+	} else {		/* LINK */
+		*version = dev->link_ver;
+	}
+
+	return *version;
+}
+
+static unsigned long it9135_drv_disable_gpio_pins(struct it9135_dev_ctx *dev)
+{
+	/* For strapping, gpioh1/gpioh5/ghioh7 have been program, just IT9135; */
+	unsigned long error = ERROR_NO_ERROR;
+
+	deb_func("Enter %s Function\n", __func__);
+
+	error =
+	    it9135_write_reg_bits(&dev->data, 0,
+				  PROCESSOR_LINK, p_reg_top_gpioh1_en,
+				  reg_top_gpioh1_en_pos, reg_top_gpioh1_en_len,
+				  0);
+	error =
+	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
+				  p_reg_top_gpioh1_on, reg_top_gpioh1_on_pos,
+				  reg_top_gpioh1_on_len, 0);
+	error =
+	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
+				  p_reg_top_gpioh5_en, reg_top_gpioh5_en_pos,
+				  reg_top_gpioh5_en_len, 0);
+	error =
+	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
+				  p_reg_top_gpioh5_on, reg_top_gpioh5_on_pos,
+				  reg_top_gpioh5_on_len, 0);
+	error =
+	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
+				  p_reg_top_gpioh7_en, reg_top_gpioh7_en_pos,
+				  reg_top_gpioh7_en_len, 0);
+	error =
+	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
+				  p_reg_top_gpioh7_on, reg_top_gpioh7_on_pos,
+				  reg_top_gpioh7_on_len, 0);
+
+	if (error)
+		err("it9135_drv_disable_gpio_pins failed !!!\n");
+
+	return error;
+}
+
+/* Device initialize or not */
+static unsigned long it9135_drv_initialize(struct it9135_dev_ctx *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned long file_ver, cmd_ver = 0;
+
+	deb_func("Enter %s Function\n", __func__);
+
+	if (dev->data.booted) {
+		error =
+		    it9135_drv_get_firmware_version_from_file(dev,
+							      PROCESSOR_OFDM,
+							      &file_ver);
+
+		/* Use "Command_QUERYINFO" to get fw version */
+		error = it9135_get_fw_ver(&dev->data, PROCESSOR_OFDM, &cmd_ver);
+		if (error)
+			err("it9135_drv_initialize : it9135_get_fw_ver : error = 0x%08lx", (long unsigned int)error);
+
+		if (cmd_ver != file_ver) {
+			deb_info
+			    ("Reboot: Outside Fw = 0x%lX, Inside Fw = 0x%lX",
+			     (long unsigned int)file_ver,
+			     (long unsigned int)cmd_ver);
+
+			/* Patch for 2 chips reboot; */
+			if (dev->data.chip_num == 2)
+				it9135_drv_disable_gpio_pins(dev);
+
+			error = it9135_dev_reboot(&dev->data);
+			dev->boot_code = 1;
+			if (error) {
+				err("it9135_dev_reboot : error = 0x%08lx",
+				    (long unsigned int)error);
+				return error;
+			} else {
+				return ERROR_NOT_READY;
+			}
+		} else {
+			deb_info("Fw version is the same!\n");
+			error = ERROR_NO_ERROR;
+		}
+	}
+
+	error =
+	    it9135_dev_init(&dev->data, dev->data.chip_num, 8000,
+			    dev->stream_type, dev->architecture);
+	if (error)
+		err("it9135_drv_initialize fail : 0x%08lx",
+		    (long unsigned int)error);
+	else
+		deb_info("it9135_drv_initialize Ok!!");
+
+	it9135_get_fw_ver(&dev->data, PROCESSOR_OFDM, &cmd_ver);
+	deb_info("FwVer OFDM = 0x%lX,", (long unsigned int)cmd_ver);
+	it9135_get_fw_ver(&dev->data, PROCESSOR_LINK, &cmd_ver);
+	deb_info("FwVer LINK = 0x%lX\n", (long unsigned int)cmd_ver);
+
+	return error;
+}
+
+static unsigned long it9135_nim_reset_seq(struct it9135_dev_ctx *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char bootbuffer[6];
+
+	/* checksum = 0xFEDC */
+	bootbuffer[0] = 0x05;
+	bootbuffer[1] = 0x00;
+	bootbuffer[2] = 0x23;
+	bootbuffer[3] = 0x01;
+	bootbuffer[4] = 0xFE;
+	bootbuffer[5] = 0xDC;
+
+	/* GPIOH5 init */
+	error =
+	    it9135_write_reg_bits(&dev->data, 0,
+				  PROCESSOR_LINK, p_reg_top_gpioh5_en,
+				  reg_top_gpioh5_en_pos, reg_top_gpioh5_en_len,
+				  0);
+	error =
+	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
+				  p_reg_top_gpioh5_on, reg_top_gpioh5_on_pos,
+				  reg_top_gpioh5_on_len, 0);
+
+	error = it9135_drv_nim_reset(dev);
+	error = it9135_drv_init_nim_suspend_regs(dev);
+	error =
+	    it9135_write_gen_regs(&dev->data, 0, 0x01, 0x3a, 0x06, bootbuffer);
+	error =
+	    it9135_read_gen_regs(&dev->data, 0, 0x01, 0x3a, 0x05, bootbuffer);
+
+	mdelay(50);		/* Delay for Fw boot */
+
+	/* Demod & Tuner init */
+	error = it9135_drv_initialize(dev);
+
+	return error;
+}
+
+/************** DRV_ *************/
+static unsigned long it9135_drv_ir_table_download(struct it9135_dev_ctx *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	struct file *filp;
+	unsigned char buff[512];
+	int file_sz;
+	mm_segment_t oldfs;
+
+	deb_func("Enter %s Function\n", __func__);
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	filp = filp_open("/lib/firmware/af35irtbl.bin", O_RDWR, 0644);
+
+	if (IS_ERR(filp)) {
+		deb_warning("LoadIrTable : Can't open file\n");
+		goto exit;
+	}
+
+	if ((filp->f_op) == NULL) {
+		deb_warning("LoadIrTable : File Operation Method Error!!\n");
+		goto exit;
+	}
+
+	filp->f_pos = 0x00;
+	file_sz = filp->f_op->read(filp, buff, sizeof(buff), &filp->f_pos);
+
+	error =
+	    it9135_load_ir_tab((struct it9135_data *)&dev->data,
+			       (unsigned short)file_sz, buff);
+	if (error) {
+		err("it9135_load_ir_tab fail");
+		goto exit;
+	}
+
+	filp_close(filp, NULL);
+	set_fs(oldfs);
+
+	return error;
+
+exit:
+	deb_warning("LoadIrTable fail!\n");
+	return error;
+}
+
+/* Set tuner Frequency and BandWidth */
+static unsigned long it9135_drv_set_freq_bw(struct it9135_dev_ctx *dev,
+					    unsigned char chip,
+					    unsigned long freq,
+					    unsigned short bw)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned long temp_freq = freq;
+	unsigned short temp_bw = bw;
+
+	deb_func("Enter %s Function -\n ", __func__);
+	deb_info("chip = %d, Freq= %ld, BW=%d\n", chip, (long int)freq, bw);
+
+	if (dev->fc[chip].en_pid) {
+		/* Disable PID filter */
+		it9135_write_reg_bits(&dev->data, chip, PROCESSOR_OFDM,
+				      p_mp2if_pid_en, mp2if_pid_en_pos,
+				      mp2if_pid_en_len, 0);
+		dev->fc[chip].en_pid = 0;
+	}
+
+	/* Before acquireChannel, it is 1; otherwise, it is 0 */
+	dev->fc[chip].tuner_info.setting_freq = 1;
+
+	if (freq)
+		dev->fc[chip].desired_freq = freq;
+	else
+		freq = dev->fc[chip].desired_freq;
+
+	if (bw)
+		dev->fc[chip].desired_bw = bw * 1000;
+	else
+		bw = dev->fc[chip].desired_bw;
+
+	deb_info("Real Freq= %ld, BW=%d\n",
+		 (long int)dev->fc[chip].desired_freq,
+		 dev->fc[chip].desired_bw);
+
+	if (!dev->fc[chip].tuner_info.inited) {
+		deb_warning("Skip SetFreq - Tuner is still off!\n");
+		goto exit;
+	}
+
+	dev->fc[chip].tuner_info.set = 0;
+	if (dev->fc[chip].desired_freq != 0 && dev->fc[chip].desired_bw != 0) {
+		deb_info("it9135_acquire_ch: Real Freq= %ld, BW=%d\n",
+			 (long int)dev->fc[chip].desired_freq,
+			 dev->fc[chip].desired_bw);
+		error =
+		    it9135_acquire_ch(&dev->data, chip,
+				      dev->fc[chip].desired_bw,
+				      dev->fc[chip].desired_freq);
+		/* dev->fc[chip].tuner_info.setting_freq = 0; */
+		if (error) {
+			err("it9135_acquire_ch fail! 0x%08lx",
+			    (long unsigned int)error);
+			goto exit;
+		} else {	/* when success acquireChannel, record currentFreq/currentBW. */
+			dev->fc[chip].curr_freq = dev->fc[chip].desired_freq;
+			dev->fc[chip].curr_bw = dev->fc[chip].desired_bw;
+		}
+	}
+
+	if (dev->stream_type == STREAM_TYPE_DVBT_DATAGRAM)
+		dev->fc[chip].ovr_flw_chk = 5;
+
+	dev->fc[chip].tuner_info.set = 1;
+
+	/* [OMEGA] if only 1 on, set the other to the same freq. */
+	if (dev->architecture == ARCHITECTURE_PIP) {
+		if (!dev->fc[0].timer_on && !dev->fc[1].timer_on) {
+			/* case: when 1st open; */
+			error =
+			    it9135_acquire_ch(&dev->data, (!chip),
+					      dev->fc[chip].curr_bw,
+					      dev->fc[chip].curr_freq);
+		} else if ((!dev->fc[0].timer_on || !dev->fc[1].timer_on)
+			   && !dev->fc[!chip].tuner_info.locked) {
+			/* case: when only 1 active, and change freq; (the other need to change to same freq too) */
+			error =
+			    it9135_acquire_ch(&dev->data, (!chip),
+					      dev->fc[chip].curr_bw,
+					      dev->fc[chip].curr_freq);
+		}
+	}
+
+exit:
+	dev->fc[chip].tuner_info.setting_freq = 0;
+
+	if (dev->chip_ver == 1) {
+		if (error && (!dev->already_nim_reset_seq)
+		    && (chip == 1)) {
+			dev->already_nim_reset_seq = 1;
+			it9135_nim_reset_seq(dev);
+			it9135_drv_set_freq_bw(dev, chip, temp_freq, temp_bw);
+			dev->already_nim_reset_seq = 0;
+		}
+	}
+	return error;
+}
+
+/* Tuner lock signal or not */
+static unsigned long it9135_drv_is_locked(struct it9135_dev_ctx *dev,
+					  unsigned char chip, int *locked)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	*locked = 0;
+
+	error = it9135_freq_locked(&dev->data, chip, locked);
+	if (error) {
+		err("Standard_isLocked is failed!");
+	} else {
+		if (!*locked)
+			deb_info("The chip=%d signal is %s Lock\n", chip,
+				 *locked ? "" : "not");
+	}
+
+	return error;
+}
+
+unsigned long it9135_drv_get_snr_value(struct it9135_dev_ctx *dev,
+				       unsigned long *snr_value)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char snr_reg_23_16, snr_reg_15_8, snr_reg_7_0;
+
+	deb_func("Enter %s Function\n ", __func__);
+
+	error =
+	    it9135_read_reg(&dev->data, 0, PROCESSOR_OFDM, 0x2e,
+			    (unsigned char *)&snr_reg_23_16);
+	if (error)
+		err("it9135_get_snr snr_reg_23_16 is failed!");
+
+	error =
+	    it9135_read_reg(&dev->data, 0, PROCESSOR_OFDM, 0x2d,
+			    (unsigned char *)&snr_reg_15_8);
+	if (error)
+		err("it9135_get_snr snr_reg_15_8 is failed!");
+
+	error =
+	    it9135_read_reg(&dev->data, 0, PROCESSOR_OFDM, 0x2c,
+			    (unsigned char *)&snr_reg_7_0);
+	if (error)
+		err("it9135_get_snr snr_reg_7_0 is failed!");
+
+	*snr_value =
+	    (snr_reg_23_16 & 0xff) * 256 * 256 + (snr_reg_15_8 & 0xff) * 256 +
+	    (snr_reg_7_0 & 0xff);
+
+	return error;
+}
+
+unsigned long it9135_drv_get_statistic(struct it9135_dev_ctx *dev,
+				       unsigned char chip,
+				       struct it9135_statistic *statistic)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	if (dev->fc[chip].tuner_info.set) {
+		error = it9135_get_statistic(&dev->data, chip, statistic);
+	} else {
+		(*statistic).presented = 0;
+		(*statistic).locked = 0;
+		(*statistic).quality = 0;
+		(*statistic).strength = 0;
+	}
+
+	return error;
+}
+
+static unsigned long it9135_drv_init_dev_info(struct it9135_dev_ctx *dev,
+					      unsigned char chip)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	dev->fc[chip].curr_freq = 0;
+	dev->fc[chip].curr_bw = 0;
+	dev->fc[chip].desired_freq = 0;
+	dev->fc[chip].desired_bw = 6000;
+
+	/* For PID Filter Setting */
+	dev->fc[chip].en_pid = 0;
+	dev->fc[chip].ap_on = 0;
+	dev->fc[chip].reset_ts = 0;
+	dev->fc[chip].tuner_info.set = 0;
+	dev->fc[chip].tuner_info.setting_freq = 0;
+
+	return error;
+}
+
+/* Get EEPROM_IRMODE/ir_tab_load/bRAWIr/architecture config from EEPROM */
+static unsigned long it9135_drv_get_eeprom_config(struct it9135_dev_ctx *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char chip_ver = 0;
+	unsigned long chip_type;
+	unsigned char var[2];
+	/* ir_tab_load option */
+	unsigned char tmp = 0;
+	int chip;
+
+	deb_func("Enter %s Function", __func__);
+
+	/* Patch for read eeprom valid bit */
+	error =
+	    it9135_read_reg(&dev->data, 0, PROCESSOR_LINK, chip_version_7_0,
+			    &chip_ver);
+	error =
+	    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
+			     chip_version_7_0 + 1, 2, var);
+
+	if (error)
+		err("it9135_drv_get_eeprom_config fail---cannot read chip version");
+
+	chip_type = var[1] << 8 | var[0];
+	if (chip_type == 0x9135 && chip_ver == 2) {	/* Om2 */
+		dev->chip_ver = 2;
+		error =
+		    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK, 0x461d, 1,
+				     &tmp);
+		deb_info
+		    ("Chip Version is %d---and Read 461d---valid bit = 0x%02X",
+		     chip_ver, tmp);
+	} else {
+		dev->chip_ver = 1;	/* Om1 */
+		error =
+		    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK, 0x461b, 1,
+				     &tmp);
+		deb_info
+		    ("Chip Version is %d---and Read 461b---valid bit = 0x%02X",
+		     chip_ver, tmp);
+	}
+	deb_info("*** Chip Version = %d ***", chip_ver);
+	if (error) {
+		err("0x461D eeprom valid bit read fail!");
+		goto exit;
+	}
+
+	if (tmp == 0) {
+		deb_info("No need read eeprom\n");
+		dev->ir_tab_load = 0;
+		dev->proprietary_ir = 0;
+		dev->dual_ts = 0;
+		dev->architecture = ARCHITECTURE_DCA;
+		dev->data.chip_num = 1;
+		dev->dca_pip = 0;
+		dev->fc[0].tuner_info.id = 0x38;
+	} else {
+		deb_info("Need read eeprom\n");
+		error =
+		    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
+				     EEPROM_IRMODE, 1, &tmp);
+		if (error)
+			goto exit;
+
+		dev->ir_tab_load = tmp ? 1 : 0;
+		deb_info("EEPROM_IRMODE = 0x%02X, ", tmp);
+		deb_info("ir_tab_load %s\n", dev->ir_tab_load ? "ON" : "OFF");
+
+		dev->proprietary_ir = (tmp == 0x05) ? 1 : 0;
+		deb_info("proprietary_ir - %s\n",
+			 dev->proprietary_ir ? "ON" : "OFF");
+		if (dev->proprietary_ir)
+			deb_info("IT9135 propriety (raw) mode\n");
+		else
+			deb_info("IT9135 HID (keyboard) mode\n");
+
+		/* EE chose NEC RC5 RC6 threshhold table */
+		if (dev->ir_tab_load) {
+			error =
+			    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
+					     EEPROM_IRTYPE, 1, &tmp);
+			if (error)
+				goto exit;
+			dev->ir_type = tmp;
+			deb_info("ir_type %d", dev->ir_type);
+		}
+
+		/* dual_ts option */
+		dev->dual_ts = 0;
+		dev->architecture = ARCHITECTURE_DCA;
+		dev->data.chip_num = 1;
+		dev->dca_pip = 0;
+
+		error =
+		    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
+				     EEPROM_TSMODE, 1, &tmp);
+		if (error)
+			goto exit;
+		deb_info("EEPROM_TSMODE = 0x%02X", tmp);
+
+		if (tmp == 0) {
+			deb_info("TSMode = TS1 mode\n");
+		} else if (tmp == 1) {
+			deb_info("TSMode = DCA+PIP mode\n");
+			dev->architecture = ARCHITECTURE_DCA;
+			dev->data.chip_num = 2;
+			dev->dual_ts = 1;
+			dev->dca_pip = 1;
+		} else if (tmp == 2) {
+			deb_info("TSMode = DCA mode\n");
+			dev->data.chip_num = 2;
+		} else if (tmp == 3) {
+			deb_info("TSMode = PIP mode\n");
+			dev->architecture = ARCHITECTURE_PIP;
+			dev->data.chip_num = 2;
+			dev->dual_ts = 1;
+		}
+
+		/* tunerID option, Omega, not need to read register, just assign 0x38; */
+		error =
+		    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
+				     EEPROM_TUNERID, 1, &tmp);
+		if (tmp == 0x51)
+			dev->fc[0].tuner_info.id = 0x51;
+		else if (tmp == 0x52)
+			dev->fc[0].tuner_info.id = 0x52;
+		else if (tmp == 0x60)
+			dev->fc[0].tuner_info.id = 0x60;
+		else if (tmp == 0x61)
+			dev->fc[0].tuner_info.id = 0x61;
+		else if (tmp == 0x62)
+			dev->fc[0].tuner_info.id = 0x62;
+		else
+			dev->fc[0].tuner_info.id = 0x38;
+
+		deb_info("dev->fc[0].tuner_info.id = 0x%x",
+			 dev->fc[0].tuner_info.id);
+		if (dev->dual_ts) {
+			dev->fc[1].tuner_info.id = dev->fc[0].tuner_info.id;
+			deb_info("dev->fc[1].tuner_info.id = 0x%x",
+				 dev->fc[1].tuner_info.id);
+		}
+		error =
+		    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
+				     EEPROM_SUSPEND, 1, &tmp);
+		deb_info("EEPROM susped mode=%d", tmp);
+
+	}
+
+	for (chip = 0; chip <= (unsigned char)dev->dual_ts; chip++)
+		error = it9135_drv_init_dev_info(dev, chip);
+
+exit:
+	return error;
+}
+
+static unsigned long it9135_drv_set_bus_tuner(struct it9135_dev_ctx *dev,
+					      unsigned short busId,
+					      unsigned short tuner_id)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned long version = 0;
+
+	deb_func("Enter %s Function", __func__);
+	deb_info("busId = 0x%x, tuner_id =0x%x\n", busId, tuner_id);
+
+	if ((dev->usb_mode == 0x0110) && (busId == IT9135_BUS_USB20))
+		busId = IT9135_BUS_USB11;
+
+	error = it9135_set_bus_tuner(&dev->data, busId, tuner_id);
+	if (error) {
+		err("it9135_set_bus_tuner error");
+		return error;
+	}
+
+	error = it9135_get_fw_ver(&dev->data, PROCESSOR_LINK, &version);
+	if (version != 0)
+		dev->data.booted = 1;
+	else
+		dev->data.booted = 0;
+
+	if (error)
+		err("it9135_get_fw_ver error");
+
+	return error;
+}
+
+/* suspend 1 --> sleep / suspend not 1 --> resume */
+static unsigned long it9135_drv_nim_suspend(struct it9135_dev_ctx *dev,
+					    int suspend)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	deb_func("Enter %s Function\n", __func__);
+	deb_info("suspend = %s\n", suspend ? "ON" : "OFF");
+
+	if (dev->data.chip_num == 1)
+		return ERROR_NO_ERROR;
+
+	if (suspend) {		/* Sleep */
+		error =
+		    it9135_write_reg_bits(&dev->data,
+					  0, PROCESSOR_LINK, p_reg_top_gpioh5_o,
+					  reg_top_gpioh5_o_pos,
+					  reg_top_gpioh5_o_len, 1);
+		mdelay(20);
+	} else {		/* Resume */
+		error =
+		    it9135_write_reg_bits(&dev->data,
+					  0, PROCESSOR_LINK, p_reg_top_gpioh5_o,
+					  reg_top_gpioh5_o_pos,
+					  reg_top_gpioh5_o_len, 0);
+		mdelay(100);
+	}
+
+	return error;
+}
+
+/* Set tuner power saving and control */
+static unsigned long it9135_drv_ap_ctrl(struct it9135_dev_ctx *dev,
+					unsigned char chip, int onoff)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned long version = 0;
+	int i;
+
+	deb_func("Enter %s Function\n", __func__);
+	deb_info("chip = %d, onoff = %s\n", chip, onoff ? "ON" : "OFF");
+
+	if (onoff) {
+		dev->fc[chip].tuner_info.inited = 1;
+		if (dev->architecture == ARCHITECTURE_PIP) {
+			if (dev->fc[0].timer_on || dev->fc[1].timer_on) {
+				deb_info("Already all power on !!");
+				return 0;
+			}
+		}
+	} else {
+		dev->fc[chip].tuner_info.inited = 0;
+		dev->fc[chip].tuner_info.locked = 0;
+
+		/* [OMEGA] if other one still alive, do not pwr down, just need to set freq; */
+		if (dev->architecture == ARCHITECTURE_PIP) {
+			if (dev->fc[0].timer_on || dev->fc[1].timer_on) {
+				deb_info("CLOSE 1");
+				it9135_acquire_ch(&dev->data, chip,
+						  dev->fc[!chip].curr_bw,
+						  dev->fc[!chip].curr_freq);
+				return 0;
+			}
+		}
+	}
+	/*[OMEGA] clock from tuner, so close sequence demod->tuner, and 9133->9137. vice versa.
+	 * BUT! demod->tuner:57mADC, tuner->demod:37mADC
+	 */
+	if (onoff) {		/* pwr on */
+		if (dev->chip_ver == 1) {
+			if (chip == 1) {
+				error = it9135_nim_reset_seq(dev);
+				if (error)
+					it9135_nim_reset_seq(dev);
+			} else {
+				dev->usb_ctrl_timeOut = 1;
+				for (i = 0; i < 5; i++) {
+					deb_info
+					    ("it9135_drv_ap_ctrl - DummyCmd %d",
+					     i);
+					error =
+					    it9135_get_fw_ver(&dev->data,
+							      PROCESSOR_LINK,
+							      &version);
+					mdelay(1);
+				}
+				dev->usb_ctrl_timeOut = 5;
+
+				error =
+				    it9135_ctrl_tuner_pw_saving(&dev->data,
+								chip, onoff);
+				if (error)
+					err("it9135_drv_ap_ctrl::it9135_ctrl_tuner_pw_saving error = %x", (unsigned int)error);
+
+				error =
+				    it9135_ctrl_pw_saving(&dev->data, chip,
+							  onoff);
+				if (error)
+					err("it9135_drv_ap_ctrl::it9135_ctrl_pw_saving error = %x", (unsigned int)error);
+			}
+		} else {
+			if (chip == 1) {
+				error = it9135_drv_nim_suspend(dev, 0);
+			} else {
+				/* DummyCmd */
+				dev->usb_ctrl_timeOut = 1;
+				for (i = 0; i < 5; i++) {
+					deb_info
+					    ("it9135_drv_ap_ctrl - DummyCmd %d",
+					     i);
+					error =
+					    it9135_get_fw_ver(&dev->data,
+							      PROCESSOR_LINK,
+							      &version);
+					mdelay(1);
+				}
+				dev->usb_ctrl_timeOut = 5;
+			}
+
+			error =
+			    it9135_ctrl_tuner_pw_saving(&dev->data, chip,
+							onoff);
+			if (error)
+				err("it9135_drv_ap_ctrl - it9135_ctrl_tuner_pw_saving error = %x", (unsigned int)error);
+
+			error = it9135_ctrl_pw_saving(&dev->data, chip, onoff);
+			mdelay(50);
+			if (error)
+				err("it9135_drv_ap_ctrl - it9135_ctrl_pw_saving error = %x", (unsigned int)error);
+		}
+	} else {		/* pwr down:  DCA DUT: 36(all) -> 47-159(no GPIOH5, sequence change) */
+		if ((chip == 0) && (dev->data.chip_num == 2)) {
+			error = it9135_ctrl_tuner_leakage(&dev->data, 1, onoff);
+			if (error)
+				err("it9135_drv_ap_ctrl::it9135_ctrl_tuner_leakage error = %x", (unsigned int)error);
+			error = it9135_drv_nim_suspend(dev, 1);
+		}
+
+		error = it9135_ctrl_pw_saving(&dev->data, chip, onoff);
+		if (error)
+			err("it9135_drv_ap_ctrl::it9135_ctrl_pw_saving error = %x", (unsigned int)error);
+
+		error = it9135_ctrl_tuner_pw_saving(&dev->data, chip, onoff);
+		if (error)
+			err("it9135_drv_ap_ctrl::it9135_ctrl_tuner_pw_saving error = %x", (unsigned int)error);
+	}
+
+	return error;
+}
+
+static unsigned long it9135_drv_ap_reset(struct it9135_dev_ctx *dev,
+					 unsigned char chip, int onoff)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	deb_func("Enter %s Function\n", __func__);
+
+	dev->fc[chip].curr_freq = 0;
+	dev->fc[chip].curr_bw = 6000;	/* For BDAUtil */
+	dev->fc[chip].ap_on = 0;
+
+	if (!onoff) {		/* Only for stop */
+		dev->fc[chip].en_pid = 0;
+	}
+
+	/* Init Tuner info */
+	dev->fc[chip].tuner_info.setting_freq = 0;
+
+	error = it9135_drv_ap_ctrl(dev, chip, onoff);
+	if (error)
+		err("it9135_drv_ap_ctrl Fail!");
+
+	return error;
+}
+
+static unsigned long it9135_drv_dummy_cmd(struct it9135_dev_ctx *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	int i;
+
+	deb_info("it9135_drv_dummy_cmd:: patch for KJS/EEPC\n");
+	for (i = 0; i < 5; i++) {
+		error =
+		    it9135_drv_set_bus_tuner(dev, IT9135_BUS_USB20,
+					     IT9135_TUNER_ID);
+		mdelay(1);
+	}
+	if (error)
+		deb_warning("it9135_drv_dummy_cmd failed - %d\n", i);
+
+	return error;
+}
+
+/************** DL_ *************/
+
+static unsigned long it9135_dl_dummy_cmd(struct it9135_dev_ctx *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	error = it9135_drv_dummy_cmd(dev);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+static unsigned long it9135_dl_nim_reset(struct it9135_dev_ctx *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	error = it9135_drv_nim_reset(dev);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+static unsigned long it9135_dl_init_nim_suspend_regs(struct it9135_dev_ctx *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	error = it9135_drv_init_nim_suspend_regs(dev);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+static unsigned long it9135_dl_initialize(struct it9135_dev_ctx *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	error = it9135_drv_initialize(dev);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+static unsigned long it9135_dl_set_bus_tuner(struct it9135_dev_ctx *dev,
+					     unsigned short busId,
+					     unsigned short tuner_id)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	error = it9135_drv_set_bus_tuner(dev, busId, tuner_id);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+static unsigned long it9135_dl_get_eeprom_config(struct it9135_dev_ctx *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	error = it9135_drv_get_eeprom_config(dev);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+/* Load Ir Table */
+static unsigned long it9135_dl_ir_table_download(struct it9135_dev_ctx *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	error = it9135_drv_ir_table_download(dev);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_reset_pid(struct it9135_dev_ctx *dev,
+				  unsigned char chip)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	/* Reset and Clear pidTable */
+	error = it9135_reset_pid(&dev->data, chip);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_add_pid(struct it9135_dev_ctx *dev, unsigned char chip,
+				unsigned char index, unsigned short pid)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	deb_func("Enter %s Function - index: %d, pid: %x\n", __func__, index,
+		 pid);
+
+	error = it9135_add_pid_filter(&dev->data, chip, index, pid);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_remove_pid(struct it9135_dev_ctx *dev,
+				   unsigned char chip, unsigned char index,
+				   unsigned short pid)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	deb_func("Enter %s Function - index: %d, pid: %x\n", __func__, index,
+		 pid);
+
+	error = it9135_remove_pid_at(&dev->data, chip, index, pid);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_pid_on_off(struct it9135_dev_ctx *dev,
+				   unsigned char chip, int onoff)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char ctrl = 0;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	deb_func("Enter %s Function - onoff: %d\n ", __func__, onoff);
+
+	if (onoff)
+		ctrl = 1;
+	else
+		ctrl = 0;
+
+	error = it9135_ctrl_pid_filter(&dev->data, chip, 0);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_ap_ctrl(struct it9135_dev_ctx *dev, unsigned char chip,
+				int onoff)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	deb_func("Enter %s Function\n", __func__);
+	deb_info("chip = %d, onoff = %s\n", chip, onoff ? "ON" : "OFF");
+
+	mutex_lock(&dev->it9135_mutex);
+
+	error = it9135_drv_ap_ctrl(dev, chip, onoff);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_ap_reset(struct it9135_dev_ctx *dev, unsigned char chip,
+				 int on)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	error = it9135_drv_ap_reset(dev, chip, on);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_tuner_set_freq_bw(struct it9135_dev_ctx *dev,
+					  unsigned char chip,
+					  unsigned long freq, unsigned short bw)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	deb_func("Enter %s Function\n", __func__);
+
+	if (dev->fc[chip].desired_freq != freq
+	    || dev->fc[chip].desired_bw != bw * 1000)
+		error = it9135_drv_set_freq_bw(dev, chip, freq, bw);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_set_architecture(struct it9135_dev_ctx *dev,
+					 unsigned char architecture)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	deb_func("Enter %s Function\n", __func__);
+	error = it9135_set_arch(&dev->data, architecture);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_is_locked(struct it9135_dev_ctx *dev,
+				  unsigned char chip, int *locked)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	error = it9135_drv_is_locked(dev, chip, locked);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_get_signal_strength(struct it9135_dev_ctx *dev,
+					    unsigned char chip,
+					    unsigned char *strength)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	deb_func("Enter %s Function\n", __func__);
+
+	error = it9135_get_strength(&dev->data, chip, strength);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_get_signal_strength_Dbm(struct it9135_dev_ctx *dev,
+						unsigned char chip,
+						long *strength_dbm)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	deb_func("Enter %s Function\n", __func__);
+
+	error = it9135_get_strength_dbm(&dev->data, chip, strength_dbm);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_get_channel_statistic(struct it9135_dev_ctx *dev,
+					      unsigned char chip,
+					      struct it9135_ch_statistic
+					      *ch_statistic)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	deb_func("Enter %s Function\n", __func__);
+
+	error = it9135_get_ch_statistic(&dev->data, chip, ch_statistic);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_get_channel_modulation(struct it9135_dev_ctx *dev,
+					       unsigned char chip,
+					       struct it9135_ch_modulation
+					       *ch_modulation)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	deb_func("Enter %s Function\n", __func__);
+
+	error = it9135_get_ch_modulation(&dev->data, chip, ch_modulation);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_get_snr(struct it9135_dev_ctx *dev,
+				unsigned char chip,
+				unsigned char *constellation,
+				unsigned char *snr)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	deb_func("Enter %s Function\n", __func__);
+
+	error = it9135_get_snr(&dev->data, chip, snr);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_reboot(struct it9135_dev_ctx *dev)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	deb_func("Enter %s Function\n", __func__);
+
+	error = it9135_dev_reboot(&dev->data);
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+unsigned long it9135_dl_read_raw_ir(struct it9135_dev_ctx *dev,
+				    unsigned long *read_buff)
+{
+	unsigned long error = ERROR_NO_ERROR;
+
+	mutex_lock(&dev->it9135_mutex);
+
+	if (dev->proprietary_ir)
+		error = it9135_get_ir_code(&dev->data, read_buff);
+	else
+		deb_warning("RAWIr can't be used!!\n");
+
+	mutex_unlock(&dev->it9135_mutex);
+
+	return error;
+}
+
+/* Set device driver init */
+unsigned long it9135_device_init(struct usb_device *udev,
+				 struct it9135_dev_ctx *dev, int boot)
+{
+	unsigned long error = ERROR_NO_ERROR;
+	int err_cnt = 0;
+	int i;
+
+	deb_func("Enter %s Function\n", __func__);
+
+	dev_set_drvdata(&udev->dev, dev);
+
+	info("=========================================");
+	info("DRIVER_RELEASE_VERSION:    %s", DRIVER_RELEASE_VERSION);
+	info("FW_RELEASE_VERSION:        %s", dev->fw_ver);
+	info("API_RELEASE_VERSION:       %X.%X.%X", IT9135_API_VER_NUM,
+	     IT9135_API_DATE, IT9135_API_BUILD);
+	info("=========================================");
+
+#ifdef DVB_USB_ADAP_NEED_PID_FILTER
+	deb_info("DVB_USB_ADAP_NEED_PID_FILTERING\n");
+#else
+	deb_info("DVB_USB_ADAP_NOT_NEED_PID_FILTERING\n");
+#endif
+
+	/************* Set Device init Info *************/
+	dev->enter_suspend = 0;
+	dev->surprise_removal = 0;
+	dev->dev_not_resp = 0;
+	dev->selective_suspend = 0;
+	dev->tuner_pw_off = 0;
+	dev->already_nim_reset_seq = 0;
+
+	if (boot) {
+		dev->data.chip_num = 1;
+		dev->architecture = ARCHITECTURE_DCA;
+		dev->data.frequency[0] = 666000;
+		dev->data.bandwidth[0] = 8000;
+		dev->ir_tab_load = 0;
+		dev->fc[0].tuner_info.id = 0;
+		dev->fc[1].tuner_info.id = 0;
+		dev->fc[0].timer_on = 0;
+		dev->fc[1].timer_on = 0;
+		dev->dual_ts = 0;
+		dev->filter_cnt = 0;
+		dev->filter_index = 0;
+		dev->stream_type = STREAM_TYPE_DVBT_DATAGRAM;
+		dev->usb_ctrl_timeOut = 1;
+		dev->disconnect = 0;
+		if (udev->speed == USB_SPEED_FULL)
+			dev->max_packet_sz = 0x0110;
+		else
+			dev->max_packet_sz = 0x0200;
+	} else {
+		dev->usb_ctrl_timeOut = 5;
+	}
+
+	error = it9135_dl_dummy_cmd(dev);
+
+	if (boot) {
+		/************* Set USB Info *************/
+		dev->usb_mode = (dev->max_packet_sz == 0x200) ? 0x0200 : 0x0110;
+		deb_info("USB mode = 0x%x\n", dev->usb_mode);
+
+		dev->ts_packet_cnt =
+		    (dev->usb_mode ==
+		     0x200) ? IT9135_TS_PACKET_COUNT_HI :
+		    IT9135_TS_PACKET_COUNT_FU;
+		dev->ts_frames =
+		    (dev->usb_mode ==
+		     0x200) ? IT9135_TS_FRAMES_HI : IT9135_TS_FRAMES_FU;
+		dev->ts_frame_sz = IT9135_TS_PACKET_SIZE * dev->ts_packet_cnt;
+		dev->ts_frame_sz_dw = dev->ts_frame_sz / 4;
+	}
+	dev->ep12_err = 0;
+	dev->ep45_err = 0;
+	dev->active_filter = 0;
+
+	if (boot) {
+		error =
+		    it9135_dl_set_bus_tuner(dev, IT9135_BUS_USB20,
+					    IT9135_TUNER_ID);
+		if (error) {
+			err("First it9135_dl_set_bus_tuner fail : 0x%08lx",
+			    (long unsigned int)error);
+			err_cnt++;
+			goto Exit;
+		}
+
+		error = it9135_dl_get_eeprom_config(dev);
+		if (error) {
+			err("it9135_dl_get_eeprom_config fail : 0x%08lx",
+			    (long unsigned int)error);
+			err_cnt++;
+			goto Exit;
+		}
+	}
+
+	error =
+	    it9135_dl_set_bus_tuner(dev, IT9135_BUS_USB20,
+				    dev->fc[0].tuner_info.id);
+	if (error) {
+		err("it9135_dl_set_bus_tuner fail!");
+		err_cnt++;
+		goto Exit;
+	}
+
+	if (dev->data.chip_num == 2 && !dev->data.booted) {	/* plug/cold-boot/S4 */
+		error = it9135_dl_nim_reset(dev);
+	} else if (dev->data.chip_num == 2 && dev->data.booted) {	/* warm-boot/(S1) */
+		/* pwr on for init. */
+		for (i = 0; i < dev->data.chip_num; i++)
+			error = it9135_dl_ap_ctrl(dev, i, 1);
+	} else if (dev->data.chip_num == 1 && dev->data.booted) {	/* warm-boot/(S1) */
+		/* pwr on for init, but seems not necessary. */
+		error = it9135_dl_ap_ctrl(dev, 0, 1);
+	}
+
+	if (error)
+		err("it9135_dl_nim_reset or dl_nim_suspend fail!");
+
+	error = it9135_dl_initialize(dev);
+	if (error) {
+		err("it9135_dl_initialize fail! 0x%08lx",
+		    (long unsigned int)error);
+		err_cnt++;
+		goto Exit;
+	}
+
+	if (dev->ir_tab_load) {
+		error = it9135_dl_ir_table_download(dev);
+		if (error) {
+			err("it9135_dl_ir_table_download fail");
+			err_cnt++;
+		}
+	}
+
+	if (dev->data.chip_num == 2) {
+		error = it9135_dl_init_nim_suspend_regs(dev);
+		if (error)
+			err("it9135_dl_init_nim_suspend_regs fail!");
+	}
+
+	for (i = dev->data.chip_num; i > 0; i--) {
+		error = it9135_dl_ap_ctrl(dev, (i - 1), 0);
+		if (error)
+			err("%d: it9135_dl_ap_ctrl Fail!", i);
+
+	}
+
+	info("%s success!!", __func__);
+
+Exit:
+	if (err_cnt)
+		err("[Device_init] Error %d\n", err_cnt);
+	return error;
+}
+
+int dca_to_pip(struct it9135_dev_ctx *dev)
+{
+	dev->filter_index = dev->filter_cnt;
+
+	deb_info("dca_to_pip - %d\n", dev->filter_cnt);
+
+	if (dev->filter_cnt == 1) {
+		/* Do nothing, stay in DCA. */
+		it9135_dl_set_architecture(dev, ARCHITECTURE_DCA);
+		mdelay(50);
+	} else if (dev->filter_cnt == 2) {
+		it9135_dl_set_architecture(dev, ARCHITECTURE_PIP);
+		mdelay(50);
+	}
+
+	return 0;
+}
+
+int pip_to_dca(struct it9135_dev_ctx *dev)
+{
+	deb_info("pip_to_dca - %d, %d\n", dev->filter_cnt, dev->filter_index);
+
+	if (dev->filter_cnt == 1) {
+		if (dev->filter_index == 0) {	/*Close filter 0. */
+			dev->swap_filter = 1;
+			it9135_dl_set_architecture(dev, ARCHITECTURE_DCA);
+			it9135_dl_tuner_set_freq_bw(dev, 0,
+						    dev->fc[1].curr_freq, 0);
+			dev->swap_filter = 0;
+		} else {	/* Close filter 1. */
+
+			it9135_dl_set_architecture(dev, ARCHITECTURE_DCA);
+			it9135_dl_tuner_set_freq_bw(dev, 0,
+						    dev->fc[0].curr_freq, 0);
+		}
+
+		dev->fc[1].timer_on = 0;
+		dev->fc[0].timer_on = 1;
+	} else if (dev->filter_cnt == 0) {
+		dev->fc[1].timer_on = 0;
+		dev->fc[0].timer_on = 0;
+	}
+	return 0;
+}
+
+/* IT9135 device tuner on init */
+static int it9135_init(struct dvb_frontend *demod)
+{
+	struct it9135_dev_ctx *dev =
+	    (struct it9135_dev_ctx *)demod->demodulator_priv;
+	unsigned long error = ERROR_NO_ERROR;
+	int i;
+
+	deb_func("Enter %s Function - chip=%d\n", __func__, demod->dvb->num);
+
+	if (dev->disconnect)
+		return 0;
+
+	dev->filter_cnt++;
+
+	if (dev->dca_pip) {
+		for (i = 0; i < dev->data.chip_num; i++)
+			error = it9135_dl_ap_ctrl(dev, i, 1);
+
+		error = dca_to_pip(dev);
+	}
+
+	if (error)
+		return -EREMOTEIO;
+
+	if ((dev->architecture == ARCHITECTURE_PIP) && (dev->filter_cnt == 2)) {
+		/* Do nothging, MODE = DCA+PIP, because 2 tuners have turn on from DCA. */
+	} else if (dev->architecture == ARCHITECTURE_DCA) {	/* Single or DCA */
+		for (i = 0; i < dev->data.chip_num; i++)
+			error = it9135_dl_ap_ctrl(dev, i, 1);
+	} else {
+		/* PIP */
+		/* pwr on 2 chips directly; */
+		for (i = 0; i < dev->data.chip_num; i++)
+			error = it9135_dl_ap_ctrl(dev, i, 1);
+	}
+
+	if (error)
+		return -EREMOTEIO;
+
+	dev->fc[demod->dvb->num].timer_on = 1;
+
+	return 0;
+}
+
+/* IT9135 device tuner off sleep */
+static int it9135_sleep(struct dvb_frontend *demod)
+{
+	struct it9135_dev_ctx *dev =
+	    (struct it9135_dev_ctx *)demod->demodulator_priv;
+	unsigned long error = ERROR_NO_ERROR;
+	int i;
+
+	deb_func("Enter %s Function\n", __func__);
+
+	if (dev->disconnect)
+		return 0;
+
+	dev->filter_cnt--;
+	dev->fc[demod->dvb->num].timer_on = 0;
+
+	if (dev->dca_pip)
+		error = pip_to_dca(dev);
+
+	if (dev->filter_cnt == 1) {
+		/* Do nothing, Mode = DCA+PIP, because from PIP to DCA */
+		deb_info("ARCHITECTURE_DCA - %d\n", dev->filter_cnt);
+	} else {		/* Single or DCA */
+		deb_info("ARCHITECTURE_DCA2 - %d\n", dev->filter_cnt);
+
+		for (i = dev->data.chip_num; i > 0; i--)
+			error = it9135_dl_ap_reset(dev, i - 1, 0);
+
+	}
+
+	if (error)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int it9135_get_frontend(struct dvb_frontend *fe,
+			       struct dvb_frontend_parameters *fep)
+{
+	struct it9135_dev_ctx *dev =
+	    (struct it9135_dev_ctx *)fe->demodulator_priv;
+
+	if (dev->data.chip_num != 2)
+		deb_func("Enter %s Function\n", __func__);
+	else
+		deb_func("Enter %s Function - chip=%d\n", __func__,
+			 fe->dvb->num);
+
+	fep->inversion = INVERSION_AUTO;
+	return 0;
+}
+
+/* Set OFDM bandwidth and tuner frequency */
+static int it9135_set_frontend(struct dvb_frontend *fe,
+			       struct dvb_frontend_parameters *fep)
+{
+	struct it9135_dev_ctx *dev =
+	    (struct it9135_dev_ctx *)fe->demodulator_priv;
+	struct it9135_ofdm_channel ch;
+	unsigned long error = ERROR_NO_ERROR;
+
+	ch.rf_khz = 0;
+	ch.bw = 0;
+
+	if (dev->disconnect)
+		return 0;
+
+	if (dev->data.chip_num != 2)
+		deb_func("Enter %s Function\n", __func__);
+	else
+		deb_func("Enter %s Function - chip=%d RF=%d, BW=%d\n", __func__,
+			 fe->dvb->num, ch.rf_khz, ch.bw);
+
+	if (fep->u.ofdm.bandwidth == 0)
+		fep->u.ofdm.bandwidth = 8;
+	if (fep->u.ofdm.bandwidth == 1)
+		fep->u.ofdm.bandwidth = 7;
+	if (fep->u.ofdm.bandwidth == 2)
+		fep->u.ofdm.bandwidth = 6;
+
+	ch.rf_khz = fep->frequency / 1000;
+	ch.bw = fep->u.ofdm.bandwidth;
+
+	if (ch.rf_khz < 177000 || ch.rf_khz > 8585000)
+		ch.rf_khz = 950000;
+
+	if (dev->data.chip_num != 2)
+		error = it9135_dl_tuner_set_freq_bw(dev, 0, ch.rf_khz, ch.bw);
+	else
+		error =
+		    it9135_dl_tuner_set_freq_bw(dev, fe->dvb->num, ch.rf_khz,
+						ch.bw);
+
+	if (error)
+		err("it9135_set_frontend return error");
+
+	return 0;
+}
+
+/* Tuner signal lock frequency */
+static int it9135_read_status(struct dvb_frontend *fe, fe_status_t * stat)
+{
+	struct it9135_dev_ctx *dev =
+	    (struct it9135_dev_ctx *)fe->demodulator_priv;
+	unsigned long error = ERROR_NO_ERROR;
+	int locked;
+
+	if (dev->disconnect)
+		return 0;
+
+	*stat = 0;
+
+	if (dev->data.chip_num != 2)
+		error = it9135_dl_is_locked(dev, 0, &locked);
+	else
+		error = it9135_dl_is_locked(dev, fe->dvb->num, &locked);
+
+	if (error)
+		return 0;
+
+	if (locked) {
+		/* It's seems ok that always return lock to AP */
+		*stat |= FE_HAS_SIGNAL;
+		*stat |= FE_HAS_CARRIER;
+		*stat |= FE_HAS_LOCK;
+		*stat |= FE_HAS_VITERBI;
+		*stat |= FE_HAS_SYNC;
+	} else
+		*stat |= FE_TIMEDOUT;
+
+	return 0;
+}
+
+/* Get it9135_ch_statistic and calculate ber value */
+static int it9135_read_ber(struct dvb_frontend *fe, u32 * ber)
+{
+	struct it9135_dev_ctx *dev =
+	    (struct it9135_dev_ctx *)fe->demodulator_priv;
+	unsigned long error = ERROR_NO_ERROR;
+	struct it9135_ch_statistic ch_statistic;
+
+	if (dev->disconnect)
+		return 0;
+
+	if (dev->data.chip_num != 2)
+		error = it9135_dl_get_channel_statistic(dev, 0, &ch_statistic);
+	else
+		error =
+		    it9135_dl_get_channel_statistic(dev, fe->dvb->num,
+						    &ch_statistic);
+	if (error)
+		return error;
+
+	deb_info
+	    ("it9135_read_ber post_vit_err_cnt: %ld, post_vitbit_cnt: %ld\n",
+	     (long int)ch_statistic.post_vit_err_cnt,
+	     (long int)ch_statistic.post_vitbit_cnt);
+
+	*ber =
+	    ch_statistic.post_vit_err_cnt * (0xFFFFFFFF /
+					     ch_statistic.post_vitbit_cnt);
+
+	return 0;
+}
+
+/* Calculate SNR value */
+static int it9135_read_snr(struct dvb_frontend *fe, u16 * snr)
+{
+	struct it9135_dev_ctx *dev =
+	    (struct it9135_dev_ctx *)fe->demodulator_priv;
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char constellation;
+	unsigned char SignalSnr = 0;
+
+	if (dev->disconnect)
+		return 0;
+
+	if (dev->data.chip_num != 2)
+		error = it9135_dl_get_snr(dev, 0, &constellation, &SignalSnr);
+	else
+		error =
+		    it9135_dl_get_snr(dev, fe->dvb->num, &constellation,
+				      &SignalSnr);
+	if (error)
+		return error;
+
+	deb_info("it9135_read_snr constellation: %d, SignalSnr: %d\n",
+		 constellation, SignalSnr);
+
+	if (constellation == 0) {
+		*snr = (u16)SignalSnr * (0xFFFF / 23);
+	} else if (constellation == 1) {
+		*snr = (u16)SignalSnr * (0xFFFF / 26);
+	} else if (constellation == 2) {
+		*snr = (u16)SignalSnr * (0xFFFF / 29);
+	} else {
+		deb_warning("Get constellation is failed!\n");
+	}
+
+	return 0;
+}
+
+static int it9135_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
+{
+	*unc = 0;
+	return 0;
+}
+
+/* Read signal strength and calculate strength value */
+static int it9135_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
+{
+	struct it9135_dev_ctx *dev =
+	    (struct it9135_dev_ctx *)fe->demodulator_priv;
+	unsigned long error = ERROR_NO_ERROR;
+	unsigned char st = 0;
+
+	if (dev->disconnect)
+		return 0;
+
+	deb_func("Enter %s Function\n", __func__);
+
+	if (dev->data.chip_num != 2)
+		error = it9135_dl_get_signal_strength(dev, 0, &st);
+	else
+		error = it9135_dl_get_signal_strength(dev, fe->dvb->num, &st);
+	if (error)
+		return error;
+
+	deb_info("%s is %d\n", __func__, st);
+	*strength = (u16)st * (0xFFFF / 100);
+
+	return 0;
+}
+
+static void it9135_release(struct dvb_frontend *fe)
+{
+	deb_func("%s:\n", __func__);
+	kfree(fe);
+}
+
+static struct dvb_frontend_ops it9135_ops;
+struct dvb_frontend *it9135_attach(struct dvb_usb_adapter *adap)
+{
+	struct dvb_frontend *frontend;
+	struct it9135_dev_ctx *dev = dev_get_drvdata(&adap->dev->udev->dev);
+
+	frontend = kzalloc(sizeof(*frontend), GFP_KERNEL);
+	if (frontend == NULL)
+		goto error;
+
+	frontend->demodulator_priv = dev;
+	memcpy(&frontend->ops, &it9135_ops, sizeof(it9135_ops));
+
+	return frontend;
+
+error:
+	kfree(frontend);
+	return NULL;
+}
+
+static struct dvb_frontend_ops it9135_ops = {
+	.info = {
+		 .name = "IT9135 USB DVB-T",
+		 .type = FE_OFDM,
+		 .frequency_min = 44250000,
+		 .frequency_max = 867250000,
+		 .frequency_stepsize = 62500,
+		 .caps = FE_CAN_INVERSION_AUTO |
+		 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+		 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+		 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+		 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+		 FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
+		 },
+
+	.release = it9135_release,
+
+	.init = it9135_init,
+	.sleep = it9135_sleep,
+
+	.set_frontend = it9135_set_frontend,
+	.get_frontend = it9135_get_frontend,
+
+	.read_status = it9135_read_status,
+	.read_ber = it9135_read_ber,
+	.read_signal_strength = it9135_read_signal_strength,
+	.read_snr = it9135_read_snr,
+	.read_ucblocks = it9135_read_unc_blocks,
+};
+
+/* -------------------------------------------------------------------------- */
+
+/*
+ * init it9135 properties
+ */
+
+static int it9135_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+	struct it9135_dev_ctx *dev =
+	    (struct it9135_dev_ctx *)adap->fe->demodulator_priv;
+	int ret = 0;
+
+	deb_info("%s: onoff:%d\n", __func__, onoff);
+
+	if (!onoff) {
+		deb_info("Reset PID Table\n");
+
+		if (dev->data.chip_num != 2)
+			it9135_dl_reset_pid(dev, 0);
+		else
+			it9135_dl_reset_pid(dev, (unsigned char)adap->id);
+	}
+
+	dev->fc[adap->id].en_pid = onoff;
+
+	if (dev->data.chip_num != 2)
+		ret = it9135_dl_pid_on_off(dev, 0, dev->fc[adap->id].en_pid);
+	else
+		ret =
+		    it9135_dl_pid_on_off(dev, (unsigned char)adap->id,
+					 dev->fc[adap->id].en_pid);
+
+	deb_info("Set pid onoff ok\n");
+
+	return ret;
+}
+
+static int it9135_pid_filter(struct dvb_usb_adapter *adap, int index,
+			     u16 pidnum, int onoff)
+{
+	struct it9135_dev_ctx *dev =
+	    (struct it9135_dev_ctx *)adap->fe->demodulator_priv;
+	unsigned short pid;
+	int ret = 0;
+
+	deb_info
+	    ("%s: set pid filter, feedcount %d, index %d, pid %x, onoff %d.\n",
+	     __func__, adap->feedcount, index, pidnum, onoff);
+
+	if (onoff) {
+		/* Cannot use it as pid_filter_ctrl since it has to be done before setting the first pid */
+		if (adap->feedcount == 1) {
+			deb_info("first pid set, enable pid table\n");
+			ret = it9135_pid_filter_ctrl(adap, onoff);
+			if (ret)
+				return ret;
+		}
+
+		pid = (unsigned short)pidnum;
+		if (dev->data.chip_num != 2)
+			ret = it9135_dl_add_pid(dev, 0, index, pid);
+		else
+			ret =
+			    it9135_dl_add_pid(dev, (unsigned char)adap->id,
+					      index, pid);
+		if (ret)
+			return ret;
+	} else {
+		pid = (unsigned short)pidnum;
+		if (dev->data.chip_num != 2)
+			ret = it9135_dl_remove_pid(dev, 0, index, pid);
+		else
+			ret =
+			    it9135_dl_remove_pid(dev, (unsigned char)adap->id,
+						 index, pid);
+		if (ret)
+			return ret;
+
+		if (adap->feedcount == 0) {
+			deb_info("last pid unset, disable pid table\n");
+			ret = it9135_pid_filter_ctrl(adap, onoff);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+struct it9135_val_set *script_parser(const struct firmware *fw,
+				     int *fw_file_pos, u16 * script_sets)
+{
+	int pos = *fw_file_pos;
+	struct it9135_val_set *scripts_temp = NULL;
+	int j = 0;
+	int i = 0;
+
+	/* fw_file_pos+0 ~ +3 == VERSION1 VERSION2 VERSION3 VERSION4 */
+	pos += 4;
+
+	/* OMEGA_ADDRESS */
+	pos += 1;
+
+	/* OMEGA_SCRIPTSETLENGTH */
+	if (fw->data[pos] != 1) {
+		err("OMEGA_SCRIPTSETLENGTH != 1 !!");
+		return NULL;
+	}
+	pos += 4;
+
+	/* scriptSets */
+	*script_sets = fw->data[pos] + (fw->data[pos + 1] << 8);
+	pos += 2;
+
+	/* OMEGA_LNA_Config_2_scripts */
+	scripts_temp =
+	    kzalloc((*script_sets) * sizeof(*scripts_temp), GFP_KERNEL);
+	for (i = 0; i < (*script_sets); i++) {
+		scripts_temp[i].address = fw->data[pos + j] +
+		    (fw->data[pos + j + 1] << 8) +
+		    (fw->data[pos + j + 2] << 16) +
+		    (fw->data[pos + j + 3] << 24);
+
+		scripts_temp[i].value = fw->data[pos + j + 4];
+		j += 5;
+	}
+
+	pos += j;
+	*fw_file_pos = pos;
+
+	return scripts_temp;
+}
+
+static int it9135_download_firmware(struct usb_device *udev,
+				    const struct firmware *fw)
+{
+	int retval = -ENOMEM;
+	struct it9135_dev_ctx *dev = NULL;
+	struct it9135_segment *segs = NULL;
+	u8 *fw_codes;
+	u16 *script_sets;
+	struct it9135_val_set *scripts = NULL;
+	int fw_file_pos = 0;
+	unsigned int fw_code_len = 0;
+	unsigned char var[2];
+	u32 fw_script_len_v1 = 0;
+	u32 fw_script_len_v2 = 0;
+	u32 partition_len_v1 = 0;
+	u32 partition_len_v2 = 0;
+	int chip_v2 = 0;
+	int i = 0;
+	int j = 0;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL) {
+		err("Alloc dev out of memory");
+		return -ENOTTY;
+	}
+
+	/* init mutex */
+	mutex_init(&dev->it9135_mutex);
+	dev->data.it9135_fw = fw;
+
+	dev->data.driver = (void *)udev;
+
+	/* check device chip version */
+	retval =
+	    it9135_read_reg(&dev->data, 0, PROCESSOR_LINK, chip_version_7_0,
+			    &dev->data.chip_ver);
+	retval =
+	    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
+			     chip_version_7_0 + 1, 2, var);
+	if (retval)
+		info("Cannot read chip version");
+
+	dev->data.chip_type = var[1] << 8 | var[0];
+
+	if ((dev->data.chip_type == 0x9135) && (dev->data.chip_ver == 2)) {
+		chip_v2 = 1;
+		info("This is IT9135 chip v2");
+	} else {
+		info("This is IT9135 chip v1");
+	}
+
+	/* byte 0~7 = OMEGA1 */
+	if ((fw->data[0] != 'I') || (fw->data[1] != 'T') || (fw->data[2] != '9')
+	    || (fw->data[3] != '1') || (fw->data[4] != '3')
+	    || (fw->data[5] != '5') || (fw->data[6] != 'A')
+	    || (fw->data[7] != 'X')) {
+		err("IT9135 chip v1 FW format Error");
+		return -ENOENT;
+	}
+	fw_file_pos += 8;
+
+	/* byte 8~11 = OMEGA1 fw & script length */
+	fw_script_len_v1 =
+	    (fw->data[fw_file_pos]) + (fw->data[fw_file_pos + 1] << 8) +
+	    (fw->data[fw_file_pos + 2] << 16) +
+	    (fw->data[fw_file_pos + 3] << 24);
+	fw_file_pos += 4;
+	partition_len_v1 = 8 + 4 + fw_script_len_v1;
+
+	if (chip_v2) {
+		fw_file_pos += fw_script_len_v1;
+		if ((fw->data[fw_file_pos] != 'I')
+		    || (fw->data[fw_file_pos + 1] != 'T')
+		    || (fw->data[fw_file_pos + 2] != '9')
+		    || (fw->data[fw_file_pos + 3] != '1')
+		    || (fw->data[fw_file_pos + 4] != '3')
+		    || (fw->data[fw_file_pos + 5] != '5')
+		    || (fw->data[fw_file_pos + 6] != 'B')
+		    || (fw->data[fw_file_pos + 7] != 'X')) {
+			err("IT9135 chip v2 FW format Error");
+			return -ENOENT;
+		}
+		fw_file_pos += 8;
+
+		fw_script_len_v2 =
+		    (fw->data[fw_file_pos]) + (fw->data[fw_file_pos + 1] << 8) +
+		    (fw->data[fw_file_pos + 2] << 16) +
+		    (fw->data[fw_file_pos + 3] << 24);
+		fw_file_pos += 4;
+
+		partition_len_v2 = 8 + 4 + fw_script_len_v2;
+
+		if (fw->size != (partition_len_v1 + partition_len_v2)) {
+			err("FW file size error!!");
+			return -ENOENT;
+		}
+	}
+
+	/* 32 byte Fw version */
+	for (i = 0; i < 32; i++)
+		dev->fw_ver[i] = fw->data[fw_file_pos + i];
+
+	dev->fw_ver[31] = '\0';
+	fw_file_pos += 32;
+
+	/*------------------------ Parsing Firmware ------------------------*/
+
+	/* byte fw_file_pos+0 ~ +7 = OFDM & LINK version */
+	dev->link_ver =
+	    (fw->data[fw_file_pos] << 24) + (fw->data[fw_file_pos + 1] << 16) +
+	    (fw->data[fw_file_pos + 2] << 8) + (fw->data[fw_file_pos + 3]);
+	fw_file_pos += 4;
+
+	dev->ofdm_ver =
+	    (fw->data[fw_file_pos] << 24) + (fw->data[fw_file_pos + 1] << 16) +
+	    (fw->data[fw_file_pos + 2] << 8) + (fw->data[fw_file_pos + 3]);
+	fw_file_pos += 4;
+
+	deb_info("@@@@@@@@@@@@@ Omega 1or2_OFDM ver = 0x%x, LINK ver = 0x%x",
+		 (unsigned int)dev->link_ver, (unsigned int)dev->ofdm_ver);
+
+	/* byte fw_file_pos+0 ~ +3 = FirmwareV2_CODELENGTH */
+	fw_code_len = fw->data[fw_file_pos] + (fw->data[fw_file_pos + 1] << 8) +
+	    (fw->data[fw_file_pos + 2] << 16) +
+	    (fw->data[fw_file_pos + 3] << 24);
+
+	fw_file_pos += 4;
+	/* byte fw_file_pos+0 ~ +3 = FirmwareV2_SEGMENTLENGTH, only first one byte has value */
+	dev->data.fw_parts = fw->data[fw_file_pos];
+	fw_file_pos += 4;
+
+	/* byte fw_file_pos+0 ~ +3 = FirmwareV2_PARTITIONLENGTH */
+	if (fw->data[fw_file_pos] != 1) {
+		err("FirmwareV2_PARTITIONLENGTH != 1 !!");
+		return -EPERM;
+	}
+	fw_file_pos += 4;
+
+	/* byte fw_file_pos+0 ~ +(fw_code_len-1) == Fw code */
+	fw_codes = kzalloc(fw_code_len * sizeof(*fw_codes), GFP_KERNEL);
+	for (i = 0; i < fw_code_len; i++) {
+		fw_codes[i] = (unsigned char)fw->data[fw_file_pos + i];
+	}	
+	dev->data.fw_codes = fw_codes;
+
+	fw_file_pos += fw_code_len;
+
+	/* FirmwareV2_segments */
+	segs = kzalloc(dev->data.fw_parts * sizeof(*segs), GFP_KERNEL);
+	for (i = 0; i < dev->data.fw_parts; i++) {
+		segs[i].type = fw->data[fw_file_pos + j];
+		segs[i].length =
+		    fw->data[fw_file_pos + j + 1] +
+		    (fw->data[fw_file_pos + j + 2] << 8) +
+		    (fw->data[fw_file_pos + j + 3] << 16) +
+		    (fw->data[fw_file_pos + j + 4] << 24);
+		j += 5;
+	}
+	dev->data.fw_segs = segs;
+
+	fw_file_pos += j;
+
+	/* FirmwareV2_partitions */
+	if (dev->data.fw_parts != fw->data[fw_file_pos]) {
+		err("FirmwareV2_SEGMENTLENGTH != FirmwareV2_partitions[0], parsing error!!!");
+		return -EPERM;
+	}
+
+	fw_file_pos += 1;
+
+	/* FirmwareV2_SCRIPTSETLENGTH == 1 */
+	if (fw->data[fw_file_pos] != 1) {
+		err("FirmwareV2_SCRIPTSETLENGTH != 1 !!");
+		return -EPERM;
+	}
+
+	fw_file_pos += 4;
+
+	/* Word FirmwareV2_scriptSets */
+	script_sets = kzalloc(sizeof(u16), GFP_KERNEL);
+	*script_sets = fw->data[fw_file_pos] + (fw->data[fw_file_pos + 1] << 8);
+	dev->data.script_sets = script_sets;
+
+	fw_file_pos += 2;
+
+	/* FirmwareV2_scripts */
+	j = 0;
+	scripts = kzalloc(*script_sets * sizeof(*scripts), GFP_KERNEL);
+	for (i = 0; i < *script_sets; i++) {
+		scripts[i].address = fw->data[fw_file_pos + j] +
+		    (fw->data[fw_file_pos + j + 1] << 8) +
+		    (fw->data[fw_file_pos + j + 2] << 16) +
+		    (fw->data[fw_file_pos + j + 3] << 24);
+
+		scripts[i].value = fw->data[fw_file_pos + j + 4];
+		j += 5;
+	}
+
+	dev->data.scripts = scripts;
+	fw_file_pos += j;
+
+	if (chip_v2 && (fw_file_pos == fw->size)) {
+		info("FW file only include IT9135 v2 firmware");
+		goto end_of_fw;
+	} else if (!chip_v2 && (fw_file_pos == partition_len_v1)) {
+		info("FW file only include IT9135 v1 firmware!");
+		goto end_of_fw;
+	}
+
+	/*--- Parsing Firmware_Afa_Omega_Script ---*/
+
+	dev->data.tuner_script_normal = script_parser(fw, &fw_file_pos,
+						      &(dev->data.
+							tuner_script_sets_normal));
+
+	if (dev->data.tuner_script_normal == NULL)
+		return -EPERM;
+
+	if (chip_v2 && (fw_file_pos == fw->size)) {
+		info("~~~ .Fw file only include Omega2 firmware&Omega_Script!!");
+		goto end_of_fw;
+	} else if (!chip_v2 && (fw_file_pos == partition_len_v1)) {
+		info("~~~ .Fw file only include Omega1 firmware&Omega_Script!!");
+		goto end_of_fw;
+	}
+
+	/*--- Parsing Firmware_Afa_Omega_LNA_Config_1_Script ---*/
+
+	dev->data.tuner_script_lna1 =
+	    script_parser(fw, &fw_file_pos,
+			  &(dev->data.tuner_script_sets_lna1));
+
+	if (dev->data.tuner_script_lna1 == NULL)
+		return -EPERM;
+	if (chip_v2 && (fw_file_pos == fw->size)) {
+		info("~~~ .Fw file only include Omega2 firmware Script1!!");
+		goto end_of_fw;
+	} else if (!chip_v2 && (fw_file_pos == partition_len_v1)) {
+		info("~~~ .Fw file only include Omega1 firmware, Script1!!");
+		goto end_of_fw;
+	}
+
+	/*--- Parsing Firmware_Afa_Omega_LNA_Config_2_Script_V2 ---*/
+	dev->data.tuner_script_lna2 =
+	    script_parser(fw, &fw_file_pos,
+			  &(dev->data.tuner_script_sets_lna2));
+
+	if (dev->data.tuner_script_lna2 == NULL)
+		return -EPERM;
+
+	if (chip_v2 && (fw_file_pos == fw->size)) {
+		info("~~~ .Fw file only include Omega2 firmware, Scripts1&2!!");
+		goto end_of_fw;
+	} else if (!chip_v2 && (fw_file_pos == partition_len_v1)) {
+		info("~~~ .Fw file only include Omega1 firmware, Scripts1&2!!");
+		goto end_of_fw;
+	}
+
+end_of_fw:
+
+	/**** Init Device first ****/
+	retval = it9135_device_init(udev, dev, true);
+	if (retval) {
+		if (retval)
+			err("device_init Fail: 0x%08x\n", retval);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < it9135_device_count; i++) {
+		if (dev->architecture == ARCHITECTURE_PIP) {
+			deb_info("@@@@@@@ adapter == 2");
+			it9135_properties[i].num_adapters = 2;
+			it9135_properties[i].caps = DVB_USB_IS_AN_I2C_ADAPTER;
+		} else {
+			deb_info("@@@@@@@ adapter == 1");
+			it9135_properties[i].caps = 0;
+			it9135_properties[i].num_adapters = 1;
+		}
+
+		/* USB1.1 set smaller buffersize and disable 2nd adapter */
+		if (udev->speed == USB_SPEED_FULL) {
+			it9135_properties[i].adapter[0].stream.u.bulk.buffersize
+			    = (188 * 21);
+		} else {
+			it9135_properties[i].adapter[0].stream.u.bulk.buffersize
+			    = (188 * 348);
+		}
+
+	}
+
+	return 0;
+}
+
+static int it9135_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	return 0;
+}
+
+static int it9135_identify_state(struct usb_device *udev,
+				 struct dvb_usb_device_properties *props,
+				 struct dvb_usb_device_description **desc,
+				 int *cold)
+{
+	/* *cold = 0; */
+	return 0;
+}
+
+static int it9135_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+			   int num)
+{
+	return 0;
+}
+
+static u32 it9135_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm it9135_i2c_algo = {
+	.master_xfer = it9135_i2c_xfer,
+	.functionality = it9135_i2c_func,
+};
+
+/* Called to attach the possible frontends */
+static int it9135_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	deb_func("Enter %s Function - chip=%d\n", __func__, adap->id);
+
+	adap->fe = it9135_attach(adap);
+
+	return adap->fe == NULL ? -ENODEV : 0;
+}
+
+static int it9135_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+	deb_func("Enter %s Function - (%s) streaming state for chip=%d\n",
+		 __func__, onoff ? "ON" : "OFF", adap->id);
+
+	return 0;
+}
+
+/* -------------------------------------------------------------------------- */
+
+/* ******* IT9135 DVB USB DEVICE ******* */
+
+/* Table of devices that work with this driver */
+struct usb_device_id it9135_usb_id_table[] = {
+	{USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135)},
+	{USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005)},
+	{USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006)},
+	{0},			/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, it9135_usb_id_table);
+
+struct dvb_usb_device_properties it9135_properties[] = {
+	{
+	 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+	 .download_firmware = it9135_download_firmware,
+	 .firmware = "dvb-usb-it9135.fw",
+
+	 .size_of_priv = sizeof(struct it9135_state),
+	 .i2c_algo = &it9135_i2c_algo,
+
+	 .usb_ctrl = DEVICE_SPECIFIC,
+
+	 .no_reconnect = 1,
+	 .power_ctrl = it9135_power_ctrl,
+	 .identify_state = it9135_identify_state,
+	 .num_adapters = 2,
+	 .adapter = {
+		     {
+		      .caps =
+		      DVB_USB_ADAP_HAS_PID_FILTER |
+		      DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+		      .pid_filter_count = 32,
+		      .pid_filter = it9135_pid_filter,
+		      .pid_filter_ctrl = it9135_pid_filter_ctrl,
+		      .frontend_attach = it9135_frontend_attach,
+		      .streaming_ctrl = it9135_streaming_ctrl,
+		      .stream = {
+				 .type = USB_BULK,
+				 .count = 4,
+				 .endpoint = 0x84,
+				 .u = {
+				       .bulk = {
+						.buffersize = (188 * 348),
+						}
+				       }
+				 }
+		      },
+		     {
+		      .caps =
+		      DVB_USB_ADAP_HAS_PID_FILTER |
+		      DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+		      .pid_filter_count = 32,
+		      .pid_filter = it9135_pid_filter,
+		      .pid_filter_ctrl = it9135_pid_filter_ctrl,
+		      .frontend_attach = it9135_frontend_attach,
+		      .streaming_ctrl = it9135_streaming_ctrl,
+		      .stream = {
+				 .type = USB_BULK,
+				 .count = 4,
+				 .endpoint = 0x85,
+				 .u = {
+				       .bulk = {
+						.buffersize = (188 * 348),
+						}
+				       }
+				 }
+		      },
+		     },
+	 .num_device_descs = 1,
+	 .devices = {
+		     {"ITEtech USB2.0 DVB-T Recevier",
+		      {&it9135_usb_id_table[0], &it9135_usb_id_table[1],
+		       &it9135_usb_id_table[2], NULL},
+		      {NULL},
+		      },
+		     {NULL},
+
+		     }
+	 }
+};
+
+int it9135_device_count = ARRAY_SIZE(it9135_properties);
+
+/* Register a DVB_USB device and a USB device node end */
+static int it9135_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	int retval = -ENOMEM;
+	int i;
+	struct dvb_usb_device *d = NULL;
+
+	if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
+
+		if (it9135_device_count > 2)
+			it9135_device_count = 2;
+
+		for (i = 0; i < it9135_device_count; i++) {
+			retval =
+			    dvb_usb_device_init(intf, &it9135_properties[i],
+						THIS_MODULE, &d, adapter_nr);
+
+			if (!retval) {
+				deb_info("dvb_usb_device_init success!!\n");
+				break;
+			}
+			if (retval != -ENODEV)
+				return retval;
+		}
+		if (retval)
+			return retval;
+	}
+
+	return retval;
+}
+
+static int it9135_suspend(struct usb_interface *intf, pm_message_t state)
+{
+	deb_func("Enter %s Function\n", __func__);
+	return 0;
+}
+
+static int it9135_resume(struct usb_interface *intf)
+{
+	deb_func("Enter %s Function\n", __func__);
+	return 0;
+}
+
+static int it9135_reset_resume(struct usb_interface *intf)
+{
+	int retval = -ENOMEM;
+	int i;
+	struct it9135_dev_ctx *dev = NULL;
+	struct usb_device *udev;
+
+	deb_func("Enter %s Function\n", __func__);
+
+	udev = interface_to_usbdev(intf);
+	dev = dev_get_drvdata(&udev->dev);
+
+	retval = it9135_device_init(udev, dev, 1);
+	if (retval) {
+		if (retval)
+			err("device_init Fail: 0x%08x", retval);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < dev->data.chip_num; i++)
+		it9135_dl_ap_ctrl(dev, i, 1);
+
+	return 0;
+}
+
+static void it9135_i2c_exit(struct dvb_usb_device *d)
+{
+	struct it9135_state *state = d->priv;
+
+	deb_func("%s:\n", __func__);
+
+	/* remove 2nd I2C adapter */
+	if (d->state & DVB_USB_STATE_I2C) {
+		try_module_get(THIS_MODULE);
+		i2c_del_adapter(&state->i2c_adap);
+	}
+}
+
+static void it9135_disconnect(struct usb_interface *intf)
+{
+	struct it9135_dev_ctx *dev;
+	struct usb_device *udev;
+	int minor = intf->minor;
+	struct dvb_usb_device *d = usb_get_intfdata(intf);
+
+	deb_func("%s:\n", __func__);
+
+	udev = interface_to_usbdev(intf);
+	dev = dev_get_drvdata(&udev->dev);
+	dev->disconnect = 1;
+
+	kfree(dev->data.script_sets);
+	kfree(dev->data.scripts);
+	kfree(dev->data.fw_codes);
+	kfree(dev->data.fw_segs);
+	kfree(dev->data.tuner_script_normal);
+	kfree(dev->data.tuner_script_lna1);
+	kfree(dev->data.tuner_script_lna2);
+	kfree(dev);
+
+	/* remove 2nd I2C adapter */
+	if (d != NULL && d->desc != NULL)
+		it9135_i2c_exit(d);
+
+	try_module_get(THIS_MODULE);
+	dvb_usb_device_exit(intf);
+
+	deb_info("ITEtech USB #%d now disconnected", minor);
+}
+
+static struct usb_driver it9135_driver = {
+	.name = "dvb_usb_it9135",
+	.probe = it9135_probe,
+	.disconnect = it9135_disconnect,
+	.id_table = it9135_usb_id_table,
+	.suspend = it9135_suspend,
+	.resume = it9135_resume,
+	.reset_resume = it9135_reset_resume,
+};
+
+/* Insert it9135 module and prepare to register it9135 driver */
+static int __init it9135_module_init(void)
+{
+	int ret;
+
+	deb_info("dvb_usb_it9135 Module is loaded\n");
+
+	ret = usb_register(&it9135_driver);
+
+	if (ret) {
+		err("usb_register failed. Error number %d", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/* Deregister this driver with the USB subsystem */
+static void __exit it9135_module_exit(void)
+{
+	deb_info("dvb_usb_it9135 Module is unloaded!\n");
+	usb_deregister(&it9135_driver);
+}
+
+module_init(it9135_module_init);
+module_exit(it9135_module_exit);
+
+MODULE_AUTHOR("Jason Dong <jason.dong@ite.com.tw>");
+MODULE_DESCRIPTION("Driver for devices based on ITEtech IT9135");
+MODULE_VERSION(DRIVER_RELEASE_VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/it9135.h b/drivers/media/dvb/dvb-usb/it9135.h
new file mode 100644
index 0000000..d1cf54c
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/it9135.h
@@ -0,0 +1,155 @@
+/*
+ * DVB USB Linux driver for IT9135 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2011 ITE Technologies, INC.
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ */
+
+#ifndef _IT9135_H_
+#define _IT9135_H_
+
+#define DVB_USB_LOG_PREFIX "IT9135"
+
+#include <linux/version.h>
+
+#include "dvb-usb.h"
+#include "it9135-fe.h"
+
+#define DRIVER_RELEASE_VERSION	"v11.08.02.1"
+/* **************** customization **************** */
+extern int dvb_usb_it9135_debug;
+
+#ifdef CONFIG_DVB_USB_IT9135_DEBUG
+#define deb_func(args...)	printk(KERN_INFO args)
+#define deb_info(args...)	printk(KERN_INFO args)
+#define deb_warning(args...)	printk(KERN_INFO args)
+#define dmg(format, arg...)	printk(KERN_ERR DVB_USB_LOG_PREFIX "::" "%s: " format "\n" , __func__, ## arg)
+#else
+#define deb_func(args...)	dprintk(dvb_usb_it9135_debug, 0x01, args)
+#define deb_info(args...)	dprintk(dvb_usb_it9135_debug, 0x02, args)
+#define deb_warning(args...)	dprintk(dvb_usb_it9135_debug, 0x04, args)
+#define dmg(format, arg...)	printk(KERN_ERR DVB_USB_LOG_PREFIX "::" "%s: " format "\n" , __func__, ## arg)
+#endif
+/* **************** from device.h **************** */
+#define IT9135_TS_PACKET_SIZE		188
+#define IT9135_TS_PACKET_COUNT_HI	348
+#define IT9135_TS_PACKET_COUNT_FU	21
+
+/* **************** from driver.h **************** */
+#define IT9135_TS_FRAMES_HI		128
+#define IT9135_TS_FRAMES_FU		128
+#define IT9135_MAX_USB20_IRP_NUM	5
+#define IT9135_MAX_USB11_IRP_NUM	2
+
+/* **************** from afdrv.h **************** */
+#define EEPROM_FLB_OFS		8
+
+#define EEPROM_IRMODE       (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x10)	/* 00:disabled, 01:HID */
+#define EEPROM_SELSUSPEND   (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28)	/* Selective Suspend Mode */
+#define EEPROM_TSMODE       (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+1)	/* 0:one ts, 1:dual ts */
+#define EEPROM_2WIREADDR    (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+2)	/* MPEG2 2WireAddr */
+#define EEPROM_SUSPEND      (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+3)	/* Suspend Mode */
+#define EEPROM_IRTYPE       (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+4)	/* 0:NEC, 1:RC6 */
+#define EEPROM_SAWBW1       (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+5)
+#define EEPROM_XTAL1        (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+6)	/* 0:28800, 1:20480 */
+#define EEPROM_SPECINV1     (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+7)
+#define EEPROM_TUNERID      (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x30+4)
+#define EEPROM_IFFREQL      (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x30)
+#define EEPROM_IFFREQH      (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x30+1)
+#define EEPROM_IF1L         (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x30+2)
+#define EEPROM_IF1H         (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x30+3)
+#define EEPROM_SHIFT        (0x10)	/* EEPROM Addr Shift for slave front end */
+
+/* **************** from device.h **************** */
+struct it9135_state {
+	struct i2c_adapter i2c_adap;	/* I2C adapter for 2nd FE */
+	u8 rc_repeat;
+	u32 rc_keycode;
+};
+
+struct it9135_tuner_info {
+	int inited;
+	int setting_freq;
+	unsigned short id;
+	int set;
+	int locked;
+};
+
+struct it9135_filter_ctx_hw {
+	struct it9135_tuner_info tuner_info;
+	unsigned long curr_freq;
+	unsigned short curr_bw;
+	unsigned long desired_freq;
+	unsigned short desired_bw;
+	int timer_on;
+	int en_pid;
+	int ap_on;
+	int reset_ts;
+	unsigned char ovr_flw_chk;
+};
+
+/* IT9135 device context */
+struct it9135_dev_ctx {
+	struct it9135_filter_ctx_hw fc[2];
+	struct mutex it9135_mutex;
+	int boot_code;
+	int ep12_err;
+	int ep45_err;
+	int dual_ts;
+	int ir_tab_load;
+	int proprietary_ir;
+	u8 ir_type;		/* EE chose NEC RC5 RC6 table */
+	int surprise_removal;
+	int dev_not_resp;
+	int enter_suspend;
+	u16 usb_mode;
+	u16 max_packet_sz;
+	u32 ts_frames;
+	u32 ts_frame_sz;
+	u32 ts_frame_sz_dw;
+	u32 ts_packet_cnt;
+	int selective_suspend;
+	u32 active_filter;
+	unsigned char architecture;
+	unsigned char stream_type;
+	int dca_pip;
+	int swap_filter;
+	u8 filter_cnt;
+	u8 filter_index;
+	int tuner_pw_off;
+	u8 usb_ctrl_timeOut;
+	struct it9135_data data;
+	int disconnect;
+	/* patch for Om1 Om2 EE */
+	unsigned char chip_ver;
+	int already_nim_reset_seq;
+	/* Fw versiion */
+	u32 ofdm_ver;
+	u32 link_ver;
+	u8 fw_ver[32];
+
+};
+
+struct it9135_ofdm_channel {
+	u32 rf_khz;
+	u8 bw;
+	s16 nfft;
+	s16 guard;
+	s16 nqam;
+	s16 vit_hrch;
+	s16 vit_select_hp;
+	s16 vit_alpha;
+	s16 vit_code_rate_hp;
+	s16 vit_code_rate_lp;
+	u8 intlv_native;
+};
+
+/**********************************************/
+
+extern int it9135_device_count;
+
+#endif
-- 
1.7.1




^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 1/2] IT9135 Add support for KWORLD_UB499_2T_T09 (id 1b80:e409)
  2011-08-05 10:24 [PATCH 1/1] Add driver support for ITE IT9135 device jasondong
@ 2011-08-06  9:51 ` Malcolm Priestley
  2011-08-06  9:52 ` [PATCH 2/2] IT9135 add MFE support to driver Malcolm Priestley
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Malcolm Priestley @ 2011-08-06  9:51 UTC (permalink / raw)
  To: linux-media; +Cc: jasondong

Add support for KWORLD_UB499_2T_T09 to IT9135 Driver

***Please note*** that adapter 2 on this device does not function
correctly.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
 drivers/media/dvb/dvb-usb/dvb-usb-ids.h |    1 +
 drivers/media/dvb/dvb-usb/it9135.c      |   23 ++++++++++++-----------
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index a0f2ee9..4208d3f 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -137,6 +137,7 @@
 #define USB_PID_KWORLD_PC160_2T				0xc160
 #define USB_PID_KWORLD_PC160_T				0xc161
 #define USB_PID_KWORLD_UB383_T				0xe383
+#define USB_PID_KWORLD_UB499_2T_T09			0xe409
 #define USB_PID_KWORLD_VSTREAM_COLD			0x17de
 #define USB_PID_KWORLD_VSTREAM_WARM			0x17df
 #define USB_PID_TERRATEC_CINERGY_T_USB_XE		0x0055
diff --git a/drivers/media/dvb/dvb-usb/it9135.c b/drivers/media/dvb/dvb-usb/it9135.c
index 7fa21c7..772adf4 100644
--- a/drivers/media/dvb/dvb-usb/it9135.c
+++ b/drivers/media/dvb/dvb-usb/it9135.c
@@ -2256,6 +2256,7 @@ struct usb_device_id it9135_usb_id_table[] = {
 	{USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135)},
 	{USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005)},
 	{USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006)},
+	{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09)},
 	{0},			/* Terminating entry */
 };
 
@@ -2319,18 +2320,18 @@ struct dvb_usb_device_properties it9135_properties[] = {
 				       }
 				 }
 		      },
-		     },
-	 .num_device_descs = 1,
+	},
+	 .num_device_descs = 2,
 	 .devices = {
-		     {"ITEtech USB2.0 DVB-T Recevier",
-		      {&it9135_usb_id_table[0], &it9135_usb_id_table[1],
-		       &it9135_usb_id_table[2], NULL},
-		      {NULL},
-		      },
-		     {NULL},
-
-		     }
-	 }
+		{   "ITEtech USB2.0 DVB-T Recevier",
+			{ &it9135_usb_id_table[0], &it9135_usb_id_table[1],
+				&it9135_usb_id_table[2], NULL },
+			},
+		{   "Kworld UB499-2T T09",
+			{ &it9135_usb_id_table[3], NULL },
+			},
+		}
+	}
 };
 
 int it9135_device_count = ARRAY_SIZE(it9135_properties);
-- 
1.7.4.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] IT9135 add MFE support to driver
  2011-08-05 10:24 [PATCH 1/1] Add driver support for ITE IT9135 device jasondong
  2011-08-06  9:51 ` [PATCH 1/2] IT9135 Add support for KWORLD_UB499_2T_T09 (id 1b80:e409) Malcolm Priestley
@ 2011-08-06  9:52 ` Malcolm Priestley
  2011-08-24 18:08 ` [PATCH 1/1] Add driver support for ITE IT9135 device Arkadiusz Miskiewicz
  2011-09-03 13:44 ` Mauro Carvalho Chehab
  3 siblings, 0 replies; 6+ messages in thread
From: Malcolm Priestley @ 2011-08-06  9:52 UTC (permalink / raw)
  To: linux-media; +Cc: jasondong

Add MFE Support.

 Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>

---
 drivers/media/dvb/dvb-usb/it9135.c |    8 +++-----
 1 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/media/dvb/dvb-usb/it9135.c b/drivers/media/dvb/dvb-usb/it9135.c
index 772adf4..a8ab028 100644
--- a/drivers/media/dvb/dvb-usb/it9135.c
+++ b/drivers/media/dvb/dvb-usb/it9135.c
@@ -1781,8 +1781,7 @@ static struct dvb_frontend_ops it9135_ops = {
 
 static int it9135_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
-	struct it9135_dev_ctx *dev =
-	    (struct it9135_dev_ctx *)adap->fe->demodulator_priv;
+	struct it9135_dev_ctx *dev = adap->fe[0]->demodulator_priv;
 	int ret = 0;
 
 	deb_info("%s: onoff:%d\n", __func__, onoff);
@@ -1813,8 +1812,7 @@ static int it9135_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
 static int it9135_pid_filter(struct dvb_usb_adapter *adap, int index,
 			     u16 pidnum, int onoff)
 {
-	struct it9135_dev_ctx *dev =
-	    (struct it9135_dev_ctx *)adap->fe->demodulator_priv;
+	struct it9135_dev_ctx *dev = adap->fe[0]->demodulator_priv;
 	unsigned short pid;
 	int ret = 0;
 
@@ -2234,7 +2232,7 @@ static int it9135_frontend_attach(struct dvb_usb_adapter *adap)
 {
 	deb_func("Enter %s Function - chip=%d\n", __func__, adap->id);
 
-	adap->fe = it9135_attach(adap);
+	adap->fe[0] = it9135_attach(adap);
 
 	return adap->fe == NULL ? -ENODEV : 0;
 }
-- 
1.7.4.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/1] Add driver support for ITE IT9135 device
  2011-08-05 10:24 [PATCH 1/1] Add driver support for ITE IT9135 device jasondong
  2011-08-06  9:51 ` [PATCH 1/2] IT9135 Add support for KWORLD_UB499_2T_T09 (id 1b80:e409) Malcolm Priestley
  2011-08-06  9:52 ` [PATCH 2/2] IT9135 add MFE support to driver Malcolm Priestley
@ 2011-08-24 18:08 ` Arkadiusz Miskiewicz
  2011-08-24 20:27   ` Arkadiusz Miskiewicz
  2011-09-03 13:44 ` Mauro Carvalho Chehab
  3 siblings, 1 reply; 6+ messages in thread
From: Arkadiusz Miskiewicz @ 2011-08-24 18:08 UTC (permalink / raw)
  To: jasondong; +Cc: linux-media

On Friday 05 of August 2011, jasondong wrote:
> This is DVB USB Linux driver for ITEtech IT9135 base USB TV module.
> It supported the IT9135 AX and BX chip versions.

Hi,

The quick review by crop@freenode was:

"I quick check it and didnt like much since it is not plitted logically 
correct, as usb-bridge, demod and tuner. now all are rather much one big 
blob".

so I guess you have to split it into pieces in a way other dvb drivers already 
in kernel tree are done. Unfortunately I don't know which existing driver is 
the best example on how to do things.

ps. are the IT9135 docs available anywhere?

ps2. on current linus 3.1 git + your 2 patches it is at least detected (cannot 
test more yet - no dbv-t signal here; it's to be available in incoming days)

[ 1152.752132] usb 2-2: new high speed USB device number 10 using ehci_hcd
[ 1152.820365] hub 2-0:1.0: unable to enumerate USB device on port 2
[ 1153.156792] hub 6-0:1.0: unable to enumerate USB device on port 2
[ 1157.056107] usb 2-1: new high speed USB device number 11 using ehci_hcd
[ 1157.192287] usb 2-1: New USB device found, idVendor=048d, idProduct=9005
[ 1157.192297] usb 2-1: New USB device strings: Mfr=1, Product=0, 
SerialNumber=3
[ 1157.192304] usb 2-1: Manufacturer: ITE Technologies, Inc.
[ 1157.192309] usb 2-1: SerialNumber: AF0102020700001
[ 1157.193145] dvb-usb: found a 'ITEtech USB2.0 DVB-T Recevier' in cold state, 
will try to load a firmware
[ 1157.196882] dvb-usb: downloading firmware from file 'dvb-usb-it9135.fw'
[ 1157.198578] IT9135: This is IT9135 chip v1
[ 1157.198678] IT9135: ~~~ .Fw file only include Omega1 firmware, Scripts1&2!!
[ 1157.198684] IT9135: =========================================
[ 1157.198689] IT9135: DRIVER_RELEASE_VERSION:    v11.08.02.1
[ 1157.198694] IT9135: FW_RELEASE_VERSION:        V1_0_26_2
[ 1157.198700] IT9135: API_RELEASE_VERSION:       203.20110426.0
[ 1157.198705] IT9135: =========================================
[ 1157.504659] IT9135: it9135_device_init success!!
[ 1157.504686] dvb-usb: found a 'ITEtech USB2.0 DVB-T Recevier' in warm state.
[ 1157.504708] dvb-usb: will pass the complete MPEG2 transport stream to the 
software demuxer.
[ 1157.505522] DVB: registering new adapter (ITEtech USB2.0 DVB-T Recevier)
[ 1157.506763] DVB: registering adapter 0 frontend 0 (IT9135 USB DVB-T)...
[ 1157.506920] dvb-usb: ITEtech USB2.0 DVB-T Recevier successfully initialized 
and connected.
-- 
Arkadiusz Miśkiewicz        PLD/Linux Team
arekm / maven.pl            http://ftp.pld-linux.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/1] Add driver support for ITE IT9135 device
  2011-08-24 18:08 ` [PATCH 1/1] Add driver support for ITE IT9135 device Arkadiusz Miskiewicz
@ 2011-08-24 20:27   ` Arkadiusz Miskiewicz
  0 siblings, 0 replies; 6+ messages in thread
From: Arkadiusz Miskiewicz @ 2011-08-24 20:27 UTC (permalink / raw)
  To: jasondong; +Cc: linux-media

On Wednesday 24 of August 2011, Arkadiusz Miskiewicz wrote:
> On Friday 05 of August 2011, jasondong wrote:
> > This is DVB USB Linux driver for ITEtech IT9135 base USB TV module.
> > It supported the IT9135 AX and BX chip versions.
> 
> Hi,
> 
> The quick review by crop@freenode was:
> 
> "I quick check it and didnt like much since it is not plitted logically
> correct, as usb-bridge, demod and tuner. now all are rather much one big
> blob".
> 
> so I guess you have to split it into pieces in a way other dvb drivers
> already in kernel tree are done. Unfortunately I don't know which existing
> driver is the best example on how to do things.

More comments from irc:
"22:09 < crope> arekm: any current DVB USB driver. there is very many of 
integrated (2-in-1, or 3-in-1) drivers which are splitted correctly
22:10 < crope> ec168, af9015, some dibcom models?, ce6320, rtl2831u
22:11 < crope> you *must* implement all logical parts as own drivers no matter 
of those are integrated to one silicon or not. it is generally seen those
               parts used are sold as not integrated too
22:12 < crope> for example that IT9135, I really think it uses af9033 demod, 
which is sold as own part and also integrated to af9015. and very likely 
IT9135
               contains same USB-brdge than AF9035. only difference is 
integrated tuner
22:13 < crope> so IT9135 == AF9035+ ITXXXX tuner in one package. when you 
split driver correctly to logical parts you can use same drivers
22:14 < crope> and AF9035 == AF903XX USB-bridge + AF9033 demod
22:17 < crope> all DVB USB drivers we have consist of 2 parts (drivers). 1) 
USB-interface driver (aka DVB USB) 2) demodulator driver 3) tuner driver
22:17 < crope> all DVB USB drivers we have consist of 3 parts (drivers). 1) 
USB-interface driver (aka DVB USB) 2) demodulator driver 3) tuner driver
"

-- 
Arkadiusz Miśkiewicz        PLD/Linux Team
arekm / maven.pl            http://ftp.pld-linux.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/1] Add driver support for ITE IT9135 device
  2011-08-05 10:24 [PATCH 1/1] Add driver support for ITE IT9135 device jasondong
                   ` (2 preceding siblings ...)
  2011-08-24 18:08 ` [PATCH 1/1] Add driver support for ITE IT9135 device Arkadiusz Miskiewicz
@ 2011-09-03 13:44 ` Mauro Carvalho Chehab
  3 siblings, 0 replies; 6+ messages in thread
From: Mauro Carvalho Chehab @ 2011-09-03 13:44 UTC (permalink / raw)
  To: jasondong; +Cc: linux-media

Hi Jason,

Em 05-08-2011 07:24, jasondong escreveu:
> This is DVB USB Linux driver for ITEtech IT9135 base USB TV module.
> It supported the IT9135 AX and BX chip versions.

See my comments bellow.

Thanks,
Mauro

> 
> Signed-off-by: jasondong <jason.dong@ite.com.tw>
> ---
>  Documentation/dvb/get_dvb_firmware      |   17 +-
>  drivers/media/dvb/dvb-usb/Kconfig       |    6 +
>  drivers/media/dvb/dvb-usb/Makefile      |    3 +
>  drivers/media/dvb/dvb-usb/dvb-usb-ids.h |    4 +
>  drivers/media/dvb/dvb-usb/it9135-fe.c   | 4743 +++++++++++++++++++++++++++++++
>  drivers/media/dvb/dvb-usb/it9135-fe.h   | 1632 +++++++++++
>  drivers/media/dvb/dvb-usb/it9135.c      | 2492 ++++++++++++++++
>  drivers/media/dvb/dvb-usb/it9135.h      |  155 +
>  8 files changed, 9051 insertions(+), 1 deletions(-)
>  mode change 100644 => 100755 Documentation/dvb/get_dvb_firmware
>  create mode 100644 drivers/media/dvb/dvb-usb/it9135-fe.c
>  create mode 100644 drivers/media/dvb/dvb-usb/it9135-fe.h
>  create mode 100644 drivers/media/dvb/dvb-usb/it9135.c
>  create mode 100644 drivers/media/dvb/dvb-usb/it9135.h
> 
> diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
> old mode 100644
> new mode 100755
> index 3348d31..1b30198
> --- a/Documentation/dvb/get_dvb_firmware
> +++ b/Documentation/dvb/get_dvb_firmware
> @@ -27,7 +27,7 @@ use IO::Handle;
>  		"or51211", "or51132_qam", "or51132_vsb", "bluebird",
>  		"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
>  		"af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395",
> -		"lme2510c_s7395_old");
> +		"lme2510c_s7395_old", "it9135");
>  
>  # Check args
>  syntax() if (scalar(@ARGV) != 1);
> @@ -634,6 +634,21 @@ sub lme2510c_s7395_old {
>      $outfile;
>  }
>  
> +sub it9135 {
> +	my $sourcefile = "dvb-usb-it9135.zip";
> +	my $url = "http://www.ite.com.tw/uploads/firmware/v3.6.0.0/$sourcefile";
> +	my $hash = "1e55f6c8833f1d0ae067c2bb2953e6a9";
> +	my $outfile = "dvb-usb-it9135.fw";
> +
> +	checkstandard();
> +
> +	wgetfile($sourcefile, $url);
> +	unzip($sourcefile, "");
> +	verify("$outfile", $hash);
> +
> +	$outfile;
> +}
> +
>  # ---------------------------------------------------------------
>  # Utilities
>  
> diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
> index e85304c..468fe8e 100644
> --- a/drivers/media/dvb/dvb-usb/Kconfig
> +++ b/drivers/media/dvb/dvb-usb/Kconfig
> @@ -373,3 +373,9 @@ config DVB_USB_TECHNISAT_USB2
>  	select DVB_STV6110x if !DVB_FE_CUSTOMISE
>  	help
>  	  Say Y here to support the Technisat USB2 DVB-S/S2 device
> +
> +config DVB_USB_IT9135
> +	tristate "ITEtech IT9135 DVB-T USB2.0 support"
> +	depends on DVB_USB
> +	help
> +	  Say Y here to support the ITE IT9135 based DVB-T USB2.0 receiver
> diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
> index 4bac13d..466b23c 100644
> --- a/drivers/media/dvb/dvb-usb/Makefile
> +++ b/drivers/media/dvb/dvb-usb/Makefile
> @@ -94,6 +94,9 @@ obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
>  dvb-usb-technisat-usb2-objs = technisat-usb2.o
>  obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
>  
> +dvb-usb-it9135-objs := it9135.o it9135-fe.o
> +obj-$(CONFIG_DVB_USB_IT9135) += dvb-usb-it9135.o
> +
>  EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
>  # due to tuner-xc3028
>  EXTRA_CFLAGS += -Idrivers/media/common/tuners
> diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
> index 21b1549..ffeb338 100644
> --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
> +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
> @@ -67,6 +67,7 @@
>  #define USB_VID_EVOLUTEPC			0x1e59
>  #define USB_VID_AZUREWAVE			0x13d3
>  #define USB_VID_TECHNISAT			0x14f7
> +#define USB_VID_ITETECH				0x048d
>  
>  /* Product IDs */
>  #define USB_PID_ADSTECH_USB2_COLD			0xa333
> @@ -320,4 +321,7 @@
>  #define USB_PID_TECHNISAT_USB2_HDCI_V2			0x0002
>  #define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2		0x0004
>  #define USB_PID_TECHNISAT_USB2_DVB_S2			0x0500
> +#define USB_PID_ITETECH_IT9135				0x9135
> +#define USB_PID_ITETECH_IT9135_9005			0x9005
> +#define USB_PID_ITETECH_IT9135_9006			0x9006
>  #endif
> diff --git a/drivers/media/dvb/dvb-usb/it9135-fe.c b/drivers/media/dvb/dvb-usb/it9135-fe.c
> new file mode 100644
> index 0000000..e3ddbf3
> --- /dev/null
> +++ b/drivers/media/dvb/dvb-usb/it9135-fe.c
> @@ -0,0 +1,4743 @@
> +/*
> + * DVB USB Linux driver for IT9135 DVB-T USB2.0 receiver
> + *
> + * Copyright (C) 2011 ITE Technologies, INC.
> + *
> + *    This program is free software; you can redistribute it and/or modify
> + *    it under the terms of the GNU General Public License as published by
> + *    the Free Software Foundation; either version 2 of the License, or
> + *    (at your option) any later version.
> + */
> +
> +#include <linux/delay.h>
> +
> +#include "it9135.h"
> +
> +static unsigned long it9135_enter_mutex(struct it9135_data *data)
> +{
> +	/*
> +	 *  ToDo:  Add code here
> +	 */
> +	return ERROR_NO_ERROR;
> +}
> +
> +static unsigned long it9135_leave_mutex(struct it9135_data *data)
> +{
> +	/*
> +	 *  ToDo:  Add code here
> +	 */
> +	return ERROR_NO_ERROR;
> +}

Hmmm... please implement mutexes were needed, but, instead of calling a
"generic" code for that, just call mutex_lock/mutex_unlock where needed.

> +
> +/*
> + * IT9135 command functions
> + */
> +#define IT9135_MAX_CMD_SIZE		63
> +
> +static unsigned long it9135_cmd_add_checksum(struct it9135_data *data,
> +					     unsigned long *buff_len,
> +					     unsigned char *buffer)
> +{
> +	unsigned long error = ERROR_NO_ERROR;

Don't create your own errorspace. Linux has its own.

In this specific case, the better would be to just define this function
as

static void it9135_cmd_add_checksum(...)

> +	unsigned long loop = (*buff_len - 1) / 2;
> +	unsigned long remain = (*buff_len - 1) % 2;
> +	unsigned long i;
> +	unsigned short checksum = 0;
> +
> +	for (i = 0; i < loop; i++)
> +		checksum +=
> +		    (unsigned short)(buffer[2 * i + 1] << 8) +
> +		    (unsigned short)(buffer[2 * i + 2]);
> +	if (remain)
> +		checksum += (unsigned short)(buffer[*buff_len - 1] << 8);
> +
> +	checksum = ~checksum;
> +	buffer[*buff_len] = (unsigned char)((checksum & 0xFF00) >> 8);
> +	buffer[*buff_len + 1] = (unsigned char)(checksum & 0x00FF);
> +	buffer[0] = (unsigned char)(*buff_len + 1);
> +	*buff_len += 2;
> +
> +	return error;
> +}
> +
> +static unsigned long it9135_cmd_remove_checksum(struct it9135_data *data,
> +						unsigned long *buff_len,
> +						unsigned char *buffer)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned long loop = (*buff_len - 3) / 2;
> +	unsigned long remain = (*buff_len - 3) % 2;
> +	unsigned long i;
> +	unsigned short checksum = 0;
> +
> +	for (i = 0; i < loop; i++)
> +		checksum +=
> +		    (unsigned short)(buffer[2 * i + 1] << 8) +
> +		    (unsigned short)(buffer[2 * i + 2]);
> +	if (remain)
> +		checksum += (unsigned short)(buffer[*buff_len - 3] << 8);
> +
> +	checksum = ~checksum;
> +	if (((unsigned short)(buffer[*buff_len - 2] << 8) +
> +	     (unsigned short)(buffer[*buff_len - 1])) != checksum) {
> +		error = ERROR_WRONG_CHECKSUM;

If that means that the message arrived wrong, -EIO is the proper error code.

> +		goto exit;
> +	}
> +	if (buffer[2])
> +		error = ERROR_FIRMWARE_STATUS | buffer[2];
> +
> +	buffer[0] = (unsigned char)(*buff_len - 3);
> +	*buff_len -= 2;
> +
> +exit:
> +	return error;
> +}
> +
> +#define IT9135_USB_BULK_TIMEOUT		2000

Better to put such define at the beginning of the file.

> +
> +static unsigned long it9135_cmd_bus_tx(struct it9135_data *data,
> +				       unsigned long buff_len,
> +				       unsigned char *buffer)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	int act_len, ret;
> +
> +	ret = usb_bulk_msg(usb_get_dev(data->driver),
> +			   usb_sndbulkpipe(usb_get_dev(data->driver), 0x02),
> +			   buffer, buff_len, &act_len, IT9135_USB_BULK_TIMEOUT);
> +
> +	if (ret) {
> +		error = ERROR_USB_WRITE_FAIL;

No. Please return the error code from usb_bulk_msg.

> +		err(" it9135_cmd_bus_tx fail : %d!", ret);
> +	}
> +
> +	return error;
> +}
> +
> +static unsigned long it9135_cmd_bus_rx(struct it9135_data *data,
> +				       unsigned long buff_len,
> +				       unsigned char *buffer)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	int act_len, ret;
> +
> +	ret = usb_bulk_msg(usb_get_dev(data->driver),
> +			   usb_rcvbulkpipe(usb_get_dev(data->driver), 129),
> +			   buffer, 125, &act_len, IT9135_USB_BULK_TIMEOUT);
> +
> +	if (ret) {
> +		error = ERROR_USB_WRITE_FAIL;

No. Please return the error code from usb_bulk_msg.

I won't repeat this over and over. All functions that return errors
should just use the standard error codes defined on Linux, or 0 if
no error.

> +		err(" it9135_cmd_bus_rx fail: %d!", ret);
> +	}
> +
> +	return error;
> +}
> +
> +static unsigned long it9135_cmd_loadfirmware(struct it9135_data *data,
> +					     unsigned long length,
> +					     unsigned char *firmware)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned short command;
> +	unsigned long loop;
> +	unsigned long remain;
> +	unsigned long i, j, k;
> +	unsigned char buffer[255];
> +	unsigned long payloadLength;

Please don't use CamelCase in Linux. "payload_len" is a better naming.

> +	unsigned long buff_len;
> +	unsigned long remain_len;
> +	unsigned long send_len;
> +
> +	it9135_enter_mutex(data);
> +
> +	payloadLength = (IT9135_MAX_CMD_SIZE - 6);

> +	loop = length / payloadLength;
> +	remain = length % payloadLength;
> +
> +	k = 0;
> +	command = it9135_build_command(CMD_FW_DOWNLOAD, PROCESSOR_LINK, 0);
> +	for (i = 0; i < loop; i++) {
> +		buffer[1] = (unsigned char)(command >> 8);
> +		buffer[2] = (unsigned char)command;
> +		buffer[3] = (unsigned char)data->cmd_seq++;
> +
> +		for (j = 0; j < payloadLength; j++)
> +			buffer[4 + j] = firmware[j + i * payloadLength];
> +
> +		buff_len = 4 + payloadLength;
> +		error = it9135_cmd_add_checksum(data, &buff_len, buffer);
> +		if (error)
> +			goto exit;
> +
> +		send_len = 0;
> +		remain_len = IT9135_MAX_CMD_SIZE;
> +		while (remain_len > 0) {
> +			k = (remain_len >
> +			     IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
> +			    : (remain_len);
> +			error = it9135_cmd_bus_tx(data, k, &buffer[send_len]);
> +			if (error)
> +				goto exit;
> +
> +			send_len += k;
> +			remain_len -= k;
> +		}
> +	}
> +
> +	if (remain) {
> +		buffer[1] = (unsigned char)(command >> 8);
> +		buffer[2] = (unsigned char)command;
> +		buffer[3] = (unsigned char)data->cmd_seq++;
> +
> +		for (j = 0; j < remain; j++)
> +			buffer[4 + j] = firmware[j + i * payloadLength];
> +
> +		buff_len = 4 + remain;
> +		error = it9135_cmd_add_checksum(data, &buff_len, buffer);
> +		if (error)
> +			goto exit;
> +
> +		send_len = 0;
> +		remain_len = buff_len;
> +		while (remain_len > 0) {
> +			k = (remain_len >
> +			     IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
> +			    : (remain_len);
> +			error = it9135_cmd_bus_tx(data, k, &buffer[send_len]);
> +			if (error)
> +				goto exit;
> +
> +			send_len += k;
> +			remain_len -= k;
> +		}
> +	}
> +
> +exit:
> +	it9135_leave_mutex(data);
> +	return error;
> +}
> +
> +static unsigned long it9135_cmd_reboot(struct it9135_data *data,
> +				       unsigned char chip)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned short command;
> +	unsigned char buffer[255];
> +	unsigned long buff_len;
> +
> +	it9135_enter_mutex(data);

Please use, instead, something like:
	mutex_lock(data->mutex);

> +
> +	command = it9135_build_command(CMD_REBOOT, PROCESSOR_LINK, chip);
> +	buffer[1] = (unsigned char)(command >> 8);
> +	buffer[2] = (unsigned char)command;
> +	buffer[3] = (unsigned char)data->cmd_seq++;
> +	buff_len = 4;
> +	error = it9135_cmd_add_checksum(data, &buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +	error = it9135_cmd_bus_tx(data, buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +exit:
> +	it9135_leave_mutex(data);

mutex_unlock(data->mutex);

> +	return error;
> +}
> +
> +/*
> + * Send the command to device.
> + *
> + * @param struct it9135_data the handle of IT9135.
> + * @param command the command to be send.
> + * @param chip The index of IT9135. The possible values are 0~7.
> + * @param processor The processor of specified register. Because each chip
> + *        has two processor so user have to specify the processor. The
> + *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
> + * @param w_buff_len the number of registers to be write.
> + * @param w_buff a unsigned char array which is used to store values to be write.
> + * @param r_buff_len the number of registers to be read.
> + * @param r_buff a unsigned char array which is used to store values to be read.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */


The function prototype is wrong. If you're commenting the arguments, it should
be instead:

/**
 * it9135_cmd_sendcommand() - Send the command to device
 *
 * @data:	the handle of IT9135.
...

Please read Documentation/kernel-doc-nano-HOWTO.txt for more details.


> +static unsigned long it9135_cmd_sendcommand(struct it9135_data *data,
> +					    unsigned short command,
> +					    unsigned char chip,
> +					    unsigned char processor,
> +					    unsigned long w_buff_len,
> +					    unsigned char *w_buff,
> +					    unsigned long r_buff_len,
> +					    unsigned char *r_buff)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char buffer[255];
> +	unsigned long buff_len;
> +	unsigned long remain_len;
> +	unsigned long send_len;
> +	unsigned long i, k;
> +
> +	it9135_enter_mutex(data);

Again, use the proper mutex call. I won't be repeating this forever. So, replace it
on all places at the document. Please remember to properly initialize the mutex with
mutex_init() when you initialize the "data" struct, otherwise you'll get oopses.

> +
> +	if ((w_buff_len + 6) > IT9135_MAX_CMD_SIZE) {
> +		error = ERROR_INVALID_DATA_LENGTH;

-EINVAL.

> +		goto exit;
> +	}
> +
> +	if ((r_buff_len + 5) > IT9135_MAX_PKT_SIZE) {
> +		error = ERROR_INVALID_DATA_LENGTH;
> +		goto exit;
> +	}
> +
> +	if ((r_buff_len + 5) > IT9135_MAX_CMD_SIZE) {
> +		error = ERROR_INVALID_DATA_LENGTH;
> +		goto exit;
> +	}
> +
> +	if (w_buff_len == 0) {
> +		command = it9135_build_command(command, processor, chip);
> +		buffer[1] = (unsigned char)(command >> 8);
> +		buffer[2] = (unsigned char)command;
> +		buffer[3] = (unsigned char)data->cmd_seq++;
> +		buff_len = 4;
> +		error = it9135_cmd_add_checksum(data, &buff_len, buffer);
> +		if (error)
> +			goto exit;
> +
> +		/* send command packet */
> +		i = 0;
> +		send_len = 0;
> +		remain_len = buff_len;
> +		while (remain_len > 0) {
> +			i = (remain_len >
> +			     IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
> +			    : (remain_len);
> +			error = it9135_cmd_bus_tx(data, i, &buffer[send_len]);
> +			if (error)
> +				goto exit;
> +
> +			send_len += i;
> +			remain_len -= i;
> +		}
> +	} else {
> +		command = it9135_build_command(command, processor, chip);
> +		buffer[1] = (unsigned char)(command >> 8);
> +		buffer[2] = (unsigned char)command;
> +		buffer[3] = (unsigned char)data->cmd_seq++;
> +		for (k = 0; k < w_buff_len; k++)
> +			buffer[k + 4] = w_buff[k];
> +
> +		buff_len = 4 + w_buff_len;
> +		error = it9135_cmd_add_checksum(data, &buff_len, buffer);
> +		if (error)
> +			goto exit;
> +
> +		/* send command */
> +		i = 0;
> +		send_len = 0;
> +		remain_len = buff_len;
> +		while (remain_len > 0) {
> +			i = (remain_len >
> +			     IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
> +			    : (remain_len);
> +			error = it9135_cmd_bus_tx(data, i, &buffer[send_len]);
> +			if (error)
> +				goto exit;
> +
> +			send_len += i;
> +			remain_len -= i;
> +		}
> +	}
> +
> +	buff_len = 5 + r_buff_len;
> +
> +	error = it9135_cmd_bus_rx(data, buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +	error = it9135_cmd_remove_checksum(data, &buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +	if (r_buff_len) {
> +		for (k = 0; k < r_buff_len; k++)
> +			r_buff[k] = buffer[k + 3];
> +	}
> +
> +exit:
> +	it9135_leave_mutex(data);
> +	return error;
> +}
> +
> +/*
> + * IT9135 tuner functions
> + */
> +
> +static unsigned int it9135_tuner_get_nv(unsigned int nc)
> +{
> +	unsigned int nv;
> +
> +	switch (nc) {
> +	case 0:
> +		nv = 48;
> +		break;
> +	case 1:
> +		nv = 32;
> +		break;
> +	case 2:
> +		nv = 24;
> +		break;
> +	case 3:
> +		nv = 16;
> +		break;
> +	case 4:
> +		nv = 12;
> +		break;
> +	case 5:
> +		nv = 8;
> +		break;
> +	case 6:
> +		nv = 6;
> +		break;
> +	case 7:
> +		nv = 4;
> +		break;

> +	case 8:		/* L-band */
> +		nv = 2;
> +		break;
> +	default:
> +		nv = 2;
> +		break;

Just do, instead:
	case 8:		/* L-band */
	default: 
		nv = 2;
		break;


> +	}
> +
> +	return nv;
> +}
> +
> +static unsigned int it9135_fn_min[] = {
> +	53000, 74000, 111000, 148000, 222000, 296000, 445000, 573000, 950000
> +};
> +
> +static unsigned long it9135_tuner_init(struct it9135_data *data,
> +				       unsigned char chip)
> +{
> +	unsigned long error = 0;
> +	unsigned char buf[4], val;
> +	unsigned int m_bdry, nc, nv;
> +	unsigned long tmp_numer, tmp_denom;
> +	unsigned int cnt;
> +
> +#define OMEGA_TUNER_INIT_POLL_INTERVAL	2
> +#define OMEGA_TUNER_INIT_POLL_COUNTS	50
> +
> +	/* ----- read ----- */
> +	/* p_reg_p_tsm_init_clock_mode */
> +	error = it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xEC86, 1, buf);

We generally use lowercase for hexadecimal values.

> +	if (error)
> +		goto exit;
> +	/* p_reg_p_fbc_n_code */
> +	error =
> +	    it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xED03, 1, &buf[1]);
> +	if (error)
> +		goto exit;
> +	/* r_reg_r_fbc_m_bdry_7_0 */
> +	error =
> +	    it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xED23, 2, &buf[2]);
> +	if (error)
> +		goto exit;
> +
> +	/* ----- set_clock_mode ----- */
> +	data->clock_mode = buf[0];
> +
> +	/* ----- set_fref_kHz & m_cal ----- */
> +	switch (data->clock_mode) {
> +	case 0:		/* 12.00MHz, 12000/18 = 2000/3 */
> +		data->fxtal_khz = 2000;
> +		data->fdiv = 3;
> +		val = 16;
> +		break;
> +	case 1:		/* 20.48MHz, 20480/32 = 640/1 */
> +		data->fxtal_khz = 640;
> +		data->fdiv = 1;
> +		val = 6;
> +		break;
> +	default:		/* 20.48MHz, 20480/32 = 640/1 */
> +		data->fxtal_khz = 640;
> +		data->fdiv = 1;
> +		val = 6;
> +		break;
> +	}
> +
> +	/* ----- set_fbdry ----- */
> +	nc = buf[1];
> +	nv = it9135_tuner_get_nv(nc);
> +	m_bdry = (buf[3] << 8) + buf[2];	/* m_bdry = m_bdry_15_8 << 8 + m_bdry_7_0 */
> +
> +	/* ----- patch to wait for fbc done ----- */
> +	cnt = 1;
> +	while (m_bdry == 0 && cnt < OMEGA_TUNER_INIT_POLL_COUNTS) {
> +		mdelay(OMEGA_TUNER_INIT_POLL_INTERVAL);
> +		/* r_reg_r_fbc_m_bdry_7_0 */
> +		error =
> +		    it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xED23, 2,
> +				     &buf[2]);
> +		if (error)
> +			goto exit;
> +		m_bdry = (buf[3] << 8) + buf[2];	/* m_bdry = m_bdry_15_8 << 8 + m_bdry_7_0 */
> +		cnt++;
> +	}
> +
> +	if (m_bdry == 0) {
> +		error = ERROR_TUNER_INIT_FAIL;
> +		goto exit;
> +	}
> +
> +	tmp_numer = (unsigned long)data->fxtal_khz * (unsigned long)m_bdry;
> +	tmp_denom = (unsigned long)data->fdiv * (unsigned long)nv;
> +	it9135_fn_min[7] = (unsigned int)(tmp_numer / tmp_denom);
> +
> +	/* ----- patch to wait for all cal done, borrow p_reg_p_tsm_init_mode ----- */
> +	cnt = 1;
> +
> +	if (data->chip_type == 0x9135 && data->chip_ver == 2) {
> +		mdelay(50);	/* for omega2 */

Except if you really need an exact time, don't use mdelay(). It makes the CPU to run
a loop, blocking it to be used by other proccesses, so, impacting at the machine
performance, instead of letting it to do something else or to save energy. Normal 
delays should use, instead:

	msleep(50);


> +	} else {
> +		/* p_reg_p_tsm_init_mode */
> +		error =
> +		    it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xEC82, 1,
> +				     buf);
> +		if (error)
> +			goto exit;
> +
> +		while (buf[0] == 0 && cnt < OMEGA_TUNER_INIT_POLL_COUNTS) {
> +			mdelay(OMEGA_TUNER_INIT_POLL_INTERVAL);
> +			/* p_reg_p_tsm_init_mode */
> +			error =
> +			    it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xEC82,
> +					     1, buf);
> +			if (error)
> +				goto exit;
> +			cnt++;
> +		}
> +		if (buf[0] == 0) {
> +			error = ERROR_TUNER_INIT_FAIL;
> +			goto exit;
> +		}
> +	}
> +
> +	/* p_reg_p_iqik_m_cal */
> +	error = it9135_write_regs(data, chip, PROCESSOR_OFDM, 0xED81, 1, &val);
> +
> +exit:
> +	return error;
> +}
> +
> +static unsigned int it9135_tuner_get_nc(unsigned int rf_freq_khz)
> +{
> +	unsigned int nc;
> +
> +	if ((rf_freq_khz <= it9135_fn_min[1])) {	/* 74 */
> +		nc = 0;
> +	} else if ((rf_freq_khz > it9135_fn_min[1]) && (rf_freq_khz <= it9135_fn_min[2])) {	/* 74 111 */
> +		nc = 1;
> +	} else if ((rf_freq_khz > it9135_fn_min[2]) && (rf_freq_khz <= it9135_fn_min[3])) {	/* 111 148 */
> +		nc = 2;
> +	} else if ((rf_freq_khz > it9135_fn_min[3]) && (rf_freq_khz <= it9135_fn_min[4])) {	/* 148 222 */
> +		nc = 3;
> +	} else if ((rf_freq_khz > it9135_fn_min[4]) && (rf_freq_khz <= it9135_fn_min[5])) {	/* 222 296 */
> +		nc = 4;
> +	} else if ((rf_freq_khz > it9135_fn_min[5]) && (rf_freq_khz <= it9135_fn_min[6])) {	/* 296 445 */
> +		nc = 5;
> +	} else if ((rf_freq_khz > it9135_fn_min[6]) && (rf_freq_khz <= it9135_fn_min[7])) {	/* 445 573 */
> +		nc = 6;
> +	} else if ((rf_freq_khz > it9135_fn_min[7]) && (rf_freq_khz <= it9135_fn_min[8])) {	/* 573 890 */
> +		nc = 7;
> +	} else {		/* L-band */
> +		nc = 8;
> +	}

Code will be cleaner if you use a for loop.

> +
> +	return nc;
> +}
> +
> +static unsigned int it9135_tuner_get_freq_code(struct it9135_data *data,
> +					       unsigned int rf_freq_khz,
> +					       unsigned int *nc,
> +					       unsigned int *nv,
> +					       unsigned int *mv)
> +{
> +	unsigned int freq_code;
> +	unsigned long tmp_tg, tmp_cal, tmp_m;
> +
> +	*nc = it9135_tuner_get_nc(rf_freq_khz);
> +	*nv = it9135_tuner_get_nv(*nc);

The better would be to merge both functions into one, and use a loop inside it,
instead of 8 if's and 8 case conditions.

> +	tmp_tg =
> +	    (unsigned long)rf_freq_khz * (unsigned long)(*nv) *
> +	    (unsigned long)data->fdiv;
> +	tmp_m = (tmp_tg / (unsigned long)data->fxtal_khz);
> +	tmp_cal = tmp_m * (unsigned long)data->fxtal_khz;

On Linux, both "long" and "int" have 32 bits. If 32 bits is ok, you can just
remove the typecast and define tmp_* as unsigned int. On the other hand, if
you need 64 bits to avoid overflow, you'll need to use "u64" and use div_u64()
for division.

> +
> +	if ((tmp_tg - tmp_cal) >= (data->fxtal_khz >> 1))
> +		tmp_m = tmp_m + 1;
> +
> +	*mv = (unsigned int)(tmp_m);
> +
> +	freq_code = (((*nc) & 0x07) << 13) + (*mv);
> +
> +	return freq_code;
> +}
> +
> +static unsigned int it9135_tuner_get_freq_iqik(struct it9135_data *data,
> +					       unsigned int rf_freq_khz,
> +					       unsigned char iqik_m_cal)
> +{
> +	unsigned int nc, nv, mv, cal_freq;
> +
> +#define OMEGA_IQIK_M_CAL_MAX	64
> +#define OMEGA_IQIK_M_CAL_MID	32
> +
> +	cal_freq = it9135_tuner_get_freq_code(data, rf_freq_khz, &nc, &nv, &mv);
> +	if (data->clock_mode == 0 && (iqik_m_cal < OMEGA_IQIK_M_CAL_MID)) {
> +		mv = mv + ((((unsigned int)iqik_m_cal) * nv * 9) >> 5);
> +	} else if (data->clock_mode == 0
> +		   && (iqik_m_cal >= OMEGA_IQIK_M_CAL_MID)) {
> +		iqik_m_cal = OMEGA_IQIK_M_CAL_MAX - iqik_m_cal;
> +		mv = mv - ((((unsigned int)iqik_m_cal) * nv * 9) >> 5);
> +	} else if (data->clock_mode == 1 && (iqik_m_cal < OMEGA_IQIK_M_CAL_MID)) {
> +		mv = mv + ((((unsigned int)iqik_m_cal) * nv) >> 1);
> +	} else {		/* (data->clock_mode==1 && (iqik_m_cal >= OMEGA_IQIK_M_CAL_MID)) */
> +		iqik_m_cal = OMEGA_IQIK_M_CAL_MAX - iqik_m_cal;
> +		mv = mv - ((((unsigned int)iqik_m_cal) * nv) >> 1);
> +	}
> +	cal_freq = ((nc & 0x07) << 13) + mv;
> +
> +	return cal_freq;
> +}
> +
> +/* the reason to use 392000(but not 400000) because cal_rssi will use 400000-8000= 392000; */
> +static unsigned int it9135_lna_fband_min[] = {
> +	392000, 440000, 484000, 533000, 587000, 645000, 710000, 782000, 860000,
> +	1450000, 1492000, 1660000, 1685000
> +};
> +
> +static unsigned char it9135_tuner_get_lna_cap_sel(unsigned int rf_freq_khz)
> +{
> +	unsigned char lna_cap_sel;
> +
> +	if (rf_freq_khz <= it9135_lna_fband_min[1]) {	/* <=440 */
> +		lna_cap_sel = 0;
> +	} else if (rf_freq_khz > it9135_lna_fband_min[1] && rf_freq_khz <= it9135_lna_fband_min[2]) {	/* 440 484 */
> +		lna_cap_sel = 1;
> +	} else if (rf_freq_khz > it9135_lna_fband_min[2] && rf_freq_khz <= it9135_lna_fband_min[3]) {	/* 484 533 */
> +		lna_cap_sel = 2;
> +	} else if (rf_freq_khz > it9135_lna_fband_min[3] && rf_freq_khz <= it9135_lna_fband_min[4]) {	/* 533 587 */
> +		lna_cap_sel = 3;
> +	} else if (rf_freq_khz > it9135_lna_fband_min[4] && rf_freq_khz <= it9135_lna_fband_min[5]) {	/* 587 645 */
> +		lna_cap_sel = 4;
> +	} else if (rf_freq_khz > it9135_lna_fband_min[5] && rf_freq_khz <= it9135_lna_fband_min[6]) {	/* 645 710 */
> +		lna_cap_sel = 5;
> +	} else if (rf_freq_khz > it9135_lna_fband_min[6] && rf_freq_khz <= it9135_lna_fband_min[7]) {	/* 710 782 */
> +		lna_cap_sel = 6;
> +	} else {		/* >782 */
> +		lna_cap_sel = 7;
> +	}

Same as above: Please use a loop for it.

> +
> +	return lna_cap_sel;
> +}
> +
> +static unsigned int it9135_tuner_get_lo_freq(struct it9135_data *data,
> +					     unsigned int rf_freq_khz)
> +{
> +	unsigned int nc, nv, mv, lo_freq;
> +
> +	lo_freq = it9135_tuner_get_freq_code(data, rf_freq_khz, &nc, &nv, &mv);
> +
> +	return lo_freq;
> +}
> +
> +static unsigned char it9135_tuner_get_lpf_bw(unsigned int bw_khz)
> +{
> +	unsigned char lpf_bw;
> +
> +	switch (bw_khz) {	/*5.0MHz */
> +	case 5000:
> +		lpf_bw = 0;
> +		break;
> +	case 5500:		/*5.5MHz */
> +		lpf_bw = 1;
> +		break;
> +	case 6000:		/*6.0MHz */
> +		lpf_bw = 2;
> +		break;
> +	case 6500:		/*6.5MHz */
> +		lpf_bw = 3;
> +		break;
> +	case 7000:		/*7.0MHz */
> +		lpf_bw = 4;
> +		break;
> +	case 7500:		/*7.5MHz */
> +		lpf_bw = 5;
> +		break;
> +	case 8000:		/*8.0MHz */
> +		lpf_bw = 6;
> +		break;
> +	case 8500:		/*8.5MHz */
> +		lpf_bw = 7;
> +		break;
> +	default:		/*default: 8MHz */
> +		lpf_bw = 6;
> +		break;
> +	}
> +
> +	return lpf_bw;
> +}
> +
> +static unsigned long it9135_tuner_set_freq(struct it9135_data *data,
> +					   unsigned char chip,
> +					   unsigned int bw_khz,
> +					   unsigned int rf_freq_khz)
> +{
> +	unsigned long error = 0;
> +	unsigned char val[7];
> +	unsigned char buf[2];
> +	unsigned int tmp;
> +
> +#define IT9135_CAP_FREQ_UHF_MIN		392000

Better to put all those devices altogheter on the beginning of the file.

> +
> +	/* p_reg_t_ctrl */
> +	error = it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xEC4C, 1, buf);
> +	if (error)
> +		goto exit;
> +	/* p_reg_p_iqik_m_cal */
> +	error =
> +	    it9135_read_regs(data, chip, PROCESSOR_OFDM, 0xED81, 1, &buf[1]);
> +	if (error)
> +		goto exit;
> +
> +	val[0] = it9135_tuner_get_lna_cap_sel(rf_freq_khz);
> +	val[1] = it9135_tuner_get_lpf_bw(bw_khz);
> +
> +	/* ----- set_rf_mode ----- */
> +	if (rf_freq_khz < IT9135_CAP_FREQ_UHF_MIN)
> +		val[2] = buf[0] & 0xE7;	/* ctrl<4:3>=0b00 for VHF */
> +	else
> +		val[2] = (buf[0] & 0xE7) | 0x08;	/* ctrl<4:3>=0b01 for UHF */
> +
> +	/* ----- set_cal_freq ----- */
> +	tmp = it9135_tuner_get_freq_iqik(data, rf_freq_khz, buf[1]);
> +	val[3] = (unsigned char)(tmp & 0xFF);
> +	val[4] = (unsigned char)((tmp >> 8) & 0xFF);
> +	/* ----- set_lo_freq ----- */
> +	tmp = it9135_tuner_get_lo_freq(data, rf_freq_khz);
> +	val[5] = (unsigned char)(tmp & 0xFF);
> +	val[6] = (unsigned char)((tmp >> 8) & 0xFF);
> +	/* ----- write ----- */
> +	error =
> +	    it9135_write_regs(data, chip, PROCESSOR_OFDM, var_pre_lna_cap_sel,
> +			      1, val);
> +	if (error)
> +		goto exit;
> +	/* p_reg_t_lpf_bw */
> +	error =
> +	    it9135_write_regs(data, chip, PROCESSOR_OFDM, 0xEC56, 1, &val[1]);
> +	if (error)
> +		goto exit;
> +	/* p_reg_t_ctrl */
> +	error =
> +	    it9135_write_regs(data, chip, PROCESSOR_OFDM, 0xEC4C, 1, &val[2]);
> +	if (error)
> +		goto exit;
> +	/*----- the writing sequence is important for cal_freq and lo_freq, thus separate ----- */
> +	/* p_reg_t_cal_freq_7_0 */
> +	error =
> +	    it9135_write_regs(data, chip, PROCESSOR_OFDM, 0xEC4D, 1, &val[3]);
> +	if (error)
> +		goto exit;
> +	/* p_reg_t_cal_freq_15_8 */
> +	error =
> +	    it9135_write_regs(data, chip, PROCESSOR_OFDM, 0xEC4E, 1, &val[4]);
> +	if (error)
> +		goto exit;
> +
> +	error =
> +	    it9135_write_regs(data, chip, PROCESSOR_OFDM, var_pre_lo_freq_7_0,
> +			      1, &val[5]);
> +	if (error)
> +		goto exit;
> +
> +	error =
> +	    it9135_write_regs(data, chip, PROCESSOR_OFDM, var_pre_lo_freq_15_8,
> +			      1, &val[6]);
> +
> +exit:
> +	return error;
> +}
> +
> +/*
> + * Demodular functions
> + */
> +
> +static unsigned long it9135_divider(struct it9135_data *data, unsigned long a,
> +				    unsigned long b, unsigned long x)
> +{
> +	unsigned long answer = 0;
> +	unsigned long c = 0;
> +	unsigned long i = 0;
> +
> +	if (a > b) {
> +		c = a / b;
> +		a = a - c * b;
> +	}
> +
> +	for (i = 0; i < x; i++) {
> +		if (a >= b) {
> +			answer += 1;
> +			a -= b;
> +		}
> +		a <<= 1;
> +		answer <<= 1;
> +	}
> +
> +	answer = (c << (long)x) + answer;
> +
> +	return answer;
> +}


As I've explained above, "long" is 32 bits on Linux. You don't need that.
On the other hand, if you need 64 bits, just use one of the functions
defined on include/linux/math64.h.

> +
> +/* @param crystal_Freq: Crystal frequency (Hz) */
> +static unsigned long it9135_compute_crystal(struct it9135_data *data,
> +					    long crystal_frequency,
> +					    unsigned long *crystal)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	*crystal =
> +	    (long)it9135_divider(data, (unsigned long)crystal_frequency,
> +				 1000000ul, 19ul);
> +
> +	return error;
> +}
> +
> +/* @param adcFrequency: ADC frequency (Hz) */
> +static unsigned long it9135_compute_adc(struct it9135_data *data, long adc_freq,
> +					unsigned long *adc)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	*adc =
> +	    (long)it9135_divider(data, (unsigned long)adc_freq, 1000000ul,
> +				 19ul);
> +
> +	return error;
> +}
> +
> +/*
> + * @param adcFrequency: ADC frequency (Hz)
> + * @param ifFrequency:  IF frequency (Hz)
> + * @param inversion:    RF spectrum inversion
> + */
> +static unsigned long it9135_compute_fcw(struct it9135_data *data,
> +					long adc_frequency, long if_frequency,
> +					int inversion, unsigned long *fcw)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	long if_freq;
> +	long adc_freq;
> +	long adc_freq_half;
> +	long adc_freq_sample;
> +	long inv_bfs;
> +	long ctrl_word;
> +	unsigned char adc_multiplier;
> +
> +	adc_freq = adc_frequency;
> +	if_freq = if_frequency;
> +	adc_freq_half = adc_freq / 2;
> +
> +	if (inversion)
> +		if_freq = -1 * if_freq;
> +
> +	adc_freq_sample = if_freq;
> +
> +	if (adc_freq_sample >= 0) {
> +		inv_bfs = 1;
> +	} else {
> +		inv_bfs = -1;
> +		adc_freq_sample = adc_freq_sample * -1;
> +	}
> +
> +	while (adc_freq_sample > adc_freq_half)
> +		adc_freq_sample = adc_freq_sample - adc_freq;
> +
> +	/* Sample, spectrum at positive frequency */
> +	if (adc_freq_sample >= 0) {
> +		inv_bfs = inv_bfs * -1;
> +	} else {
> +		inv_bfs = inv_bfs * 1;
> +		adc_freq_sample = adc_freq_sample * (-1);	/* Absolute value */
> +	}
> +
> +	ctrl_word =
> +	    (long)it9135_divider(data, (unsigned long)adc_freq_sample,
> +				 (unsigned long)adc_freq, 23ul);
> +
> +	if (inv_bfs == -1)
> +		ctrl_word *= -1;
> +
> +	/* Get ADC multiplier */
> +	error =
> +	    it9135_read_reg(data, 0, PROCESSOR_OFDM, adcx2, &adc_multiplier);
> +	if (error)
> +		goto exit;
> +
> +	if (adc_multiplier == 1)
> +		ctrl_word /= 2;
> +
> +	*fcw = ctrl_word & 0x7FFFFF;
> +
> +exit:
> +	return error;
> +}
> +
> +static unsigned long it9135_mask_dca_output(struct it9135_data *data)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char i;
> +
> +	if ((data->chip_num > 1)
> +	    && (data->architecture == ARCHITECTURE_DCA)) {
> +		for (i = 0; i < data->chip_num; i++) {
> +			error =
> +			    it9135_write_reg_bits(data, i,
> +						  PROCESSOR_OFDM,
> +						  p_reg_dca_upper_out_en,
> +						  reg_dca_upper_out_en_pos,
> +						  reg_dca_upper_out_en_len, 0);
> +			if (error)
> +				goto exit;
> +		}
> +		mdelay(5);
> +	}
> +
> +exit:
> +	return error;
> +}
> +
> +static struct it9135_coeff_param coeff_tab[] = {
> +	/* adc_freq 20156250 */
> +	{20156250, 5000, 0x02449b5c, 0x01224dae, 0x00912b60, 0x009126d7,
> +	 0x0091224e, 0x01224dae, 0x009126d7, 0x0048936b, 0x0387, 0x0122},
> +	{20156250, 6000, 0x02b8ba6e, 0x015c5d37, 0x00ae340d, 0x00ae2e9b,
> +	 0x00ae292a, 0x015c5d37, 0x00ae2e9b, 0x0057174e, 0x02f1, 0x015c},
> +	{20156250, 7000, 0x032cd980, 0x01966cc0, 0x00cb3cba, 0x00cb3660,
> +	 0x00cb3007, 0x01966cc0, 0x00cb3660, 0x00659b30, 0x0285, 0x0196},
> +	{20156250, 8000, 0x03a0f893, 0x01d07c49, 0x00e84567, 0x00e83e25,
> +	 0x00e836e3, 0x01d07c49, 0x00e83e25, 0x00741f12, 0x0234, 0x01d0},
> +	/* adc_freq 20187500 */
> +	{20187500, 5000, 0x0243b546, 0x0121daa3, 0x0090f1d9, 0x0090ed51,
> +	 0x0090e8ca, 0x0121daa3, 0x0090ed51, 0x004876a9, 0x0388, 0x0122},
> +	{20187500, 6000, 0x02b7a654, 0x015bd32a, 0x00adef04, 0x00ade995,
> +	 0x00ade426, 0x015bd32a, 0x00ade995, 0x0056f4ca, 0x02f2, 0x015c},
> +	{20187500, 7000, 0x032b9761, 0x0195cbb1, 0x00caec30, 0x00cae5d8,
> +	 0x00cadf81, 0x0195cbb1, 0x00cae5d8, 0x006572ec, 0x0286, 0x0196},
> +	{20187500, 8000, 0x039f886f, 0x01cfc438, 0x00e7e95b, 0x00e7e21c,
> +	 0x00e7dadd, 0x01cfc438, 0x00e7e21c, 0x0073f10e, 0x0235, 0x01d0},
> +	/* adc_freq 20250000 */
> +	{20250000, 5000, 0x0241eb3b, 0x0120f59e, 0x00907f53, 0x00907acf,
> +	 0x0090764b, 0x0120f59e, 0x00907acf, 0x00483d67, 0x038b, 0x0121},
> +	{20250000, 6000, 0x02b580ad, 0x015ac057, 0x00ad6597, 0x00ad602b,
> +	 0x00ad5ac1, 0x015ac057, 0x00ad602b, 0x0056b016, 0x02f4, 0x015b},
> +	{20250000, 7000, 0x03291620, 0x01948b10, 0x00ca4bda, 0x00ca4588,
> +	 0x00ca3f36, 0x01948b10, 0x00ca4588, 0x006522c4, 0x0288, 0x0195},
> +	{20250000, 8000, 0x039cab92, 0x01ce55c9, 0x00e7321e, 0x00e72ae4,
> +	 0x00e723ab, 0x01ce55c9, 0x00e72ae4, 0x00739572, 0x0237, 0x01ce},
> +	/* adc_freq 20583333 */
> +	{20583333, 5000, 0x02388f54, 0x011c47aa, 0x008e2846, 0x008e23d5,
> +	 0x008e1f64, 0x011c47aa, 0x008e23d5, 0x004711ea, 0x039a, 0x011c},
> +	{20583333, 6000, 0x02aa4598, 0x015522cc, 0x00aa96bb, 0x00aa9166,
> +	 0x00aa8c12, 0x015522cc, 0x00aa9166, 0x005548b3, 0x0300, 0x0155},
> +	{20583333, 7000, 0x031bfbdc, 0x018dfdee, 0x00c7052f, 0x00c6fef7,
> +	 0x00c6f8bf, 0x018dfdee, 0x00c6fef7, 0x00637f7b, 0x0293, 0x018e},
> +	{20583333, 8000, 0x038db21f, 0x01c6d910, 0x00e373a3, 0x00e36c88,
> +	 0x00e3656d, 0x01c6d910, 0x00e36c88, 0x0071b644, 0x0240, 0x01c7},
> +	/* adc_freq 20416667 */
> +	{20416667, 5000, 0x023d337f, 0x011e99c0, 0x008f515a, 0x008f4ce0,
> +	 0x008f4865, 0x011e99c0, 0x008f4ce0, 0x0047a670, 0x0393, 0x011f},
> +	{20416667, 6000, 0x02afd765, 0x0157ebb3, 0x00abfb39, 0x00abf5d9,
> +	 0x00abf07a, 0x0157ebb3, 0x00abf5d9, 0x0055faed, 0x02fa, 0x0158},
> +	{20416667, 7000, 0x03227b4b, 0x01913da6, 0x00c8a518, 0x00c89ed3,
> +	 0x00c8988e, 0x01913da6, 0x00c89ed3, 0x00644f69, 0x028d, 0x0191},
> +	{20416667, 8000, 0x03951f32, 0x01ca8f99, 0x00e54ef7, 0x00e547cc,
> +	 0x00e540a2, 0x01ca8f99, 0x00e547cc, 0x0072a3e6, 0x023c, 0x01cb},
> +	/* adc_freq 20480000 */
> +	{20480000, 5000, 0x023b6db7, 0x011db6db, 0x008edfe5, 0x008edb6e,
> +	 0x008ed6f7, 0x011db6db, 0x008edb6e, 0x00476db7, 0x0396, 0x011e},
> +	{20480000, 6000, 0x02adb6db, 0x0156db6e, 0x00ab7312, 0x00ab6db7,
> +	 0x00ab685c, 0x0156db6e, 0x00ab6db7, 0x0055b6db, 0x02fd, 0x0157},
> +	{20480000, 7000, 0x03200000, 0x01900000, 0x00c80640, 0x00c80000,
> +	 0x00c7f9c0, 0x01900000, 0x00c80000, 0x00640000, 0x028f, 0x0190},
> +	{20480000, 8000, 0x03924925, 0x01c92492, 0x00e4996e, 0x00e49249,
> +	 0x00e48b25, 0x01c92492, 0x00e49249, 0x00724925, 0x023d, 0x01c9},
> +	/* adc_freq 20500000 */
> +	{20500000, 5000, 0x023adeff, 0x011d6f80, 0x008ebc36, 0x008eb7c0,
> +	 0x008eb34a, 0x011d6f80, 0x008eb7c0, 0x00475be0, 0x0396, 0x011d},
> +	{20500000, 6000, 0x02ad0b99, 0x015685cc, 0x00ab4840, 0x00ab42e6,
> +	 0x00ab3d8c, 0x015685cc, 0x00ab42e6, 0x0055a173, 0x02fd, 0x0157},
> +	{20500000, 7000, 0x031f3832, 0x018f9c19, 0x00c7d44b, 0x00c7ce0c,
> +	 0x00c7c7ce, 0x018f9c19, 0x00c7ce0c, 0x0063e706, 0x0290, 0x0190},
> +	{20500000, 8000, 0x039164cb, 0x01c8b266, 0x00e46056, 0x00e45933,
> +	 0x00e45210, 0x01c8b266, 0x00e45933, 0x00722c99, 0x023e, 0x01c9},
> +	/* adc_freq 20625000 */
> +	{20625000, 5000, 0x02376948, 0x011bb4a4, 0x008ddec1, 0x008dda52,
> +	 0x008dd5e3, 0x011bb4a4, 0x008dda52, 0x0046ed29, 0x039c, 0x011c},
> +	{20625000, 6000, 0x02a8e4bd, 0x0154725e, 0x00aa3e81, 0x00aa392f,
> +	 0x00aa33de, 0x0154725e, 0x00aa392f, 0x00551c98, 0x0302, 0x0154},
> +	{20625000, 7000, 0x031a6032, 0x018d3019, 0x00c69e41, 0x00c6980c,
> +	 0x00c691d8, 0x018d3019, 0x00c6980c, 0x00634c06, 0x0294, 0x018d},
> +	{20625000, 8000, 0x038bdba6, 0x01c5edd3, 0x00e2fe02, 0x00e2f6ea,
> +	 0x00e2efd2, 0x01c5edd3, 0x00e2f6ea, 0x00717b75, 0x0242, 0x01c6}
> +};
> +
> +static int it915_coeff_tab_count = ARRAY_SIZE(coeff_tab);
> +
> +static unsigned long it9135_get_coeff_param(struct it9135_coeff_param *coeff)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	int i;
> +
> +	deb_info("it9135_get_coeff_param - %ld, %d\n", coeff->adc_freq,
> +		 coeff->bandwidth);
> +
> +	for (i = 0; i < it915_coeff_tab_count; i++) {
> +		if ((coeff->adc_freq == coeff_tab[i].adc_freq)
> +		    && (coeff->bandwidth == coeff_tab[i].bandwidth)) {
> +			memcpy(coeff, &coeff_tab[i], sizeof(*coeff));
> +			deb_info("find coeff table - %ld, %d\n",
> +				 coeff->adc_freq, coeff->bandwidth);
> +			break;
> +		}
> +	}
> +
> +	if (i == it915_coeff_tab_count)
> +		error = ERROR_INVALID_BW;
> +
> +	return error;
> +}
> +
> +/*
> + * Program the bandwidth related parameters to IT9135.
> + *
> + * @param struct it9135_data the handle of IT9135.
> + * @param chip The index of IT9135. The possible values are 0~7.
> + *        NOTE: When the architecture is set to ARCHITECTURE_DCA
> + *        this parameter is regard as don't care.
> + * @param bandwidth DVB channel bandwidth in KHz. The possible values
> + *        are 5000, 6000, 7000, and 8000 (KHz).
> + * @param adc_freq The value of desire internal ADC frequency (Hz) ex: 20480000.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +static unsigned long it9135_select_bandwidth(struct it9135_data *data,
> +					     unsigned char chip,
> +					     unsigned short bandwidth,
> +					     unsigned long adc_freq)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	struct it9135_coeff_param coeff;
> +	unsigned char temp0;
> +	unsigned char temp1;
> +	unsigned char temp2;
> +	unsigned char temp3;
> +	unsigned char buffer[36];
> +	unsigned char bw;
> +	unsigned char adc_multiplier;
> +
> +	switch (bandwidth) {
> +	case 5000:
> +		bw = 3;
> +		break;
> +	case 6000:
> +		bw = 0;
> +		break;
> +	case 7000:
> +		bw = 1;
> +		break;
> +	case 8000:
> +		bw = 2;
> +		break;
> +	default:
> +		error = ERROR_INVALID_BW;

-EINVAL

> +		goto exit;
> +	}
> +
> +	error =
> +	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM, g_reg_bw,
> +				  reg_bw_pos, reg_bw_len, bw);
> +	if (error)
> +		goto exit;
> +
> +	/* Program CFOE */
> +	coeff.adc_freq = adc_freq;
> +	coeff.bandwidth = bandwidth;
> +	error = it9135_get_coeff_param(&coeff);
> +	if (error)
> +		goto exit;
> +
> +	/* Get ADC multiplier */
> +	error =
> +	    it9135_read_reg(data, 0, PROCESSOR_OFDM, adcx2, &adc_multiplier);
> +	if (error)
> +		goto exit;
> +
> +	if (adc_multiplier == 1) {
> +		coeff.coeff1_2048Nu /= 2;
> +		coeff.coeff1_4096Nu /= 2;
> +		coeff.coeff1_8191Nu /= 2;
> +		coeff.coeff1_8192Nu /= 2;
> +		coeff.coeff1_8193Nu /= 2;
> +		coeff.coeff2_2k /= 2;
> +		coeff.coeff2_4k /= 2;
> +		coeff.coeff2_8k /= 2;
> +	}
> +
> +	/* Write coeff1_2048Nu */
> +	/* Get unsigned char0 */
> +	temp0 = (unsigned char)(coeff.coeff1_2048Nu & 0x000000FF);
> +	/* Get unsigned char1 */
> +	temp1 = (unsigned char)((coeff.coeff1_2048Nu & 0x0000FF00) >> 8);
> +	/* Get unsigned char2 */
> +	temp2 = (unsigned char)((coeff.coeff1_2048Nu & 0x00FF0000) >> 16);
> +	/* Get unsigned char3 */
> +	temp3 = (unsigned char)((coeff.coeff1_2048Nu & 0x03000000) >> 24);
> +
> +	/* Big endian to make 8051 happy */
> +	buffer[cfoe_NS_2048_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
> +	buffer[cfoe_NS_2048_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
> +	buffer[cfoe_NS_2048_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
> +	buffer[cfoe_NS_2048_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
> +
> +	/* Write coeff2_2k */
> +	/* Get unsigned char0 */
> +	temp0 = (unsigned char)((coeff.coeff2_2k & 0x000000FF));
> +	/* Get unsigned char1 */
> +	temp1 = (unsigned char)((coeff.coeff2_2k & 0x0000FF00) >> 8);
> +	/* Get unsigned char2 */
> +	temp2 = (unsigned char)((coeff.coeff2_2k & 0x00FF0000) >> 16);
> +	/* Get unsigned char3 */
> +	temp3 = (unsigned char)((coeff.coeff2_2k & 0x01000000) >> 24);
> +
> +	/* Big endian to make 8051 happy */
> +	buffer[cfoe_NS_2k_coeff2_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
> +	buffer[cfoe_NS_2k_coeff2_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
> +	buffer[cfoe_NS_2k_coeff2_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
> +	buffer[cfoe_NS_2k_coeff2_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
> +
> +	/* Write coeff1_8191Nu */
> +	/* Get unsigned char0 */
> +	temp0 = (unsigned char)((coeff.coeff1_8191Nu & 0x000000FF));
> +	/* Get unsigned char1 */
> +	temp1 = (unsigned char)((coeff.coeff1_8191Nu & 0x0000FF00) >> 8);
> +	/* Get unsigned char2 */
> +	temp2 = (unsigned char)((coeff.coeff1_8191Nu & 0x00FFC000) >> 16);
> +	/* Get unsigned char3 */
> +	temp3 = (unsigned char)((coeff.coeff1_8191Nu & 0x03000000) >> 24);
> +
> +	/* Big endian to make 8051 happy */
> +	buffer[cfoe_NS_8191_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
> +	buffer[cfoe_NS_8191_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
> +	buffer[cfoe_NS_8191_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
> +	buffer[cfoe_NS_8191_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
> +
> +	/* Write coeff1_8192Nu */
> +	/* Get unsigned char0 */
> +	temp0 = (unsigned char)(coeff.coeff1_8192Nu & 0x000000FF);
> +	/* Get unsigned char1 */
> +	temp1 = (unsigned char)((coeff.coeff1_8192Nu & 0x0000FF00) >> 8);
> +	/* Get unsigned char2 */
> +	temp2 = (unsigned char)((coeff.coeff1_8192Nu & 0x00FFC000) >> 16);
> +	/* Get unsigned char3 */
> +	temp3 = (unsigned char)((coeff.coeff1_8192Nu & 0x03000000) >> 24);
> +
> +	/* Big endian to make 8051 happy */
> +	buffer[cfoe_NS_8192_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
> +	buffer[cfoe_NS_8192_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
> +	buffer[cfoe_NS_8192_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
> +	buffer[cfoe_NS_8192_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
> +
> +	/* Write coeff1_8193Nu */
> +	/* Get unsigned char0 */
> +	temp0 = (unsigned char)((coeff.coeff1_8193Nu & 0x000000FF));
> +	/* Get unsigned char1 */
> +	temp1 = (unsigned char)((coeff.coeff1_8193Nu & 0x0000FF00) >> 8);
> +	/* Get unsigned char2 */
> +	temp2 = (unsigned char)((coeff.coeff1_8193Nu & 0x00FFC000) >> 16);
> +	/* Get unsigned char3 */
> +	temp3 = (unsigned char)((coeff.coeff1_8193Nu & 0x03000000) >> 24);
> +
> +	/* Big endian to make 8051 happy */
> +	buffer[cfoe_NS_8193_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
> +	buffer[cfoe_NS_8193_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
> +	buffer[cfoe_NS_8193_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
> +	buffer[cfoe_NS_8193_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
> +
> +	/* Write coeff2_8k */
> +	/* Get unsigned char0 */
> +	temp0 = (unsigned char)((coeff.coeff2_8k & 0x000000FF));
> +	/* Get unsigned char1 */
> +	temp1 = (unsigned char)((coeff.coeff2_8k & 0x0000FF00) >> 8);
> +	/* Get unsigned char2 */
> +	temp2 = (unsigned char)((coeff.coeff2_8k & 0x00FF0000) >> 16);
> +	/* Get unsigned char3 */
> +	temp3 = (unsigned char)((coeff.coeff2_8k & 0x01000000) >> 24);
> +
> +	/* Big endian to make 8051 happy */
> +	buffer[cfoe_NS_8k_coeff2_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
> +	buffer[cfoe_NS_8k_coeff2_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
> +	buffer[cfoe_NS_8k_coeff2_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
> +	buffer[cfoe_NS_8k_coeff2_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
> +
> +	/* Write coeff1_4096Nu */
> +	/* Get unsigned char0 */
> +	temp0 = (unsigned char)(coeff.coeff1_4096Nu & 0x000000FF);
> +	/* Get unsigned char1 */
> +	temp1 = (unsigned char)((coeff.coeff1_4096Nu & 0x0000FF00) >> 8);
> +	/* Get unsigned char2 */
> +	temp2 = (unsigned char)((coeff.coeff1_4096Nu & 0x00FF0000) >> 16);
> +	/* Get unsigned char3[1:0] */
> +	/* Bit[7:2] will be written soon and so don't have to care them */
> +	temp3 = (unsigned char)((coeff.coeff1_4096Nu & 0x03000000) >> 24);
> +
> +	/* Big endian to make 8051 happy */
> +	buffer[cfoe_NS_4096_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
> +	buffer[cfoe_NS_4096_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
> +	buffer[cfoe_NS_4096_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
> +	buffer[cfoe_NS_4096_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
> +
> +	/* Write coeff2_4k */
> +	/* Get unsigned char0 */
> +	temp0 = (unsigned char)((coeff.coeff2_4k & 0x000000FF));
> +	/* Get unsigned char1 */
> +	temp1 = (unsigned char)((coeff.coeff2_4k & 0x0000FF00) >> 8);
> +	/* Get unsigned char2 */
> +	temp2 = (unsigned char)((coeff.coeff2_4k & 0x00FF0000) >> 16);
> +	/* Get unsigned char3 */
> +	temp3 = (unsigned char)((coeff.coeff2_4k & 0x01000000) >> 24);
> +
> +	/* Big endian to make 8051 happy */
> +	buffer[cfoe_NS_4k_coeff2_24 - cfoe_NS_2048_coeff1_25_24] = temp3;
> +	buffer[cfoe_NS_4k_coeff2_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2;
> +	buffer[cfoe_NS_4k_coeff2_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
> +	buffer[cfoe_NS_4k_coeff2_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
> +
> +	/* Get unsigned char0 */
> +	temp0 = (unsigned char)(coeff.bfsfcw_fftindex_ratio & 0x00FF);
> +	/* Get unsigned char1 */
> +	temp1 = (unsigned char)((coeff.bfsfcw_fftindex_ratio & 0xFF00) >> 8);
> +
> +	/* Big endian to make 8051 happy */
> +	buffer[bfsfcw_fftindex_ratio_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
> +	buffer[bfsfcw_fftindex_ratio_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
> +
> +	/* Get unsigned char0 */
> +	temp0 = (unsigned char)(coeff.fftindex_bfsfcw_ratio & 0x00FF);
> +	/* Get unsigned char1 */
> +	temp1 = (unsigned char)((coeff.fftindex_bfsfcw_ratio & 0xFF00) >> 8);
> +
> +	/* Big endian to make 8051 happy */
> +	buffer[fftindex_bfsfcw_ratio_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1;
> +	buffer[fftindex_bfsfcw_ratio_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0;
> +
> +	error =
> +	    it9135_write_regs(data, chip, PROCESSOR_OFDM,
> +			      cfoe_NS_2048_coeff1_25_24, 36, buffer);
> +	if (error)
> +		goto exit;
> +
> +exit:
> +	return error;
> +}
> +
> +/*
> + * The type defination of band table.
> + */
> +struct it9135_freq_band {
> +	unsigned long mini;	/* The minimum frequency of this band */
> +	unsigned long max;	/* The maximum frequency of this band */
> +};
> +
> +static struct it9135_freq_band it9135_freq_band_tab[] = {
> +	{30000, 300000},	/* VHF 30MHz ~ 300MHz */
> +	{300000, 1000000},	/* UHF 300MHz ~ 1000MHz */
> +	{1670000, 1680000}	/* L-BAND */
> +};
> +
> +static int it915_freq_band_tab_count = ARRAY_SIZE(it9135_freq_band_tab);
> +
> +/*
> + * Set frequency.
> + *
> + * @param struct it9135_data the handle of IT9135.
> + * @param chip The index of IT9135. The possible values are 0~7.
> + * @param frequency The desired frequency.
> + * @return ERROR_NO_ERROR: successful, other non-zero error code otherwise.
> + */
> +static unsigned long it9135_set_frequency(struct it9135_data *data,
> +					  unsigned char chip,
> +					  unsigned long frequency)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned long freq = frequency;
> +	unsigned char band;
> +	unsigned char i;
> +
> +	/* Clear easy mode flag first */
> +	error =
> +	    it9135_write_reg(data, chip, PROCESSOR_OFDM, Training_Mode, 0x00);
> +	if (error)
> +		goto exit;
> +
> +	/* Clear empty_channel_status lock flag */
> +	error =
> +	    it9135_write_reg(data, chip, PROCESSOR_OFDM, empty_channel_status,
> +			     0x00);
> +	if (error)
> +		goto exit;
> +
> +	/* Clear MPEG2 lock flag */
> +	error =
> +	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
> +				  r_mp2if_sync_byte_locked,
> +				  mp2if_sync_byte_locked_pos,
> +				  mp2if_sync_byte_locked_len, 0x00);
> +	if (error)
> +		goto exit;
> +
> +	/* Determine frequency band */
> +	band = 0xFF;
> +	for (i = 0; i < it915_freq_band_tab_count; i++) {
> +		if ((frequency >= it9135_freq_band_tab[i].mini)
> +		    && (frequency <= it9135_freq_band_tab[i].max)) {
> +			band = i;
> +			break;
> +		}
> +	}
> +	error = it9135_write_reg(data, chip, PROCESSOR_OFDM, FreBand, band);
> +	if (error)
> +		goto exit;
> +
> +	if (data->chip_num > 1 && chip == 0)
> +		freq += 100;
> +	else if (data->chip_num > 1 && chip == 1)
> +		freq -= 100;
> +
> +	error =
> +	    it9135_tuner_set_freq(data, chip, data->bandwidth[chip], frequency);
> +	if (error)
> +		goto exit;
> +
> +	/* Trigger ofsm */
> +	error = it9135_write_reg(data, chip, PROCESSOR_OFDM, trigger_ofsm, 0);
> +	if (error)
> +		goto exit;
> +
> +	data->frequency[chip] = frequency;
> +
> +exit:
> +	return error;
> +}
> +
> +/*
> + * Load firmware to device
> + *
> + * @param struct it9135_data the handle of IT9135.
> + * @fw_codes pointer to fw binary.
> + * @fw_segs pointer to fw segments.
> + * @fw_parts pointer to fw partition.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +static unsigned long it9135_load_firmware(struct it9135_data *data,
> +					  unsigned char *fw_codes,
> +					  struct it9135_segment *fw_segs,
> +					  unsigned char *fw_parts)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned long beginPartition = 0;
> +	unsigned long endPartition = 0;
> +	unsigned long version;
> +	unsigned long firmwareLength;
> +	unsigned char *firmwareCodesPointer;
> +	unsigned short command;
> +	unsigned long i;
> +
> +/* Define I2C master speed, the default value 0x07 means 366KHz (1000000000 / (24.4 * 16 * User_I2C_SPEED)). */
> +#define User_I2C_SPEED              0x07
> +
> +	/* Set I2C master clock speed. */
> +	error =
> +	    it9135_write_reg(data, 0, PROCESSOR_LINK,
> +			     p_reg_one_cycle_counter_tuner, User_I2C_SPEED);
> +	if (error)
> +		goto exit;
> +
> +	firmwareCodesPointer = fw_codes;
> +
> +	beginPartition = 0;
> +	endPartition = fw_parts[0];
> +
> +	for (i = beginPartition; i < endPartition; i++) {
> +		firmwareLength = fw_segs[i].length;
> +		if (fw_segs[i].type == 0) {
> +			/* Dwonload firmware */
> +			error =
> +			    it9135_cmd_sendcommand(data, CMD_FW_DOWNLOAD_BEGIN,
> +						   0, PROCESSOR_LINK, 0, NULL,
> +						   0, NULL);
> +			if (error)
> +				goto exit;
> +			error =
> +			    it9135_cmd_loadfirmware(data, firmwareLength,
> +						    firmwareCodesPointer);
> +			if (error)
> +				goto exit;
> +			error =
> +			    it9135_cmd_sendcommand(data, CMD_FW_DOWNLOAD_END, 0,
> +						   PROCESSOR_LINK, 0, NULL, 0,
> +						   NULL);
> +			if (error)
> +				goto exit;
> +		} else if (fw_segs[i].type == 1) {
> +			/* Copy firmware */
> +			error =
> +			    it9135_cmd_sendcommand(data,
> +						   CMD_SCATTER_WRITE, 0,
> +						   PROCESSOR_LINK,
> +						   firmwareLength,
> +						   firmwareCodesPointer, 0,
> +						   NULL);
> +			if (error)
> +				goto exit;
> +		} else {
> +			/* Direct write firmware */
> +			command =
> +			    (unsigned short)(firmwareCodesPointer[0] << 8) +
> +			    (unsigned short)firmwareCodesPointer[1];
> +			error =
> +			    it9135_cmd_sendcommand(data, command, 0,
> +						   PROCESSOR_LINK,
> +						   firmwareLength - 2,
> +						   firmwareCodesPointer + 2, 0,
> +						   NULL);
> +			if (error)
> +				goto exit;
> +		}
> +		firmwareCodesPointer += firmwareLength;
> +	}
> +
> +	/* Boot */
> +	error =
> +	    it9135_cmd_sendcommand(data, CMD_BOOT, 0, PROCESSOR_LINK, 0, NULL,
> +				   0, NULL);
> +	if (error)
> +		goto exit;
> +
> +	mdelay(10);
> +
> +	/* Check if firmware is running */
> +	version = 0;
> +	error = it9135_get_fw_ver(data, PROCESSOR_LINK, &version);
> +	if (error)
> +		goto exit;
> +	if (version == 0)
> +		error = ERROR_BOOT_FAIL;
> +
> +exit:
> +	return error;
> +}
> +
> +/*
> + * Load initial script to device
> + *
> + * @param struct it9135_data the handle of IT9135.
> + * @script_sets pointer to script_sets.
> + * @scripts pointer to fw scripts.
> + * @tuner_script_sets pointer to tunerScriptSets.
> + * @tuner_scripts pointer to tunerScripts.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +static unsigned long it9135_load_script(struct it9135_data *data,
> +					unsigned short *script_sets,
> +					struct it9135_val_set *scripts,
> +					unsigned short *tuner_script_sets,
> +					struct it9135_val_set *tuner_scripts)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned short beginScript;
> +	unsigned short endScript;
> +	unsigned char i, value1 = 0, prechip_version = 0, supportRelay =
> +	    0, chip_num = 0, bufferLens = 1;
> +	unsigned short j;
> +	unsigned char buffer[20] = { 0 };
> +	unsigned long tunerAddr, tunerAddrTemp;
> +
> +	/* Querry SupportRelayCommandWrite */
> +	error = it9135_read_reg(data, 0, PROCESSOR_OFDM, 0x004D, &supportRelay);
> +	if (error)
> +		goto exit;
> +
> +	if (supportRelay && data->chip_num == 2)
> +		chip_num = 1;
> +	else
> +		chip_num = data->chip_num;
> +
> +	/* Enable RelayCommandWrite */
> +	if (supportRelay) {
> +		error = it9135_write_reg(data, 0, PROCESSOR_OFDM, 0x004E, 1);
> +		if (error)
> +			goto exit;
> +	}
> +
> +	if ((script_sets[0] != 0) && (scripts != NULL)) {
> +		beginScript = 0;
> +		endScript = script_sets[0];
> +
> +		for (i = 0; i < chip_num; i++) {
> +			/* Load OFSM init script */
> +			for (j = beginScript; j < endScript; j++) {
> +				tunerAddr = tunerAddrTemp = scripts[j].address;
> +				buffer[0] = scripts[j].value;
> +
> +				while (j < endScript && bufferLens < 20) {
> +					tunerAddrTemp += 1;
> +					if (tunerAddrTemp !=
> +					    scripts[j + 1].address)
> +						break;
> +
> +					buffer[bufferLens] =
> +					    scripts[j + 1].value;
> +					bufferLens++;
> +					j++;
> +				}
> +
> +				error =
> +				    it9135_write_regs(data, i, PROCESSOR_OFDM,
> +						      tunerAddr, bufferLens,
> +						      buffer);
> +				if (error)
> +					goto exit;
> +				bufferLens = 1;
> +			}
> +		}
> +	}
> +
> +	/* Distinguish chip type */
> +	error =
> +	    it9135_read_reg(data, 0, PROCESSOR_LINK, chip_version_7_0, &value1);
> +	if (error)
> +		goto exit;
> +
> +	error =
> +	    it9135_read_reg(data, 0, PROCESSOR_LINK, prechip_version_7_0,
> +			    &prechip_version);
> +	if (error)
> +		goto exit;
> +
> +	if ((tuner_script_sets[0] != 0) && (tuner_scripts != NULL)) {
> +		if (tuner_script_sets[1] == tuner_script_sets[0]
> +		    && !(data->chip_ver == 0xF8 && prechip_version == 0xEA)) {
> +			/* New version */
> +			beginScript = tuner_script_sets[0];
> +			endScript = tuner_script_sets[0] + tuner_script_sets[1];
> +		} else {
> +			/* Old version */
> +			beginScript = 0;
> +			endScript = tuner_script_sets[0];
> +		}
> +
> +		for (i = 0; i < chip_num; i++) {
> +			/* Load tuner init script */
> +			for (j = beginScript; j < endScript; j++) {
> +				tunerAddr = tunerAddrTemp =
> +				    tuner_scripts[j].address;
> +				buffer[0] = tuner_scripts[j].value;
> +
> +				while (j < endScript && bufferLens < 20) {
> +					tunerAddrTemp += 1;
> +					if (tunerAddrTemp !=
> +					    tuner_scripts[j + 1].address)
> +						break;
> +
> +					buffer[bufferLens] =
> +					    tuner_scripts[j + 1].value;
> +					bufferLens++;
> +					j++;
> +				}
> +
> +				error =
> +				    it9135_write_regs(data, i, PROCESSOR_OFDM,
> +						      tunerAddr, bufferLens,
> +						      buffer);
> +				if (error)
> +					goto exit;
> +				bufferLens = 1;
> +			}
> +		}
> +	}
> +
> +	/* Disable RelayCommandWrite */
> +	if (supportRelay) {
> +		error = it9135_write_reg(data, 0, PROCESSOR_OFDM, 0x004E, 0);
> +		if (error)
> +			goto exit;
> +	}
> +
> +exit:
> +	return error;
> +}
> +
> +/* end of local functions */
> +
> +unsigned long it9135_write_regs(struct it9135_data *data, unsigned char chip,
> +				unsigned char processor, unsigned long reg_addr,
> +				unsigned long w_buff_len, unsigned char *w_buff)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned short command;
> +	unsigned char buffer[255];
> +	unsigned long buff_len;
> +	unsigned long remain_len;
> +	unsigned long send_len;
> +	unsigned long i;
> +	unsigned char reg_addr_len = 2;
> +
> +	it9135_enter_mutex(data);
> +
> +	if (w_buff_len == 0)
> +		goto exit;
> +	if (reg_addr_len > 4) {
> +		error = ERROR_PROTOCOL_FORMAT_INVALID;
> +		goto exit;
> +	}
> +
> +	if ((w_buff_len + 12) > IT9135_MAX_CMD_SIZE) {
> +		error = ERROR_INVALID_DATA_LENGTH;
> +		goto exit;
> +	}
> +
> +	/* add frame header */
> +	command = it9135_build_command(CMD_REG_DEMOD_WRITE, processor, chip);
> +	buffer[1] = (unsigned char)(command >> 8);
> +	buffer[2] = (unsigned char)command;
> +	buffer[3] = (unsigned char)data->cmd_seq++;
> +	buffer[4] = (unsigned char)w_buff_len;
> +	buffer[5] = (unsigned char)reg_addr_len;
> +	buffer[6] = (unsigned char)((reg_addr) >> 24);	/* Get first unsigned char of reg. address  */
> +	buffer[7] = (unsigned char)((reg_addr) >> 16);	/* Get second unsigned char of reg. address */
> +	buffer[8] = (unsigned char)((reg_addr) >> 8);	/* Get third unsigned char of reg. address  */
> +	buffer[9] = (unsigned char)(reg_addr);	/* Get fourth unsigned char of reg. address */
> +
> +	/* add frame data */
> +	for (i = 0; i < w_buff_len; i++)
> +		buffer[10 + i] = w_buff[i];
> +
> +	/* add frame check-sum */
> +	buff_len = 10 + w_buff_len;
> +	error = it9135_cmd_add_checksum(data, &buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +	/* send frame */
> +	i = 0;
> +	send_len = 0;
> +	remain_len = buff_len;
> +	while (remain_len > 0) {
> +		i = (remain_len > IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
> +		    : (remain_len);
> +		error = it9135_cmd_bus_tx(data, i, &buffer[send_len]);
> +		if (error)
> +			goto exit;
> +
> +		send_len += i;
> +		remain_len -= i;
> +	}
> +
> +	/* get reply frame */
> +	buff_len = 5;
> +	error = it9135_cmd_bus_rx(data, buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +	/* remove check-sum from reply frame */
> +	error = it9135_cmd_remove_checksum(data, &buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +exit:
> +	it9135_leave_mutex(data);
> +	return error;
> +}
> +
> +unsigned long it9135_write_gen_regs(struct it9135_data *data,
> +				    unsigned char chip,
> +				    unsigned char interfaceIndex,
> +				    unsigned char slaveAddress,
> +				    unsigned char buff_len,
> +				    unsigned char *buffer)
> +{
> +	unsigned char w_buff[256];
> +	unsigned char i;
> +
> +	w_buff[0] = buff_len;
> +	w_buff[1] = interfaceIndex;
> +	w_buff[2] = slaveAddress;
> +
> +	for (i = 0; i < buff_len; i++)
> +		w_buff[3 + i] = buffer[i];
> +
> +	return it9135_cmd_sendcommand(data, CMD_GENERIC_WRITE, chip,
> +				      PROCESSOR_LINK, buff_len + 3, w_buff, 0,
> +				      NULL);
> +}
> +
> +unsigned long it9135_write_reg(struct it9135_data *data, unsigned char chip,
> +			       unsigned char processor, unsigned long reg_addr,
> +			       unsigned char value)
> +{
> +	return it9135_write_regs(data, chip, processor, reg_addr, 1, &value);
> +}
> +
> +unsigned long it9135_write_ee_vals(struct it9135_data *data, unsigned char chip,
> +				   unsigned short reg_addr,
> +				   unsigned char w_buff_len,
> +				   unsigned char *w_buff)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned short command;
> +	unsigned char buffer[255];
> +	unsigned long buff_len;
> +	unsigned long remain_len;
> +	unsigned long send_len;
> +	unsigned long i;
> +	unsigned char eeprom_addr = 1;
> +	unsigned char reg_addr_len = 1;
> +
> +	it9135_enter_mutex(data);
> +
> +	if (w_buff_len == 0)
> +		goto exit;
> +
> +	if ((unsigned long)(w_buff_len + 11) > IT9135_MAX_CMD_SIZE) {
> +		error = ERROR_INVALID_DATA_LENGTH;
> +		goto exit;
> +	}
> +
> +	/* add frame header */
> +	command =
> +	    it9135_build_command(CMD_REG_EEPROM_WRITE, PROCESSOR_LINK, chip);
> +	buffer[1] = (unsigned char)(command >> 8);
> +	buffer[2] = (unsigned char)command;
> +	buffer[3] = (unsigned char)data->cmd_seq++;
> +	buffer[4] = (unsigned char)w_buff_len;
> +	buffer[5] = (unsigned char)eeprom_addr;
> +	buffer[6] = (unsigned char)reg_addr_len;
> +	buffer[7] = (unsigned char)(reg_addr >> 8);	/* Get high unsigned char of reg. address */
> +	buffer[8] = (unsigned char)reg_addr;	/* Get low unsigned char of reg. address  */
> +
> +	/* add frame data */
> +	for (i = 0; i < w_buff_len; i++)
> +		buffer[9 + i] = w_buff[i];
> +
> +	/* add frame check-sum */
> +	buff_len = 9 + w_buff_len;
> +	error = it9135_cmd_add_checksum(data, &buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +	/* send frame */
> +	i = 0;
> +	send_len = 0;
> +	remain_len = buff_len;
> +	while (remain_len > 0) {
> +		i = (remain_len > IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
> +		    : (remain_len);
> +		error = it9135_cmd_bus_tx(data, i, &buffer[send_len]);
> +		if (error)
> +			goto exit;
> +
> +		send_len += i;
> +		remain_len -= i;
> +	}
> +
> +	/* get reply frame */
> +	buff_len = 5;
> +	error = it9135_cmd_bus_rx(data, buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +	/* remove check-sum from reply frame */
> +	error = it9135_cmd_remove_checksum(data, &buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +exit:
> +	it9135_leave_mutex(data);
> +	return error;
> +}
> +
> +static unsigned char it9135_reg_bit_mask[8] = {
> +	0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF
> +};
> +
> +unsigned long it9135_write_reg_bits(struct it9135_data *data,
> +				    unsigned char chip, unsigned char processor,
> +				    unsigned long reg_addr,
> +				    unsigned char position,
> +				    unsigned char length, unsigned char value)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char temp;
> +
> +	if (length == 8) {
> +		error =
> +		    it9135_write_regs(data, chip, processor, reg_addr, 1,
> +				      &value);
> +	} else {
> +		error =
> +		    it9135_read_regs(data, chip, processor, reg_addr, 1, &temp);
> +		if (error)
> +			goto exit;
> +
> +		temp =
> +		    REG_CREATE(it9135_reg_bit_mask, value, temp, position,
> +			       length);
> +
> +		error =
> +		    it9135_write_regs(data, chip, processor, reg_addr, 1,
> +				      &temp);
> +	}
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_read_reg(struct it9135_data *data, unsigned char chip,
> +			      unsigned char processor, unsigned long reg_addr,
> +			      unsigned char *value)
> +{
> +	return it9135_read_regs(data, chip, processor, reg_addr, 1, value);
> +}
> +
> +unsigned long it9135_read_regs(struct it9135_data *data, unsigned char chip,
> +			       unsigned char processor, unsigned long reg_addr,
> +			       unsigned long r_buff_len, unsigned char *r_buff)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned short command;
> +	unsigned char buffer[255];
> +	unsigned long buff_len;
> +	unsigned long send_len;
> +	unsigned long remain_len;
> +	unsigned long i, k;
> +	unsigned char reg_addr_len = 2;
> +
> +	it9135_enter_mutex(data);
> +
> +	if (r_buff_len == 0)
> +		goto exit;
> +	if (reg_addr_len > 4) {
> +		error = ERROR_PROTOCOL_FORMAT_INVALID;
> +		goto exit;
> +	}
> +
> +	if ((r_buff_len + 5) > IT9135_MAX_PKT_SIZE) {
> +		error = ERROR_INVALID_DATA_LENGTH;
> +		goto exit;
> +	}
> +
> +	if ((r_buff_len + 5) > IT9135_MAX_CMD_SIZE) {
> +		error = ERROR_INVALID_DATA_LENGTH;
> +		goto exit;
> +	}
> +
> +	/* add frame header */
> +	command = it9135_build_command(CMD_REG_DEMOD_READ, processor, chip);
> +	buffer[1] = (unsigned char)(command >> 8);
> +	buffer[2] = (unsigned char)command;
> +	buffer[3] = (unsigned char)data->cmd_seq++;
> +	buffer[4] = (unsigned char)r_buff_len;
> +	buffer[5] = (unsigned char)reg_addr_len;
> +	buffer[6] = (unsigned char)(reg_addr >> 24);	/* Get first unsigned char of reg. address  */
> +	buffer[7] = (unsigned char)(reg_addr >> 16);	/* Get second unsigned char of reg. address */
> +	buffer[8] = (unsigned char)(reg_addr >> 8);	/* Get third unsigned char of reg. address  */
> +	buffer[9] = (unsigned char)(reg_addr);	/* Get fourth unsigned char of reg. address */
> +
> +	/* add frame check-sum */
> +	buff_len = 10;
> +	error = it9135_cmd_add_checksum(data, &buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +	/* send frame */
> +	i = 0;
> +	send_len = 0;
> +	remain_len = buff_len;
> +	while (remain_len > 0) {
> +		i = (remain_len > IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
> +		    : (remain_len);
> +		error = it9135_cmd_bus_tx(data, i, &buffer[send_len]);
> +		if (error)
> +			goto exit;
> +
> +		send_len += i;
> +		remain_len -= i;
> +	}
> +
> +	/* get reply frame */
> +	buff_len = 5 + r_buff_len;
> +	error = it9135_cmd_bus_rx(data, buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +	/* remove check-sum from reply frame */
> +	error = it9135_cmd_remove_checksum(data, &buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +	for (k = 0; k < r_buff_len; k++)
> +		r_buff[k] = buffer[k + 3];
> +
> +exit:
> +	it9135_leave_mutex(data);
> +	return error;
> +}
> +
> +unsigned long it9135_read_gen_regs(struct it9135_data *data, unsigned char chip,
> +				   unsigned char interfaceIndex,
> +				   unsigned char slaveAddress,
> +				   unsigned char buff_len,
> +				   unsigned char *buffer)
> +{
> +	unsigned char w_buff[3];
> +
> +	w_buff[0] = buff_len;
> +	w_buff[1] = interfaceIndex;
> +	w_buff[2] = slaveAddress;
> +
> +	return it9135_cmd_sendcommand(data, CMD_GENERIC_READ, chip,
> +				      PROCESSOR_LINK, 3, w_buff, buff_len,
> +				      buffer);
> +}
> +
> +unsigned long it9135_read_ee_vals(struct it9135_data *data, unsigned char chip,
> +				  unsigned short reg_addr,
> +				  unsigned char r_buff_len,
> +				  unsigned char *r_buff)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned short command;
> +	unsigned char buffer[255];
> +	unsigned long buff_len;
> +	unsigned long remain_len;
> +	unsigned long send_len;
> +	unsigned long i, k;
> +	unsigned char eeprom_addr = 1;
> +	unsigned char reg_addr_len = 1;
> +
> +	it9135_enter_mutex(data);
> +
> +	if (r_buff_len == 0)
> +		goto exit;
> +
> +	if ((unsigned long)(r_buff_len + 5) > IT9135_MAX_PKT_SIZE) {
> +		error = ERROR_INVALID_DATA_LENGTH;
> +		goto exit;
> +	}
> +
> +	if ((unsigned long)(r_buff_len + 5) > IT9135_MAX_CMD_SIZE) {
> +		error = ERROR_INVALID_DATA_LENGTH;
> +		goto exit;
> +	}
> +
> +	/* add command header */
> +	command =
> +	    it9135_build_command(CMD_REG_EEPROM_READ, PROCESSOR_LINK, chip);
> +	buffer[1] = (unsigned char)(command >> 8);
> +	buffer[2] = (unsigned char)command;
> +	buffer[3] = (unsigned char)data->cmd_seq++;
> +	buffer[4] = (unsigned char)r_buff_len;
> +	buffer[5] = (unsigned char)eeprom_addr;
> +	buffer[6] = (unsigned char)reg_addr_len;
> +	buffer[7] = (unsigned char)(reg_addr >> 8);	/* Get high unsigned char of reg. address */
> +	buffer[8] = (unsigned char)reg_addr;	/* Get low unsigned char of reg. address  */
> +
> +	/* add frame check-sum */
> +	buff_len = 9;
> +	error = it9135_cmd_add_checksum(data, &buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +	/* send frame */
> +	i = 0;
> +	send_len = 0;
> +	remain_len = buff_len;
> +	while (remain_len > 0) {
> +		i = (remain_len > IT9135_MAX_PKT_SIZE) ? (IT9135_MAX_PKT_SIZE)
> +		    : (remain_len);
> +		error = it9135_cmd_bus_tx(data, i, &buffer[send_len]);
> +		if (error)
> +			goto exit;
> +
> +		send_len += i;
> +		remain_len -= i;
> +	}
> +
> +	/* get reply frame */
> +	buff_len = 5 + r_buff_len;
> +	error = it9135_cmd_bus_rx(data, buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +	/* remove frame check-sum */
> +	error = it9135_cmd_remove_checksum(data, &buff_len, buffer);
> +	if (error)
> +		goto exit;
> +
> +	for (k = 0; k < r_buff_len; k++)
> +		r_buff[k] = buffer[k + 3];
> +
> +exit:
> +	it9135_leave_mutex(data);
> +	return error;
> +}
> +
> +unsigned long it9135_read_reg_bits(struct it9135_data *data,
> +				   unsigned char chip, unsigned char processor,
> +				   unsigned long reg_addr,
> +				   unsigned char position, unsigned char length,
> +				   unsigned char *value)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char temp = 0;
> +
> +	error = it9135_read_regs(data, chip, processor, reg_addr, 1, &temp);
> +	if (error)
> +		goto exit;
> +
> +	if (length == 8) {
> +		*value = temp;
> +	} else {
> +		temp = REG_GET(it9135_reg_bit_mask, temp, position, length);
> +		*value = temp;
> +	}
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_get_fw_ver(struct it9135_data *data,
> +				unsigned char processor, unsigned long *version)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char w_buff[1] = { 1 };
> +	unsigned char r_buff[4] = { 0, 0, 0, 0 };
> +
> +	error =
> +	    it9135_cmd_sendcommand(data, CMD_QUERYINFO, 0, processor, 1, w_buff,
> +				   4, r_buff);
> +	if (error)
> +		goto exit;
> +
> +	*version =
> +	    (unsigned long)(((unsigned long)r_buff[0] << 24) +
> +			    ((unsigned long)r_buff[1] << 16) +
> +			    ((unsigned long)r_buff[2] << 8) +
> +			    (unsigned long)r_buff[3]);
> +
> +exit:
> +	return error;
> +}
> +
> +/*
> + * Set the counting range for Post-Viterbi and Post-Viterbi.
> + *
> + * @param struct it9135_data the handle of IT9135.
> + * @param chip The index of IT9135. The possible values are 0~7.
> + *        NOTE: When the architecture is set to ARCHITECTURE_DCA
> + *        this parameter is regard as don't care.
> + * @param post_err_cnt the number of super frame for Pre-Viterbi (24 bits).
> + * @param post_bit_cnt the number of packet unit for Post-Viterbi (16 bits).
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_get_post_vitber(struct it9135_data *data,
> +				     unsigned char chip,
> +				     unsigned long *post_err_cnt,
> +				     unsigned long *post_bit_cnt,
> +				     unsigned short *abort_cnt)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned long err_cnt;
> +	unsigned long bit_cnt;
> +	unsigned char buffer[7];
> +	unsigned short abort;
> +
> +	*post_err_cnt = 0;
> +	*post_bit_cnt = 0;
> +
> +	error =
> +	    it9135_read_regs(data, chip, PROCESSOR_OFDM,
> +			     rsd_abort_packet_cnt_7_0,
> +			     r_rsd_packet_unit_15_8 - rsd_abort_packet_cnt_7_0 +
> +			     1, buffer);
> +	if (error)
> +		goto exit;
> +
> +	abort = ((unsigned short)
> +		 buffer[rsd_abort_packet_cnt_15_8 - rsd_abort_packet_cnt_7_0]
> +		 << 8) + buffer[rsd_abort_packet_cnt_7_0 -
> +				rsd_abort_packet_cnt_7_0];
> +	err_cnt = ((unsigned long)
> +		   buffer[rsd_bit_err_cnt_23_16 -
> +			  rsd_abort_packet_cnt_7_0] << 16) + ((unsigned long)
> +							      buffer
> +							      [rsd_bit_err_cnt_15_8
> +							       -
> +							       rsd_abort_packet_cnt_7_0]
> +							      << 8) +
> +	    buffer[rsd_bit_err_cnt_7_0 - rsd_abort_packet_cnt_7_0];
> +	bit_cnt = ((unsigned long)
> +		   buffer[r_rsd_packet_unit_15_8 -
> +			  rsd_abort_packet_cnt_7_0] << 8) +
> +	    buffer[r_rsd_packet_unit_7_0 - rsd_abort_packet_cnt_7_0];
> +
> +	if (bit_cnt == 0) {
> +		/*error = ERROR_RSD_PKT_CNT_0; */
> +		*post_err_cnt = 1;
> +		*post_bit_cnt = 2;
> +		*abort_cnt = 1000;
> +		goto exit;
> +	}
> +
> +	*abort_cnt = abort;
> +	bit_cnt = bit_cnt - (unsigned long)abort;
> +	if (bit_cnt == 0) {
> +		*post_err_cnt = 1;
> +		*post_bit_cnt = 2;
> +	} else {
> +		*post_err_cnt = err_cnt - (unsigned long)abort * 8 * 8;
> +		*post_bit_cnt = bit_cnt * 204 * 8;
> +	}
> +
> +exit:
> +	return error;
> +}
> +
> +/* NorDig 3.4.4.6 & Table 3.4 */
> +static int it9135_Pref_values[3][5] = {
> +	{-93, -91, -90, -89, -88},	/* QPSK    CodeRate 1/2 ~ 7/8 Pref Values */
> +	{-87, -85, -84, -83, -82},	/* 16QAM   CodeRate 1/2 ~ 7/8 Pref Values */
> +	{-82, -80, -78, -77, -76},	/* 64QAM   CodeRate 1/2 ~ 7/8 Pref Values */
> +};
> +
> +/*
> + * Get siganl quality.


typo: signal instead of siganl

> + *
> + * @param struct it9135_data the handle of IT9135.
> + * @param chip The index of IT9135. The possible values are 0~7.
> + *        NOTE: When the architecture is set to ARCHITECTURE_DCA
> + *        this parameter is regard as don't care.
> + * @param quality The value of signal quality.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_get_signal_quality(struct it9135_data *data,
> +					unsigned char chip,
> +					unsigned char *quality)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	error = it9135_read_reg(data, chip, PROCESSOR_OFDM, signal_quality, quality);
> +	
> +	return (error);

Don't use parenthesis for return. You should check your code with:

	scripts/checkpatch.pl

This script points you about trivial Coding Style issues like that.


> +}
> +
> +unsigned long it9135_get_strength(struct it9135_data *data, unsigned char chip,
> +				  unsigned char *strength)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char temp, lna_gain_offset;
> +	struct it9135_ch_modulation ch_modulation;
> +	int Prec, Pref, Prel;
> +
> +	error =
> +	    it9135_read_reg(data, chip, PROCESSOR_OFDM, var_p_inband, &temp);
> +	if (error)
> +		goto exit;
> +
> +	error = it9135_get_ch_modulation(data, chip, &ch_modulation);
> +	if (error)
> +		goto exit;
> +
> +	if (ch_modulation.frequency < 300000)
> +		lna_gain_offset = 7;	/* VHF */
> +	else
> +		lna_gain_offset = 14;	/* UHF */
> +
> +	Prec = (temp - 100) - lna_gain_offset;
> +
> +	if (ch_modulation.priority == PRIORITY_HIGH)
> +		Pref = it9135_Pref_values[ch_modulation.constellation]
> +		    [ch_modulation.h_code_rate];
> +	else
> +		Pref = it9135_Pref_values[ch_modulation.constellation]
> +		    [ch_modulation.l_code_rate];
> +
> +	Prel = Prec - Pref;
> +
> +	if (Prel < -15)
> +		*strength = 0;
> +	else if ((-15 <= Prel) && (Prel < 0))
> +		*strength = (unsigned char)((2 * (Prel + 15)) / 3);
> +	else if ((0 <= Prel) && (Prel < 20))
> +		*strength = (unsigned char)(4 * Prel + 10);
> +	else if ((20 <= Prel) && (Prel < 35))
> +		*strength = ((unsigned char)(2 * (Prel - 20)) / 3 + 90);
> +	else if (Prel >= 35)
> +		*strength = 100;
> +
> +exit:
> +	return error;
> +}
> +
> +/* @param strength_dbm: DBm */
> +unsigned long it9135_get_strength_dbm(struct it9135_data *data,
> +				      unsigned char chip, long *strength_dbm)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char temp;
> +
> +	error =
> +	    it9135_read_reg(data, chip, PROCESSOR_OFDM, var_p_inband, &temp);
> +	if (error)
> +		goto exit;
> +
> +	*strength_dbm = (long)(temp - 100);
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_load_ir_tab(struct it9135_data *data,
> +				 unsigned short tab_len, unsigned char *table)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char base_high;
> +	unsigned char base_low;
> +	unsigned short reg_base;
> +	unsigned short i;
> +
> +	error =
> +	    it9135_read_reg(data, 0, PROCESSOR_LINK, ir_table_start_15_8,
> +			    &base_high);
> +	if (error)
> +		goto exit;
> +	error =
> +	    it9135_read_reg(data, 0, PROCESSOR_LINK, ir_table_start_7_0,
> +			    &base_low);
> +	if (error)
> +		goto exit;
> +
> +	reg_base = (unsigned short)(base_high << 8) + (unsigned short)base_low;
> +
> +	if (reg_base) {
> +		for (i = 0; i < tab_len; i++) {
> +			error =
> +			    it9135_write_reg(data, 0, PROCESSOR_LINK,
> +					     reg_base + i, table[i]);
> +			if (error)
> +				goto exit;
> +		}
> +	}
> +
> +exit:
> +	return error;
> +}
> +
> +static struct it9135_freq_clk it9135_freq_clk_tab[2] = {
> +	{12000, 20250000},
> +	{20480, 20480000}
> +};
> +
> +unsigned long it9135_dev_init(struct it9135_data *data, unsigned char chip_num,
> +			      unsigned short saw_band, unsigned char streamType,
> +			      unsigned char architecture)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned long crystal = 0;
> +	unsigned long adc = 0;
> +	unsigned long fcw = 0;
> +	unsigned char buffer[4];
> +	unsigned long version = 0;
> +	unsigned short *tuner_script_sets = NULL;
> +	struct it9135_val_set *tuner_scripts = NULL;
> +	unsigned char i;
> +	unsigned char var[2];
> +
> +#define IT9135_IF_FREQUENCY				0
> +#define IT9135_IF_INVERSION				0
> +/* Define I2C address of secondary chip when Diversity mode or PIP mode is active. */
> +#define IT9135_CHIP2_I2C_ADDR      0x3A
> +
> +	data->chip_num = chip_num;
> +	data->fcw = 0x00000000;
> +	data->frequency[0] = 642000;
> +	data->frequency[1] = 642000;
> +	data->inited = 0;
> +	data->host_if[0] = 0;
> +	data->cmd_seq = 0;
> +	data->pid_info.pid_init = 0;
> +
> +	error =
> +	    it9135_read_reg(data, 0, PROCESSOR_LINK, chip_version_7_0,
> +			    &data->chip_ver);
> +	if (error)
> +		goto exit;
> +	error =
> +	    it9135_read_regs(data, 0, PROCESSOR_LINK, chip_version_7_0 + 1, 2,
> +			     var);
> +	if (error)
> +		goto exit;
> +	data->chip_type = var[1] << 8 | var[0];
> +
> +	if (data->busId == 0xFFFF || data->tuner_desc.id == 0xFFFF)
> +		goto exit;
> +
> +	error = it9135_get_fw_ver(data, PROCESSOR_LINK, &version);
> +	if (error)
> +		goto exit;
> +	if (version != 0)
> +		data->booted = 1;
> +	else
> +		data->booted = 0;
> +
> +	/*if (data->chip_type == 0x9135 && data->chip_ver == 2) {
> +	   data->fw_codes = FirmwareV2_codes;
> +	   data->fw_segs = FirmwareV2_segments;
> +	   data->fw_parts = FirmwareV2_partitions;
> +	   data->script_sets = FirmwareV2_scriptSets;
> +	   data->scripts = FirmwareV2_scripts;
> +	   } else {
> +	   data->fw_codes = Firmware_codes;
> +	   data->fw_segs = Firmware_segments;
> +	   data->fw_parts = Firmware_partitions;
> +	   data->script_sets = Firmware_scriptSets;
> +	   data->scripts = Firmware_scripts;
> +	   } */

Better to put commented code like the above into:

#if 0
	dead_code();
#endif

Also, identation of the above is broken.

Btw, doesn't it needed to be uncommented? Maybe you should add there
something like:

#if 0
	/* FIXME: add support for version 2 of the chipset */
...
#endif

> +	tuner_script_sets = data->tuner_desc.script_sets;
> +	tuner_scripts = data->tuner_desc.scripts;
> +
> +	error =
> +	    it9135_read_reg_bits(data, 0, PROCESSOR_LINK,
> +				 r_io_mux_pwron_clk_strap,
> +				 io_mux_pwron_clk_strap_pos,
> +				 io_mux_pwron_clk_strap_len, &i);
> +	if (error)
> +		goto exit;
> +
> +	data->crystal_Freq = it9135_freq_clk_tab[0].crystal_Freq;
> +	data->adc_freq = it9135_freq_clk_tab[0].adc_freq;
> +
> +	/* Write secondary I2C address to device */
> +	/* Enable or disable clock for 2nd chip power saving */
> +	if (data->chip_num > 1) {
> +		error =
> +		    it9135_write_reg(data, 0, PROCESSOR_LINK,
> +				     second_i2c_address, IT9135_CHIP2_I2C_ADDR);
> +		if (error)
> +			goto exit;
> +
> +		error =
> +		    it9135_write_reg(data, 0, PROCESSOR_LINK, p_reg_top_clkoen,
> +				     1);
> +		if (error)
> +			goto exit;
> +
> +	} else {
> +		error =
> +		    it9135_write_reg(data, 0, PROCESSOR_LINK,
> +				     second_i2c_address, 0x00);
> +		if (error)
> +			goto exit;
> +
> +		error =
> +		    it9135_write_reg(data, 0, PROCESSOR_LINK, p_reg_top_clkoen,
> +				     0);
> +		if (error)
> +			goto exit;
> +	}
> +
> +	/* Load firmware */
> +	if (data->fw_codes != NULL) {
> +		if (!data->booted) {
> +			error =
> +			    it9135_load_firmware(data,
> +						 data->fw_codes, data->fw_segs,
> +						 &data->fw_parts);
> +			if (error)
> +				goto exit;
> +			data->booted = 1;
> +		}
> +	}
> +
> +	/* Set I2C master clock 100k in order to support tuner I2C. */
> +	error =
> +	    it9135_write_reg(data, 0, PROCESSOR_LINK,
> +			     p_reg_one_cycle_counter_tuner, 0x1a);
> +	if (error)
> +		goto exit;
> +
> +	for (i = 0; i < data->chip_num; i++) {
> +		error = it9135_write_reg(data, i, PROCESSOR_OFDM, 0xEC4C, 0x68);
> +		if (error)
> +			goto exit;
> +		mdelay(10);
> +	}
> +
> +	if (data->chip_type == 0x9135 && data->chip_ver == 1) {
> +		/* Open tuner */
> +		for (i = 0; i < data->chip_num; i++) {
> +
> +			/* Set 0xD827 to 0 as open drain for tuner i2c */
> +			error =
> +			    it9135_write_reg(data, i, PROCESSOR_LINK,
> +					     p_reg_top_padodpu, 0);
> +			if (error)
> +				goto exit;
> +
> +			/* Set 0xD829 to 0 as push pull for tuner AGC */
> +			error =
> +			    it9135_write_reg(data, i, PROCESSOR_LINK,
> +					     p_reg_top_agc_od, 0);
> +			if (error)
> +				goto exit;
> +		}
> +
> +		for (i = 0; i < data->chip_num; i++) {
> +			error = it9135_tuner_init(data, i);
> +			if (error)
> +				goto exit;
> +		}
> +	}
> +
> +	for (i = 0; i < data->chip_num; i++) {
> +		/* Tell firmware the type of tuner. */
> +		error =
> +		    it9135_write_reg(data, i, PROCESSOR_LINK,
> +				     p_reg_link_ofsm_dummy_15_8,
> +				     (unsigned char)data->tuner_desc.id);
> +		if (error)
> +			goto exit;
> +	}
> +
> +	/* Initialize OFDM */
> +	if (data->booted) {
> +		for (i = 0; i < data->chip_num; i++) {
> +			/* Set read-update bit to 1 for constellation */
> +			error =
> +			    it9135_write_reg_bits(data, i,
> +						  PROCESSOR_OFDM,
> +						  p_reg_feq_read_update,
> +						  reg_feq_read_update_pos,
> +						  reg_feq_read_update_len, 1);
> +			if (error)
> +				goto exit;
> +
> +			/* Enable FEC Monitor */
> +			error =
> +			    it9135_write_reg_bits(data, i,
> +						  PROCESSOR_OFDM,
> +						  p_fec_vtb_rsd_mon_en,
> +						  fec_vtb_rsd_mon_en_pos,
> +						  fec_vtb_rsd_mon_en_len, 1);
> +			if (error)
> +				goto exit;
> +		}
> +
> +		/* Compute ADC and load them to device */
> +		error =
> +		    it9135_compute_crystal(data,
> +					   (long)data->crystal_Freq * 1000,
> +					   &crystal);
> +		if (error)
> +			goto exit;
> +
> +		buffer[0] = (unsigned char)(crystal & 0x000000FF);
> +		buffer[1] = (unsigned char)((crystal & 0x0000FF00) >> 8);
> +		buffer[2] = (unsigned char)((crystal & 0x00FF0000) >> 16);
> +		buffer[3] = (unsigned char)((crystal & 0xFF000000) >> 24);
> +		for (i = 0; i < data->chip_num; i++) {
> +			error =
> +			    it9135_write_regs(data, i, PROCESSOR_OFDM,
> +					      crystal_clk_7_0, 4, buffer);
> +			if (error)
> +				goto exit;
> +		}
> +
> +		/* Compute ADC and load them to device */
> +		error = it9135_compute_adc(data, (long)data->adc_freq, &adc);
> +		if (error)
> +			goto exit;
> +
> +		buffer[0] = (unsigned char)(adc & 0x000000FF);
> +		buffer[1] = (unsigned char)((adc & 0x0000FF00) >> 8);
> +		buffer[2] = (unsigned char)((adc & 0x00FF0000) >> 16);
> +		for (i = 0; i < data->chip_num; i++) {
> +			error =
> +			    it9135_write_regs(data, i, PROCESSOR_OFDM,
> +					      p_reg_f_adc_7_0, 3, buffer);
> +			if (error)
> +				goto exit;
> +		}
> +
> +		/* Compute FCW and load them to device */
> +		error =
> +		    it9135_compute_fcw(data,
> +				       (long)data->adc_freq,
> +				       (long)IT9135_IF_FREQUENCY,
> +				       IT9135_IF_INVERSION, &fcw);
> +		if (error)
> +			goto exit;
> +		data->fcw = fcw;
> +
> +		buffer[0] = (unsigned char)(fcw & 0x000000FF);
> +		buffer[1] = (unsigned char)((fcw & 0x0000FF00) >> 8);
> +		buffer[2] = (unsigned char)((fcw & 0x007F0000) >> 16);
> +		for (i = 0; i < data->chip_num; i++) {
> +			error =
> +			    it9135_write_regs(data, i,
> +					      PROCESSOR_OFDM, bfs_fcw_7_0,
> +					      bfs_fcw_22_16 - bfs_fcw_7_0 + 1,
> +					      buffer);
> +			if (error)
> +				goto exit;
> +		}
> +	}
> +
> +	/* Load script */
> +	if (data->scripts != NULL) {
> +		error =
> +		    it9135_load_script(data, data->script_sets,
> +				       data->scripts, tuner_script_sets,
> +				       tuner_scripts);
> +		if (error)
> +			goto exit;
> +	}
> +
> +	if ((data->chip_type == 0x9135 && data->chip_ver == 2)
> +	    || data->chip_type == 0x9175) {
> +		for (i = 0; i < data->chip_num; i++) {
> +			error =
> +			    it9135_write_reg(data, i, PROCESSOR_OFDM,
> +					     trigger_ofsm, 0x01);
> +			if (error)
> +				goto exit;
> +		}
> +
> +		/* Open tuner */
> +		for (i = 0; i < data->chip_num; i++) {
> +
> +			/* Set 0xD827 to 0 as open drain for tuner i2c */
> +			error =
> +			    it9135_write_reg(data, i, PROCESSOR_LINK,
> +					     p_reg_top_padodpu, 0);
> +			if (error)
> +				goto exit;
> +
> +			/* Set 0xD829 to 0 as push pull for tuner AGC */
> +			error =
> +			    it9135_write_reg(data, i, PROCESSOR_LINK,
> +					     p_reg_top_agc_od, 0);
> +			if (error)
> +				goto exit;
> +		}
> +
> +		for (i = 0; i < data->chip_num; i++) {
> +			error = it9135_tuner_init(data, i);
> +			if (error)
> +				goto exit;
> +		}
> +	}
> +
> +	/* Set the desired stream type */
> +	error = it9135_set_stream_type(data, streamType);
> +	if (error)
> +		goto exit;
> +
> +	/* Set the desired architecture type */
> +	error = it9135_set_arch(data, architecture);
> +	if (error)
> +		goto exit;
> +
> +	for (i = 0; i < data->chip_num; i++) {
> +		/* Set H/W MPEG2 locked detection */
> +		error =
> +		    it9135_write_reg(data, i, PROCESSOR_LINK,
> +				     p_reg_top_lock3_out, 1);
> +		if (error)
> +			goto exit;
> +		error =
> +		    it9135_write_reg(data, i, PROCESSOR_LINK,
> +				     p_reg_top_padmiscdrsr, 1);
> +		if (error)
> +			goto exit;
> +		/* Set registers for driving power 0xD830 */
> +		error =
> +		    it9135_write_reg(data, i, PROCESSOR_LINK,
> +				     p_reg_top_padmiscdr2, 0);
> +		if (error)
> +			goto exit;
> +		/* enhance the performance while using DIP crystals */
> +		error = it9135_write_reg(data, i, PROCESSOR_OFDM, 0xEC57, 0);
> +		if (error)
> +			goto exit;
> +		error = it9135_write_reg(data, i, PROCESSOR_OFDM, 0xEC58, 0);
> +		if (error)
> +			goto exit;
> +		/* Set ADC frequency multiplier */
> +		error = it9135_set_multiplier(data, Multiplier_2X);
> +		if (error)
> +			goto exit;
> +		/* Set registers for driving power 0xD831 */
> +		error =
> +		    it9135_write_reg(data, i, PROCESSOR_LINK,
> +				     p_reg_top_padmiscdr4, 0);
> +		if (error)
> +			goto exit;
> +		/* Set registers for driving power 0xD832 */
> +		error =
> +		    it9135_write_reg(data, i, PROCESSOR_LINK,
> +				     p_reg_top_padmiscdr8, 0);
> +		if (error)
> +			goto exit;
> +	}
> +
> +	data->inited = 1;
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_tps_locked(struct it9135_data *data, unsigned char chip,
> +				int *locked)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char temp;
> +
> +	*locked = 0;
> +
> +	error =
> +	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM, p_fd_tpsd_lock,
> +				 fd_tpsd_lock_pos, fd_tpsd_lock_len, &temp);
> +	if (error)
> +		goto exit;
> +	if (temp)
> +		*locked = 1;
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_mp2_locked(struct it9135_data *data, unsigned char chip,
> +				int *locked)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char temp;
> +
> +	*locked = 0;
> +
> +	error =
> +	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM,
> +				 r_mp2if_sync_byte_locked,
> +				 mp2if_sync_byte_locked_pos,
> +				 mp2if_sync_byte_locked_len, &temp);
> +	if (error)
> +		goto exit;
> +
> +	if (temp)
> +		*locked = 1;
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_freq_locked(struct it9135_data *data, unsigned char chip,
> +				 int *locked)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned short empty_loop = 0;
> +	unsigned short tps_loop = 0;
> +	unsigned short mpeg2_loop = 0;
> +	unsigned char channels[2];
> +	unsigned char begin;
> +	unsigned char end;
> +	unsigned char i;
> +	unsigned char empty_ch = 1;
> +	unsigned char tps_locked = 0;
> +	int retry = 1;
> +
> +check_lock:
> +	*locked = 0;
> +
> +	if (data->architecture == ARCHITECTURE_DCA) {
> +		begin = 0;
> +		end = data->chip_num;
> +	} else {
> +		begin = chip;
> +		end = begin + 1;
> +	}
> +
> +	for (i = begin; i < end; i++) {
> +		data->statistic[i].presented = 0;
> +		data->statistic[i].locked = 0;
> +		data->statistic[i].quality = 0;
> +		data->statistic[i].strength = 0;
> +	}
> +
> +	channels[0] = 2;
> +	channels[1] = 2;
> +	while (empty_loop < 40) {
> +		for (i = begin; i < end; i++) {
> +			error =
> +			    it9135_read_reg(data, i, PROCESSOR_OFDM,
> +					    empty_channel_status, &channels[i]);
> +			if (error)
> +				goto exit;
> +		}
> +		if ((channels[0] == 1) || (channels[1] == 1)) {
> +			empty_ch = 0;
> +			break;
> +		}
> +		if ((channels[0] == 2) && (channels[1] == 2)) {
> +			empty_ch = 1;
> +			goto exit;
> +		}
> +		mdelay(25);
> +		empty_loop++;
> +	}
> +
> +	if (empty_ch == 1)
> +		goto exit;
> +
> +	while (tps_loop < 50) {
> +		for (i = begin; i < end; i++) {
> +			/* TPS check */
> +			error =
> +			    it9135_tps_locked(data, i,
> +					      &data->statistic[i].presented);
> +			if (error)
> +				goto exit;
> +			if (data->statistic[i].presented) {
> +				tps_locked = 1;
> +				break;
> +			}
> +		}
> +
> +		if (tps_locked == 1)
> +			break;
> +
> +		mdelay(25);
> +		tps_loop++;
> +	}
> +
> +	if (tps_locked == 0)
> +		goto exit;
> +
> +	while (mpeg2_loop < 40) {
> +		if (data->architecture == ARCHITECTURE_DCA) {
> +			error =
> +			    it9135_mp2_locked(data, 0,
> +					      &data->statistic[0].locked);
> +			if (error)
> +				goto exit;
> +			if (data->statistic[0].locked) {
> +				for (i = begin; i < end; i++) {
> +					data->statistic[i].quality = 80;
> +					data->statistic[i].strength = 80;
> +				}
> +				*locked = 1;
> +				break;
> +			}
> +		} else {
> +			error =
> +			    it9135_mp2_locked(data, chip,
> +					      &data->statistic[chip].locked);
> +			if (error)
> +				goto exit;
> +			if (data->statistic[chip].locked) {
> +				data->statistic[chip].quality = 80;
> +				data->statistic[chip].strength = 80;
> +				*locked = 1;
> +				break;
> +			}
> +		}
> +		mdelay(25);
> +		mpeg2_loop++;
> +	}
> +	for (i = begin; i < end; i++) {
> +		data->statistic[i].quality = 0;
> +		data->statistic[i].strength = 20;
> +	}
> +
> +exit:
> +	if (*locked == 0 && retry == 1) {
> +		retry = 0;
> +		mpeg2_loop = 0;
> +		tps_loop = 0;
> +		empty_loop = 0;
> +		empty_ch = 1;
> +		tps_locked = 0;
> +		/* Clear empty_channel_status lock flag */
> +		error =
> +		    it9135_write_reg(data, chip, PROCESSOR_OFDM,
> +				     empty_channel_status, 0x00);
> +		if (error)
> +			goto exit;
> +
> +		/* Trigger ofsm */
> +		error =
> +		    it9135_write_reg(data, chip, PROCESSOR_OFDM, trigger_ofsm,
> +				     0);
> +		if (error)
> +			goto exit;
> +
> +		goto check_lock;
> +	}
> +
> +	return error;
> +}
> +
> +unsigned long it9135_get_ch_modulation(struct it9135_data *data,
> +				       unsigned char chip,
> +				       struct it9135_ch_modulation
> +				       *ch_modulation)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char temp;
> +
> +	/* Get constellation type */
> +	error =
> +	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM,
> +				 g_reg_tpsd_const, reg_tpsd_const_pos,
> +				 reg_tpsd_const_len, &temp);
> +	if (error)
> +		goto exit;
> +	ch_modulation->constellation = temp;
> +
> +	/* Get TPS hierachy and alpha value */
> +	error =
> +	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM,
> +				 g_reg_tpsd_hier, reg_tpsd_hier_pos,
> +				 reg_tpsd_hier_len, &temp);
> +	if (error)
> +		goto exit;
> +	ch_modulation->hierarchy = temp;
> +
> +	/* Get high/low priority */
> +	error =
> +	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM, g_reg_dec_pri,
> +				 reg_dec_pri_pos, reg_dec_pri_len, &temp);
> +	if (error)
> +		goto exit;
> +	if (temp)
> +		ch_modulation->priority = PRIORITY_HIGH;
> +	else
> +		ch_modulation->priority = PRIORITY_LOW;
> +
> +	/* Get high code rate */
> +	error =
> +	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM,
> +				 g_reg_tpsd_hpcr, reg_tpsd_hpcr_pos,
> +				 reg_tpsd_hpcr_len, &temp);
> +	if (error)
> +		goto exit;
> +	ch_modulation->h_code_rate = temp;
> +
> +	/* Get low code rate */
> +	error =
> +	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM,
> +				 g_reg_tpsd_lpcr, reg_tpsd_lpcr_pos,
> +				 reg_tpsd_lpcr_len, &temp);
> +	if (error)
> +		goto exit;
> +	ch_modulation->l_code_rate = temp;
> +
> +	/* Get guard interval */
> +	error =
> +	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM, g_reg_tpsd_gi,
> +				 reg_tpsd_gi_pos, reg_tpsd_gi_len, &temp);
> +	if (error)
> +		goto exit;
> +	ch_modulation->interval = temp;
> +
> +	/* Get FFT mode */
> +	error =
> +	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM,
> +				 g_reg_tpsd_txmod, reg_tpsd_txmod_pos,
> +				 reg_tpsd_txmod_len, &temp);
> +	if (error)
> +		goto exit;
> +	ch_modulation->trans_mode = temp;
> +
> +	/* Get bandwidth */
> +	error =
> +	    it9135_read_reg_bits(data, chip, PROCESSOR_OFDM, g_reg_bw,
> +				 reg_bw_pos, reg_bw_len, &temp);
> +	if (error)
> +		goto exit;
> +	ch_modulation->bandwidth = temp;
> +
> +	/* Get frequency */
> +	ch_modulation->frequency = data->frequency[chip];
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_acquire_ch(struct it9135_data *data, unsigned char chip,
> +				unsigned short bandwidth,
> +				unsigned long frequency)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char begin;
> +	unsigned char end;
> +	unsigned char i;
> +
> +	if (data->architecture == ARCHITECTURE_DCA) {
> +		begin = 0;
> +		end = data->chip_num;
> +	} else {
> +		begin = chip;
> +		end = begin + 1;
> +	}
> +
> +	for (i = begin; i < end; i++) {
> +		error =
> +		    it9135_select_bandwidth(data, i, bandwidth, data->adc_freq);
> +		if (error)
> +			goto exit;
> +		data->bandwidth[i] = bandwidth;
> +	}
> +
> +	error = it9135_mask_dca_output(data);
> +	if (error)
> +		goto exit;
> +
> +	/* Set frequency */
> +	for (i = begin; i < end; i++) {
> +		error = it9135_set_frequency(data, i, frequency);
> +		if (error)
> +			goto exit;
> +	}
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_set_stream_type(struct it9135_data *data,
> +				     unsigned char streamType)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char i;
> +
> +	for (i = 0; i < data->chip_num; i++) {
> +		error =
> +		    it9135_write_reg_bits(data, i, PROCESSOR_OFDM,
> +					  p_reg_mpeg_full_speed,
> +					  reg_mpeg_full_speed_pos,
> +					  reg_mpeg_full_speed_len, 0);
> +		if (error)
> +			goto exit;
> +	}
> +
> +	/* Enable DVB-T mode */
> +	for (i = 0; i < data->chip_num; i++) {
> +		error =
> +		    it9135_write_reg_bits(data, i, PROCESSOR_LINK,
> +					  p_reg_dvbt_en, reg_dvbt_en_pos,
> +					  reg_dvbt_en_len, 1);
> +		if (error)
> +			goto exit;
> +	}
> +
> +	/* Pictor & Orion & Omega & Omega_LNA */
> +	if (data->tuner_desc.id == 0x35
> +	    || data->tuner_desc.id == 0x39
> +	    || data->tuner_desc.id == 0x3A || data->chip_type == 0x9135
> +	    || data->chip_type == 0x9175) {
> +		/* Enter sub mode */
> +		error =
> +		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +					  p_mp2if_mpeg_ser_mode,
> +					  mp2if_mpeg_ser_mode_pos,
> +					  mp2if_mpeg_ser_mode_len, 0);
> +		if (error)
> +			goto exit;
> +		error =
> +		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +					  p_mp2if_mpeg_par_mode,
> +					  mp2if_mpeg_par_mode_pos,
> +					  mp2if_mpeg_par_mode_len, 0);
> +		if (error)
> +			goto exit;
> +		/* Fix current leakage */
> +		error =
> +		    it9135_write_reg_bits(data, 0, PROCESSOR_LINK,
> +					  p_reg_top_hostb_mpeg_ser_mode,
> +					  reg_top_hostb_mpeg_ser_mode_pos,
> +					  reg_top_hostb_mpeg_ser_mode_len, 0);
> +		if (error)
> +			goto exit;
> +		error =
> +		    it9135_write_reg_bits(data, 0, PROCESSOR_LINK,
> +					  p_reg_top_hostb_mpeg_par_mode,
> +					  reg_top_hostb_mpeg_par_mode_pos,
> +					  reg_top_hostb_mpeg_par_mode_len, 0);
> +		if (error)
> +			goto exit;
> +	} else {
> +		/* Enter sub mode */
> +		error =
> +		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +					  p_mp2if_mpeg_ser_mode,
> +					  mp2if_mpeg_ser_mode_pos,
> +					  mp2if_mpeg_ser_mode_len, 0);
> +		if (error)
> +			goto exit;
> +		error =
> +		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +					  p_mp2if_mpeg_par_mode,
> +					  mp2if_mpeg_par_mode_pos,
> +					  mp2if_mpeg_par_mode_len, 0);
> +		if (error)
> +			goto exit;
> +		/* Fix current leakage */
> +		if (data->chip_num > 1) {
> +			if (data->host_if[0]) {
> +				error =
> +				    it9135_write_reg_bits(data, 0,
> +							  PROCESSOR_LINK,
> +							  p_reg_top_hostb_mpeg_ser_mode,
> +							  reg_top_hostb_mpeg_ser_mode_pos,
> +							  reg_top_hostb_mpeg_ser_mode_len,
> +							  0);
> +				if (error)
> +					goto exit;
> +				error =
> +				    it9135_write_reg_bits(data, 0,
> +							  PROCESSOR_LINK,
> +							  p_reg_top_hostb_mpeg_par_mode,
> +							  reg_top_hostb_mpeg_par_mode_pos,
> +							  reg_top_hostb_mpeg_par_mode_len,
> +							  1);
> +				if (error)
> +					goto exit;
> +			} else {
> +				error =
> +				    it9135_write_reg_bits(data, 0,
> +							  PROCESSOR_LINK,
> +							  p_reg_top_hosta_mpeg_ser_mode,
> +							  reg_top_hosta_mpeg_ser_mode_pos,
> +							  reg_top_hosta_mpeg_ser_mode_len,
> +							  0);
> +				if (error)
> +					goto exit;
> +				error =
> +				    it9135_write_reg_bits(data, 0,
> +							  PROCESSOR_LINK,
> +							  p_reg_top_hosta_mpeg_par_mode,
> +							  reg_top_hosta_mpeg_par_mode_pos,
> +							  reg_top_hosta_mpeg_par_mode_len,
> +							  1);
> +				if (error)
> +					goto exit;
> +			}
> +		} else {
> +			error =
> +			    it9135_write_reg_bits(data, 0,
> +						  PROCESSOR_LINK,
> +						  p_reg_top_hosta_mpeg_ser_mode,
> +						  reg_top_hosta_mpeg_ser_mode_pos,
> +						  reg_top_hosta_mpeg_ser_mode_len,
> +						  0);
> +			if (error)
> +				goto exit;
> +			error =
> +			    it9135_write_reg_bits(data, 0,
> +						  PROCESSOR_LINK,
> +						  p_reg_top_hosta_mpeg_par_mode,
> +						  reg_top_hosta_mpeg_par_mode_pos,
> +						  reg_top_hosta_mpeg_par_mode_len,
> +						  1);
> +			if (error)
> +				goto exit;
> +			error =
> +			    it9135_write_reg_bits(data, 0,
> +						  PROCESSOR_LINK,
> +						  p_reg_top_hostb_mpeg_ser_mode,
> +						  reg_top_hostb_mpeg_ser_mode_pos,
> +						  reg_top_hostb_mpeg_ser_mode_len,
> +						  0);
> +			if (error)
> +				goto exit;
> +			error =
> +			    it9135_write_reg_bits(data, 0,
> +						  PROCESSOR_LINK,
> +						  p_reg_top_hostb_mpeg_par_mode,
> +						  reg_top_hostb_mpeg_par_mode_pos,
> +						  reg_top_hostb_mpeg_par_mode_len,
> +						  1);
> +			if (error)
> +				goto exit;
> +		}
> +	}
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_set_arch(struct it9135_data *data,
> +			      unsigned char architecture)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned short frame_sz;
> +	unsigned char packet_sz;
> +	unsigned char buffer[2];
> +	unsigned char standalone[2];
> +	unsigned char upper_chip[2];
> +	unsigned char upper_host[2];
> +	unsigned char lower_chip[2];
> +	unsigned char lower_host[2];
> +	unsigned char dca_en[2];
> +	unsigned char phase_latch[2];
> +	unsigned char fpga_latch[2];
> +	unsigned char i;
> +	int pip_valid = 0;
> +
> +/* Define USB frame size */
> +#define IT9135_USB20_MAX_PACKET_SIZE      512
> +#ifdef DVB_USB_ADAP_NEED_PID_FILTER
> +#define IT9135_USB20_FRAME_SIZE           (188 * 21)
> +#else
> +#define IT9135_USB20_FRAME_SIZE           (188 * 348)
> +#endif
> +#define IT9135_USB20_FRAME_SIZE_DW        (IT9135_USB20_FRAME_SIZE / 4)
> +#define IT9135_USB11_MAX_PACKET_SIZE      64
> +#define IT9135_USB11_FRAME_SIZE           (188 * 21)
> +#define IT9135_USB11_FRAME_SIZE_DW        (IT9135_USB11_FRAME_SIZE / 4)
> +
> +	if (architecture == ARCHITECTURE_DCA) {
> +		for (i = 0; i < data->chip_num; i++) {
> +			standalone[i] = 0;
> +			upper_chip[i] = 0;
> +			upper_host[i] = 0;
> +			lower_chip[i] = 0;
> +			lower_host[i] = 0;
> +			dca_en[i] = 1;
> +			phase_latch[i] = 0;
> +			fpga_latch[i] = 0;
> +		}
> +
> +		if (data->chip_num == 1) {
> +			standalone[0] = 1;
> +			dca_en[0] = 0;
> +		} else {
> +			/* Pictor & Orion & Omega */
> +			if (data->tuner_desc.id == 0x35
> +			    || data->tuner_desc.id == 0x39
> +			    || data->tuner_desc.id == 0x3A) {
> +				upper_chip[data->chip_num - 1] = 1;
> +				upper_host[0] = 1;
> +				lower_chip[0] = 1;
> +				lower_host[data->chip_num - 1] = 1;
> +				phase_latch[0] = 0;
> +				phase_latch[data->chip_num - 1] = 0;
> +				fpga_latch[0] = 0;
> +				fpga_latch[data->chip_num - 1] = 0;
> +			} else if (data->chip_type == 0x9135
> +				   || data->chip_type == 0x9175) {
> +				upper_chip[data->chip_num - 1] = 1;
> +				upper_host[0] = 1;
> +
> +				lower_chip[0] = 1;
> +				lower_host[data->chip_num - 1] = 1;
> +
> +				phase_latch[0] = 1;
> +				phase_latch[data->chip_num - 1] = 1;
> +
> +				fpga_latch[0] = 0x44;
> +				fpga_latch[data->chip_num - 1] = 0x44;
> +			} else {
> +				upper_chip[data->chip_num - 1] = 1;
> +				upper_host[0] = 1;
> +				lower_chip[0] = 1;
> +				lower_host[data->chip_num - 1] = 1;
> +				phase_latch[0] = 1;
> +				phase_latch[data->chip_num - 1] = 1;
> +				fpga_latch[0] = 0x77;
> +				fpga_latch[data->chip_num - 1] = 0x77;
> +			}
> +		}
> +	} else {
> +		for (i = 0; i < data->chip_num; i++) {
> +			standalone[i] = 1;
> +			upper_chip[i] = 0;
> +			upper_host[i] = 0;
> +			lower_chip[i] = 0;
> +			lower_host[i] = 0;
> +			dca_en[i] = 0;
> +			phase_latch[i] = 0;
> +			fpga_latch[i] = 0;
> +		}
> +	}
> +
> +	if (data->inited) {
> +		error = it9135_mask_dca_output(data);
> +		if (error)
> +			goto exit;
> +	}
> +
> +	/* Pictor & Orion & Omega & Omega_LNA */
> +	if (data->tuner_desc.id == 0x35
> +	    || data->tuner_desc.id == 0x39
> +	    || data->tuner_desc.id == 0x3A || data->chip_type == 0x9135
> +	    || data->chip_type == 0x9175) {
> +		for (i = data->chip_num; i > 0; i--) {
> +			/* Set dca_upper_chip */
> +			error =
> +			    it9135_write_reg_bits(data, i - 1,
> +						  PROCESSOR_OFDM,
> +						  p_reg_dca_upper_chip,
> +						  reg_dca_upper_chip_pos,
> +						  reg_dca_upper_chip_len,
> +						  upper_chip[i - 1]);
> +			if (error)
> +				goto exit;
> +			error =
> +			    it9135_write_reg_bits(data, i - 1,
> +						  PROCESSOR_LINK,
> +						  p_reg_top_hostb_dca_upper,
> +						  reg_top_hostb_dca_upper_pos,
> +						  reg_top_hostb_dca_upper_len,
> +						  upper_host[i - 1]);
> +			if (error)
> +				goto exit;
> +
> +			/* Set dca_lower_chip */
> +			error =
> +			    it9135_write_reg_bits(data, i - 1,
> +						  PROCESSOR_OFDM,
> +						  p_reg_dca_lower_chip,
> +						  reg_dca_lower_chip_pos,
> +						  reg_dca_lower_chip_len,
> +						  lower_chip[i - 1]);
> +			if (error)
> +				goto exit;
> +			error =
> +			    it9135_write_reg_bits(data, i - 1,
> +						  PROCESSOR_LINK,
> +						  p_reg_top_hostb_dca_lower,
> +						  reg_top_hostb_dca_lower_pos,
> +						  reg_top_hostb_dca_lower_len,
> +						  lower_host[i - 1]);
> +			if (error)
> +				goto exit;
> +
> +			/* Set phase latch */
> +			error =
> +			    it9135_write_reg_bits(data, i - 1,
> +						  PROCESSOR_OFDM,
> +						  p_reg_dca_platch,
> +						  reg_dca_platch_pos,
> +						  reg_dca_platch_len,
> +						  phase_latch[i - 1]);
> +			if (error)
> +				goto exit;
> +
> +			/* Set fpga latch */
> +			error =
> +			    it9135_write_reg_bits(data, i - 1, PROCESSOR_OFDM,
> +						  p_reg_dca_fpga_latch,
> +						  reg_dca_fpga_latch_pos,
> +						  reg_dca_fpga_latch_len,
> +						  fpga_latch[i - 1]);
> +			if (error)
> +				goto exit;
> +		}
> +	} else {
> +		/* Set upper chip first in order to avoid I/O conflict */
> +		for (i = data->chip_num; i > 0; i--) {
> +			/* Set dca_upper_chip */
> +			error =
> +			    it9135_write_reg_bits(data, i - 1,
> +						  PROCESSOR_OFDM,
> +						  p_reg_dca_upper_chip,
> +						  reg_dca_upper_chip_pos,
> +						  reg_dca_upper_chip_len,
> +						  upper_chip[i - 1]);
> +			if (error)
> +				goto exit;
> +			if (i == 1) {
> +				if (data->host_if[0]) {
> +					error =
> +					    it9135_write_reg_bits
> +					    (data, i - 1, PROCESSOR_LINK,
> +					     p_reg_top_hosta_dca_upper,
> +					     reg_top_hosta_dca_upper_pos,
> +					     reg_top_hosta_dca_upper_len,
> +					     upper_host[i - 1]);
> +					if (error)
> +						goto exit;
> +					error =
> +					    it9135_write_reg_bits
> +					    (data, i - 1, PROCESSOR_LINK,
> +					     p_reg_top_hostb_dca_upper,
> +					     reg_top_hostb_dca_upper_pos,
> +					     reg_top_hostb_dca_upper_len, 0);
> +					if (error)
> +						goto exit;
> +				} else {
> +					error =
> +					    it9135_write_reg_bits
> +					    (data, i - 1, PROCESSOR_LINK,
> +					     p_reg_top_hostb_dca_upper,
> +					     reg_top_hostb_dca_upper_pos,
> +					     reg_top_hostb_dca_upper_len,
> +					     upper_host[i - 1]);
> +					if (error)
> +						goto exit;
> +					error =
> +					    it9135_write_reg_bits
> +					    (data, i - 1, PROCESSOR_LINK,
> +					     p_reg_top_hosta_dca_upper,
> +					     reg_top_hosta_dca_upper_pos,
> +					     reg_top_hosta_dca_upper_len, 0);
> +					if (error)
> +						goto exit;
> +				}
> +			} else {
> +				error =
> +				    it9135_write_reg_bits(data,
> +							  i - 1,
> +							  PROCESSOR_LINK,
> +							  p_reg_top_hostb_dca_upper,
> +							  reg_top_hostb_dca_upper_pos,
> +							  reg_top_hostb_dca_upper_len,
> +							  upper_host[i - 1]);
> +				if (error)
> +					goto exit;
> +				error =
> +				    it9135_write_reg_bits(data,
> +							  i - 1,
> +							  PROCESSOR_LINK,
> +							  p_reg_top_hosta_dca_upper,
> +							  reg_top_hosta_dca_upper_pos,
> +							  reg_top_hosta_dca_upper_len,
> +							  0);
> +				if (error)
> +					goto exit;
> +			}
> +
> +			/* Set dca_lower_chip */
> +			error =
> +			    it9135_write_reg_bits(data, i - 1,
> +						  PROCESSOR_OFDM,
> +						  p_reg_dca_lower_chip,
> +						  reg_dca_lower_chip_pos,
> +						  reg_dca_lower_chip_len,
> +						  lower_chip[i - 1]);
> +			if (error)
> +				goto exit;
> +			if (i == 1) {
> +				if (data->host_if[0]) {
> +					error =
> +					    it9135_write_reg_bits
> +					    (data, i - 1, PROCESSOR_LINK,
> +					     p_reg_top_hosta_dca_lower,
> +					     reg_top_hosta_dca_lower_pos,
> +					     reg_top_hosta_dca_lower_len,
> +					     lower_host[i - 1]);
> +					if (error)
> +						goto exit;
> +					error =
> +					    it9135_write_reg_bits
> +					    (data, i - 1, PROCESSOR_LINK,
> +					     p_reg_top_hostb_dca_lower,
> +					     reg_top_hostb_dca_lower_pos,
> +					     reg_top_hostb_dca_lower_len, 0);
> +					if (error)
> +						goto exit;
> +				} else {
> +					error =
> +					    it9135_write_reg_bits
> +					    (data, i - 1, PROCESSOR_LINK,
> +					     p_reg_top_hostb_dca_lower,
> +					     reg_top_hostb_dca_lower_pos,
> +					     reg_top_hostb_dca_lower_len,
> +					     lower_host[i - 1]);
> +					if (error)
> +						goto exit;
> +					error =
> +					    it9135_write_reg_bits
> +					    (data, i - 1, PROCESSOR_LINK,
> +					     p_reg_top_hosta_dca_lower,
> +					     reg_top_hosta_dca_lower_pos,
> +					     reg_top_hosta_dca_lower_len, 0);
> +					if (error)
> +						goto exit;
> +				}
> +			} else {
> +				error =
> +				    it9135_write_reg_bits(data,
> +							  i - 1,
> +							  PROCESSOR_LINK,
> +							  p_reg_top_hostb_dca_lower,
> +							  reg_top_hostb_dca_lower_pos,
> +							  reg_top_hostb_dca_lower_len,
> +							  lower_host[i - 1]);
> +				if (error)
> +					goto exit;
> +				error =
> +				    it9135_write_reg_bits(data,
> +							  i - 1,
> +							  PROCESSOR_LINK,
> +							  p_reg_top_hosta_dca_lower,
> +							  reg_top_hosta_dca_lower_pos,
> +							  reg_top_hosta_dca_lower_len,
> +							  0);
> +				if (error)
> +					goto exit;
> +			}
> +
> +			/* Set phase latch */
> +			error =
> +			    it9135_write_reg_bits(data, i - 1,
> +						  PROCESSOR_OFDM,
> +						  p_reg_dca_platch,
> +						  reg_dca_platch_pos,
> +						  reg_dca_platch_len,
> +						  phase_latch[i - 1]);
> +			if (error)
> +				goto exit;
> +
> +			/* Set fpga latch */
> +			error =
> +			    it9135_write_reg_bits(data, i - 1,
> +						  PROCESSOR_OFDM,
> +						  p_reg_dca_fpga_latch,
> +						  reg_dca_fpga_latch_pos,
> +						  reg_dca_fpga_latch_len,
> +						  fpga_latch[i - 1]);
> +			if (error)
> +				goto exit;
> +		}
> +	}
> +
> +	for (i = 0; i < data->chip_num; i++) {
> +		/* Set stand alone */
> +		error =
> +		    it9135_write_reg_bits(data, i, PROCESSOR_OFDM,
> +					  p_reg_dca_stand_alone,
> +					  reg_dca_stand_alone_pos,
> +					  reg_dca_stand_alone_len,
> +					  standalone[i]);
> +		if (error)
> +			goto exit;
> +
> +		/* Set DCA enable */
> +		error =
> +		    it9135_write_reg_bits(data, i, PROCESSOR_OFDM,
> +					  p_reg_dca_en, reg_dca_en_pos,
> +					  reg_dca_en_len, dca_en[i]);
> +		if (error)
> +			goto exit;
> +	}
> +
> +	if (data->inited) {
> +		for (i = 0; i < data->chip_num; i++) {
> +			error =
> +			    it9135_write_reg(data, i, PROCESSOR_OFDM,
> +					     trigger_ofsm, 0);
> +			if (error)
> +				goto exit;
> +		}
> +	}
> +
> +	frame_sz = IT9135_USB20_FRAME_SIZE_DW;
> +	packet_sz = (unsigned char)(IT9135_USB20_MAX_PACKET_SIZE / 4);
> +
> +	if (data->busId == IT9135_BUS_USB11) {
> +		frame_sz = IT9135_USB11_FRAME_SIZE_DW;
> +		packet_sz = (unsigned char)(IT9135_USB11_MAX_PACKET_SIZE / 4);
> +	}
> +
> +	if ((data->chip_num > 1) && (architecture == ARCHITECTURE_PIP))
> +		pip_valid = 1;
> +
> +	/* Reset EP4 */
> +	error =
> +	    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM, p_reg_mp2_sw_rst,
> +				  reg_mp2_sw_rst_pos, reg_mp2_sw_rst_len, 1);
> +	if (error)
> +		goto exit;
> +
> +	/* Reset EP5 */
> +	error =
> +	    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +				  p_reg_mp2if2_sw_rst, reg_mp2if2_sw_rst_pos,
> +				  reg_mp2if2_sw_rst_len, 1);
> +	if (error)
> +		goto exit;
> +
> +	/* Disable EP4 */
> +	error =
> +	    it9135_write_reg_bits(data, 0, PROCESSOR_LINK, p_reg_ep4_tx_en,
> +				  reg_ep4_tx_en_pos, reg_ep4_tx_en_len, 0);
> +	if (error)
> +		goto exit;
> +
> +	/* Disable EP5 */
> +	error =
> +	    it9135_write_reg_bits(data, 0, PROCESSOR_LINK, p_reg_ep5_tx_en,
> +				  reg_ep5_tx_en_pos, reg_ep5_tx_en_len, 0);
> +	if (error)
> +		goto exit;
> +
> +	/* Disable EP4 NAK */
> +	error =
> +	    it9135_write_reg_bits(data, 0, PROCESSOR_LINK, p_reg_ep4_tx_nak,
> +				  reg_ep4_tx_nak_pos, reg_ep4_tx_nak_len, 0);
> +	if (error)
> +		goto exit;
> +
> +	/* Disable EP5 NAK */
> +	error =
> +	    it9135_write_reg_bits(data, 0, PROCESSOR_LINK, p_reg_ep5_tx_nak,
> +				  reg_ep5_tx_nak_pos, reg_ep5_tx_nak_len, 0);
> +	if (error)
> +		goto exit;
> +
> +	/* Enable EP4 */
> +	error =
> +	    it9135_write_reg_bits(data, 0, PROCESSOR_LINK, p_reg_ep4_tx_en,
> +				  reg_ep4_tx_en_pos, reg_ep4_tx_en_len, 1);
> +	if (error)
> +		goto exit;
> +
> +	/* Set EP4 transfer length */
> +	buffer[p_reg_ep4_tx_len_7_0 - p_reg_ep4_tx_len_7_0] =
> +	    (unsigned char)frame_sz;
> +	buffer[p_reg_ep4_tx_len_15_8 - p_reg_ep4_tx_len_7_0] =
> +	    (unsigned char)(frame_sz >> 8);
> +	error =
> +	    it9135_write_regs(data, 0, PROCESSOR_LINK, p_reg_ep4_tx_len_7_0, 2,
> +			      buffer);
> +
> +	/* Set EP4 packet size */
> +	error =
> +	    it9135_write_reg(data, 0, PROCESSOR_LINK, p_reg_ep4_max_pkt,
> +			     packet_sz);
> +	if (error)
> +		goto exit;
> +
> +	if (pip_valid) {
> +		/* Enable EP5 */
> +		error =
> +		    it9135_write_reg_bits(data, 0, PROCESSOR_LINK,
> +					  p_reg_ep5_tx_en, reg_ep5_tx_en_pos,
> +					  reg_ep5_tx_en_len, 1);
> +		if (error)
> +			goto exit;
> +
> +		/* Set EP5 transfer length */
> +		buffer[p_reg_ep5_tx_len_7_0 - p_reg_ep5_tx_len_7_0] =
> +		    (unsigned char)frame_sz;
> +		buffer[p_reg_ep5_tx_len_15_8 - p_reg_ep5_tx_len_7_0] =
> +		    (unsigned char)(frame_sz >> 8);
> +		error =
> +		    it9135_write_regs(data, 0, PROCESSOR_LINK,
> +				      p_reg_ep5_tx_len_7_0, 2, buffer);
> +
> +		/* Set EP5 packet size */
> +		error =
> +		    it9135_write_reg(data, 0, PROCESSOR_LINK, p_reg_ep5_max_pkt,
> +				     packet_sz);
> +		if (error)
> +			goto exit;
> +	}
> +
> +	/* Disable 15 SER/PAR mode */
> +	error =
> +	    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +				  p_mp2if_mpeg_ser_mode,
> +				  mp2if_mpeg_ser_mode_pos,
> +				  mp2if_mpeg_ser_mode_len, 0);
> +	if (error)
> +		goto exit;
> +	error =
> +	    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +				  p_mp2if_mpeg_par_mode,
> +				  mp2if_mpeg_par_mode_pos,
> +				  mp2if_mpeg_par_mode_len, 0);
> +	if (error)
> +		goto exit;
> +
> +	if (pip_valid) {
> +		/* Enable mp2if2 */
> +		error =
> +		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +					  p_reg_mp2if2_en, reg_mp2if2_en_pos,
> +					  reg_mp2if2_en_len, 1);
> +		if (error)
> +			goto exit;
> +
> +		for (i = 1; i < data->chip_num; i++) {
> +			/* Enable serial mode */
> +			error =
> +			    it9135_write_reg_bits(data, i,
> +						  PROCESSOR_OFDM,
> +						  p_mp2if_mpeg_ser_mode,
> +						  mp2if_mpeg_ser_mode_pos,
> +						  mp2if_mpeg_ser_mode_len, 1);
> +			if (error)
> +				goto exit;
> +
> +			/* Enable HostB serial */
> +			error =
> +			    it9135_write_reg_bits(data, i,
> +						  PROCESSOR_LINK,
> +						  p_reg_top_hostb_mpeg_ser_mode,
> +						  reg_top_hostb_mpeg_ser_mode_pos,
> +						  reg_top_hostb_mpeg_ser_mode_len,
> +						  1);
> +			if (error)
> +				goto exit;
> +		}
> +
> +		/* Enable tsis */
> +		error =
> +		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +					  p_reg_tsis_en, reg_tsis_en_pos,
> +					  reg_tsis_en_len, 1);
> +		if (error)
> +			goto exit;
> +	} else {
> +		/* Disable mp2if2 */
> +		error =
> +		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +					  p_reg_mp2if2_en, reg_mp2if2_en_pos,
> +					  reg_mp2if2_en_len, 0);
> +		if (error)
> +			goto exit;
> +
> +		for (i = 1; i < data->chip_num; i++) {
> +			/* Disable serial mode */
> +			error =
> +			    it9135_write_reg_bits(data, i,
> +						  PROCESSOR_OFDM,
> +						  p_mp2if_mpeg_ser_mode,
> +						  mp2if_mpeg_ser_mode_pos,
> +						  mp2if_mpeg_ser_mode_len, 0);
> +			if (error)
> +				goto exit;
> +
> +			/* Disable HostB serial */
> +			error =
> +			    it9135_write_reg_bits(data, i,
> +						  PROCESSOR_LINK,
> +						  p_reg_top_hostb_mpeg_ser_mode,
> +						  reg_top_hostb_mpeg_ser_mode_pos,
> +						  reg_top_hostb_mpeg_ser_mode_len,
> +						  0);
> +			if (error)
> +				goto exit;
> +		}
> +
> +		/* Disable tsis */
> +		error =
> +		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +					  p_reg_tsis_en, reg_tsis_en_pos,
> +					  reg_tsis_en_len, 0);
> +		if (error)
> +			goto exit;
> +	}
> +
> +	/* Negate EP4 reset */
> +	error =
> +	    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM, p_reg_mp2_sw_rst,
> +				  reg_mp2_sw_rst_pos, reg_mp2_sw_rst_len, 0);
> +	if (error)
> +		goto exit;
> +
> +	/* Negate EP5 reset */
> +	error =
> +	    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +				  p_reg_mp2if2_sw_rst, reg_mp2if2_sw_rst_pos,
> +				  reg_mp2if2_sw_rst_len, 0);
> +	if (error)
> +		goto exit;
> +
> +	if (pip_valid) {
> +		/* Split 15 PSB to 1K + 1K and enable flow control */
> +		error =
> +		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +					  p_reg_mp2if2_half_psb,
> +					  reg_mp2if2_half_psb_pos,
> +					  reg_mp2if2_half_psb_len, 0);
> +		if (error)
> +			goto exit;
> +		error =
> +		    it9135_write_reg_bits(data, 0, PROCESSOR_OFDM,
> +					  p_reg_mp2if_stop_en,
> +					  reg_mp2if_stop_en_pos,
> +					  reg_mp2if_stop_en_len, 1);
> +		if (error)
> +			goto exit;
> +
> +		for (i = 1; i < data->chip_num; i++) {
> +			error =
> +			    it9135_write_reg_bits(data, i, PROCESSOR_OFDM,
> +						  p_reg_mpeg_full_speed,
> +						  reg_mpeg_full_speed_pos,
> +						  reg_mpeg_full_speed_len, 1);
> +			if (error)
> +				goto exit;
> +			error =
> +			    it9135_write_reg_bits(data, i,
> +						  PROCESSOR_OFDM,
> +						  p_reg_mp2if_stop_en,
> +						  reg_mp2if_stop_en_pos,
> +						  reg_mp2if_stop_en_len, 0);
> +			if (error)
> +				goto exit;
> +		}
> +	}
> +
> +	data->architecture = architecture;
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_get_statistic(struct it9135_data *data, unsigned char chip,
> +				   struct it9135_statistic *statistic)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char quality = 0;
> +	unsigned char strength;
> +	unsigned char buffer[2];
> +
> +	/* Get statistic by stream type */
> +	error =
> +	    it9135_read_regs(data, chip, PROCESSOR_OFDM, tpsd_lock,
> +			     mpeg_lock - tpsd_lock + 1, buffer);
> +	if (error)
> +		goto exit;
> +
> +	if (buffer[tpsd_lock - tpsd_lock])
> +		data->statistic[chip].presented = 1;
> +	else
> +		data->statistic[chip].presented = 0;
> +
> +	if (buffer[mpeg_lock - tpsd_lock])
> +		data->statistic[chip].locked = 1;
> +	else
> +		data->statistic[chip].locked = 0;
> +
> +	error = it9135_get_signal_quality(data, chip, &quality);
> +	if (error)
> +		goto exit;
> +
> +	data->statistic[chip].quality = quality;
> +	error = it9135_get_strength(data, chip, &strength);
> +	if (error)
> +		goto exit;
> +
> +	data->statistic[chip].strength = strength;
> +
> +	*statistic = data->statistic[chip];
> +
> +exit:
> +	return error;
> +}
> +
> +/* get ir raw code (4 unsigned chars) */
> +unsigned long it9135_get_ir_code(struct it9135_data *data, unsigned long *code)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char r_buff[4];
> +
> +	error =
> +	    it9135_cmd_sendcommand(data, CMD_IR_GET, 0, PROCESSOR_LINK, 0, NULL,
> +				   4, r_buff);
> +	if (error)
> +		goto exit;
> +
> +	*code =
> +	    (unsigned long)((r_buff[0] << 24) + (r_buff[1] << 16) +
> +			    (r_buff[2] << 8) + r_buff[3]);
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_dev_reboot(struct it9135_data *data)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned long version;
> +	unsigned char i;
> +
> +	error = it9135_get_fw_ver(data, PROCESSOR_LINK, &version);
> +	if (error)
> +		goto exit;
> +	if (version == 0xFFFFFFFF)
> +		goto exit;	/* I2M and I2U */
> +	if (version != 0) {
> +		for (i = data->chip_num; i > 0; i--) {
> +			error = it9135_cmd_reboot(data, i - 1);
> +			mdelay(1);
> +			if (error)
> +				goto exit;
> +		}
> +	}
> +
> +	data->booted = 0;
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_ctrl_pw_saving(struct it9135_data *data,
> +				    unsigned char chip, unsigned char control)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char temp;
> +	unsigned char j;
> +
> +	if (control) {
> +		/* Power up case */
> +		error =
> +		    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
> +					  p_reg_afe_mem0, 3, 1, 0);
> +		if (error)
> +			goto exit;
> +		error =
> +		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_dyn0_clk,
> +				     0);
> +		if (error)
> +			goto exit;
> +
> +		/* Fixed current leakage */
> +		if ((data->chip_num > 1) && (chip > 0)) {
> +			/* Pictor & Orion & Omega & Omega_LNA */
> +			if (data->tuner_desc.id == 0x35
> +			    || data->tuner_desc.id == 0x39) {
> +				/* Disable HostB parallel */
> +				error =
> +				    it9135_write_reg_bits
> +				    (data, chip, PROCESSOR_LINK,
> +				     p_reg_top_hostb_mpeg_ser_mode,
> +				     reg_top_hostb_mpeg_ser_mode_pos,
> +				     reg_top_hostb_mpeg_ser_mode_len, 0);
> +				if (error)
> +					goto exit;
> +				error =
> +				    it9135_write_reg_bits
> +				    (data, chip, PROCESSOR_LINK,
> +				     p_reg_top_hostb_mpeg_par_mode,
> +				     reg_top_hostb_mpeg_par_mode_pos,
> +				     reg_top_hostb_mpeg_par_mode_len, 0);
> +				if (error)
> +					goto exit;
> +			} else if (data->chip_type == 0x9135
> +				   || data->chip_type == 0x9175) {
> +				/* Enable HostB serial */
> +				if ((data->architecture == ARCHITECTURE_PIP))
> +					error =
> +					    it9135_write_reg_bits
> +					    (data, chip,
> +					     PROCESSOR_LINK,
> +					     p_reg_top_hostb_mpeg_ser_mode,
> +					     reg_top_hostb_mpeg_ser_mode_pos,
> +					     reg_top_hostb_mpeg_ser_mode_len,
> +					     1);
> +				else
> +					error =
> +					    it9135_write_reg_bits
> +					    (data, chip,
> +					     PROCESSOR_LINK,
> +					     p_reg_top_hostb_mpeg_ser_mode,
> +					     reg_top_hostb_mpeg_ser_mode_pos,
> +					     reg_top_hostb_mpeg_ser_mode_len,
> +					     0);
> +				if (error)
> +					goto exit;
> +				/* Disable HostB parallel */
> +				error =
> +				    it9135_write_reg_bits
> +				    (data, chip, PROCESSOR_LINK,
> +				     p_reg_top_hostb_mpeg_par_mode,
> +				     reg_top_hostb_mpeg_par_mode_pos,
> +				     reg_top_hostb_mpeg_par_mode_len, 0);
> +				if (error)
> +					goto exit;
> +			}
> +		}
> +	} else {
> +		/* Power down case */
> +		error =
> +		    it9135_write_reg(data, chip, PROCESSOR_OFDM, suspend_flag,
> +				     1);
> +		if (error)
> +			goto exit;
> +		error =
> +		    it9135_write_reg(data, chip, PROCESSOR_OFDM, trigger_ofsm,
> +				     0);
> +		if (error)
> +			goto exit;
> +
> +		for (j = 0; j < 150; j++) {
> +			error =
> +			    it9135_read_reg(data, chip, PROCESSOR_OFDM,
> +					    suspend_flag, &temp);
> +			if (error)
> +				goto exit;
> +			if (!temp)
> +				break;
> +			mdelay(10);
> +		}
> +		/* power down demod adc */
> +		error =
> +		    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
> +					  p_reg_afe_mem0, 3, 1, 1);
> +		if (error)
> +			goto exit;
> +
> +		/* Fixed current leakage */
> +		if ((data->chip_num > 1) && (chip > 0)) {
> +			/* Pictor & Orion & Omega */
> +			if (data->tuner_desc.id ==
> +			    0x35
> +			    || data->tuner_desc.id ==
> +			    0x39 || data->chip_type == 0x9135
> +			    || data->chip_type == 0x9175) {
> +				/* Enable HostB parallel */
> +				error =
> +				    it9135_write_reg_bits
> +				    (data, chip, PROCESSOR_LINK,
> +				     p_reg_top_hostb_mpeg_ser_mode,
> +				     reg_top_hostb_mpeg_ser_mode_pos,
> +				     reg_top_hostb_mpeg_ser_mode_len, 0);
> +				if (error)
> +					goto exit;
> +				error =
> +				    it9135_write_reg_bits
> +				    (data, chip, PROCESSOR_LINK,
> +				     p_reg_top_hostb_mpeg_par_mode,
> +				     reg_top_hostb_mpeg_par_mode_pos,
> +				     reg_top_hostb_mpeg_par_mode_len, 1);
> +				if (error)
> +					goto exit;
> +			}
> +		}
> +	}
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_ctrl_tuner_leakage(struct it9135_data *data,
> +					unsigned char chip,
> +					unsigned char control)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char value[15] = { 0 };
> +
> +	if (control) {
> +		/* Power up case */
> +		error =
> +		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_p_if_en,
> +				     1);
> +		if (error)
> +			goto exit;
> +	} else {
> +		/* Fixed tuner current leakage */
> +		error =
> +		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_dyn0_clk,
> +				     0);
> +		if (error)
> +			goto exit;
> +		/* 0xec40 */
> +		error =
> +		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_p_if_en,
> +				     0);
> +		if (error)
> +			goto exit;
> +
> +		value[1] = 0x0c;
> +
> +		error =
> +		    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_reg_pd_a,
> +				      15, value);
> +		if (error)
> +			goto exit;
> +
> +		value[1] = 0;
> +
> +		/* 0xec12~0xec15 */
> +		error =
> +		    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_reg_lna_g,
> +				      4, value);
> +		if (error)
> +			goto exit;
> +		/* oxec17~0xec1f */
> +		error =
> +		    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_reg_pgc, 9,
> +				      value);
> +		if (error)
> +			goto exit;
> +		/* 0xec22~0xec2b */
> +		error =
> +		    it9135_write_regs(data, chip, PROCESSOR_OFDM,
> +				      p_reg_clk_del_sel, 10, value);
> +		if (error)
> +			goto exit;
> +		/* 0xec20 */
> +		error = it9135_write_reg(data, chip, PROCESSOR_OFDM, 0xec20, 0);
> +		if (error)
> +			goto exit;
> +		/* 0xec3f */
> +		error = it9135_write_reg(data, chip, PROCESSOR_OFDM, 0xec3F, 1);
> +		if (error)
> +			goto exit;
> +	}
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_ctrl_tuner_pw_saving(struct it9135_data *data,
> +					  unsigned char chip,
> +					  unsigned char control)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char value[15] = { 0 };
> +
> +	if (control) {
> +		/* Power up case */
> +		error =
> +		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_p_if_en,
> +				     1);
> +		if (error)
> +			goto exit;
> +	} else {
> +		/* tuner power down */
> +		error =
> +		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_dyn0_clk,
> +				     0);
> +		if (error)
> +			goto exit;
> +		/* 0xec40 */
> +		error =
> +		    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_reg_p_if_en,
> +				     0);
> +		if (error)
> +			goto exit;
> +
> +		value[0] = 0x3F;	/* 0xec02 */
> +		value[1] = 0x1F;	/* 0xec03 */
> +		value[2] = 0x3F;	/* 0xec04 */
> +		value[3] = 0x3E;	/* 0xec05 */
> +
> +		error =
> +		    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_reg_pd_a,
> +				      15, value);
> +		if (error)
> +			goto exit;
> +
> +		value[0] = 0;
> +		value[1] = 0;
> +		value[2] = 0;
> +		value[3] = 0;
> +
> +		/* 0xec12~0xec15 */
> +		error =
> +		    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_reg_lna_g,
> +				      4, value);
> +		if (error)
> +			goto exit;
> +		/* oxec17~0xec1f */
> +		error =
> +		    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_reg_pgc, 9,
> +				      value);
> +		if (error)
> +			goto exit;
> +		/* 0xec22~0xec2b */
> +		error =
> +		    it9135_write_regs(data, chip, PROCESSOR_OFDM,
> +				      p_reg_clk_del_sel, 10, value);
> +		if (error)
> +			goto exit;
> +		/* 0xec20 */
> +		error = it9135_write_reg(data, chip, PROCESSOR_OFDM, 0xec20, 0);
> +		if (error)
> +			goto exit;
> +		/* 0xec3f */
> +		error = it9135_write_reg(data, chip, PROCESSOR_OFDM, 0xec3F, 1);
> +		if (error)
> +			goto exit;
> +	}
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_ctrl_pid_filter(struct it9135_data *data,
> +				     unsigned char chip, unsigned char control)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	error =
> +	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
> +				  p_mp2if_pid_en, mp2if_pid_en_pos,
> +				  mp2if_pid_en_len, control);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_reset_pid_filter(struct it9135_data *data,
> +				      unsigned char chip)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	error =
> +	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM, p_mp2if_pid_rst,
> +				  mp2if_pid_rst_pos, mp2if_pid_rst_len, 1);
> +	if (error)
> +		goto exit;
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_add_pid_filter(struct it9135_data *data,
> +				    unsigned char chip, unsigned char index,
> +				    unsigned short pid)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char w_buff[2];
> +
> +	/* Enable pid filter */
> +	error =
> +	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM, p_mp2if_pid_en,
> +				  mp2if_pid_en_pos, mp2if_pid_en_len, 1);
> +	if (error)
> +		goto exit;
> +
> +	w_buff[0] = (unsigned char)pid;
> +	w_buff[1] = (unsigned char)(pid >> 8);
> +
> +	error =
> +	    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_mp2if_pid_dat_l, 2,
> +			      w_buff);
> +	if (error)
> +		goto exit;
> +
> +	error =
> +	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
> +				  p_mp2if_pid_index_en, mp2if_pid_index_en_pos,
> +				  mp2if_pid_index_en_len, 1);
> +	if (error)
> +		goto exit;
> +
> +	error =
> +	    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_mp2if_pid_index,
> +			     index);
> +	if (error)
> +		goto exit;
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_get_snr(struct it9135_data *data, unsigned char chip,
> +			     unsigned char *snr)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	struct it9135_ch_modulation ch_modulation;
> +	unsigned long snr_value;
> +
> +	error = it9135_get_ch_modulation(data, chip, &ch_modulation);
> +	if (error)
> +		goto exit;
> +
> +	error = it9135_get_snr_val(data, chip, &snr_value);
> +	if (error)
> +		goto exit;
> +
> +	if (ch_modulation.trans_mode == TransmissionMode_2K)
> +		snr_value = snr_value * 4;
> +	else if (ch_modulation.trans_mode == TransmissionMode_4K)
> +		snr_value = snr_value * 2;
> +	else
> +		snr_value = snr_value * 1;
> +
> +	if (ch_modulation.constellation == 0) {	/* CONSTELLATION_QPSK */
> +		if (snr_value < 0xB4771)
> +			*snr = 0;
> +		else if (snr_value < 0xC1AED)
> +			*snr = 1;
> +		else if (snr_value < 0xD0D27)
> +			*snr = 2;
> +		else if (snr_value < 0xE4D19)
> +			*snr = 3;
> +		else if (snr_value < 0xE5DA8)
> +			*snr = 4;
> +		else if (snr_value < 0x107097)
> +			*snr = 5;
> +		else if (snr_value < 0x116975)
> +			*snr = 6;
> +		else if (snr_value < 0x1252D9)
> +			*snr = 7;
> +		else if (snr_value < 0x131FA4)
> +			*snr = 8;
> +		else if (snr_value < 0x13D5E1)
> +			*snr = 9;
> +		else if (snr_value < 0x148E53)
> +			*snr = 10;
> +		else if (snr_value < 0x15358B)
> +			*snr = 11;
> +		else if (snr_value < 0x15DD29)
> +			*snr = 12;
> +		else if (snr_value < 0x168112)
> +			*snr = 13;
> +		else if (snr_value < 0x170B61)
> +			*snr = 14;
> +		else if (snr_value < 0x17A532)
> +			*snr = 15;
> +		else if (snr_value < 0x180F94)
> +			*snr = 16;
> +		else if (snr_value < 0x186ED2)
> +			*snr = 17;
> +		else if (snr_value < 0x18B271)
> +			*snr = 18;
> +		else if (snr_value < 0x18E118)
> +			*snr = 19;
> +		else if (snr_value < 0x18FF4B)
> +			*snr = 20;
> +		else if (snr_value < 0x190AF1)
> +			*snr = 21;
> +		else if (snr_value < 0x191451)
> +			*snr = 22;
> +		else
> +			*snr = 23;
> +	} else if (ch_modulation.constellation == 1) {	/* CONSTELLATION_16QAM */
> +		if (snr_value < 0x4F0D5)
> +			*snr = 0;
> +		else if (snr_value < 0x5387A)
> +			*snr = 1;
> +		else if (snr_value < 0x573A4)
> +			*snr = 2;
> +		else if (snr_value < 0x5A99E)
> +			*snr = 3;
> +		else if (snr_value < 0x5CC80)
> +			*snr = 4;
> +		else if (snr_value < 0x5EB62)
> +			*snr = 5;
> +		else if (snr_value < 0x5FECF)
> +			*snr = 6;
> +		else if (snr_value < 0x60B80)
> +			*snr = 7;
> +		else if (snr_value < 0x62501)
> +			*snr = 8;
> +		else if (snr_value < 0x64865)
> +			*snr = 9;
> +		else if (snr_value < 0x69604)
> +			*snr = 10;
> +		else if (snr_value < 0x6F356)
> +			*snr = 11;
> +		else if (snr_value < 0x7706A)
> +			*snr = 12;
> +		else if (snr_value < 0x804D3)
> +			*snr = 13;
> +		else if (snr_value < 0x89D1A)
> +			*snr = 14;
> +		else if (snr_value < 0x93E3D)
> +			*snr = 15;
> +		else if (snr_value < 0x9E35D)
> +			*snr = 16;
> +		else if (snr_value < 0xA7C3C)
> +			*snr = 17;
> +		else if (snr_value < 0xAFAF8)
> +			*snr = 18;
> +		else if (snr_value < 0xB719D)
> +			*snr = 19;
> +		else if (snr_value < 0xBDA6A)
> +			*snr = 20;
> +		else if (snr_value < 0xC0C75)
> +			*snr = 21;
> +		else if (snr_value < 0xC3F7D)
> +			*snr = 22;
> +		else if (snr_value < 0xC5E62)
> +			*snr = 23;
> +		else if (snr_value < 0xC6C31)
> +			*snr = 24;
> +		else if (snr_value < 0xC7925)
> +			*snr = 25;
> +		else
> +			*snr = 26;
> +	} else if (ch_modulation.constellation == 2) {	/* CONSTELLATION_64QAM */
> +		if (snr_value < 0x256D0)
> +			*snr = 0;
> +		else if (snr_value < 0x27A65)
> +			*snr = 1;
> +		else if (snr_value < 0x29873)
> +			*snr = 2;
> +		else if (snr_value < 0x2B7FE)
> +			*snr = 3;
> +		else if (snr_value < 0x2CF1E)
> +			*snr = 4;
> +		else if (snr_value < 0x2E234)
> +			*snr = 5;
> +		else if (snr_value < 0x2F409)
> +			*snr = 6;
> +		else if (snr_value < 0x30046)
> +			*snr = 7;
> +		else if (snr_value < 0x30844)
> +			*snr = 8;
> +		else if (snr_value < 0x30A02)
> +			*snr = 9;
> +		else if (snr_value < 0x30CDE)
> +			*snr = 10;
> +		else if (snr_value < 0x31031)
> +			*snr = 11;
> +		else if (snr_value < 0x3144C)
> +			*snr = 12;
> +		else if (snr_value < 0x315DD)
> +			*snr = 13;
> +		else if (snr_value < 0x31920)
> +			*snr = 14;
> +		else if (snr_value < 0x322D0)
> +			*snr = 15;
> +		else if (snr_value < 0x339FC)
> +			*snr = 16;
> +		else if (snr_value < 0x364A1)
> +			*snr = 17;
> +		else if (snr_value < 0x38BCC)
> +			*snr = 18;
> +		else if (snr_value < 0x3C7D3)
> +			*snr = 19;
> +		else if (snr_value < 0x408CC)
> +			*snr = 20;
> +		else if (snr_value < 0x43BED)
> +			*snr = 21;
> +		else if (snr_value < 0x48061)
> +			*snr = 22;
> +		else if (snr_value < 0x4BE95)
> +			*snr = 23;
> +		else if (snr_value < 0x4FA7D)
> +			*snr = 24;
> +		else if (snr_value < 0x52405)
> +			*snr = 25;
> +		else if (snr_value < 0x5570D)
> +			*snr = 26;
> +		else if (snr_value < 0x59FEB)
> +			*snr = 27;
> +		else if (snr_value < 0x5BF38)
> +			*snr = 28;
> +		else if (snr_value < 0x5F78F)
> +			*snr = 29;
> +		else if (snr_value < 0x612C3)
> +			*snr = 30;
> +		else if (snr_value < 0x626BE)
> +			*snr = 31;
> +		else
> +			*snr = 32;


The above function seems weird for me. Maximum value for SNR in Linux
should be 65535, and not 32. It seems that all you need is to do something
like (for CONSTELLATION_64QAM. Same logic applies also to the other constellation):

	if (snr_value >=  0x626BE)
		*snr = 65535;
	else	{
		u64 snr64 = snr_value * 65536;
		*snr = do_div_u64 (snr64, 0x626BE);
	}


> +	} else
> +		goto exit;
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_get_snr_val(struct it9135_data *data, unsigned char chip,
> +				 unsigned long *snr_value)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char super_frame_num = 0;
> +	unsigned char snr_reg[3];
> +
> +	error = it9135_read_regs(data, chip, PROCESSOR_OFDM, 0x2c, 3, snr_reg);
> +	if (error)
> +		goto exit;
> +
> +	*snr_value = (snr_reg[2] << 16) + (snr_reg[1] << 8) + snr_reg[0];
> +
> +	/* gets superFrame num */
> +	error =
> +	    it9135_read_reg(data, chip, PROCESSOR_OFDM, 0xF78b,
> +			    (unsigned char *)&super_frame_num);
> +	if (error)
> +		goto exit;
> +
> +	if (super_frame_num)
> +		*snr_value /= super_frame_num;
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_set_multiplier(struct it9135_data *data,
> +				    unsigned char multiplier)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char new_adc_mul = 0;
> +	unsigned char buffer[3];
> +	long ctl_word;
> +	unsigned char i;
> +
> +	if (multiplier == Multiplier_1X)
> +		new_adc_mul = 0;
> +	else
> +		new_adc_mul = 1;
> +
> +	for (i = 0; i < data->chip_num; i++) {
> +		/* Write ADC multiplier factor to firmware. */
> +		error =
> +		    it9135_write_reg(data, i, PROCESSOR_OFDM, adcx2,
> +				     new_adc_mul);
> +		if (error)
> +			goto exit;
> +	}
> +
> +	/* Compute FCW and load them to device */
> +	if (data->fcw >= 0x00400000)
> +		ctl_word = data->fcw - 0x00800000;
> +	else
> +		ctl_word = data->fcw;
> +
> +	if (new_adc_mul == 1)
> +		ctl_word /= 2;
> +	else
> +		ctl_word *= 2;
> +
> +	data->fcw = 0x7FFFFF & ctl_word;
> +
> +	buffer[0] = (unsigned char)(data->fcw & 0x000000FF);
> +	buffer[1] = (unsigned char)((data->fcw & 0x0000FF00) >> 8);
> +	buffer[2] = (unsigned char)((data->fcw & 0x007F0000) >> 16);
> +	for (i = 0; i < data->chip_num; i++)
> +		error =
> +		    it9135_write_regs(data, i, PROCESSOR_OFDM, bfs_fcw_7_0,
> +				      bfs_fcw_22_16 - bfs_fcw_7_0 + 1, buffer);
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_reset_pid(struct it9135_data *data, unsigned char chip)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char i;
> +
> +	for (i = 0; i < 32; i++)
> +		data->pid_info.pid_tab[chip].pid[i] = 0xFFFF;
> +
> +	error =
> +	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM, p_mp2if_pid_rst,
> +				  mp2if_pid_rst_pos, mp2if_pid_rst_len, 1);
> +	if (error)
> +		goto exit;
> +
> +	data->pid_info.pid_cnt = 0;
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_remove_pid_at(struct it9135_data *data, unsigned char chip,
> +				   unsigned char index, unsigned short pid)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	error =
> +	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
> +				  p_mp2if_pid_index_en, mp2if_pid_index_en_pos,
> +				  mp2if_pid_index_en_len, 0);
> +	if (error)
> +		goto exit;
> +
> +	error =
> +	    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_mp2if_pid_index,
> +			     index);
> +	if (error)
> +		goto exit;
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_get_ch_statistic(struct it9135_data *data,
> +				      unsigned char chip,
> +				      struct it9135_ch_statistic *ch_statistic)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned long post_err_cnt;
> +	unsigned long post_bit_cnt;
> +	unsigned short rsd_abort_cnt;
> +
> +	/* Get BER if couter is ready, error = ERROR_RSD_COUNTER_NOT_READY if counter is not ready */
> +	if (data->architecture == ARCHITECTURE_PIP) {
> +		error =
> +		    it9135_get_post_vitber(data, chip, &post_err_cnt,
> +					   &post_bit_cnt, &rsd_abort_cnt);
> +		if (error == ERROR_NO_ERROR) {
> +			data->ch_statistic[chip].post_vit_err_cnt =
> +			    post_err_cnt;
> +			data->ch_statistic[chip].post_vitbit_cnt = post_bit_cnt;
> +			data->ch_statistic[chip].abort_cnt = rsd_abort_cnt;
> +		}
> +	} else {
> +		error =
> +		    it9135_get_post_vitber(data, 0, &post_err_cnt,
> +					   &post_bit_cnt, &rsd_abort_cnt);
> +		if (error == ERROR_NO_ERROR) {
> +			data->ch_statistic[chip].post_vit_err_cnt =
> +			    post_err_cnt;
> +			data->ch_statistic[chip].post_vitbit_cnt = post_bit_cnt;
> +			data->ch_statistic[chip].abort_cnt = rsd_abort_cnt;
> +		}
> +	}
> +
> +	*ch_statistic = data->ch_statistic[chip];
> +
> +	return error;
> +}
> +
> +static struct it9135_tuner_desc tuner_def_desc = {
> +	NULL,
> +	NULL,
> +	0x38,			/* tuner id */
> +};
> +
> +unsigned long it9135_set_bus_tuner(struct it9135_data *data,
> +				   unsigned short busId,
> +				   unsigned short tuner_id)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char support_type = OMEGA_NORMAL;
> +
> +	data->busId = busId;
> +	memcpy(&data->tuner_desc, &tuner_def_desc, sizeof(data->tuner_desc));
> +
> +	switch (tuner_id) {
> +	case IT9135_TUNER_ID:
> +		support_type = OMEGA_NORMAL;
> +		break;
> +	case IT9135_TUNER_ID_LNA_CONFIG1:
> +		support_type = OMEGA_LNA_CONFIG1;
> +		break;
> +	case IT9135_TUNER_ID_LNA_CONFIG2:
> +		support_type = OMEGA_LNA_CONFIG2;
> +		break;
> +	case IT9135_TUNER_ID_V2:
> +		support_type = OMEGA_NORMAL;
> +		break;
> +	case IT9135_TUNER_ID_V2_LNA_CONFIG1:
> +		support_type = OMEGA_LNA_CONFIG1;
> +		break;
> +	case IT9135_TUNER_ID_V2_LNA_CONFIG2:
> +		support_type = OMEGA_LNA_CONFIG2;
> +		break;

Please split the tuner code from the main driver. How are tuner is interconnected?
Via I2C? If so, the tuner should use I2C core.

> +	default:
> +		error = ERROR_INVALID_TUNER_TYPE;
> +		goto exit;
> +	}
> +
> +	if (data->chip_type == 0x9135 && data->chip_ver == 2) {
> +		switch (support_type) {
> +		case OMEGA_NORMAL:
> +			data->tuner_desc.scripts = data->tuner_script_normal;
> +			data->tuner_desc.script_sets =
> +			    &data->tuner_script_sets_normal;
> +			data->tuner_desc.id = IT9135_TUNER_ID_V2;
> +			error = ERROR_NO_ERROR;
> +			break;
> +		case OMEGA_LNA_CONFIG1:
> +			data->tuner_desc.scripts = data->tuner_script_lna1;
> +			data->tuner_desc.script_sets =
> +			    &data->tuner_script_sets_lna1;
> +			data->tuner_desc.id = IT9135_TUNER_ID_V2_LNA_CONFIG1;
> +			error = ERROR_NO_ERROR;
> +			break;
> +		case OMEGA_LNA_CONFIG2:
> +			data->tuner_desc.scripts = data->tuner_script_lna2;
> +			data->tuner_desc.script_sets =
> +			    &data->tuner_script_sets_lna2;
> +			data->tuner_desc.id = IT9135_TUNER_ID_V2_LNA_CONFIG2;
> +			error = ERROR_NO_ERROR;
> +			break;
> +		default:
> +			break;
> +		}
> +	} else {
> +		switch (support_type) {
> +		case OMEGA_NORMAL:
> +			data->tuner_desc.scripts = data->tuner_script_normal;
> +			data->tuner_desc.script_sets =
> +			    &data->tuner_script_sets_normal;
> +			data->tuner_desc.id = IT9135_TUNER_ID;
> +			error = ERROR_NO_ERROR;
> +			break;
> +		case OMEGA_LNA_CONFIG1:
> +			data->tuner_desc.scripts = data->tuner_script_lna1;
> +			data->tuner_desc.script_sets =
> +			    &data->tuner_script_sets_lna1;
> +			data->tuner_desc.id = IT9135_TUNER_ID_LNA_CONFIG1;
> +			error = ERROR_NO_ERROR;
> +			break;
> +		case OMEGA_LNA_CONFIG2:
> +			data->tuner_desc.scripts = data->tuner_script_lna2;
> +			data->tuner_desc.script_sets =
> +			    &data->tuner_script_sets_lna2;
> +			data->tuner_desc.id = IT9135_TUNER_ID_LNA_CONFIG2;
> +			error = ERROR_NO_ERROR;
> +			break;
> +		default:
> +
> +			break;
> +		}
> +	}
> +
> +	if (data->tuner_desc.scripts == NULL) {
> +		data->tuner_desc.scripts = NULL;
> +		data->tuner_desc.script_sets = NULL;
> +	}
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_add_pid(struct it9135_data *data, unsigned char chip,
> +			     unsigned short pid)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char w_buff[2];
> +	unsigned char i, j;
> +	int found = 0;
> +
> +	if (!data->pid_info.pid_init) {
> +		for (i = 0; i < data->chip_num; i++) {
> +			for (j = 0; j < 32; j++)
> +				data->pid_info.pid_tab[i].pid[j] = 0xFFFF;
> +		}
> +		data->pid_info.pid_init = 1;
> +	}
> +
> +	/* Enable pid filter */
> +	if (data->pid_info.pid_cnt == 0) {
> +		error =
> +		    it9135_write_reg_bits(data, chip,
> +					  PROCESSOR_OFDM, p_mp2if_pid_en,
> +					  mp2if_pid_en_pos, mp2if_pid_en_len,
> +					  1);
> +		if (error)
> +			goto exit;
> +	} else {
> +		for (i = 0; i < 32; i++) {
> +			if (data->pid_info.pid_tab[chip].pid[i] == pid) {
> +				found = 1;
> +				break;
> +			}
> +		}
> +		if (found)
> +			goto exit;
> +	}
> +
> +	for (i = 0; i < 32; i++) {
> +		if (data->pid_info.pid_tab[chip].pid[i] == 0xFFFF)
> +			break;
> +	}
> +	if (i == 32) {
> +		error = ERROR_PID_FILTER_FULL;
> +		goto exit;
> +	}
> +
> +	w_buff[0] = (unsigned char)pid;
> +	w_buff[1] = (unsigned char)(pid >> 8);
> +
> +	error =
> +	    it9135_write_regs(data, chip, PROCESSOR_OFDM, p_mp2if_pid_dat_l, 2,
> +			      w_buff);
> +	if (error)
> +		goto exit;
> +
> +	error =
> +	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
> +				  p_mp2if_pid_index_en, mp2if_pid_index_en_pos,
> +				  mp2if_pid_index_en_len, 1);
> +	if (error)
> +		goto exit;
> +
> +	error =
> +	    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_mp2if_pid_index, i);
> +	if (error)
> +		goto exit;
> +
> +	data->pid_info.pid_tab[chip].pid[i] = pid;
> +	data->pid_info.pid_cnt++;
> +
> +exit:
> +	return error;
> +}
> +
> +unsigned long it9135_add_pid_at(struct it9135_data *data, unsigned char chip,
> +				unsigned char index, unsigned short pid)
> +{
> +	return it9135_add_pid_filter(data, chip, index, pid);
> +}
> +
> +unsigned long it9135_remove_pid(struct it9135_data *data, unsigned char chip,
> +				unsigned short pid)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char i;
> +	int found = 0;
> +
> +	for (i = 0; i < 32; i++) {
> +		if (data->pid_info.pid_tab[chip].pid[i] == pid) {
> +			found = 1;
> +			break;
> +		}
> +	}
> +	if (!found)
> +		goto exit;
> +
> +	error =
> +	    it9135_write_reg_bits(data, chip, PROCESSOR_OFDM,
> +				  p_mp2if_pid_index_en, mp2if_pid_index_en_pos,
> +				  mp2if_pid_index_en_len, 0);
> +	if (error)
> +		goto exit;
> +
> +	error =
> +	    it9135_write_reg(data, chip, PROCESSOR_OFDM, p_mp2if_pid_index, i);
> +	if (error)
> +		goto exit;
> +
> +	data->pid_info.pid_tab[chip].pid[i] = 0xFFFF;
> +
> +	/* Disable pid filter */
> +	if (data->pid_info.pid_cnt == 1) {
> +		error =
> +		    it9135_write_reg_bits(data, chip,
> +					  PROCESSOR_OFDM, p_mp2if_pid_en,
> +					  mp2if_pid_en_pos, mp2if_pid_en_len,
> +					  0);
> +	}
> +
> +	data->pid_info.pid_cnt--;
> +
> +exit:
> +	return error;
> +}
> diff --git a/drivers/media/dvb/dvb-usb/it9135-fe.h b/drivers/media/dvb/dvb-usb/it9135-fe.h
> new file mode 100644
> index 0000000..1744ba4
> --- /dev/null
> +++ b/drivers/media/dvb/dvb-usb/it9135-fe.h
> @@ -0,0 +1,1632 @@
> +/*
> + * DVB USB Linux driver for IT9135 DVB-T USB2.0 receiver
> + *
> + * Copyright (C) 2011 ITE Technologies, INC.
> + *
> + *    This program is free software; you can redistribute it and/or modify
> + *    it under the terms of the GNU General Public License as published by
> + *    the Free Software Foundation; either version 2 of the License, or
> + *    (at your option) any later version.
> + */
> +
> +#ifndef __IT9135_FE_H__
> +#define __IT9135_FE_H__
> +
> +#define IT9135_API_VER_NUM	0x0203
> +#define IT9135_API_DATE		0x20110426
> +#define IT9135_API_BUILD	0x00
> +
> +/*
> + * Hardware register define
> + */
> +#define    p_reg_pd_a				0xEC02
> +#define	reg_pd_a_pos 0
> +#define	reg_pd_a_len 6
> +#define	reg_pd_a_lsb 0
> +#define    p_reg_pd_c				0xEC04
> +#define	reg_pd_c_pos 0
> +#define	reg_pd_c_len 6
> +#define	reg_pd_c_lsb 0
> +#define    p_reg_pd_d				0xEC05
> +#define	reg_pd_d_pos 0
> +#define	reg_pd_d_len 6
> +#define	reg_pd_d_lsb 0
> +#define    p_reg_tst_a				0xEC06
> +#define	reg_tst_a_pos 0
> +#define	reg_tst_a_len 6
> +#define	reg_tst_a_lsb 0
> +#define    p_reg_tst_b				0xEC07
> +#define	reg_tst_b_pos 0
> +#define	reg_tst_b_len 2
> +#define	reg_tst_b_lsb 0
> +#define    p_reg_ctrl_a				0xEC08
> +#define	reg_ctrl_a_pos 0
> +#define	reg_ctrl_a_len 6
> +#define	reg_ctrl_a_lsb 0
> +#define    p_reg_ctrl_b				0xEC09
> +#define	reg_ctrl_b_pos 0
> +#define	reg_ctrl_b_len 2
> +#define	reg_ctrl_b_lsb 0
> +#define    p_reg_cal_freq_a			0xEC0A
> +#define	reg_cal_freq_a_pos 0
> +#define	reg_cal_freq_a_len 6
> +#define	reg_cal_freq_a_lsb 0
> +#define    p_reg_cal_freq_b			0xEC0B
> +#define	reg_cal_freq_b_pos 0
> +#define	reg_cal_freq_b_len 6
> +#define	reg_cal_freq_b_lsb 0
> +#define    p_reg_cal_freq_c			0xEC0C
> +#define	reg_cal_freq_c_pos 0
> +#define	reg_cal_freq_c_len 4
> +#define	reg_cal_freq_c_lsb 0
> +#define    p_reg_lo_freq_a			0xEC0D
> +#define	reg_lo_freq_a_pos 0
> +#define	reg_lo_freq_a_len 6
> +#define	reg_lo_freq_a_lsb 0
> +#define    p_reg_lo_freq_b			0xEC0E
> +#define	reg_lo_freq_b_pos 0
> +#define	reg_lo_freq_b_len 6
> +#define	reg_lo_freq_b_lsb 0
> +#define    p_reg_lo_freq_c			0xEC0F
> +#define	reg_lo_freq_c_pos 0
> +#define	reg_lo_freq_c_len 4
> +#define	reg_lo_freq_c_lsb 0
> +#define    p_reg_lo_cap				0xEC10
> +#define	reg_lo_cap_pos 0
> +#define	reg_lo_cap_len 6
> +#define	reg_lo_cap_lsb 0
> +#define    p_reg_clk02_select			0xEC11
> +#define	reg_clk02_select_pos 0
> +#define	reg_clk02_select_len 3
> +#define	reg_clk02_select_lsb 0
> +#define    p_reg_clk01_select			0xEC11
> +#define	reg_clk01_select_pos 3
> +#define	reg_clk01_select_len 3
> +#define	reg_clk01_select_lsb 0
> +#define    p_reg_lna_cap			0xEC13
> +#define	reg_lna_cap_pos 0
> +#define	reg_lna_cap_len 6
> +#define	reg_lna_cap_lsb 0
> +#define    p_reg_lna_g				0xEC12
> +#define	reg_lna_g_pos 0
> +#define	reg_lna_g_len 3
> +#define	reg_lna_g_lsb 0
> +#define    p_reg_lna_band			0xEC14
> +#define	reg_lna_band_pos 0
> +#define	reg_lna_band_len 3
> +#define	reg_lna_band_lsb 0
> +#define    p_reg_pga				0xEC15
> +#define	reg_pga_pos 0
> +#define	reg_pga_len 6
> +#define	reg_pga_lsb 0
> +#define    p_reg_pgc				0xEC17
> +#define	reg_pgc_pos 0
> +#define	reg_pgc_len 3
> +#define	reg_pgc_lsb 0
> +#define    p_reg_lpf_cap			0xEC18
> +#define	reg_lpf_cap_pos 0
> +#define	reg_lpf_cap_len 5
> +#define	reg_lpf_cap_lsb 0
> +#define    p_reg_lpf_bw				0xEC19
> +#define	reg_lpf_bw_pos 0
> +#define	reg_lpf_bw_len 3
> +#define	reg_lpf_bw_lsb 0
> +#define    p_reg_ofsi				0xEC1A
> +#define	reg_ofsi_pos 0
> +#define	reg_ofsi_len 6
> +#define	reg_ofsi_lsb 0
> +#define    p_reg_ofsq				0xEC1B
> +#define	reg_ofsq_pos 0
> +#define	reg_ofsq_len 6
> +#define	reg_ofsq_lsb 0
> +#define    p_reg_dcxo_a				0xEC1C
> +#define	reg_dcxo_a_pos 0
> +#define	reg_dcxo_a_len 6
> +#define	reg_dcxo_a_lsb 0
> +#define    p_reg_dcxo_b				0xEC1D
> +#define	reg_dcxo_b_pos 0
> +#define	reg_dcxo_b_len 4
> +#define	reg_dcxo_b_lsb 0
> +#define    p_reg_tddo				0xEC1E
> +#define	reg_tddo_pos 0
> +#define	reg_tddo_len 6
> +#define	reg_tddo_lsb 0
> +#define    p_reg_strength_setting		0xEC1F
> +#define	reg_strength_setting_pos 0
> +#define	reg_strength_setting_len 6
> +#define	reg_strength_setting_lsb 0
> +#define    p_reg_gi				0xEC22
> +#define	reg_gi_pos 0
> +#define	reg_gi_len 2
> +#define	reg_gi_lsb 0
> +#define    p_reg_clk_del_sel			0xEC22
> +#define	reg_clk_del_sel_pos 2
> +#define	reg_clk_del_sel_len 2
> +#define	reg_clk_del_sel_lsb 0
> +#define    p_reg_p2s_ck_sel			0xEC22
> +#define	reg_p2s_ck_sel_pos 4
> +#define	reg_p2s_ck_sel_len 1
> +#define	reg_p2s_ck_sel_lsb 0
> +#define    p_reg_rssi_sel			0xEC22
> +#define	reg_rssi_sel_pos 5
> +#define	reg_rssi_sel_len 1
> +#define	reg_rssi_sel_lsb 0
> +#define    p_reg_tst_sel			0xEC23
> +#define	reg_tst_sel_pos 4
> +#define	reg_tst_sel_len 2
> +#define	reg_tst_sel_lsb 0
> +#define    p_reg_ctrl_c				0xEC24
> +#define	reg_ctrl_c_pos 0
> +#define	reg_ctrl_c_len 6
> +#define	reg_ctrl_c_lsb 0
> +#define    p_reg_ctrl_d				0xEC25
> +#define	reg_ctrl_d_pos 0
> +#define	reg_ctrl_d_len 6
> +#define	reg_ctrl_d_lsb 0
> +#define    p_reg_ctrl_e				0xEC26
> +#define	reg_ctrl_e_pos 0
> +#define	reg_ctrl_e_len 6
> +#define	reg_ctrl_e_lsb 0
> +#define    p_reg_ctrl_f				0xEC27
> +#define	reg_ctrl_f_pos 0
> +#define	reg_ctrl_f_len 6
> +#define	reg_ctrl_f_lsb 0
> +#define    p_reg_lo_bias			0xEC28
> +#define	reg_lo_bias_pos 0
> +#define	reg_lo_bias_len 3
> +#define	reg_lo_bias_lsb 0
> +#define    p_reg_ext_lna_en			0xEC29
> +#define	reg_ext_lna_en_pos 0
> +#define	reg_ext_lna_en_len 1
> +#define	reg_ext_lna_en_lsb 0
> +#define    p_reg_pga_bak			0xEC2A
> +#define	reg_pga_bak_pos 0
> +#define	reg_pga_bak_len 3
> +#define	reg_pga_bak_lsb 0
> +#define    p_reg_cpll_cap			0xEC2B
> +#define	reg_cpll_cap_pos 0
> +#define	reg_cpll_cap_len 6
> +#define	reg_cpll_cap_lsb 0
> +#define    p_reg_p_if_en			0xEC40
> +#define	reg_p_if_en_pos 0
> +#define	reg_p_if_en_len 2
> +#define	reg_p_if_en_lsb 0
> +#define    p_reg_one_cycle_counter_tuner	0xF103
> +#define	reg_one_cycle_counter_tuner_pos 0
> +#define	reg_one_cycle_counter_tuner_len 8
> +#define	reg_one_cycle_counter_tuner_lsb 0
> +#define    p_reg_f_adc_7_0			0xF1CD
> +#define	reg_f_adc_7_0_pos 0
> +#define	reg_f_adc_7_0_len 8
> +#define	reg_f_adc_7_0_lsb 0
> +#define    p_reg_dvbt_en			0xF41A
> +#define	reg_dvbt_en_pos 0
> +#define	reg_dvbt_en_len 1
> +#define	reg_dvbt_en_lsb 0
> +#define    p_fd_tpsd_lock			0xF5A9
> +#define	fd_tpsd_lock_pos 0
> +#define	fd_tpsd_lock_len 1
> +#define	fd_tpsd_lock_lsb 0
> +#define    p_reg_feq_read_update		0xF5CA
> +#define	reg_feq_read_update_pos 0
> +#define	reg_feq_read_update_len 1
> +#define	reg_feq_read_update_lsb 0
> +#define    p_reg_link_ofsm_dummy_15_8		0xF641
> +#define	reg_link_ofsm_dummy_15_8_pos 0
> +#define	reg_link_ofsm_dummy_15_8_len 8
> +#define	reg_link_ofsm_dummy_15_8_lsb 8
> +#define    p_fec_vtb_rsd_mon_en			0xF715
> +#define	fec_vtb_rsd_mon_en_pos 0
> +#define	fec_vtb_rsd_mon_en_len 1
> +#define	fec_vtb_rsd_mon_en_lsb 0
> +#define    p_reg_dca_platch			0xF730
> +#define	reg_dca_platch_pos 0
> +#define	reg_dca_platch_len 1
> +#define	reg_dca_platch_lsb 0
> +#define    p_reg_dca_upper_chip			0xF731
> +#define	reg_dca_upper_chip_pos 0
> +#define	reg_dca_upper_chip_len 1
> +#define	reg_dca_upper_chip_lsb 0
> +#define    p_reg_dca_lower_chip			0xF732
> +#define	reg_dca_lower_chip_pos 0
> +#define	reg_dca_lower_chip_len 1
> +#define	reg_dca_lower_chip_lsb 0
> +#define    p_reg_dca_stand_alone		0xF73C
> +#define	reg_dca_stand_alone_pos 0
> +#define	reg_dca_stand_alone_len 1
> +#define	reg_dca_stand_alone_lsb 0
> +#define    p_reg_dca_upper_out_en		0xF73D
> +#define	reg_dca_upper_out_en_pos 0
> +#define	reg_dca_upper_out_en_len 1
> +#define	reg_dca_upper_out_en_lsb 0
> +#define    p_reg_dca_en				0xF776
> +#define	reg_dca_en_pos 0
> +#define	reg_dca_en_len 1
> +#define	reg_dca_en_lsb 0
> +#define    p_reg_dca_fpga_latch			0xF778
> +#define	reg_dca_fpga_latch_pos 0
> +#define	reg_dca_fpga_latch_len 8
> +#define	reg_dca_fpga_latch_lsb 0
> +#define    g_reg_tpsd_txmod			0xF900
> +#define	reg_tpsd_txmod_pos 0
> +#define	reg_tpsd_txmod_len 2
> +#define	reg_tpsd_txmod_lsb 0
> +#define    g_reg_tpsd_gi			0xF901
> +#define	reg_tpsd_gi_pos 0
> +#define	reg_tpsd_gi_len 2
> +#define	reg_tpsd_gi_lsb 0
> +#define    g_reg_tpsd_hier			0xF902
> +#define	reg_tpsd_hier_pos 0
> +#define	reg_tpsd_hier_len 3
> +#define	reg_tpsd_hier_lsb 0
> +#define    g_reg_tpsd_const			0xF903
> +#define	reg_tpsd_const_pos 0
> +#define	reg_tpsd_const_len 2
> +#define	reg_tpsd_const_lsb 0
> +#define    g_reg_bw				0xF904
> +#define	reg_bw_pos 0
> +#define	reg_bw_len 2
> +#define	reg_bw_lsb 0
> +#define    g_reg_dec_pri			0xF905
> +#define	reg_dec_pri_pos 0
> +#define	reg_dec_pri_len 1
> +#define	reg_dec_pri_lsb 0
> +#define    g_reg_tpsd_hpcr			0xF906
> +#define	reg_tpsd_hpcr_pos 0
> +#define	reg_tpsd_hpcr_len 3
> +#define	reg_tpsd_hpcr_lsb 0
> +#define    g_reg_tpsd_lpcr			0xF907
> +#define	reg_tpsd_lpcr_pos 0
> +#define	reg_tpsd_lpcr_len 3
> +#define	reg_tpsd_lpcr_lsb 0
> +#define    p_mp2if_mpeg_ser_mode		0xF985
> +#define	mp2if_mpeg_ser_mode_pos 0
> +#define	mp2if_mpeg_ser_mode_len 1
> +#define	mp2if_mpeg_ser_mode_lsb 0
> +#define    p_mp2if_mpeg_par_mode		0xF986
> +#define	mp2if_mpeg_par_mode_pos 0
> +#define	mp2if_mpeg_par_mode_len 1
> +#define	mp2if_mpeg_par_mode_lsb 0
> +#define    p_reg_mpeg_full_speed		0xF990
> +#define	reg_mpeg_full_speed_pos 0
> +#define	reg_mpeg_full_speed_len 1
> +#define	reg_mpeg_full_speed_lsb 0
> +#define    p_mp2if_pid_rst			0xF992
> +#define	mp2if_pid_rst_pos 0
> +#define	mp2if_pid_rst_len 1
> +#define	mp2if_pid_rst_lsb 0
> +#define    p_mp2if_pid_en			0xF993
> +#define	mp2if_pid_en_pos 0
> +#define	mp2if_pid_en_len 1
> +#define	mp2if_pid_en_lsb 0
> +#define    p_mp2if_pid_index_en			0xF994
> +#define	mp2if_pid_index_en_pos 0
> +#define	mp2if_pid_index_en_len 1
> +#define	mp2if_pid_index_en_lsb 0
> +#define    p_mp2if_pid_index			0xF995
> +#define	mp2if_pid_index_pos 0
> +#define	mp2if_pid_index_len 5
> +#define	mp2if_pid_index_lsb 0
> +#define    p_mp2if_pid_dat_l			0xF996
> +#define	mp2if_pid_dat_l_pos 0
> +#define	mp2if_pid_dat_l_len 8
> +#define	mp2if_pid_dat_l_lsb 0
> +#define    r_mp2if_sync_byte_locked		0xF999
> +#define	mp2if_sync_byte_locked_pos 0
> +#define	mp2if_sync_byte_locked_len 1
> +#define	mp2if_sync_byte_locked_lsb 0
> +#define    p_reg_mp2_sw_rst			0xF99D
> +#define	reg_mp2_sw_rst_pos 0
> +#define	reg_mp2_sw_rst_len 1
> +#define	reg_mp2_sw_rst_lsb 0
> +#define    p_reg_mp2if2_en			0xF9A3
> +#define	reg_mp2if2_en_pos 0
> +#define	reg_mp2if2_en_len 1
> +#define	reg_mp2if2_en_lsb 0
> +#define    p_reg_mp2if2_sw_rst			0xF9A4
> +#define	reg_mp2if2_sw_rst_pos 0
> +#define	reg_mp2if2_sw_rst_len 1
> +#define	reg_mp2if2_sw_rst_lsb 0
> +#define    p_reg_mp2if2_half_psb		0xF9A5
> +#define	reg_mp2if2_half_psb_pos 0
> +#define	reg_mp2if2_half_psb_len 1
> +#define	reg_mp2if2_half_psb_lsb 0
> +#define    p_reg_mp2if_stop_en			0xF9B5
> +#define	reg_mp2if_stop_en_pos 0
> +#define	reg_mp2if_stop_en_len 1
> +#define	reg_mp2if_stop_en_lsb 0
> +#define    p_reg_tsis_en			0xF9CD
> +#define	reg_tsis_en_pos 0
> +#define	reg_tsis_en_len 1
> +#define	reg_tsis_en_lsb 0
> +#define    p_reg_afe_mem0			0xFB24
> +#define	reg_afe_mem0_pos 0
> +#define	reg_afe_mem0_len 8
> +#define	reg_afe_mem0_lsb 0
> +#define    p_reg_dyn0_clk			0xFBA8
> +#define	reg_dyn0_clk_pos 0
> +#define	reg_dyn0_clk_len 1
> +#define	reg_dyn0_clk_lsb 0
> +#define    r_io_mux_pwron_clk_strap		0xD800
> +#define	io_mux_pwron_clk_strap_pos 0
> +#define	io_mux_pwron_clk_strap_len 4
> +#define	io_mux_pwron_clk_strap_lsb 0
> +#define    p_reg_top_pwrdw_hwen			0xD809
> +#define	reg_top_pwrdw_hwen_pos 0
> +#define	reg_top_pwrdw_hwen_len 1
> +#define	reg_top_pwrdw_hwen_lsb 0
> +#define    p_reg_top_pwrdw			0xD80B
> +#define	reg_top_pwrdw_pos 0
> +#define	reg_top_pwrdw_len 1
> +#define	reg_top_pwrdw_lsb 0
> +#define    p_reg_top_padodpu			0xD827
> +#define	reg_top_padodpu_pos 0
> +#define	reg_top_padodpu_len 1
> +#define	reg_top_padodpu_lsb 0
> +#define    p_reg_top_agc_od			0xD829
> +#define	reg_top_agc_od_pos 0
> +#define	reg_top_agc_od_len 1
> +#define	reg_top_agc_od_lsb 0
> +#define    p_reg_top_padmiscdr2			0xD830
> +#define	reg_top_padmiscdr2_pos 0
> +#define	reg_top_padmiscdr2_len 1
> +#define	reg_top_padmiscdr2_lsb 0
> +#define    p_reg_top_padmiscdr4			0xD831
> +#define	reg_top_padmiscdr4_pos 0
> +#define	reg_top_padmiscdr4_len 1
> +#define	reg_top_padmiscdr4_lsb 0
> +#define    p_reg_top_padmiscdr8			0xD832
> +#define	reg_top_padmiscdr8_pos 0
> +#define	reg_top_padmiscdr8_len 1
> +#define	reg_top_padmiscdr8_lsb 0
> +#define    p_reg_top_padmiscdrsr		0xD833
> +#define	reg_top_padmiscdrsr_pos 0
> +#define	reg_top_padmiscdrsr_len 1
> +#define	reg_top_padmiscdrsr_lsb 0
> +#define    p_reg_top_gpioh1_o			0xD8AF
> +#define	reg_top_gpioh1_o_pos 0
> +#define	reg_top_gpioh1_o_len 1
> +#define	reg_top_gpioh1_o_lsb 0
> +#define    p_reg_top_gpioh1_en			0xD8B0
> +#define	reg_top_gpioh1_en_pos 0
> +#define	reg_top_gpioh1_en_len 1
> +#define	reg_top_gpioh1_en_lsb 0
> +#define    p_reg_top_gpioh1_on			0xD8B1
> +#define	reg_top_gpioh1_on_pos 0
> +#define	reg_top_gpioh1_on_len 1
> +#define	reg_top_gpioh1_on_lsb 0
> +#define    p_reg_top_gpioh3_o			0xD8B3
> +#define	reg_top_gpioh3_o_pos 0
> +#define	reg_top_gpioh3_o_len 1
> +#define	reg_top_gpioh3_o_lsb 0
> +#define    p_reg_top_gpioh3_en			0xD8B4
> +#define	reg_top_gpioh3_en_pos 0
> +#define	reg_top_gpioh3_en_len 1
> +#define	reg_top_gpioh3_en_lsb 0
> +#define    p_reg_top_gpioh3_on			0xD8B5
> +#define	reg_top_gpioh3_on_pos 0
> +#define	reg_top_gpioh3_on_len 1
> +#define	reg_top_gpioh3_on_lsb 0
> +#define    p_reg_top_gpioh5_o			0xD8BB
> +#define	reg_top_gpioh5_o_pos 0
> +#define	reg_top_gpioh5_o_len 1
> +#define	reg_top_gpioh5_o_lsb 0
> +#define    p_reg_top_gpioh5_en			0xD8BC
> +#define	reg_top_gpioh5_en_pos 0
> +#define	reg_top_gpioh5_en_len 1
> +#define	reg_top_gpioh5_en_lsb 0
> +#define    p_reg_top_gpioh5_on			0xD8BD
> +#define	reg_top_gpioh5_on_pos 0
> +#define	reg_top_gpioh5_on_len 1
> +#define	reg_top_gpioh5_on_lsb 0
> +#define    p_reg_top_gpioh7_en			0xD8C4
> +#define	reg_top_gpioh7_en_pos 0
> +#define	reg_top_gpioh7_en_len 1
> +#define	reg_top_gpioh7_en_lsb 0
> +#define    p_reg_top_gpioh7_on			0xD8C5
> +#define	reg_top_gpioh7_on_pos 0
> +#define	reg_top_gpioh7_on_len 1
> +#define	reg_top_gpioh7_on_lsb 0
> +#define    p_reg_top_lock3_out			0xD8FD
> +#define	reg_top_lock3_out_pos 0
> +#define	reg_top_lock3_out_len 1
> +#define	reg_top_lock3_out_lsb 0
> +#define    p_reg_top_hostb_mpeg_par_mode	0xD91B
> +#define	reg_top_hostb_mpeg_par_mode_pos 0
> +#define	reg_top_hostb_mpeg_par_mode_len 1
> +#define	reg_top_hostb_mpeg_par_mode_lsb 0
> +#define    p_reg_top_hostb_mpeg_ser_mode	0xD91C
> +#define	reg_top_hostb_mpeg_ser_mode_pos 0
> +#define	reg_top_hostb_mpeg_ser_mode_len 1
> +#define	reg_top_hostb_mpeg_ser_mode_lsb 0
> +#define    p_reg_top_hostb_dca_upper		0xD91E
> +#define	reg_top_hostb_dca_upper_pos 0
> +#define	reg_top_hostb_dca_upper_len 1
> +#define	reg_top_hostb_dca_upper_lsb 0
> +#define    p_reg_top_hostb_dca_lower		0xD91F
> +#define	reg_top_hostb_dca_lower_pos 0
> +#define	reg_top_hostb_dca_lower_len 1
> +#define	reg_top_hostb_dca_lower_lsb 0
> +#define    p_reg_ep4_max_pkt			0xDD0C
> +#define	reg_ep4_max_pkt_pos 0
> +#define	reg_ep4_max_pkt_len 8
> +#define	reg_ep4_max_pkt_lsb 0
> +#define    p_reg_ep5_max_pkt			0xDD0D
> +#define	reg_ep5_max_pkt_pos 0
> +#define	reg_ep5_max_pkt_len 8
> +#define	reg_ep5_max_pkt_lsb 0
> +#define    p_reg_ep4_tx_en			0xDD11
> +#define	reg_ep4_tx_en_pos 5
> +#define	reg_ep4_tx_en_len 1
> +#define	reg_ep4_tx_en_lsb 0
> +#define    p_reg_ep5_tx_en			0xDD11
> +#define	reg_ep5_tx_en_pos 6
> +#define	reg_ep5_tx_en_len 1
> +#define	reg_ep5_tx_en_lsb 0
> +#define    p_reg_ep4_tx_nak			0xDD13
> +#define	reg_ep4_tx_nak_pos 5
> +#define	reg_ep4_tx_nak_len 1
> +#define	reg_ep4_tx_nak_lsb 0
> +#define    p_reg_ep5_tx_nak			0xDD13
> +#define	reg_ep5_tx_nak_pos 6
> +#define	reg_ep5_tx_nak_len 1
> +#define	reg_ep5_tx_nak_lsb 0
> +#define    p_reg_ep4_tx_len_7_0			0xDD88
> +#define	reg_ep4_tx_len_7_0_pos 0
> +#define	reg_ep4_tx_len_7_0_len 8
> +#define	reg_ep4_tx_len_7_0_lsb 0
> +#define    p_reg_ep4_tx_len_15_8		0xDD89
> +#define	reg_ep4_tx_len_15_8_pos 0
> +#define	reg_ep4_tx_len_15_8_len 8
> +#define	reg_ep4_tx_len_15_8_lsb 8
> +#define    p_reg_ep5_tx_len_7_0			0xDD8A
> +#define	reg_ep5_tx_len_7_0_pos 0
> +#define	reg_ep5_tx_len_7_0_len 8
> +#define	reg_ep5_tx_len_7_0_lsb 0
> +#define    p_reg_ep5_tx_len_15_8		0xDD8B
> +#define	reg_ep5_tx_len_15_8_pos 0
> +#define	reg_ep5_tx_len_15_8_len 8
> +#define	reg_ep5_tx_len_15_8_lsb 8
> +#define    r_reg_aagc_rf_gain			0xCFFF
> +#define	reg_aagc_rf_gain_pos 0
> +#define	reg_aagc_rf_gain_len 8
> +#define	reg_aagc_rf_gain_lsb 0
> +#define    r_reg_aagc_if_gain			0xCFFF
> +#define	reg_aagc_if_gain_pos 0
> +#define	reg_aagc_if_gain_len 8
> +#define	reg_aagc_if_gain_lsb 0
> +#define    p_reg_top_clkoen			0xCFFF
> +#define reg_top_clkoen_pos 0
> +#define reg_top_clkoen_len 1
> +#define reg_top_clkoen_lsb 0
> +#define    p_reg_top_hosta_mpeg_ser_mode	0xCFFF
> +#define reg_top_hosta_mpeg_ser_mode_pos 0
> +#define reg_top_hosta_mpeg_ser_mode_len 1
> +#define reg_top_hosta_mpeg_ser_mode_lsb 0
> +#define    p_reg_top_hosta_mpeg_par_mode	0xCFFF
> +#define reg_top_hosta_mpeg_par_mode_pos 0
> +#define reg_top_hosta_mpeg_par_mode_len 1
> +#define reg_top_hosta_mpeg_par_mode_lsb 0
> +#define    p_reg_top_hosta_dca_upper		0xCFFF
> +#define reg_top_hosta_dca_upper_pos 0
> +#define reg_top_hosta_dca_upper_len 1
> +#define reg_top_hosta_dca_upper_lsb 0
> +#define    p_reg_top_hosta_dca_lower		0xCFFF
> +#define reg_top_hosta_dca_lower_pos 0
> +#define reg_top_hosta_dca_lower_len 1
> +#define reg_top_hosta_dca_lower_lsb 0
> +
> +/*
> + * IT9135 variable defines
> + */
> +/* ----- LL variables ----- */
> +#define OVA_BASE			0x4C00	/* omega variable address base */
> +#define OVA_LINK_VERSION		(OVA_BASE-4)	/* 4 bytes */
> +#define OVA_LINK_VERSION_31_24		(OVA_LINK_VERSION+0)
> +#define OVA_LINK_VERSION_23_16		(OVA_LINK_VERSION+1)
> +#define OVA_LINK_VERSION_15_8		(OVA_LINK_VERSION+2)
> +#define OVA_LINK_VERSION_7_0		(OVA_LINK_VERSION+3)
> +#define OVA_SECOND_DEMOD_I2C_ADDR	(OVA_BASE-5)
> +#define OVA_EEPROM_CFG			(OVA_BASE-620)	/* 256 bytes */
> +#define OVA_IR_TABLE_ADDR		(OVA_BASE-363)	/* 2 bytes pointer point to IR_TABLE */
> +#define OVA_IR_TABLE_ADDR_15_18		(OVA_IR_TABLE_ADDR+0)
> +#define OVA_IR_TABLE_ADDR_7_0		(OVA_IR_TABLE_ADDR+1)
> +
> +/* For API variable name, not use in firmware */
> +#define second_i2c_address		OVA_SECOND_DEMOD_I2C_ADDR
> +#define ir_table_start_15_8		OVA_IR_TABLE_ADDR_15_18
> +#define ir_table_start_7_0		OVA_IR_TABLE_ADDR_7_0
> +#define prechip_version_7_0		0x384F
> +#define chip_version_7_0		0x1222
> +#define link_version_31_24		OVA_LINK_VERSION_31_24
> +#define link_version_23_16		OVA_LINK_VERSION_23_16
> +#define link_version_15_8		OVA_LINK_VERSION_15_8
> +#define link_version_7_0		OVA_LINK_VERSION_7_0
> +
> +/* ----- OFDM variables ----- */
> +/* 2k */
> +#define var_addr_base			0x418b
> +#define log_addr_base			0x418d
> +#define log_data_base			0x418f
> +#define LowerLocalRetra			0x43bb
> +
> +#define trigger_ofsm			0x0000
> +#define cfoe_NS_2048_coeff1_25_24	0x0001
> +#define cfoe_NS_2048_coeff1_23_16	0x0002
> +#define cfoe_NS_2048_coeff1_15_8	0x0003
> +#define cfoe_NS_2048_coeff1_7_0		0x0004
> +#define cfoe_NS_2k_coeff2_24		0x0005
> +#define cfoe_NS_2k_coeff2_23_16		0x0006
> +#define cfoe_NS_2k_coeff2_15_8		0x0007
> +#define cfoe_NS_2k_coeff2_7_0		0x0008
> +
> +/* 8k */
> +#define cfoe_NS_8191_coeff1_25_24	0x0009
> +#define cfoe_NS_8191_coeff1_23_16	0x000a
> +#define cfoe_NS_8191_coeff1_15_8	0x000b
> +#define cfoe_NS_8191_coeff1_7_0		0x000c
> +#define cfoe_NS_8192_coeff1_25_24	0x000d
> +#define cfoe_NS_8192_coeff1_23_16	0x000e
> +#define cfoe_NS_8192_coeff1_15_8	0x000f
> +#define cfoe_NS_8192_coeff1_7_0		0x0010
> +#define cfoe_NS_8193_coeff1_25_24	0x0011
> +#define cfoe_NS_8193_coeff1_23_16	0x0012
> +#define cfoe_NS_8193_coeff1_15_8	0x0013
> +#define cfoe_NS_8193_coeff1_7_0		0x0014
> +
> +#define cfoe_NS_8k_coeff2_24		0x0015
> +#define cfoe_NS_8k_coeff2_23_16		0x0016
> +#define cfoe_NS_8k_coeff2_15_8		0x0017
> +#define cfoe_NS_8k_coeff2_7_0		0x0018
> +
> +/* 4k */
> +#define cfoe_NS_4096_coeff1_25_24	0x0019
> +#define cfoe_NS_4096_coeff1_23_16	0x001a
> +#define cfoe_NS_4096_coeff1_15_8	0x001b
> +#define cfoe_NS_4096_coeff1_7_0		0x001c
> +#define cfoe_NS_4k_coeff2_24		0x001d
> +#define cfoe_NS_4k_coeff2_23_16		0x001e
> +#define cfoe_NS_4k_coeff2_15_8		0x001f
> +#define cfoe_NS_4k_coeff2_7_0		0x0020
> +
> +#define bfsfcw_fftindex_ratio_7_0	0x0021
> +#define bfsfcw_fftindex_ratio_15_8	0x0022
> +#define fftindex_bfsfcw_ratio_7_0	0x0023
> +#define fftindex_bfsfcw_ratio_15_8	0x0024
> +
> +#define crystal_clk_7_0			0x0025
> +#define crystal_clk_15_8		0x0026
> +#define crystal_clk_23_16		0x0027
> +#define crystal_clk_31_24		0x0028
> +
> +#define bfs_fcw_7_0			0x0029
> +#define bfs_fcw_15_8			0x002a
> +#define bfs_fcw_22_16			0x002b
> +
> +#define rsd_abort_packet_cnt_7_0	0x0032
> +#define rsd_abort_packet_cnt_15_8	0x0033
> +#define rsd_bit_err_cnt_7_0		0x0034
> +#define rsd_bit_err_cnt_15_8		0x0035
> +#define rsd_bit_err_cnt_23_16		0x0036
> +#define r_rsd_packet_unit_7_0		0x0037
> +#define r_rsd_packet_unit_15_8		0x0038
> +
> +#define tpsd_lock			0x003c
> +#define mpeg_lock			0x003d
> +
> +#define Training_Mode			0x0040
> +
> +#define adcx2				0x0045
> +
> +#define empty_channel_status		0x0047
> +#define signal_quality			0x0049
> +
> +#define FreBand				0x004b
> +#define suspend_flag			0x004c
> +
> +#define var_p_inband			0x00f7
> +
> +#define var_pre_lo_freq_7_0		0x011e
> +#define var_pre_lo_freq_15_8		0x011f
> +#define var_pre_lna_cap_sel		0x0120
> +
> +#define ofdm_version_31_24		0x4191
> +#define ofdm_version_23_16		0x4192
> +#define ofdm_version_15_8		0x4193
> +#define ofdm_version_7_0		0x4194
> +
> +/*
> + * Error code
> + */
> +enum it9135_err_code {
> +	ERROR_NO_ERROR = 0x00000000ul,
> +	ERROR_RESET_TIMEOUT = 0x00000001ul,
> +	ERROR_WRITE_REG_TIMEOUT = 0x00000002ul,
> +	ERROR_WRITE_TUNER_TIMEOUT = 0x00000003ul,
> +	ERROR_WRITE_TUNER_FAIL = 0x00000004ul,
> +	ERROR_RSD_COUNTER_NOT_READY = 0x00000005ul,
> +	ERROR_VTB_COUNTER_NOT_READY = 0x00000006ul,
> +	ERROR_FEC_MON_NOT_ENABLED = 0x00000007ul,
> +	ERROR_INVALID_DEV_TYPE = 0x00000008ul,
> +	ERROR_INVALID_TUNER_TYPE = 0x00000009ul,
> +	ERROR_OPEN_FILE_FAIL = 0x0000000Aul,
> +	ERROR_WRITEFILE_FAIL = 0x0000000Bul,
> +	ERROR_READFILE_FAIL = 0x0000000Cul,
> +	ERROR_CREATEFILE_FAIL = 0x0000000Dul,
> +	ERROR_MALLOC_FAIL = 0x0000000Eul,
> +	ERROR_INVALID_FILE_SIZE = 0x0000000Ful,
> +	ERROR_INVALID_READ_SIZE = 0x00000010ul,
> +	ERROR_LOAD_FW_DONE_BUT_FAIL = 0x00000011ul,
> +	ERROR_NOT_IMPLEMENTED = 0x00000012ul,
> +	ERROR_NOT_SUPPORT = 0x00000013ul,
> +	ERROR_WRITE_MBX_TUNER_TIMEOUT = 0x00000014ul,
> +	ERROR_DIV_MORE_THAN_8_CHIPS = 0x00000015ul,
> +	ERROR_DIV_NO_CHIPS = 0x00000016ul,
> +	ERROR_SUPER_FRAME_CNT_0 = 0x00000017ul,
> +	ERROR_INVALID_FFT_MODE = 0x00000018ul,
> +	ERROR_INVALID_CONSTELLATION_MODE = 0x00000019ul,
> +	ERROR_RSD_PKT_CNT_0 = 0x0000001Aul,
> +	ERROR_FFT_SHIFT_TIMEOUT = 0x0000001Bul,
> +	ERROR_WAIT_TPS_TIMEOUT = 0x0000001Cul,
> +	ERROR_INVALID_BW = 0x0000001Dul,
> +	ERROR_INVALID_BUF_LEN = 0x0000001Eul,
> +	ERROR_NULL_PTR = 0x0000001Ful,
> +	ERROR_INVALID_AGC_VOLT = 0x00000020ul,
> +	ERROR_MT_OPEN_FAIL = 0x00000021ul,
> +	ERROR_MT_TUNE_FAIL = 0x00000022ul,
> +	ERROR_CMD_NOT_SUPPORTED = 0x00000023ul,
> +	ERROR_CE_NOT_READY = 0x00000024ul,
> +	ERROR_EMBX_INT_NOT_CLEARED = 0x00000025ul,
> +	ERROR_INV_PULLUP_VOLT = 0x00000026ul,
> +	ERROR_FREQ_OUT_OF_RANGE = 0x00000027ul,
> +	ERROR_INDEX_OUT_OF_RANGE = 0x00000028ul,
> +	ERROR_NULL_SETTUNER_PTR = 0x00000029ul,
> +	ERROR_NULL_INITSCRIPT_PTR = 0x0000002Aul,
> +	ERROR_INVALID_INITSCRIPT_LEN = 0x0000002Bul,
> +	ERROR_INVALID_POS = 0x0000002Cul,
> +	ERROR_BACK_TO_BOOTCODE_FAIL = 0x0000002Dul,
> +	ERROR_GET_BUFFER_VALUE_FAIL = 0x0000002Eul,
> +	ERROR_INVALID_REG_VALUE = 0x0000002Ful,
> +	ERROR_INVALID_INDEX = 0x00000030ul,
> +	ERROR_READ_TUNER_TIMEOUT = 0x00000031ul,
> +	ERROR_READ_TUNER_FAIL = 0x00000032ul,
> +	ERROR_UNDEFINED_SAW_BW = 0x00000033ul,
> +	ERROR_MT_NOT_AVAILABLE = 0x00000034ul,
> +	ERROR_NO_SUCH_TABLE = 0x00000035ul,
> +	ERROR_WRONG_CHECKSUM = 0x00000036ul,
> +	ERROR_INVALID_XTAL_FREQ = 0x00000037ul,
> +	ERROR_COUNTER_NOT_AVAILABLE = 0x00000038ul,
> +	ERROR_INVALID_DATA_LENGTH = 0x00000039ul,
> +	ERROR_BOOT_FAIL = 0x0000003Aul,
> +	ERROR_BUFFER_INSUFFICIENT = 0x0000003Bul,
> +	ERROR_NOT_READY = 0x0000003Cul,
> +	ERROR_DRIVER_INVALID = 0x0000003Dul,
> +	ERROR_INTERFACE_FAIL = 0x0000003Eul,
> +	ERROR_PID_FILTER_FULL = 0x0000003Ful,
> +	ERROR_OPERATION_TIMEOUT = 0x00000040ul,
> +	ERROR_LOADFIRMWARE_SKIPPED = 0x00000041ul,
> +	ERROR_REBOOT_FAIL = 0x00000042ul,
> +	ERROR_PROTOCOL_FORMAT_INVALID = 0x00000043ul,
> +	ERROR_ACTIVESYNC_ERROR = 0x00000044ul,
> +	ERROR_CE_READWRITEBUS_ERROR = 0x00000045ul,
> +	ERROR_CE_NODATA_ERROR = 0x00000046ul,
> +	ERROR_NULL_FW_SCRIPT = 0x00000047ul,
> +	ERROR_NULL_TUNER_SCRIPT = 0x00000048ul,
> +	ERROR_INVALID_CHIP_TYPE = 0x00000049ul,
> +	ERROR_TUNER_TYPE_NOT_COMPATIBLE = 0x0000004Aul,
> +	/* Error Code of Gemini System */
> +	ERROR_INVALID_INDICATOR_TYPE = 0x00000101ul,
> +	ERROR_INVALID_SC_NUMBER = 0x00000102ul,
> +	ERROR_INVALID_SC_INFO = 0x00000103ul,
> +	ERROR_FIGBYPASS_FAIL = 0x00000104ul,
> +	/* Error Code of Firmware */
> +	ERROR_FIRMWARE_STATUS = 0x01000000ul,
> +	/* Error Code of I2C Module */
> +	ERROR_I2C_DATA_HIGH_FAIL = 0x02001000ul,
> +	ERROR_I2C_CLK_HIGH_FAIL = 0x02002000ul,
> +	ERROR_I2C_WRITE_NO_ACK = 0x02003000ul,
> +	ERROR_I2C_DATA_LOW_FAIL = 0x02004000ul,
> +	/* Error Code of USB Module */
> +	ERROR_USB_NULL_HANDLE = 0x03010001ul,
> +	ERROR_USB_WRITEFILE_FAIL = 0x03000002ul,
> +	ERROR_USB_READFILE_FAIL = 0x03000003ul,
> +	ERROR_USB_INVALID_READ_SIZE = 0x03000004ul,
> +	ERROR_USB_INVALID_STATUS = 0x03000005ul,
> +	ERROR_USB_INVALID_SN = 0x03000006ul,
> +	ERROR_USB_INVALID_PKT_SIZE = 0x03000007ul,
> +	ERROR_USB_INVALID_HEADER = 0x03000008ul,
> +	ERROR_USB_NO_IR_PKT = 0x03000009ul,
> +	ERROR_USB_INVALID_IR_PKT = 0x0300000Aul,
> +	ERROR_USB_INVALID_DATA_LEN = 0x0300000Bul,
> +	ERROR_USB_EP4_READFILE_FAIL = 0x0300000Cul,
> +	ERROR_USB_EP$_INVALID_READ_SIZE = 0x0300000Dul,
> +	ERROR_USB_BOOT_INVALID_PKT_TYPE = 0x0300000Eul,
> +	ERROR_USB_BOOT_BAD_CONFIG_HEADER = 0x0300000Ful,
> +	ERROR_USB_BOOT_BAD_CONFIG_SIZE = 0x03000010ul,
> +	ERROR_USB_BOOT_BAD_CONFIG_SN = 0x03000011ul,
> +	ERROR_USB_BOOT_BAD_CONFIG_SUBTYPE = 0x03000012ul,
> +	ERROR_USB_BOOT_BAD_CONFIG_VALUE = 0x03000013ul,
> +	ERROR_USB_BOOT_BAD_CONFIG_CHKSUM = 0x03000014ul,
> +	ERROR_USB_BOOT_BAD_CONFIRM_HEADER = 0x03000015ul,
> +	ERROR_USB_BOOT_BAD_CONFIRM_SIZE = 0x03000016ul,
> +	ERROR_USB_BOOT_BAD_CONFIRM_SN = 0x03000017ul,
> +	ERROR_USB_BOOT_BAD_CONFIRM_SUBTYPE = 0x03000018ul,
> +	ERROR_USB_BOOT_BAD_CONFIRM_VALUE = 0x03000019ul,
> +	ERROR_USB_BOOT_BAD_CONFIRM_CHKSUM = 0x03000020ul,
> +	ERROR_USB_BOOT_BAD_BOOT_HEADER = 0x03000021ul,
> +	ERROR_USB_BOOT_BAD_BOOT_SIZE = 0x03000022ul,
> +	ERROR_USB_BOOT_BAD_BOOT_SN = 0x03000023ul,
> +	ERROR_USB_BOOT_BAD_BOOT_PATTERN_01 = 0x03000024ul,
> +	ERROR_USB_BOOT_BAD_BOOT_PATTERN_10 = 0x03000025ul,
> +	ERROR_USB_BOOT_BAD_BOOT_CHKSUM = 0x03000026ul,
> +	ERROR_USB_INVALID_BOOT_PKT_TYPE = 0x03000027ul,
> +	ERROR_USB_BOOT_BAD_CONFIG_VAlUE = 0x03000028ul,
> +	ERROR_USB_COINITIALIZEEX_FAIL = 0x03000029ul,
> +	ERROR_USB_COCREATEINSTANCE_FAIL = 0x0300003Aul,
> +	ERROR_USB_COCREATCLSEENUMERATOR_FAIL = 0x0300002Bul,
> +	ERROR_USB_QUERY_INTERFACE_FAIL = 0x0300002Cul,
> +	ERROR_USB_PKSCTRL_NULL = 0x0300002Dul,
> +	ERROR_USB_INVALID_REGMODE = 0x0300002Eul,
> +	ERROR_USB_INVALID_REG_COUNT = 0x0300002Ful,
> +	ERROR_USB_INVALID_HANDLE = 0x03000100ul,
> +	ERROR_USB_WRITE_FAIL = 0x03000200ul,
> +	ERROR_USB_UNEXPECTED_WRITE_LEN = 0x03000300ul,
> +	ERROR_USB_READ_FAIL = 0x03000400ul,
> +	/* Error code of Omega */
> +	ERROR_TUNER_INIT_FAIL = 0x05000000ul
> +};

Please, don't create your own error space. Error codes on Linux are well
defined, and specified at the DVB API spec. For example, the generic
error codes are:
	http://linuxtv.org/downloads/v4l-dvb-apis/gen_errors.html#gen-errors

And some ioctl's also device special meanings for some error codes, like:
http://linuxtv.org/downloads/v4l-dvb-apis/frontend_fcalls.html#FE_SET_FRONTEND


> +
> +enum it9135_tuner_id {
> +	/* 0x50~0x5f reserved for OMEGA use */
> +	IT9135_TUNER_ID = 0x38,
> +	IT9135_TUNER_ID_LNA_CONFIG1 = 0x51,
> +	IT9135_TUNER_ID_LNA_CONFIG2 = 0x52,
> +	/* 0x60~0x6f reserved for OMEGA V2 use */
> +	IT9135_TUNER_ID_V2 = 0x60,
> +	IT9135_TUNER_ID_V2_LNA_CONFIG1 = 0x61,
> +	IT9135_TUNER_ID_V2_LNA_CONFIG2 = 0x62
> +};
> +
> +enum it9135_tuner_lna {
> +	OMEGA_NORMAL = 0x00,
> +	OMEGA_LNA_CONFIG1 = 0x01,
> +	OMEGA_LNA_CONFIG2 = 0x02,
> +};
> +
> +struct it9135_val_set {
> +	unsigned long address;	/* The address of target register */
> +	unsigned char value;	/* The value of target register   */
> +};
> +
> +struct it9135_tuner_desc {
> +	struct it9135_val_set *scripts;
> +	unsigned short *script_sets;
> +	unsigned short id;
> +};
> +
> +/*
> + * The type defination of clock table.
> + */
> +struct it9135_freq_clk {
> +	unsigned long crystal_Freq;	/* The frequency of crystal. */
> +	unsigned long adc_freq;	/* The frequency of ADC.     */
> +};
> +
> +#define IT9135_MAX_PKT_SIZE	255
> +
> +/* Define commands */
> +enum it9135_cmd {
> +	CMD_REG_DEMOD_READ = 0x0000,
> +	CMD_REG_DEMOD_WRITE = 0x0001,
> +	CMD_REG_EEPROM_READ = 0x0004,
> +	CMD_REG_EEPROM_WRITE = 0x0005,
> +	CMD_IR_GET = 0x0018,
> +	CMD_FW_DOWNLOAD = 0x0021,
> +	CMD_QUERYINFO = 0x0022,
> +	CMD_BOOT = 0x0023,
> +	CMD_REBOOT = 0x0023,
> +	CMD_FW_DOWNLOAD_BEGIN = 0x0024,
> +	CMD_FW_DOWNLOAD_END = 0x0025,
> +	CMD_SCATTER_WRITE = 0x0029,
> +	CMD_GENERIC_READ = 0x002A,
> +	CMD_GENERIC_WRITE = 0x002B
> +};
> +
> +#define it9135_build_command(command, processor, chip) \
> +		(command + (unsigned short) (processor << 12) + (unsigned short) (chip << 12))
> +
> +/*
> + * The type defination of channel Statistic.
> + */
> +struct it9135_ch_statistic {
> +	unsigned short abort_cnt;
> +	unsigned long post_vitbit_cnt;
> +	unsigned long post_vit_err_cnt;
> +};
> +
> +/*
> + * The type defination of Segment
> + */
> +struct it9135_segment {
> +	unsigned char type;	/* 0:Firmware download 1:Rom copy 2:Direct command */
> +	unsigned long length;
> +};
> +
> +/*
> + * The type defination of TransmissionMode.
> + */
> +enum it9135_transmission_modes {
> +	TransmissionMode_2K = 0,	/* OFDM frame consists of 2048 different carriers (2K FFT mode) */
> +	TransmissionMode_8K,	/* OFDM frame consists of 8192 different carriers (8K FFT mode) */
> +	TransmissionMode_4K	/* OFDM frame consists of 4096 different carriers (4K FFT mode) */
> +};
> +
> +/*
> + * The type defination of Priority.
> + */
> +enum it9135_priority {
> +	PRIORITY_HIGH = 0,	/* DVB-T and DVB-H - identifies high-priority stream */
> +	PRIORITY_LOW		/* DVB-T and DVB-H - identifies low-priority stream  */
> +};
> +
> +/*
> + * The type defination of CodeRate.
> + */
> +enum it9135_code_rate {
> +	CodeRate_1_OVER_2 = 0,	/* Signal uses FEC coding ratio of 1/2 */
> +	CodeRate_2_OVER_3,	/* Signal uses FEC coding ratio of 2/3 */
> +	CodeRate_3_OVER_4,	/* Signal uses FEC coding ratio of 3/4 */
> +	CodeRate_5_OVER_6,	/* Signal uses FEC coding ratio of 5/6 */
> +	CodeRate_7_OVER_8,	/* Signal uses FEC coding ratio of 7/8 */
> +	CodeRate_NONE		/* None, NXT doesn't have this one     */
> +};
> +
> +/*
> + * TPS Hierarchy and Alpha value.
> + */
> +enum it9135_hierarchy {
> +	Hierarchy_NONE = 0,	/* Signal is non-hierarchical        */
> +	Hierarchy_ALPHA_1,	/* Signalling format uses alpha of 1 */
> +	Hierarchy_ALPHA_2,	/* Signalling format uses alpha of 2 */
> +	Hierarchy_ALPHA_4	/* Signalling format uses alpha of 4 */
> +};
> +
> +/*
> + * The type defination of Multiplier.
> + */
> +enum it9135_multiplier {
> +	Multiplier_1X = 0,
> +	Multiplier_2X
> +};
> +
> +/*
> + * The type defination of StreamType.
> + */
> +enum it9135_stream_type {
> +	STREAM_TYPE_NONE = 0,	/* Invalid (Null) StreamType                */
> +	STREAM_TYPE_DVBT_DATAGRAM = 3,	/* DVB-T mode, store data in device buffer  */
> +	STREAM_TYPE_DVBT_PARALLEL,	/* DVB-T mode, output via paralle interface */
> +	STREAM_TYPE_DVBT_SERIAL,	/* DVB-T mode, output via serial interface  */
> +};
> +
> +/*
> + * The type defination of Architecture.
> + */
> +enum it9135_architecture {
> +	ARCHITECTURE_NONE = 0,	/* Inavalid (Null) Architecture.                                    */
> +	ARCHITECTURE_DCA,	/* Diversity combine architecture. Only valid when chip number > 1. */
> +	ARCHITECTURE_PIP	/* Picture in picture. Only valid when chip number > 1.             */
> +};
> +
> +/*
> + * The type defination of processor.
> + */
> +enum it9135_processor {
> +	PROCESSOR_LINK = 0,
> +	PROCESSOR_OFDM = 8
> +};
> +
> +/*
> + * The type defination of Constellation.
> + */
> +enum Constellation {
> +	CONSTELLATION_QPSK = 0,	/* Signal uses QPSK constellation  */
> +	CONSTELLATION_16QAM,	/* Signal uses 16QAM constellation */
> +	CONSTELLATION_64QAM	/* Signal uses 64QAM constellation */
> +};
> +
> +/*
> + * The defination of ChannelModulation.
> + */
> +struct it9135_ch_modulation {
> +	unsigned long frequency;	/* Channel frequency in KHz.                                */
> +	unsigned char trans_mode;	/* Number of carriers used for OFDM signal                  */
> +	unsigned char constellation;	/* Constellation scheme (FFT mode) in use           */
> +	unsigned char interval;	/* Fraction of symbol length used as guard (Guard Interval) */
> +	unsigned char priority;	/* The priority of stream                                   */
> +	unsigned char h_code_rate;	/* FEC coding ratio of high-priority stream                 */
> +	unsigned char l_code_rate;	/* FEC coding ratio of low-priority stream                  */
> +	unsigned char hierarchy;	/* Hierarchy levels of OFDM signal                          */
> +	unsigned char bandwidth;
> +};
> +
> +/*
> + * The type defination of Statistic.
> + */
> +struct it9135_statistic {
> +	int presented;		/* Signal is presented.                           */
> +	int locked;		/* Signal is locked.                              */
> +	unsigned char quality;	/* Signal quality, from 0 (poor) to 100 (good).   */
> +	unsigned char strength;	/* Signal strength from 0 (weak) to 100 (strong). */
> +};
> +
> +/*
> + * The type defination of PidTable
> + */
> +struct it9135_pid_tab {
> +	unsigned short pid[32];
> +};
> +
> +struct it9135_pid_info {
> +	struct it9135_pid_tab pid_tab[2];
> +	unsigned char pid_cnt;
> +	int pid_init;
> +};
> +
> +/*
> + * The data structure of IT9135
> + */
> +struct it9135_data {
> +	/* Basic structure */
> +	void *driver;
> +
> +/* Bus types */
> +#define IT9135_BUS_USB20	2
> +#define IT9135_BUS_USB11           5
> +	unsigned short busId;
> +
> +	unsigned short tuner_id;
> +	struct it9135_tuner_desc tuner_desc;
> +
> +	unsigned char *fw_codes;
> +	struct it9135_segment *fw_segs;	/* FW seqments */
> +	unsigned char fw_parts;	/* FW partitions */
> +	unsigned short *script_sets;
> +	struct it9135_val_set *scripts;
> +	unsigned short *tuner_script_sets;
> +	struct it9135_val_set *tuner_scripts;
> +
> +	const struct firmware *it9135_fw;
> +	unsigned char chip_ver;
> +	unsigned long chip_type;
> +	unsigned char chip_num;
> +	unsigned char streamType;
> +	unsigned char architecture;
> +	unsigned long crystal_Freq;
> +	unsigned long adc_freq;
> +	unsigned short bandwidth[2];
> +	unsigned long frequency[2];
> +	unsigned long fcw;
> +	struct it9135_statistic statistic[2];
> +	struct it9135_ch_statistic ch_statistic[2];	/* releaseExternalRemove */
> +	unsigned char host_if[2];	/* Host Interface */
> +	unsigned char cmd_seq;	/* command sequence */
> +	struct it9135_pid_info pid_info;
> +	unsigned char pre_sqi;
> +
> +	int booted;
> +	int inited;
> +
> +	unsigned char clock_mode;
> +	unsigned int fxtal_khz;
> +	unsigned int fdiv;
> +
> +	/* for linux kernel driver */
> +	struct it9135_val_set *tuner_script_normal;
> +	unsigned short tuner_script_sets_normal;
> +	struct it9135_val_set *tuner_script_lna1;
> +	unsigned short tuner_script_sets_lna1;
> +	struct it9135_val_set *tuner_script_lna2;
> +	unsigned short tuner_script_sets_lna2;
> +};
> +
> +#define REG_MASK(mask, pos, len)		(mask[len-1] << pos)
> +#define REG_CLEAR(mask, temp, pos, len)		(temp & (~REG_MASK(mask, pos, len)))
> +#define REG_CREATE(mask, val, temp, pos, len)	((val << pos) | (REG_CLEAR(mask, temp, pos, len)))
> +#define REG_GET(mask, value, pos, len)		((value & REG_MASK(mask, pos, len)) >> pos)
> +#define LOWBYTE(w)				((unsigned char)((w) & 0xff))
> +#define HIGHBYTE(w)				((unsigned char)((w >> 8) & 0xff))
> +
> +struct it9135_coeff_param {
> +	unsigned long adc_freq;
> +	unsigned short bandwidth;
> +	unsigned long coeff1_2048Nu;
> +	unsigned long coeff1_4096Nu;
> +	unsigned long coeff1_8191Nu;
> +	unsigned long coeff1_8192Nu;
> +	unsigned long coeff1_8193Nu;
> +	unsigned long coeff2_2k;
> +	unsigned long coeff2_4k;
> +	unsigned long coeff2_8k;
> +	unsigned short bfsfcw_fftindex_ratio;
> +	unsigned short fftindex_bfsfcw_ratio;
> +};
> +
> +/*
> + * Write one unsigned char (8 bits) to a specific register in IT9135.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param processor: The processor of specified register. Because each chip
> + *        has two processor so user have to specify the processor. The
> + *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
> + * @param reg_addr: the address of the register to be written.
> + * @param value: the value to be written.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_write_reg(struct it9135_data *data, unsigned char chip,
> +			       unsigned char processor, unsigned long reg_addr,
> +			       unsigned char value);
> +
> +/*
> + * Write a sequence of unsigned chars to the contiguous registers in IT9135.
> + * The maximum burst size is restricted by the capacity of bus. If bus
> + * could transfer N unsigned chars in one cycle, then the maximum value of
> + * post_err_cnt would be N - 5.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param processor: The processor of specified register. Because each chip
> + *        has two processor so user have to specify the processor. The
> + *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
> + * @param reg_addr: the start address of the registers to be written.
> + * @param post_err_cnt: the number of registers to be written.
> + * @param buffer: a unsigned char array which is used to store values to be written.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_write_regs(struct it9135_data *data, unsigned char chip,
> +				unsigned char processor, unsigned long reg_addr,
> +				unsigned long w_buff_len,
> +				unsigned char *w_buff);
> +
> +/*
> + * Write a sequence of unsigned chars to the contiguous registers in slave device
> + * through specified interface (1, 2, 3).
> + * The maximum burst size is restricted by the capacity of bus. If bus
> + * could transfer N unsigned chars in one cycle, then the maximum value of
> + * post_err_cnt would be N - 6 (one more unsigned char to specify tuner address).
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param interfaceIndex: the index of interface. The possible values are 1~3.
> + * @param slaveAddress: the I2c address of slave device.
> + * @param post_err_cnt: the number of registers to be read.
> + * @param buffer: a unsigned char array which is used to store values to be read.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_write_gen_regs(struct it9135_data *data,
> +				    unsigned char chip,
> +				    unsigned char interfaceIndex,
> +				    unsigned char slaveAddress,
> +				    unsigned char post_err_cnt,
> +				    unsigned char *buffer);
> +
> +/*
> + * Write a sequence of unsigned chars to the contiguous cells in the EEPROM.
> + * The maximum burst size is restricted by the capacity of bus. If bus
> + * could transfer N unsigned chars in one cycle, then the maximum value of
> + * post_err_cnt would be N - 5 (firmware will detect EEPROM address).
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param reg_addr: the start address of the cells to be written.
> + * @param post_err_cnt: the number of cells to be written.
> + * @param buffer: a unsigned char array which is used to store values to be written.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_write_ee_vals(struct it9135_data *data, unsigned char chip,
> +				   unsigned short reg_addr,
> +				   unsigned char w_buff_len,
> +				   unsigned char *w_buff);
> +
> +/*
> + * Modify bits in the specific register.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param processor: The processor of specified register. Because each chip
> + *        has two processor so user have to specify the processor. The
> + *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
> + * @param reg_addr: the address of the register to be written.
> + * @param position: the start position of bits to be modified (0 means the
> + *        LSB of the specifyed register).
> + * @param length: the length of bits.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_write_reg_bits(struct it9135_data *data,
> +				    unsigned char chip, unsigned char processor,
> +				    unsigned long reg_addr,
> +				    unsigned char position,
> +				    unsigned char length, unsigned char value);
> +
> +/*
> + * Read one unsigned char (8 bits) from a specific register in IT9135.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param processor: The processor of specified register. Because each chip
> + *        has two processor so user have to specify the processor. The
> + *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
> + * @param reg_addr: the address of the register to be read.
> + * @param value: the pointer used to store the value read from IT9135 register.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_read_reg(struct it9135_data *data, unsigned char chip,
> +			      unsigned char processor, unsigned long reg_addr,
> +			      unsigned char *value);
> +
> +/*
> + * Read a sequence of unsigned chars from the contiguous registers in IT9135.
> + * The maximum burst size is restricted by the capacity of bus. If bus
> + * could transfer N unsigned chars in one cycle, then the maximum value of
> + * post_err_cnt would be N - 5.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param processor: The processor of specified register. Because each chip
> + *        has two processor so user have to specify the processor. The
> + *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
> + * @param reg_addr: the address of the register to be read.
> + * @param post_err_cnt: the number of registers to be read.
> + * @param buffer: a unsigned char array which is used to store values to be read.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_read_regs(struct it9135_data *data, unsigned char chip,
> +			       unsigned char processor, unsigned long reg_addr,
> +			       unsigned long r_buff_len, unsigned char *r_buff);
> +
> +/*
> + * Read a sequence of unsigned chars from the contiguous registers in slave device
> + * through specified interface (1, 2, 3).
> + * The maximum burst size is restricted by the capacity of bus. If bus
> + * could transfer N unsigned chars in one cycle, then the maximum value of
> + * post_err_cnt would be N - 6 (one more unsigned char to specify tuner address).
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param interfaceIndex: the index of interface. The possible values are 1~3.
> + * @param slaveAddress: the I2c address of slave device.
> + * @param post_err_cnt: the number of registers to be read.
> + * @param buffer: a unsigned char array which is used to store values to be read.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_read_gen_regs(struct it9135_data *data,
> +				   unsigned char chip,
> +				   unsigned char interfaceIndex,
> +				   unsigned char slaveAddress,
> +				   unsigned char post_err_cnt,
> +				   unsigned char *buffer);
> +
> +/*
> + * Read a sequence of unsigned chars from the contiguous cells in the EEPROM.
> + * The maximum burst size is restricted by the capacity of bus. If bus
> + * could transfer N unsigned chars in one cycle, then the maximum value of
> + * post_err_cnt would be N - 5 (firmware will detect EEPROM address).
> + *
> + * @param struct it9135_data the handle of IT9135.
> + * @param chip The index of IT9135. The possible values are 0~7.
> + * @param reg_addr the start address of the cells to be read.
> + * @param registerAddressLength the valid unsigned chars of reg_addr.
> + * @param post_err_cnt the number of cells to be read.
> + * @param buffer a unsigned char array which is used to store values to be read.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_read_ee_vals(struct it9135_data *data, unsigned char chip,
> +				  unsigned short reg_addr,
> +				  unsigned char r_buff_len,
> +				  unsigned char *r_buff);
> +
> +/*
> + * Read bits of the specified register.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param processor: The processor of specified register. Because each chip
> + *        has two processor so user have to specify the processor. The
> + *        possible values are PROCESSOR_LINK and PROCESSOR_OFDM.
> + * @param reg_addr: the address of the register to be read.
> + * @param position: the start position of bits to be read (0 means the
> + *        LSB of the specifyed register).
> + * @param length: the length of bits.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_read_reg_bits(struct it9135_data *data,
> +				   unsigned char chip, unsigned char processor,
> +				   unsigned long reg_addr,
> +				   unsigned char position, unsigned char length,
> +				   unsigned char *value);
> +
> +/*
> + * Get the version of firmware.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param version: the version of firmware.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_get_fw_ver(struct it9135_data *data,
> +				unsigned char processor,
> +				unsigned long *version);
> +
> +/*
> + * Get siganl strength Indication.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + *        NOTE: When the architecture is set to ARCHITECTURE_DCA
> + *        this parameter is regard as don't care.
> + * @param strength: The value of signal strength that calculations of "score mapping" from the signal strength (dBm) to the "0-100" scoring.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_get_strength(struct it9135_data *data, unsigned char chip,
> +				  unsigned char *strength);
> +
> +/*
> + * Get signal strength in dbm
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param rfpullUpVolt_X10: the pullup voltag of RF multiply 10.
> + * @param ifpullUpVolt_X10: the pullup voltag of IF multiply 10.
> + * @param strengthDbm: The value of signal strength in DBm.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_get_strength_dbm(struct it9135_data *data,
> +				      unsigned char chip, long *strength_dbm);
> +
> +/*
> + * Load the IR table for USB device.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param tab_len: The length of IR table.
> + * @param table: The content of IR table.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_load_ir_tab(struct it9135_data *data,
> +				 unsigned short tab_len, unsigned char *table);
> +
> +/*
> + * First, download firmware from host to IT9135. Actually, firmware is
> + * put in firmware.h as a part of source code. Therefore, in order to
> + * update firmware the host have to re-compile the source code.
> + * Second, setting all parameters which will be need at the beginning.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip_num: The total number of IT9135s.
> + * @param saw_band: SAW filter bandwidth in MHz. The possible values
> + *        are 6000, 7000, and 8000 (KHz).
> + * @param streamType: The format of output stream.
> + * @param architecture: the architecture of IT9135.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_dev_init(struct it9135_data *data, unsigned char chip_num,
> +			      unsigned short saw_band, unsigned char streamType,
> +			      unsigned char architecture);
> +
> +/*
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + * @example <pre>
> + * </pre>
> + */
> +unsigned long it9135_tps_locked(struct it9135_data *data, unsigned char chip,
> +				int *locked);
> +
> +/*
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + * @example <pre>
> + * </pre>
> + */
> +unsigned long it9135_mp2_locked(struct it9135_data *data, unsigned char chip,
> +				int *locked);
> +
> +/*
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + *        NOTE: When the architecture is set to ARCHITECTURE_DCA
> + *        this parameter is regard as don't care.
> + * @param locked: the result of frequency tuning. 1 if there is
> + *        IT9135 can lock signal, 0 otherwise.
> + * @example <pre>
> + * </pre>
> + */
> +unsigned long it9135_freq_locked(struct it9135_data *data, unsigned char chip,
> +				 int *locked);
> +
> +/*
> + * Get channel modulation related information.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param ch_modul: The modulation of channel.
> + * @return ERROR_NO_ERROR: successful, other non-zero error code otherwise.
> + */
> +unsigned long it9135_get_ch_modulation(struct it9135_data *data,
> +				       unsigned char chip,
> +				       struct it9135_ch_modulation *ch_modul);
> +
> +/*
> + * Specify the bandwidth of channel and tune the channel to the specific
> + * frequency. Afterwards, host could use output parameter dvbH to determine
> + * if there is a DVB-H signal.
> + * In DVB-T mode, after calling this function the output parameter dvbH
> + * should return 0 and host could use output parameter "locked" to check
> + * if the channel has correct TS output.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + *        NOTE: When the architecture is set to ARCHITECTURE_DCA
> + *        this parameter is regard as don't care.
> + * @param bandwidth: The channel bandwidth.
> + *        DVB-T: 5000, 6000, 7000, and 8000 (KHz).
> + * @param frequency: the channel frequency in KHz.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_acquire_ch(struct it9135_data *data, unsigned char chip,
> +				unsigned short bandwidth,
> +				unsigned long frequency);
> +
> +/*
> + * Set the output stream type of chip. Because the device could output in
> + * many stream type, therefore host have to choose one type before receive data.
> + *
> + * Note: Please refer to the example of Standard_acquireChannel when host want
> + *       to detect the available channels.
> + * Note: After host know all the available channels, and want to change to
> + *       specific channel, host have to choose output mode before receive
> + *       data. Please refer the example of it9135_set_stream_type.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param streamType: the possible values are
> + *        DVB-T:    STREAM_TYPE_DVBT_DATAGRAM
> + *                  STREAM_TYPE_DVBT_PARALLEL
> + *                  STREAM_TYPE_DVBT_SERIAL
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_set_stream_type(struct it9135_data *data,
> +				     unsigned char streamType);
> +
> +/*
> + * Set the architecture of chip. When two of our device are using, they could
> + * be operated in Diversity Combine Architecture (DCA) or (PIP). Therefore,
> + * host could decide which mode to be operated.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param architecture: the possible values are
> + *        ARCHITECTURE_DCA
> + *        ARCHITECTURE_PIP
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_set_arch(struct it9135_data *data,
> +			      unsigned char architecture);
> +
> +/*
> + * Get the statistic values of IT9135, it includes Pre-Viterbi BER,
> + * Post-Viterbi BER, Abort Count, Signal Presented Flag, Signal Locked Flag,
> + * Signal Quality, Signal Strength, Delta-T for DVB-H time slicing.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param statistic: the structure that store all statistic values.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_get_statistic(struct it9135_data *data, unsigned char chip,
> +				   struct it9135_statistic *statistic);
> +
> +/*
> + * @param it9135_data: the handle of IT9135.
> + * @param code: the value of IR raw code, the size should be 4 or 6,
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + * @example <pre>
> + * </pre>
> + */
> +unsigned long it9135_get_ir_code(struct it9135_data *data, unsigned long *code);
> +
> +/*
> + * Return to boot code
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + * @example <pre>
> + * </pre>
> + */
> +unsigned long it9135_dev_reboot(struct it9135_data *data);
> +
> +/*
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param contorl: 1: Power up, 0: Power down;
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + * @example <pre>
> + * </pre>
> + */
> +unsigned long it9135_ctrl_pw_saving(struct it9135_data *data,
> +				    unsigned char chip, unsigned char control);
> +
> +/*
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param contorl: 1: Power up, 0: Power down;
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + * @example <pre>
> + * </pre>
> + */
> +unsigned long it9135_ctrl_tuner_leakage(struct it9135_data *data,
> +					unsigned char chip,
> +					unsigned char control);
> +
> +/*
> + * @param it9135_data: the handle of IT9135.
> + * @param contorl: 1: Power up, 0: Power down;
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + * @example <pre>
> + * </pre>
> + */
> +unsigned long it9135_ctrl_tuner_pw_saving(struct it9135_data *data,
> +					  unsigned char chip,
> +					  unsigned char control);
> +
> +/*
> + * Control PID fileter
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param contorl: 0: Disable, 1: Enable.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + * @example <pre>
> + * </pre>
> + */
> +unsigned long it9135_ctrl_pid_filter(struct it9135_data *data,
> +				     unsigned char chip, unsigned char control);
> +
> +/*
> + * Reset PID filter.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_reset_pid_filter(struct it9135_data *data,
> +				      unsigned char chip);
> +
> +/*
> + * Add PID to PID filter.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param pid: the PID that will be add to PID filter.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_add_pid_filter(struct it9135_data *data,
> +				    unsigned char chip, unsigned char index,
> +				    unsigned short pid);
> +
> +/*
> + * get SNR .
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param snr (db).
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_get_snr(struct it9135_data *data, unsigned char chip,
> +			     unsigned char *snr);
> +
> +/*
> + * get SNR data .
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param snr_value (hex).
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_get_snr_val(struct it9135_data *IT9135, unsigned char chip,
> +				 unsigned long *snr_value);
> +
> +/*
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param multiplier: ADC frequency multiplier;
> + * @return ERROR_NO_ERROR: successful, other non-zero error code otherwise.
> + * @example <pre>
> + * </pre>
> + */
> +unsigned long it9135_set_multiplier(struct it9135_data *data,
> +				    unsigned char multiplier);
> +
> +/*
> + * Reset PID filter.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_reset_pid(struct it9135_data *data, unsigned char chip);
> +
> +/*
> + * Remove PID from PID filter by index.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param index: the index of PID filter.
> + * @param pid: the PID that will be remove from PID filter.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_remove_pid_at(struct it9135_data *data, unsigned char chip,
> +				   unsigned char index, unsigned short pid);
> +
> +/*
> + * Get the statistic values of IT9135, it includes Pre-Viterbi BER,
> + * Post-Viterbi BER, Abort Count, Signal Presented Flag, Signal Locked Flag,
> + * Signal Quality, Signal Strength, Delta-T for DVB-H time slicing.
> + *
> + * @param struct it9135_data the handle of IT9135.
> + * @param chip The index of IT9135. The possible values are 0~7.
> + * @param statistic the structure that store all statistic values.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_get_ch_statistic(struct it9135_data *data,
> +				      unsigned char chip,
> +				      struct it9135_ch_statistic *ch_statistic);
> +
> +/*
> + * Set control bus and tuner.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param busId: The ID of bus.
> + * @param tuner_id: The ID of tuner.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_set_bus_tuner(struct it9135_data *data,
> +				   unsigned short busId,
> +				   unsigned short tuner_id);
> +
> +/*
> + * Add PID to PID filter.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param pid: the PID that will be add to PID filter.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_add_pid(struct it9135_data *data, unsigned char chip,
> +			     unsigned short pid);
> +
> +/*
> + * Add PID to PID filter by index.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param index: the index of PID filter.
> + * @param pid: the PID that will be add to PID filter.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_add_pid_at(struct it9135_data *data, unsigned char chip,
> +				unsigned char index, unsigned short pid);
> +
> +/*
> + * Remove PID from PID filter.
> + *
> + * @param it9135_data: the handle of IT9135.
> + * @param chip: The index of IT9135. The possible values are 0~7.
> + * @param pid: the PID that will be remove from PID filter.
> + * @return ERROR_NO_ERROR: successful, non-zero error code otherwise.
> + */
> +unsigned long it9135_remove_pid(struct it9135_data *data, unsigned char chip,
> +				unsigned short pid);
> +
> +#endif
> diff --git a/drivers/media/dvb/dvb-usb/it9135.c b/drivers/media/dvb/dvb-usb/it9135.c
> new file mode 100644
> index 0000000..7fa21c7
> --- /dev/null
> +++ b/drivers/media/dvb/dvb-usb/it9135.c
> @@ -0,0 +1,2492 @@
> +/*
> + * DVB USB Linux driver for IT9135 DVB-T USB2.0 receiver
> + *
> + * Copyright (C) 2011 ITE Technologies, INC.
> + *
> + *    This program is free software; you can redistribute it and/or modify
> + *    it under the terms of the GNU General Public License as published by
> + *    the Free Software Foundation; either version 2 of the License, or
> + *    (at your option) any later version.
> + */
> +
> +#include "it9135.h"
> +
> +int dvb_usb_it9135_debug;
> +module_param_named(debug, dvb_usb_it9135_debug, int, 0644);
> +MODULE_PARM_DESC(debug,
> +		 "set debugging level.(func=1,info=2,warning=4)"
> +		 DVB_USB_DEBUG_STATUS);
> +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
> +
> +struct dvb_usb_device_properties it9135_properties[];
> +
> +static unsigned long it9135_drv_nim_reset(struct it9135_dev_ctx *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	/* Set AF0350 GPIOH1 to 0 to reset AF0351 */
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0,
> +				  PROCESSOR_LINK, p_reg_top_gpioh1_en,
> +				  reg_top_gpioh1_en_pos, reg_top_gpioh1_en_len,
> +				  1);
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
> +				  p_reg_top_gpioh1_on, reg_top_gpioh1_on_pos,
> +				  reg_top_gpioh1_on_len, 1);
> +
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0,
> +				  PROCESSOR_LINK, p_reg_top_gpioh1_o,
> +				  reg_top_gpioh1_o_pos, reg_top_gpioh1_o_len,
> +				  1);
> +	mdelay(50);
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0,
> +				  PROCESSOR_LINK, p_reg_top_gpioh1_o,
> +				  reg_top_gpioh1_o_pos, reg_top_gpioh1_o_len,
> +				  0);
> +	mdelay(50);
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0,
> +				  PROCESSOR_LINK, p_reg_top_gpioh1_o,
> +				  reg_top_gpioh1_o_pos, reg_top_gpioh1_o_len,
> +				  1);
> +
> +	return error;
> +}
> +
> +/* Write NIMSuspend Register */
> +static unsigned long it9135_drv_init_nim_suspend_regs(struct it9135_dev_ctx
> +						      *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0,
> +				  PROCESSOR_LINK, p_reg_top_gpioh5_en,
> +				  reg_top_gpioh5_en_pos, reg_top_gpioh5_en_len,
> +				  1);
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
> +				  p_reg_top_gpioh5_on, reg_top_gpioh5_on_pos,
> +				  reg_top_gpioh5_on_len, 1);
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
> +				  p_reg_top_gpioh5_o, reg_top_gpioh5_o_pos,
> +				  reg_top_gpioh5_o_len, 0);
> +	mdelay(10);
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 1, PROCESSOR_LINK,
> +				  p_reg_top_pwrdw, reg_top_pwrdw_pos,
> +				  reg_top_pwrdw_len, 1);
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 1, PROCESSOR_LINK,
> +				  p_reg_top_pwrdw_hwen, reg_top_pwrdw_hwen_pos,
> +				  reg_top_pwrdw_hwen_len, 1);
> +
> +	return error;
> +}
> +
> +/* Get OFDM /LINK Firmware version */
> +static unsigned long it9135_drv_get_firmware_version_from_file(struct
> +							       it9135_dev_ctx
> +							       *dev,
> +							       unsigned char
> +							       processor,
> +							       unsigned long
> +							       *version)
> +{
> +	if (processor == PROCESSOR_OFDM) {
> +		*version = dev->ofdm_ver;
> +	} else {		/* LINK */
> +		*version = dev->link_ver;
> +	}
> +
> +	return *version;
> +}
> +
> +static unsigned long it9135_drv_disable_gpio_pins(struct it9135_dev_ctx *dev)
> +{
> +	/* For strapping, gpioh1/gpioh5/ghioh7 have been program, just IT9135; */
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0,
> +				  PROCESSOR_LINK, p_reg_top_gpioh1_en,
> +				  reg_top_gpioh1_en_pos, reg_top_gpioh1_en_len,
> +				  0);
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
> +				  p_reg_top_gpioh1_on, reg_top_gpioh1_on_pos,
> +				  reg_top_gpioh1_on_len, 0);
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
> +				  p_reg_top_gpioh5_en, reg_top_gpioh5_en_pos,
> +				  reg_top_gpioh5_en_len, 0);
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
> +				  p_reg_top_gpioh5_on, reg_top_gpioh5_on_pos,
> +				  reg_top_gpioh5_on_len, 0);
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
> +				  p_reg_top_gpioh7_en, reg_top_gpioh7_en_pos,
> +				  reg_top_gpioh7_en_len, 0);
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
> +				  p_reg_top_gpioh7_on, reg_top_gpioh7_on_pos,
> +				  reg_top_gpioh7_on_len, 0);
> +
> +	if (error)
> +		err("it9135_drv_disable_gpio_pins failed !!!\n");
> +
> +	return error;
> +}
> +
> +/* Device initialize or not */
> +static unsigned long it9135_drv_initialize(struct it9135_dev_ctx *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned long file_ver, cmd_ver = 0;
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	if (dev->data.booted) {
> +		error =
> +		    it9135_drv_get_firmware_version_from_file(dev,
> +							      PROCESSOR_OFDM,
> +							      &file_ver);
> +
> +		/* Use "Command_QUERYINFO" to get fw version */
> +		error = it9135_get_fw_ver(&dev->data, PROCESSOR_OFDM, &cmd_ver);
> +		if (error)
> +			err("it9135_drv_initialize : it9135_get_fw_ver : error = 0x%08lx", (long unsigned int)error);
> +
> +		if (cmd_ver != file_ver) {
> +			deb_info
> +			    ("Reboot: Outside Fw = 0x%lX, Inside Fw = 0x%lX",
> +			     (long unsigned int)file_ver,
> +			     (long unsigned int)cmd_ver);
> +
> +			/* Patch for 2 chips reboot; */
> +			if (dev->data.chip_num == 2)
> +				it9135_drv_disable_gpio_pins(dev);
> +
> +			error = it9135_dev_reboot(&dev->data);
> +			dev->boot_code = 1;
> +			if (error) {
> +				err("it9135_dev_reboot : error = 0x%08lx",
> +				    (long unsigned int)error);
> +				return error;
> +			} else {
> +				return ERROR_NOT_READY;
> +			}
> +		} else {
> +			deb_info("Fw version is the same!\n");
> +			error = ERROR_NO_ERROR;
> +		}
> +	}
> +
> +	error =
> +	    it9135_dev_init(&dev->data, dev->data.chip_num, 8000,
> +			    dev->stream_type, dev->architecture);
> +	if (error)
> +		err("it9135_drv_initialize fail : 0x%08lx",
> +		    (long unsigned int)error);
> +	else
> +		deb_info("it9135_drv_initialize Ok!!");
> +
> +	it9135_get_fw_ver(&dev->data, PROCESSOR_OFDM, &cmd_ver);
> +	deb_info("FwVer OFDM = 0x%lX,", (long unsigned int)cmd_ver);
> +	it9135_get_fw_ver(&dev->data, PROCESSOR_LINK, &cmd_ver);
> +	deb_info("FwVer LINK = 0x%lX\n", (long unsigned int)cmd_ver);
> +
> +	return error;
> +}
> +
> +static unsigned long it9135_nim_reset_seq(struct it9135_dev_ctx *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char bootbuffer[6];
> +
> +	/* checksum = 0xFEDC */
> +	bootbuffer[0] = 0x05;
> +	bootbuffer[1] = 0x00;
> +	bootbuffer[2] = 0x23;
> +	bootbuffer[3] = 0x01;
> +	bootbuffer[4] = 0xFE;
> +	bootbuffer[5] = 0xDC;
> +
> +	/* GPIOH5 init */
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0,
> +				  PROCESSOR_LINK, p_reg_top_gpioh5_en,
> +				  reg_top_gpioh5_en_pos, reg_top_gpioh5_en_len,
> +				  0);
> +	error =
> +	    it9135_write_reg_bits(&dev->data, 0, PROCESSOR_LINK,
> +				  p_reg_top_gpioh5_on, reg_top_gpioh5_on_pos,
> +				  reg_top_gpioh5_on_len, 0);
> +
> +	error = it9135_drv_nim_reset(dev);
> +	error = it9135_drv_init_nim_suspend_regs(dev);
> +	error =
> +	    it9135_write_gen_regs(&dev->data, 0, 0x01, 0x3a, 0x06, bootbuffer);
> +	error =
> +	    it9135_read_gen_regs(&dev->data, 0, 0x01, 0x3a, 0x05, bootbuffer);
> +
> +	mdelay(50);		/* Delay for Fw boot */
> +
> +	/* Demod & Tuner init */
> +	error = it9135_drv_initialize(dev);
> +
> +	return error;
> +}
> +
> +/************** DRV_ *************/
> +static unsigned long it9135_drv_ir_table_download(struct it9135_dev_ctx *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	struct file *filp;
> +	unsigned char buff[512];
> +	int file_sz;
> +	mm_segment_t oldfs;
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	oldfs = get_fs();
> +	set_fs(KERNEL_DS);
> +	filp = filp_open("/lib/firmware/af35irtbl.bin", O_RDWR, 0644);


No! Please use the standard request_firmware() call, instead of implementing it
by hand.


> +
> +	if (IS_ERR(filp)) {
> +		deb_warning("LoadIrTable : Can't open file\n");
> +		goto exit;
> +	}
> +
> +	if ((filp->f_op) == NULL) {
> +		deb_warning("LoadIrTable : File Operation Method Error!!\n");
> +		goto exit;
> +	}
> +
> +	filp->f_pos = 0x00;
> +	file_sz = filp->f_op->read(filp, buff, sizeof(buff), &filp->f_pos);
> +
> +	error =
> +	    it9135_load_ir_tab((struct it9135_data *)&dev->data,
> +			       (unsigned short)file_sz, buff);
> +	if (error) {
> +		err("it9135_load_ir_tab fail");
> +		goto exit;
> +	}
> +
> +	filp_close(filp, NULL);
> +	set_fs(oldfs);
> +
> +	return error;
> +
> +exit:
> +	deb_warning("LoadIrTable fail!\n");
> +	return error;
> +}
> +
> +/* Set tuner Frequency and BandWidth */
> +static unsigned long it9135_drv_set_freq_bw(struct it9135_dev_ctx *dev,
> +					    unsigned char chip,
> +					    unsigned long freq,
> +					    unsigned short bw)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned long temp_freq = freq;
> +	unsigned short temp_bw = bw;
> +
> +	deb_func("Enter %s Function -\n ", __func__);
> +	deb_info("chip = %d, Freq= %ld, BW=%d\n", chip, (long int)freq, bw);
> +
> +	if (dev->fc[chip].en_pid) {
> +		/* Disable PID filter */
> +		it9135_write_reg_bits(&dev->data, chip, PROCESSOR_OFDM,
> +				      p_mp2if_pid_en, mp2if_pid_en_pos,
> +				      mp2if_pid_en_len, 0);
> +		dev->fc[chip].en_pid = 0;
> +	}
> +
> +	/* Before acquireChannel, it is 1; otherwise, it is 0 */
> +	dev->fc[chip].tuner_info.setting_freq = 1;
> +
> +	if (freq)
> +		dev->fc[chip].desired_freq = freq;
> +	else
> +		freq = dev->fc[chip].desired_freq;
> +
> +	if (bw)
> +		dev->fc[chip].desired_bw = bw * 1000;
> +	else
> +		bw = dev->fc[chip].desired_bw;
> +
> +	deb_info("Real Freq= %ld, BW=%d\n",
> +		 (long int)dev->fc[chip].desired_freq,
> +		 dev->fc[chip].desired_bw);
> +
> +	if (!dev->fc[chip].tuner_info.inited) {
> +		deb_warning("Skip SetFreq - Tuner is still off!\n");
> +		goto exit;
> +	}
> +
> +	dev->fc[chip].tuner_info.set = 0;
> +	if (dev->fc[chip].desired_freq != 0 && dev->fc[chip].desired_bw != 0) {
> +		deb_info("it9135_acquire_ch: Real Freq= %ld, BW=%d\n",
> +			 (long int)dev->fc[chip].desired_freq,
> +			 dev->fc[chip].desired_bw);
> +		error =
> +		    it9135_acquire_ch(&dev->data, chip,
> +				      dev->fc[chip].desired_bw,
> +				      dev->fc[chip].desired_freq);
> +		/* dev->fc[chip].tuner_info.setting_freq = 0; */
> +		if (error) {
> +			err("it9135_acquire_ch fail! 0x%08lx",
> +			    (long unsigned int)error);
> +			goto exit;
> +		} else {	/* when success acquireChannel, record currentFreq/currentBW. */
> +			dev->fc[chip].curr_freq = dev->fc[chip].desired_freq;
> +			dev->fc[chip].curr_bw = dev->fc[chip].desired_bw;
> +		}
> +	}
> +
> +	if (dev->stream_type == STREAM_TYPE_DVBT_DATAGRAM)
> +		dev->fc[chip].ovr_flw_chk = 5;
> +
> +	dev->fc[chip].tuner_info.set = 1;
> +
> +	/* [OMEGA] if only 1 on, set the other to the same freq. */
> +	if (dev->architecture == ARCHITECTURE_PIP) {
> +		if (!dev->fc[0].timer_on && !dev->fc[1].timer_on) {
> +			/* case: when 1st open; */
> +			error =
> +			    it9135_acquire_ch(&dev->data, (!chip),
> +					      dev->fc[chip].curr_bw,
> +					      dev->fc[chip].curr_freq);
> +		} else if ((!dev->fc[0].timer_on || !dev->fc[1].timer_on)
> +			   && !dev->fc[!chip].tuner_info.locked) {
> +			/* case: when only 1 active, and change freq; (the other need to change to same freq too) */
> +			error =
> +			    it9135_acquire_ch(&dev->data, (!chip),
> +					      dev->fc[chip].curr_bw,
> +					      dev->fc[chip].curr_freq);
> +		}
> +	}
> +
> +exit:
> +	dev->fc[chip].tuner_info.setting_freq = 0;
> +
> +	if (dev->chip_ver == 1) {
> +		if (error && (!dev->already_nim_reset_seq)
> +		    && (chip == 1)) {
> +			dev->already_nim_reset_seq = 1;
> +			it9135_nim_reset_seq(dev);
> +			it9135_drv_set_freq_bw(dev, chip, temp_freq, temp_bw);
> +			dev->already_nim_reset_seq = 0;
> +		}
> +	}
> +	return error;
> +}
> +
> +/* Tuner lock signal or not */
> +static unsigned long it9135_drv_is_locked(struct it9135_dev_ctx *dev,
> +					  unsigned char chip, int *locked)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	*locked = 0;
> +
> +	error = it9135_freq_locked(&dev->data, chip, locked);
> +	if (error) {
> +		err("Standard_isLocked is failed!");
> +	} else {
> +		if (!*locked)
> +			deb_info("The chip=%d signal is %s Lock\n", chip,
> +				 *locked ? "" : "not");
> +	}
> +
> +	return error;
> +}
> +
> +unsigned long it9135_drv_get_snr_value(struct it9135_dev_ctx *dev,
> +				       unsigned long *snr_value)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char snr_reg_23_16, snr_reg_15_8, snr_reg_7_0;
> +
> +	deb_func("Enter %s Function\n ", __func__);
> +
> +	error =
> +	    it9135_read_reg(&dev->data, 0, PROCESSOR_OFDM, 0x2e,
> +			    (unsigned char *)&snr_reg_23_16);
> +	if (error)
> +		err("it9135_get_snr snr_reg_23_16 is failed!");
> +
> +	error =
> +	    it9135_read_reg(&dev->data, 0, PROCESSOR_OFDM, 0x2d,
> +			    (unsigned char *)&snr_reg_15_8);
> +	if (error)
> +		err("it9135_get_snr snr_reg_15_8 is failed!");
> +
> +	error =
> +	    it9135_read_reg(&dev->data, 0, PROCESSOR_OFDM, 0x2c,
> +			    (unsigned char *)&snr_reg_7_0);
> +	if (error)
> +		err("it9135_get_snr snr_reg_7_0 is failed!");
> +
> +	*snr_value =
> +	    (snr_reg_23_16 & 0xff) * 256 * 256 + (snr_reg_15_8 & 0xff) * 256 +
> +	    (snr_reg_7_0 & 0xff);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_drv_get_statistic(struct it9135_dev_ctx *dev,
> +				       unsigned char chip,
> +				       struct it9135_statistic *statistic)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	if (dev->fc[chip].tuner_info.set) {
> +		error = it9135_get_statistic(&dev->data, chip, statistic);
> +	} else {
> +		(*statistic).presented = 0;
> +		(*statistic).locked = 0;
> +		(*statistic).quality = 0;
> +		(*statistic).strength = 0;
> +	}
> +
> +	return error;
> +}
> +
> +static unsigned long it9135_drv_init_dev_info(struct it9135_dev_ctx *dev,
> +					      unsigned char chip)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	dev->fc[chip].curr_freq = 0;
> +	dev->fc[chip].curr_bw = 0;
> +	dev->fc[chip].desired_freq = 0;
> +	dev->fc[chip].desired_bw = 6000;
> +
> +	/* For PID Filter Setting */
> +	dev->fc[chip].en_pid = 0;
> +	dev->fc[chip].ap_on = 0;
> +	dev->fc[chip].reset_ts = 0;
> +	dev->fc[chip].tuner_info.set = 0;
> +	dev->fc[chip].tuner_info.setting_freq = 0;
> +
> +	return error;
> +}
> +
> +/* Get EEPROM_IRMODE/ir_tab_load/bRAWIr/architecture config from EEPROM */
> +static unsigned long it9135_drv_get_eeprom_config(struct it9135_dev_ctx *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char chip_ver = 0;
> +	unsigned long chip_type;
> +	unsigned char var[2];
> +	/* ir_tab_load option */
> +	unsigned char tmp = 0;
> +	int chip;
> +
> +	deb_func("Enter %s Function", __func__);
> +
> +	/* Patch for read eeprom valid bit */
> +	error =
> +	    it9135_read_reg(&dev->data, 0, PROCESSOR_LINK, chip_version_7_0,
> +			    &chip_ver);
> +	error =
> +	    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
> +			     chip_version_7_0 + 1, 2, var);
> +
> +	if (error)
> +		err("it9135_drv_get_eeprom_config fail---cannot read chip version");
> +
> +	chip_type = var[1] << 8 | var[0];
> +	if (chip_type == 0x9135 && chip_ver == 2) {	/* Om2 */
> +		dev->chip_ver = 2;
> +		error =
> +		    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK, 0x461d, 1,
> +				     &tmp);
> +		deb_info
> +		    ("Chip Version is %d---and Read 461d---valid bit = 0x%02X",
> +		     chip_ver, tmp);
> +	} else {
> +		dev->chip_ver = 1;	/* Om1 */
> +		error =
> +		    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK, 0x461b, 1,
> +				     &tmp);
> +		deb_info
> +		    ("Chip Version is %d---and Read 461b---valid bit = 0x%02X",
> +		     chip_ver, tmp);
> +	}
> +	deb_info("*** Chip Version = %d ***", chip_ver);
> +	if (error) {
> +		err("0x461D eeprom valid bit read fail!");
> +		goto exit;
> +	}
> +
> +	if (tmp == 0) {
> +		deb_info("No need read eeprom\n");
> +		dev->ir_tab_load = 0;
> +		dev->proprietary_ir = 0;
> +		dev->dual_ts = 0;
> +		dev->architecture = ARCHITECTURE_DCA;
> +		dev->data.chip_num = 1;
> +		dev->dca_pip = 0;
> +		dev->fc[0].tuner_info.id = 0x38;
> +	} else {
> +		deb_info("Need read eeprom\n");
> +		error =
> +		    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
> +				     EEPROM_IRMODE, 1, &tmp);
> +		if (error)
> +			goto exit;
> +
> +		dev->ir_tab_load = tmp ? 1 : 0;
> +		deb_info("EEPROM_IRMODE = 0x%02X, ", tmp);
> +		deb_info("ir_tab_load %s\n", dev->ir_tab_load ? "ON" : "OFF");
> +
> +		dev->proprietary_ir = (tmp == 0x05) ? 1 : 0;
> +		deb_info("proprietary_ir - %s\n",
> +			 dev->proprietary_ir ? "ON" : "OFF");
> +		if (dev->proprietary_ir)
> +			deb_info("IT9135 propriety (raw) mode\n");
> +		else
> +			deb_info("IT9135 HID (keyboard) mode\n");
> +
> +		/* EE chose NEC RC5 RC6 threshhold table */
> +		if (dev->ir_tab_load) {
> +			error =
> +			    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
> +					     EEPROM_IRTYPE, 1, &tmp);
> +			if (error)
> +				goto exit;
> +			dev->ir_type = tmp;
> +			deb_info("ir_type %d", dev->ir_type);
> +		}
> +
> +		/* dual_ts option */
> +		dev->dual_ts = 0;
> +		dev->architecture = ARCHITECTURE_DCA;
> +		dev->data.chip_num = 1;
> +		dev->dca_pip = 0;
> +
> +		error =
> +		    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
> +				     EEPROM_TSMODE, 1, &tmp);
> +		if (error)
> +			goto exit;
> +		deb_info("EEPROM_TSMODE = 0x%02X", tmp);
> +
> +		if (tmp == 0) {
> +			deb_info("TSMode = TS1 mode\n");
> +		} else if (tmp == 1) {
> +			deb_info("TSMode = DCA+PIP mode\n");
> +			dev->architecture = ARCHITECTURE_DCA;
> +			dev->data.chip_num = 2;
> +			dev->dual_ts = 1;
> +			dev->dca_pip = 1;
> +		} else if (tmp == 2) {
> +			deb_info("TSMode = DCA mode\n");
> +			dev->data.chip_num = 2;
> +		} else if (tmp == 3) {
> +			deb_info("TSMode = PIP mode\n");
> +			dev->architecture = ARCHITECTURE_PIP;
> +			dev->data.chip_num = 2;
> +			dev->dual_ts = 1;
> +		}
> +
> +		/* tunerID option, Omega, not need to read register, just assign 0x38; */
> +		error =
> +		    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
> +				     EEPROM_TUNERID, 1, &tmp);
> +		if (tmp == 0x51)
> +			dev->fc[0].tuner_info.id = 0x51;
> +		else if (tmp == 0x52)
> +			dev->fc[0].tuner_info.id = 0x52;
> +		else if (tmp == 0x60)
> +			dev->fc[0].tuner_info.id = 0x60;
> +		else if (tmp == 0x61)
> +			dev->fc[0].tuner_info.id = 0x61;
> +		else if (tmp == 0x62)
> +			dev->fc[0].tuner_info.id = 0x62;
> +		else
> +			dev->fc[0].tuner_info.id = 0x38;

What are those "ID" values? tuner type? if so, please put those "magic" numbers
into defines. 

> +
> +		deb_info("dev->fc[0].tuner_info.id = 0x%x",
> +			 dev->fc[0].tuner_info.id);
> +		if (dev->dual_ts) {
> +			dev->fc[1].tuner_info.id = dev->fc[0].tuner_info.id;
> +			deb_info("dev->fc[1].tuner_info.id = 0x%x",
> +				 dev->fc[1].tuner_info.id);
> +		}
> +		error =
> +		    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
> +				     EEPROM_SUSPEND, 1, &tmp);
> +		deb_info("EEPROM susped mode=%d", tmp);
> +
> +	}
> +
> +	for (chip = 0; chip <= (unsigned char)dev->dual_ts; chip++)
> +		error = it9135_drv_init_dev_info(dev, chip);
> +
> +exit:
> +	return error;
> +}
> +
> +static unsigned long it9135_drv_set_bus_tuner(struct it9135_dev_ctx *dev,
> +					      unsigned short busId,
> +					      unsigned short tuner_id)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned long version = 0;
> +
> +	deb_func("Enter %s Function", __func__);
> +	deb_info("busId = 0x%x, tuner_id =0x%x\n", busId, tuner_id);
> +
> +	if ((dev->usb_mode == 0x0110) && (busId == IT9135_BUS_USB20))
> +		busId = IT9135_BUS_USB11;
> +
> +	error = it9135_set_bus_tuner(&dev->data, busId, tuner_id);
> +	if (error) {
> +		err("it9135_set_bus_tuner error");
> +		return error;
> +	}
> +
> +	error = it9135_get_fw_ver(&dev->data, PROCESSOR_LINK, &version);
> +	if (version != 0)
> +		dev->data.booted = 1;
> +	else
> +		dev->data.booted = 0;
> +
> +	if (error)
> +		err("it9135_get_fw_ver error");
> +
> +	return error;
> +}
> +
> +/* suspend 1 --> sleep / suspend not 1 --> resume */
> +static unsigned long it9135_drv_nim_suspend(struct it9135_dev_ctx *dev,
> +					    int suspend)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	deb_func("Enter %s Function\n", __func__);
> +	deb_info("suspend = %s\n", suspend ? "ON" : "OFF");
> +
> +	if (dev->data.chip_num == 1)
> +		return ERROR_NO_ERROR;
> +
> +	if (suspend) {		/* Sleep */
> +		error =
> +		    it9135_write_reg_bits(&dev->data,
> +					  0, PROCESSOR_LINK, p_reg_top_gpioh5_o,
> +					  reg_top_gpioh5_o_pos,
> +					  reg_top_gpioh5_o_len, 1);
> +		mdelay(20);
> +	} else {		/* Resume */
> +		error =
> +		    it9135_write_reg_bits(&dev->data,
> +					  0, PROCESSOR_LINK, p_reg_top_gpioh5_o,
> +					  reg_top_gpioh5_o_pos,
> +					  reg_top_gpioh5_o_len, 0);
> +		mdelay(100);
> +	}
> +
> +	return error;
> +}
> +
> +/* Set tuner power saving and control */
> +static unsigned long it9135_drv_ap_ctrl(struct it9135_dev_ctx *dev,
> +					unsigned char chip, int onoff)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned long version = 0;
> +	int i;
> +
> +	deb_func("Enter %s Function\n", __func__);
> +	deb_info("chip = %d, onoff = %s\n", chip, onoff ? "ON" : "OFF");
> +
> +	if (onoff) {
> +		dev->fc[chip].tuner_info.inited = 1;
> +		if (dev->architecture == ARCHITECTURE_PIP) {
> +			if (dev->fc[0].timer_on || dev->fc[1].timer_on) {
> +				deb_info("Already all power on !!");
> +				return 0;
> +			}
> +		}
> +	} else {
> +		dev->fc[chip].tuner_info.inited = 0;
> +		dev->fc[chip].tuner_info.locked = 0;
> +
> +		/* [OMEGA] if other one still alive, do not pwr down, just need to set freq; */
> +		if (dev->architecture == ARCHITECTURE_PIP) {
> +			if (dev->fc[0].timer_on || dev->fc[1].timer_on) {
> +				deb_info("CLOSE 1");
> +				it9135_acquire_ch(&dev->data, chip,
> +						  dev->fc[!chip].curr_bw,
> +						  dev->fc[!chip].curr_freq);
> +				return 0;
> +			}
> +		}
> +	}
> +	/*[OMEGA] clock from tuner, so close sequence demod->tuner, and 9133->9137. vice versa.
> +	 * BUT! demod->tuner:57mADC, tuner->demod:37mADC
> +	 */
> +	if (onoff) {		/* pwr on */
> +		if (dev->chip_ver == 1) {
> +			if (chip == 1) {
> +				error = it9135_nim_reset_seq(dev);
> +				if (error)
> +					it9135_nim_reset_seq(dev);
> +			} else {
> +				dev->usb_ctrl_timeOut = 1;
> +				for (i = 0; i < 5; i++) {
> +					deb_info
> +					    ("it9135_drv_ap_ctrl - DummyCmd %d",
> +					     i);
> +					error =
> +					    it9135_get_fw_ver(&dev->data,
> +							      PROCESSOR_LINK,
> +							      &version);
> +					mdelay(1);
> +				}
> +				dev->usb_ctrl_timeOut = 5;
> +
> +				error =
> +				    it9135_ctrl_tuner_pw_saving(&dev->data,
> +								chip, onoff);
> +				if (error)
> +					err("it9135_drv_ap_ctrl::it9135_ctrl_tuner_pw_saving error = %x", (unsigned int)error);
> +
> +				error =
> +				    it9135_ctrl_pw_saving(&dev->data, chip,
> +							  onoff);
> +				if (error)
> +					err("it9135_drv_ap_ctrl::it9135_ctrl_pw_saving error = %x", (unsigned int)error);
> +			}
> +		} else {
> +			if (chip == 1) {
> +				error = it9135_drv_nim_suspend(dev, 0);
> +			} else {
> +				/* DummyCmd */
> +				dev->usb_ctrl_timeOut = 1;
> +				for (i = 0; i < 5; i++) {
> +					deb_info
> +					    ("it9135_drv_ap_ctrl - DummyCmd %d",
> +					     i);
> +					error =
> +					    it9135_get_fw_ver(&dev->data,
> +							      PROCESSOR_LINK,
> +							      &version);
> +					mdelay(1);
> +				}
> +				dev->usb_ctrl_timeOut = 5;
> +			}
> +
> +			error =
> +			    it9135_ctrl_tuner_pw_saving(&dev->data, chip,
> +							onoff);
> +			if (error)
> +				err("it9135_drv_ap_ctrl - it9135_ctrl_tuner_pw_saving error = %x", (unsigned int)error);
> +
> +			error = it9135_ctrl_pw_saving(&dev->data, chip, onoff);
> +			mdelay(50);
> +			if (error)
> +				err("it9135_drv_ap_ctrl - it9135_ctrl_pw_saving error = %x", (unsigned int)error);
> +		}
> +	} else {		/* pwr down:  DCA DUT: 36(all) -> 47-159(no GPIOH5, sequence change) */
> +		if ((chip == 0) && (dev->data.chip_num == 2)) {
> +			error = it9135_ctrl_tuner_leakage(&dev->data, 1, onoff);
> +			if (error)
> +				err("it9135_drv_ap_ctrl::it9135_ctrl_tuner_leakage error = %x", (unsigned int)error);
> +			error = it9135_drv_nim_suspend(dev, 1);
> +		}
> +
> +		error = it9135_ctrl_pw_saving(&dev->data, chip, onoff);
> +		if (error)
> +			err("it9135_drv_ap_ctrl::it9135_ctrl_pw_saving error = %x", (unsigned int)error);
> +
> +		error = it9135_ctrl_tuner_pw_saving(&dev->data, chip, onoff);
> +		if (error)
> +			err("it9135_drv_ap_ctrl::it9135_ctrl_tuner_pw_saving error = %x", (unsigned int)error);
> +	}
> +
> +	return error;
> +}
> +
> +static unsigned long it9135_drv_ap_reset(struct it9135_dev_ctx *dev,
> +					 unsigned char chip, int onoff)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	dev->fc[chip].curr_freq = 0;
> +	dev->fc[chip].curr_bw = 6000;	/* For BDAUtil */
> +	dev->fc[chip].ap_on = 0;
> +
> +	if (!onoff) {		/* Only for stop */
> +		dev->fc[chip].en_pid = 0;
> +	}
> +
> +	/* Init Tuner info */
> +	dev->fc[chip].tuner_info.setting_freq = 0;
> +
> +	error = it9135_drv_ap_ctrl(dev, chip, onoff);
> +	if (error)
> +		err("it9135_drv_ap_ctrl Fail!");
> +
> +	return error;
> +}
> +
> +static unsigned long it9135_drv_dummy_cmd(struct it9135_dev_ctx *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	int i;
> +
> +	deb_info("it9135_drv_dummy_cmd:: patch for KJS/EEPC\n");
> +	for (i = 0; i < 5; i++) {
> +		error =
> +		    it9135_drv_set_bus_tuner(dev, IT9135_BUS_USB20,
> +					     IT9135_TUNER_ID);
> +		mdelay(1);
> +	}
> +	if (error)
> +		deb_warning("it9135_drv_dummy_cmd failed - %d\n", i);
> +
> +	return error;
> +}
> +
> +/************** DL_ *************/
> +
> +static unsigned long it9135_dl_dummy_cmd(struct it9135_dev_ctx *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	error = it9135_drv_dummy_cmd(dev);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +static unsigned long it9135_dl_nim_reset(struct it9135_dev_ctx *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	error = it9135_drv_nim_reset(dev);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +static unsigned long it9135_dl_init_nim_suspend_regs(struct it9135_dev_ctx *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	error = it9135_drv_init_nim_suspend_regs(dev);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +static unsigned long it9135_dl_initialize(struct it9135_dev_ctx *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	error = it9135_drv_initialize(dev);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +static unsigned long it9135_dl_set_bus_tuner(struct it9135_dev_ctx *dev,
> +					     unsigned short busId,
> +					     unsigned short tuner_id)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	error = it9135_drv_set_bus_tuner(dev, busId, tuner_id);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +static unsigned long it9135_dl_get_eeprom_config(struct it9135_dev_ctx *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	error = it9135_drv_get_eeprom_config(dev);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +/* Load Ir Table */
> +static unsigned long it9135_dl_ir_table_download(struct it9135_dev_ctx *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	error = it9135_drv_ir_table_download(dev);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_reset_pid(struct it9135_dev_ctx *dev,
> +				  unsigned char chip)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	/* Reset and Clear pidTable */
> +	error = it9135_reset_pid(&dev->data, chip);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_add_pid(struct it9135_dev_ctx *dev, unsigned char chip,
> +				unsigned char index, unsigned short pid)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	deb_func("Enter %s Function - index: %d, pid: %x\n", __func__, index,
> +		 pid);
> +
> +	error = it9135_add_pid_filter(&dev->data, chip, index, pid);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_remove_pid(struct it9135_dev_ctx *dev,
> +				   unsigned char chip, unsigned char index,
> +				   unsigned short pid)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	deb_func("Enter %s Function - index: %d, pid: %x\n", __func__, index,
> +		 pid);
> +
> +	error = it9135_remove_pid_at(&dev->data, chip, index, pid);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_pid_on_off(struct it9135_dev_ctx *dev,
> +				   unsigned char chip, int onoff)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char ctrl = 0;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	deb_func("Enter %s Function - onoff: %d\n ", __func__, onoff);
> +
> +	if (onoff)
> +		ctrl = 1;
> +	else
> +		ctrl = 0;
> +
> +	error = it9135_ctrl_pid_filter(&dev->data, chip, 0);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_ap_ctrl(struct it9135_dev_ctx *dev, unsigned char chip,
> +				int onoff)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	deb_func("Enter %s Function\n", __func__);
> +	deb_info("chip = %d, onoff = %s\n", chip, onoff ? "ON" : "OFF");
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	error = it9135_drv_ap_ctrl(dev, chip, onoff);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_ap_reset(struct it9135_dev_ctx *dev, unsigned char chip,
> +				 int on)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	error = it9135_drv_ap_reset(dev, chip, on);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_tuner_set_freq_bw(struct it9135_dev_ctx *dev,
> +					  unsigned char chip,
> +					  unsigned long freq, unsigned short bw)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	if (dev->fc[chip].desired_freq != freq
> +	    || dev->fc[chip].desired_bw != bw * 1000)
> +		error = it9135_drv_set_freq_bw(dev, chip, freq, bw);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_set_architecture(struct it9135_dev_ctx *dev,
> +					 unsigned char architecture)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	deb_func("Enter %s Function\n", __func__);
> +	error = it9135_set_arch(&dev->data, architecture);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_is_locked(struct it9135_dev_ctx *dev,
> +				  unsigned char chip, int *locked)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	error = it9135_drv_is_locked(dev, chip, locked);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_get_signal_strength(struct it9135_dev_ctx *dev,
> +					    unsigned char chip,
> +					    unsigned char *strength)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	error = it9135_get_strength(&dev->data, chip, strength);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_get_signal_strength_Dbm(struct it9135_dev_ctx *dev,
> +						unsigned char chip,
> +						long *strength_dbm)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	error = it9135_get_strength_dbm(&dev->data, chip, strength_dbm);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_get_channel_statistic(struct it9135_dev_ctx *dev,
> +					      unsigned char chip,
> +					      struct it9135_ch_statistic
> +					      *ch_statistic)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	error = it9135_get_ch_statistic(&dev->data, chip, ch_statistic);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_get_channel_modulation(struct it9135_dev_ctx *dev,
> +					       unsigned char chip,
> +					       struct it9135_ch_modulation
> +					       *ch_modulation)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	error = it9135_get_ch_modulation(&dev->data, chip, ch_modulation);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_get_snr(struct it9135_dev_ctx *dev,
> +				unsigned char chip,
> +				unsigned char *constellation,
> +				unsigned char *snr)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	error = it9135_get_snr(&dev->data, chip, snr);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_reboot(struct it9135_dev_ctx *dev)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	error = it9135_dev_reboot(&dev->data);
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +unsigned long it9135_dl_read_raw_ir(struct it9135_dev_ctx *dev,
> +				    unsigned long *read_buff)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	mutex_lock(&dev->it9135_mutex);
> +
> +	if (dev->proprietary_ir)
> +		error = it9135_get_ir_code(&dev->data, read_buff);
> +	else
> +		deb_warning("RAWIr can't be used!!\n");
> +
> +	mutex_unlock(&dev->it9135_mutex);
> +
> +	return error;
> +}
> +
> +/* Set device driver init */
> +unsigned long it9135_device_init(struct usb_device *udev,
> +				 struct it9135_dev_ctx *dev, int boot)
> +{
> +	unsigned long error = ERROR_NO_ERROR;
> +	int err_cnt = 0;
> +	int i;
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	dev_set_drvdata(&udev->dev, dev);
> +
> +	info("=========================================");
> +	info("DRIVER_RELEASE_VERSION:    %s", DRIVER_RELEASE_VERSION);
> +	info("FW_RELEASE_VERSION:        %s", dev->fw_ver);
> +	info("API_RELEASE_VERSION:       %X.%X.%X", IT9135_API_VER_NUM,
> +	     IT9135_API_DATE, IT9135_API_BUILD);
> +	info("=========================================");
> +
> +#ifdef DVB_USB_ADAP_NEED_PID_FILTER
> +	deb_info("DVB_USB_ADAP_NEED_PID_FILTERING\n");
> +#else
> +	deb_info("DVB_USB_ADAP_NOT_NEED_PID_FILTERING\n");
> +#endif
> +
> +	/************* Set Device init Info *************/
> +	dev->enter_suspend = 0;
> +	dev->surprise_removal = 0;
> +	dev->dev_not_resp = 0;
> +	dev->selective_suspend = 0;
> +	dev->tuner_pw_off = 0;
> +	dev->already_nim_reset_seq = 0;
> +
> +	if (boot) {
> +		dev->data.chip_num = 1;
> +		dev->architecture = ARCHITECTURE_DCA;
> +		dev->data.frequency[0] = 666000;
> +		dev->data.bandwidth[0] = 8000;
> +		dev->ir_tab_load = 0;
> +		dev->fc[0].tuner_info.id = 0;
> +		dev->fc[1].tuner_info.id = 0;
> +		dev->fc[0].timer_on = 0;
> +		dev->fc[1].timer_on = 0;
> +		dev->dual_ts = 0;
> +		dev->filter_cnt = 0;
> +		dev->filter_index = 0;
> +		dev->stream_type = STREAM_TYPE_DVBT_DATAGRAM;
> +		dev->usb_ctrl_timeOut = 1;
> +		dev->disconnect = 0;
> +		if (udev->speed == USB_SPEED_FULL)
> +			dev->max_packet_sz = 0x0110;
> +		else
> +			dev->max_packet_sz = 0x0200;
> +	} else {
> +		dev->usb_ctrl_timeOut = 5;
> +	}
> +
> +	error = it9135_dl_dummy_cmd(dev);
> +
> +	if (boot) {
> +		/************* Set USB Info *************/
> +		dev->usb_mode = (dev->max_packet_sz == 0x200) ? 0x0200 : 0x0110;
> +		deb_info("USB mode = 0x%x\n", dev->usb_mode);
> +
> +		dev->ts_packet_cnt =
> +		    (dev->usb_mode ==
> +		     0x200) ? IT9135_TS_PACKET_COUNT_HI :
> +		    IT9135_TS_PACKET_COUNT_FU;
> +		dev->ts_frames =
> +		    (dev->usb_mode ==
> +		     0x200) ? IT9135_TS_FRAMES_HI : IT9135_TS_FRAMES_FU;
> +		dev->ts_frame_sz = IT9135_TS_PACKET_SIZE * dev->ts_packet_cnt;
> +		dev->ts_frame_sz_dw = dev->ts_frame_sz / 4;
> +	}
> +	dev->ep12_err = 0;
> +	dev->ep45_err = 0;
> +	dev->active_filter = 0;
> +
> +	if (boot) {
> +		error =
> +		    it9135_dl_set_bus_tuner(dev, IT9135_BUS_USB20,
> +					    IT9135_TUNER_ID);
> +		if (error) {
> +			err("First it9135_dl_set_bus_tuner fail : 0x%08lx",
> +			    (long unsigned int)error);
> +			err_cnt++;
> +			goto Exit;
> +		}
> +
> +		error = it9135_dl_get_eeprom_config(dev);
> +		if (error) {
> +			err("it9135_dl_get_eeprom_config fail : 0x%08lx",
> +			    (long unsigned int)error);
> +			err_cnt++;
> +			goto Exit;
> +		}
> +	}
> +
> +	error =
> +	    it9135_dl_set_bus_tuner(dev, IT9135_BUS_USB20,
> +				    dev->fc[0].tuner_info.id);
> +	if (error) {
> +		err("it9135_dl_set_bus_tuner fail!");
> +		err_cnt++;
> +		goto Exit;
> +	}
> +
> +	if (dev->data.chip_num == 2 && !dev->data.booted) {	/* plug/cold-boot/S4 */
> +		error = it9135_dl_nim_reset(dev);
> +	} else if (dev->data.chip_num == 2 && dev->data.booted) {	/* warm-boot/(S1) */
> +		/* pwr on for init. */
> +		for (i = 0; i < dev->data.chip_num; i++)
> +			error = it9135_dl_ap_ctrl(dev, i, 1);
> +	} else if (dev->data.chip_num == 1 && dev->data.booted) {	/* warm-boot/(S1) */
> +		/* pwr on for init, but seems not necessary. */
> +		error = it9135_dl_ap_ctrl(dev, 0, 1);
> +	}
> +
> +	if (error)
> +		err("it9135_dl_nim_reset or dl_nim_suspend fail!");
> +
> +	error = it9135_dl_initialize(dev);
> +	if (error) {
> +		err("it9135_dl_initialize fail! 0x%08lx",
> +		    (long unsigned int)error);
> +		err_cnt++;
> +		goto Exit;
> +	}
> +
> +	if (dev->ir_tab_load) {
> +		error = it9135_dl_ir_table_download(dev);
> +		if (error) {
> +			err("it9135_dl_ir_table_download fail");
> +			err_cnt++;
> +		}
> +	}
> +
> +	if (dev->data.chip_num == 2) {
> +		error = it9135_dl_init_nim_suspend_regs(dev);
> +		if (error)
> +			err("it9135_dl_init_nim_suspend_regs fail!");
> +	}
> +
> +	for (i = dev->data.chip_num; i > 0; i--) {
> +		error = it9135_dl_ap_ctrl(dev, (i - 1), 0);
> +		if (error)
> +			err("%d: it9135_dl_ap_ctrl Fail!", i);
> +
> +	}
> +
> +	info("%s success!!", __func__);
> +
> +Exit:
> +	if (err_cnt)
> +		err("[Device_init] Error %d\n", err_cnt);
> +	return error;
> +}
> +
> +int dca_to_pip(struct it9135_dev_ctx *dev)
> +{
> +	dev->filter_index = dev->filter_cnt;
> +
> +	deb_info("dca_to_pip - %d\n", dev->filter_cnt);
> +
> +	if (dev->filter_cnt == 1) {
> +		/* Do nothing, stay in DCA. */
> +		it9135_dl_set_architecture(dev, ARCHITECTURE_DCA);
> +		mdelay(50);
> +	} else if (dev->filter_cnt == 2) {
> +		it9135_dl_set_architecture(dev, ARCHITECTURE_PIP);
> +		mdelay(50);
> +	}
> +
> +	return 0;
> +}
> +
> +int pip_to_dca(struct it9135_dev_ctx *dev)
> +{
> +	deb_info("pip_to_dca - %d, %d\n", dev->filter_cnt, dev->filter_index);
> +
> +	if (dev->filter_cnt == 1) {
> +		if (dev->filter_index == 0) {	/*Close filter 0. */
> +			dev->swap_filter = 1;
> +			it9135_dl_set_architecture(dev, ARCHITECTURE_DCA);
> +			it9135_dl_tuner_set_freq_bw(dev, 0,
> +						    dev->fc[1].curr_freq, 0);
> +			dev->swap_filter = 0;
> +		} else {	/* Close filter 1. */
> +
> +			it9135_dl_set_architecture(dev, ARCHITECTURE_DCA);
> +			it9135_dl_tuner_set_freq_bw(dev, 0,
> +						    dev->fc[0].curr_freq, 0);
> +		}
> +
> +		dev->fc[1].timer_on = 0;
> +		dev->fc[0].timer_on = 1;
> +	} else if (dev->filter_cnt == 0) {
> +		dev->fc[1].timer_on = 0;
> +		dev->fc[0].timer_on = 0;
> +	}
> +	return 0;
> +}
> +
> +/* IT9135 device tuner on init */
> +static int it9135_init(struct dvb_frontend *demod)
> +{
> +	struct it9135_dev_ctx *dev =
> +	    (struct it9135_dev_ctx *)demod->demodulator_priv;
> +	unsigned long error = ERROR_NO_ERROR;
> +	int i;
> +
> +	deb_func("Enter %s Function - chip=%d\n", __func__, demod->dvb->num);
> +
> +	if (dev->disconnect)
> +		return 0;
> +
> +	dev->filter_cnt++;
> +
> +	if (dev->dca_pip) {
> +		for (i = 0; i < dev->data.chip_num; i++)
> +			error = it9135_dl_ap_ctrl(dev, i, 1);
> +
> +		error = dca_to_pip(dev);
> +	}
> +
> +	if (error)
> +		return -EREMOTEIO;
> +
> +	if ((dev->architecture == ARCHITECTURE_PIP) && (dev->filter_cnt == 2)) {
> +		/* Do nothging, MODE = DCA+PIP, because 2 tuners have turn on from DCA. */
> +	} else if (dev->architecture == ARCHITECTURE_DCA) {	/* Single or DCA */
> +		for (i = 0; i < dev->data.chip_num; i++)
> +			error = it9135_dl_ap_ctrl(dev, i, 1);
> +	} else {
> +		/* PIP */
> +		/* pwr on 2 chips directly; */
> +		for (i = 0; i < dev->data.chip_num; i++)
> +			error = it9135_dl_ap_ctrl(dev, i, 1);
> +	}
> +
> +	if (error)
> +		return -EREMOTEIO;
> +
> +	dev->fc[demod->dvb->num].timer_on = 1;
> +
> +	return 0;
> +}
> +
> +/* IT9135 device tuner off sleep */
> +static int it9135_sleep(struct dvb_frontend *demod)
> +{
> +	struct it9135_dev_ctx *dev =
> +	    (struct it9135_dev_ctx *)demod->demodulator_priv;
> +	unsigned long error = ERROR_NO_ERROR;
> +	int i;
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	if (dev->disconnect)
> +		return 0;
> +
> +	dev->filter_cnt--;
> +	dev->fc[demod->dvb->num].timer_on = 0;
> +
> +	if (dev->dca_pip)
> +		error = pip_to_dca(dev);
> +
> +	if (dev->filter_cnt == 1) {
> +		/* Do nothing, Mode = DCA+PIP, because from PIP to DCA */
> +		deb_info("ARCHITECTURE_DCA - %d\n", dev->filter_cnt);
> +	} else {		/* Single or DCA */
> +		deb_info("ARCHITECTURE_DCA2 - %d\n", dev->filter_cnt);
> +
> +		for (i = dev->data.chip_num; i > 0; i--)
> +			error = it9135_dl_ap_reset(dev, i - 1, 0);
> +
> +	}
> +
> +	if (error)
> +		return -EREMOTEIO;
> +
> +	return 0;
> +}
> +
> +static int it9135_get_frontend(struct dvb_frontend *fe,
> +			       struct dvb_frontend_parameters *fep)
> +{
> +	struct it9135_dev_ctx *dev =
> +	    (struct it9135_dev_ctx *)fe->demodulator_priv;
> +
> +	if (dev->data.chip_num != 2)
> +		deb_func("Enter %s Function\n", __func__);
> +	else
> +		deb_func("Enter %s Function - chip=%d\n", __func__,
> +			 fe->dvb->num);
> +
> +	fep->inversion = INVERSION_AUTO;
> +	return 0;
> +}
> +
> +/* Set OFDM bandwidth and tuner frequency */
> +static int it9135_set_frontend(struct dvb_frontend *fe,
> +			       struct dvb_frontend_parameters *fep)
> +{
> +	struct it9135_dev_ctx *dev =
> +	    (struct it9135_dev_ctx *)fe->demodulator_priv;
> +	struct it9135_ofdm_channel ch;
> +	unsigned long error = ERROR_NO_ERROR;
> +
> +	ch.rf_khz = 0;
> +	ch.bw = 0;
> +
> +	if (dev->disconnect)
> +		return 0;
> +
> +	if (dev->data.chip_num != 2)
> +		deb_func("Enter %s Function\n", __func__);
> +	else
> +		deb_func("Enter %s Function - chip=%d RF=%d, BW=%d\n", __func__,
> +			 fe->dvb->num, ch.rf_khz, ch.bw);
> +
> +	if (fep->u.ofdm.bandwidth == 0)
> +		fep->u.ofdm.bandwidth = 8;
> +	if (fep->u.ofdm.bandwidth == 1)
> +		fep->u.ofdm.bandwidth = 7;
> +	if (fep->u.ofdm.bandwidth == 2)
> +		fep->u.ofdm.bandwidth = 6;
> +
> +	ch.rf_khz = fep->frequency / 1000;
> +	ch.bw = fep->u.ofdm.bandwidth;
> +
> +	if (ch.rf_khz < 177000 || ch.rf_khz > 8585000)
> +		ch.rf_khz = 950000;
> +
> +	if (dev->data.chip_num != 2)
> +		error = it9135_dl_tuner_set_freq_bw(dev, 0, ch.rf_khz, ch.bw);
> +	else
> +		error =
> +		    it9135_dl_tuner_set_freq_bw(dev, fe->dvb->num, ch.rf_khz,
> +						ch.bw);
> +
> +	if (error)
> +		err("it9135_set_frontend return error");
> +
> +	return 0;
> +}
> +
> +/* Tuner signal lock frequency */
> +static int it9135_read_status(struct dvb_frontend *fe, fe_status_t * stat)
> +{
> +	struct it9135_dev_ctx *dev =
> +	    (struct it9135_dev_ctx *)fe->demodulator_priv;
> +	unsigned long error = ERROR_NO_ERROR;
> +	int locked;
> +
> +	if (dev->disconnect)
> +		return 0;
> +
> +	*stat = 0;
> +
> +	if (dev->data.chip_num != 2)
> +		error = it9135_dl_is_locked(dev, 0, &locked);
> +	else
> +		error = it9135_dl_is_locked(dev, fe->dvb->num, &locked);
> +
> +	if (error)
> +		return 0;
> +
> +	if (locked) {
> +		/* It's seems ok that always return lock to AP */
> +		*stat |= FE_HAS_SIGNAL;
> +		*stat |= FE_HAS_CARRIER;
> +		*stat |= FE_HAS_LOCK;
> +		*stat |= FE_HAS_VITERBI;
> +		*stat |= FE_HAS_SYNC;
> +	} else
> +		*stat |= FE_TIMEDOUT;
> +
> +	return 0;
> +}
> +
> +/* Get it9135_ch_statistic and calculate ber value */
> +static int it9135_read_ber(struct dvb_frontend *fe, u32 * ber)
> +{
> +	struct it9135_dev_ctx *dev =
> +	    (struct it9135_dev_ctx *)fe->demodulator_priv;
> +	unsigned long error = ERROR_NO_ERROR;
> +	struct it9135_ch_statistic ch_statistic;
> +
> +	if (dev->disconnect)
> +		return 0;
> +
> +	if (dev->data.chip_num != 2)
> +		error = it9135_dl_get_channel_statistic(dev, 0, &ch_statistic);
> +	else
> +		error =
> +		    it9135_dl_get_channel_statistic(dev, fe->dvb->num,
> +						    &ch_statistic);
> +	if (error)
> +		return error;
> +
> +	deb_info
> +	    ("it9135_read_ber post_vit_err_cnt: %ld, post_vitbit_cnt: %ld\n",
> +	     (long int)ch_statistic.post_vit_err_cnt,
> +	     (long int)ch_statistic.post_vitbit_cnt);
> +
> +	*ber =
> +	    ch_statistic.post_vit_err_cnt * (0xFFFFFFFF /
> +					     ch_statistic.post_vitbit_cnt);
> +
> +	return 0;
> +}
> +
> +/* Calculate SNR value */
> +static int it9135_read_snr(struct dvb_frontend *fe, u16 * snr)
> +{
> +	struct it9135_dev_ctx *dev =
> +	    (struct it9135_dev_ctx *)fe->demodulator_priv;
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char constellation;
> +	unsigned char SignalSnr = 0;
> +
> +	if (dev->disconnect)
> +		return 0;
> +
> +	if (dev->data.chip_num != 2)
> +		error = it9135_dl_get_snr(dev, 0, &constellation, &SignalSnr);
> +	else
> +		error =
> +		    it9135_dl_get_snr(dev, fe->dvb->num, &constellation,
> +				      &SignalSnr);
> +	if (error)
> +		return error;
> +
> +	deb_info("it9135_read_snr constellation: %d, SignalSnr: %d\n",
> +		 constellation, SignalSnr);
> +
> +	if (constellation == 0) {
> +		*snr = (u16)SignalSnr * (0xFFFF / 23);
> +	} else if (constellation == 1) {
> +		*snr = (u16)SignalSnr * (0xFFFF / 26);
> +	} else if (constellation == 2) {
> +		*snr = (u16)SignalSnr * (0xFFFF / 29);
> +	} else {
> +		deb_warning("Get constellation is failed!\n");
> +	}
> +
> +	return 0;
> +}
> +
> +static int it9135_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
> +{
> +	*unc = 0;
> +	return 0;
> +}
> +
> +/* Read signal strength and calculate strength value */
> +static int it9135_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
> +{
> +	struct it9135_dev_ctx *dev =
> +	    (struct it9135_dev_ctx *)fe->demodulator_priv;
> +	unsigned long error = ERROR_NO_ERROR;
> +	unsigned char st = 0;
> +
> +	if (dev->disconnect)
> +		return 0;
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	if (dev->data.chip_num != 2)
> +		error = it9135_dl_get_signal_strength(dev, 0, &st);
> +	else
> +		error = it9135_dl_get_signal_strength(dev, fe->dvb->num, &st);
> +	if (error)
> +		return error;
> +
> +	deb_info("%s is %d\n", __func__, st);
> +	*strength = (u16)st * (0xFFFF / 100);
> +
> +	return 0;
> +}
> +
> +static void it9135_release(struct dvb_frontend *fe)
> +{
> +	deb_func("%s:\n", __func__);
> +	kfree(fe);
> +}
> +
> +static struct dvb_frontend_ops it9135_ops;
> +struct dvb_frontend *it9135_attach(struct dvb_usb_adapter *adap)
> +{
> +	struct dvb_frontend *frontend;
> +	struct it9135_dev_ctx *dev = dev_get_drvdata(&adap->dev->udev->dev);
> +
> +	frontend = kzalloc(sizeof(*frontend), GFP_KERNEL);
> +	if (frontend == NULL)
> +		goto error;
> +
> +	frontend->demodulator_priv = dev;
> +	memcpy(&frontend->ops, &it9135_ops, sizeof(it9135_ops));
> +
> +	return frontend;
> +
> +error:
> +	kfree(frontend);
> +	return NULL;
> +}
> +
> +static struct dvb_frontend_ops it9135_ops = {
> +	.info = {
> +		 .name = "IT9135 USB DVB-T",
> +		 .type = FE_OFDM,
> +		 .frequency_min = 44250000,
> +		 .frequency_max = 867250000,
> +		 .frequency_stepsize = 62500,
> +		 .caps = FE_CAN_INVERSION_AUTO |
> +		 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
> +		 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
> +		 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
> +		 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
> +		 FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
> +		 },
> +
> +	.release = it9135_release,
> +
> +	.init = it9135_init,
> +	.sleep = it9135_sleep,
> +
> +	.set_frontend = it9135_set_frontend,
> +	.get_frontend = it9135_get_frontend,
> +
> +	.read_status = it9135_read_status,
> +	.read_ber = it9135_read_ber,
> +	.read_signal_strength = it9135_read_signal_strength,
> +	.read_snr = it9135_read_snr,
> +	.read_ucblocks = it9135_read_unc_blocks,
> +};
> +
> +/* -------------------------------------------------------------------------- */
> +
> +/*
> + * init it9135 properties
> + */
> +
> +static int it9135_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
> +{
> +	struct it9135_dev_ctx *dev =
> +	    (struct it9135_dev_ctx *)adap->fe->demodulator_priv;
> +	int ret = 0;
> +
> +	deb_info("%s: onoff:%d\n", __func__, onoff);
> +
> +	if (!onoff) {
> +		deb_info("Reset PID Table\n");
> +
> +		if (dev->data.chip_num != 2)
> +			it9135_dl_reset_pid(dev, 0);
> +		else
> +			it9135_dl_reset_pid(dev, (unsigned char)adap->id);
> +	}
> +
> +	dev->fc[adap->id].en_pid = onoff;
> +
> +	if (dev->data.chip_num != 2)
> +		ret = it9135_dl_pid_on_off(dev, 0, dev->fc[adap->id].en_pid);
> +	else
> +		ret =
> +		    it9135_dl_pid_on_off(dev, (unsigned char)adap->id,
> +					 dev->fc[adap->id].en_pid);
> +
> +	deb_info("Set pid onoff ok\n");
> +
> +	return ret;
> +}
> +
> +static int it9135_pid_filter(struct dvb_usb_adapter *adap, int index,
> +			     u16 pidnum, int onoff)
> +{
> +	struct it9135_dev_ctx *dev =
> +	    (struct it9135_dev_ctx *)adap->fe->demodulator_priv;
> +	unsigned short pid;
> +	int ret = 0;
> +
> +	deb_info
> +	    ("%s: set pid filter, feedcount %d, index %d, pid %x, onoff %d.\n",
> +	     __func__, adap->feedcount, index, pidnum, onoff);
> +
> +	if (onoff) {
> +		/* Cannot use it as pid_filter_ctrl since it has to be done before setting the first pid */
> +		if (adap->feedcount == 1) {
> +			deb_info("first pid set, enable pid table\n");
> +			ret = it9135_pid_filter_ctrl(adap, onoff);
> +			if (ret)
> +				return ret;
> +		}
> +
> +		pid = (unsigned short)pidnum;
> +		if (dev->data.chip_num != 2)
> +			ret = it9135_dl_add_pid(dev, 0, index, pid);
> +		else
> +			ret =
> +			    it9135_dl_add_pid(dev, (unsigned char)adap->id,
> +					      index, pid);
> +		if (ret)
> +			return ret;
> +	} else {
> +		pid = (unsigned short)pidnum;
> +		if (dev->data.chip_num != 2)
> +			ret = it9135_dl_remove_pid(dev, 0, index, pid);
> +		else
> +			ret =
> +			    it9135_dl_remove_pid(dev, (unsigned char)adap->id,
> +						 index, pid);
> +		if (ret)
> +			return ret;
> +
> +		if (adap->feedcount == 0) {
> +			deb_info("last pid unset, disable pid table\n");
> +			ret = it9135_pid_filter_ctrl(adap, onoff);
> +			if (ret)
> +				return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +struct it9135_val_set *script_parser(const struct firmware *fw,
> +				     int *fw_file_pos, u16 * script_sets)
> +{
> +	int pos = *fw_file_pos;
> +	struct it9135_val_set *scripts_temp = NULL;
> +	int j = 0;
> +	int i = 0;
> +
> +	/* fw_file_pos+0 ~ +3 == VERSION1 VERSION2 VERSION3 VERSION4 */
> +	pos += 4;
> +
> +	/* OMEGA_ADDRESS */
> +	pos += 1;
> +
> +	/* OMEGA_SCRIPTSETLENGTH */
> +	if (fw->data[pos] != 1) {
> +		err("OMEGA_SCRIPTSETLENGTH != 1 !!");
> +		return NULL;
> +	}
> +	pos += 4;
> +
> +	/* scriptSets */
> +	*script_sets = fw->data[pos] + (fw->data[pos + 1] << 8);
> +	pos += 2;
> +
> +	/* OMEGA_LNA_Config_2_scripts */
> +	scripts_temp =
> +	    kzalloc((*script_sets) * sizeof(*scripts_temp), GFP_KERNEL);
> +	for (i = 0; i < (*script_sets); i++) {
> +		scripts_temp[i].address = fw->data[pos + j] +
> +		    (fw->data[pos + j + 1] << 8) +
> +		    (fw->data[pos + j + 2] << 16) +
> +		    (fw->data[pos + j + 3] << 24);
> +
> +		scripts_temp[i].value = fw->data[pos + j + 4];
> +		j += 5;
> +	}
> +
> +	pos += j;
> +	*fw_file_pos = pos;
> +
> +	return scripts_temp;
> +}
> +
> +static int it9135_download_firmware(struct usb_device *udev,
> +				    const struct firmware *fw)
> +{
> +	int retval = -ENOMEM;
> +	struct it9135_dev_ctx *dev = NULL;
> +	struct it9135_segment *segs = NULL;
> +	u8 *fw_codes;
> +	u16 *script_sets;
> +	struct it9135_val_set *scripts = NULL;
> +	int fw_file_pos = 0;
> +	unsigned int fw_code_len = 0;
> +	unsigned char var[2];
> +	u32 fw_script_len_v1 = 0;
> +	u32 fw_script_len_v2 = 0;
> +	u32 partition_len_v1 = 0;
> +	u32 partition_len_v2 = 0;
> +	int chip_v2 = 0;
> +	int i = 0;
> +	int j = 0;
> +
> +	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> +	if (dev == NULL) {
> +		err("Alloc dev out of memory");
> +		return -ENOTTY;
> +	}
> +
> +	/* init mutex */
> +	mutex_init(&dev->it9135_mutex);
> +	dev->data.it9135_fw = fw;
> +
> +	dev->data.driver = (void *)udev;
> +
> +	/* check device chip version */
> +	retval =
> +	    it9135_read_reg(&dev->data, 0, PROCESSOR_LINK, chip_version_7_0,
> +			    &dev->data.chip_ver);
> +	retval =
> +	    it9135_read_regs(&dev->data, 0, PROCESSOR_LINK,
> +			     chip_version_7_0 + 1, 2, var);
> +	if (retval)
> +		info("Cannot read chip version");
> +
> +	dev->data.chip_type = var[1] << 8 | var[0];
> +
> +	if ((dev->data.chip_type == 0x9135) && (dev->data.chip_ver == 2)) {
> +		chip_v2 = 1;
> +		info("This is IT9135 chip v2");
> +	} else {
> +		info("This is IT9135 chip v1");
> +	}
> +
> +	/* byte 0~7 = OMEGA1 */
> +	if ((fw->data[0] != 'I') || (fw->data[1] != 'T') || (fw->data[2] != '9')
> +	    || (fw->data[3] != '1') || (fw->data[4] != '3')
> +	    || (fw->data[5] != '5') || (fw->data[6] != 'A')
> +	    || (fw->data[7] != 'X')) {
> +		err("IT9135 chip v1 FW format Error");
> +		return -ENOENT;
> +	}
> +	fw_file_pos += 8;
> +
> +	/* byte 8~11 = OMEGA1 fw & script length */
> +	fw_script_len_v1 =
> +	    (fw->data[fw_file_pos]) + (fw->data[fw_file_pos + 1] << 8) +
> +	    (fw->data[fw_file_pos + 2] << 16) +
> +	    (fw->data[fw_file_pos + 3] << 24);
> +	fw_file_pos += 4;
> +	partition_len_v1 = 8 + 4 + fw_script_len_v1;
> +
> +	if (chip_v2) {
> +		fw_file_pos += fw_script_len_v1;
> +		if ((fw->data[fw_file_pos] != 'I')
> +		    || (fw->data[fw_file_pos + 1] != 'T')
> +		    || (fw->data[fw_file_pos + 2] != '9')
> +		    || (fw->data[fw_file_pos + 3] != '1')
> +		    || (fw->data[fw_file_pos + 4] != '3')
> +		    || (fw->data[fw_file_pos + 5] != '5')
> +		    || (fw->data[fw_file_pos + 6] != 'B')
> +		    || (fw->data[fw_file_pos + 7] != 'X')) {
> +			err("IT9135 chip v2 FW format Error");
> +			return -ENOENT;
> +		}
> +		fw_file_pos += 8;
> +
> +		fw_script_len_v2 =
> +		    (fw->data[fw_file_pos]) + (fw->data[fw_file_pos + 1] << 8) +
> +		    (fw->data[fw_file_pos + 2] << 16) +
> +		    (fw->data[fw_file_pos + 3] << 24);
> +		fw_file_pos += 4;
> +
> +		partition_len_v2 = 8 + 4 + fw_script_len_v2;
> +
> +		if (fw->size != (partition_len_v1 + partition_len_v2)) {
> +			err("FW file size error!!");
> +			return -ENOENT;
> +		}
> +	}
> +
> +	/* 32 byte Fw version */
> +	for (i = 0; i < 32; i++)
> +		dev->fw_ver[i] = fw->data[fw_file_pos + i];
> +
> +	dev->fw_ver[31] = '\0';
> +	fw_file_pos += 32;
> +
> +	/*------------------------ Parsing Firmware ------------------------*/
> +
> +	/* byte fw_file_pos+0 ~ +7 = OFDM & LINK version */
> +	dev->link_ver =
> +	    (fw->data[fw_file_pos] << 24) + (fw->data[fw_file_pos + 1] << 16) +
> +	    (fw->data[fw_file_pos + 2] << 8) + (fw->data[fw_file_pos + 3]);
> +	fw_file_pos += 4;
> +
> +	dev->ofdm_ver =
> +	    (fw->data[fw_file_pos] << 24) + (fw->data[fw_file_pos + 1] << 16) +
> +	    (fw->data[fw_file_pos + 2] << 8) + (fw->data[fw_file_pos + 3]);
> +	fw_file_pos += 4;
> +
> +	deb_info("@@@@@@@@@@@@@ Omega 1or2_OFDM ver = 0x%x, LINK ver = 0x%x",
> +		 (unsigned int)dev->link_ver, (unsigned int)dev->ofdm_ver);
> +
> +	/* byte fw_file_pos+0 ~ +3 = FirmwareV2_CODELENGTH */
> +	fw_code_len = fw->data[fw_file_pos] + (fw->data[fw_file_pos + 1] << 8) +
> +	    (fw->data[fw_file_pos + 2] << 16) +
> +	    (fw->data[fw_file_pos + 3] << 24);
> +
> +	fw_file_pos += 4;
> +	/* byte fw_file_pos+0 ~ +3 = FirmwareV2_SEGMENTLENGTH, only first one byte has value */
> +	dev->data.fw_parts = fw->data[fw_file_pos];
> +	fw_file_pos += 4;
> +
> +	/* byte fw_file_pos+0 ~ +3 = FirmwareV2_PARTITIONLENGTH */
> +	if (fw->data[fw_file_pos] != 1) {
> +		err("FirmwareV2_PARTITIONLENGTH != 1 !!");
> +		return -EPERM;
> +	}
> +	fw_file_pos += 4;
> +
> +	/* byte fw_file_pos+0 ~ +(fw_code_len-1) == Fw code */
> +	fw_codes = kzalloc(fw_code_len * sizeof(*fw_codes), GFP_KERNEL);
> +	for (i = 0; i < fw_code_len; i++) {
> +		fw_codes[i] = (unsigned char)fw->data[fw_file_pos + i];
> +	}	
> +	dev->data.fw_codes = fw_codes;
> +
> +	fw_file_pos += fw_code_len;
> +
> +	/* FirmwareV2_segments */
> +	segs = kzalloc(dev->data.fw_parts * sizeof(*segs), GFP_KERNEL);
> +	for (i = 0; i < dev->data.fw_parts; i++) {
> +		segs[i].type = fw->data[fw_file_pos + j];
> +		segs[i].length =
> +		    fw->data[fw_file_pos + j + 1] +
> +		    (fw->data[fw_file_pos + j + 2] << 8) +
> +		    (fw->data[fw_file_pos + j + 3] << 16) +
> +		    (fw->data[fw_file_pos + j + 4] << 24);
> +		j += 5;
> +	}
> +	dev->data.fw_segs = segs;
> +
> +	fw_file_pos += j;
> +
> +	/* FirmwareV2_partitions */
> +	if (dev->data.fw_parts != fw->data[fw_file_pos]) {
> +		err("FirmwareV2_SEGMENTLENGTH != FirmwareV2_partitions[0], parsing error!!!");
> +		return -EPERM;
> +	}
> +
> +	fw_file_pos += 1;
> +
> +	/* FirmwareV2_SCRIPTSETLENGTH == 1 */
> +	if (fw->data[fw_file_pos] != 1) {
> +		err("FirmwareV2_SCRIPTSETLENGTH != 1 !!");
> +		return -EPERM;
> +	}
> +
> +	fw_file_pos += 4;
> +
> +	/* Word FirmwareV2_scriptSets */
> +	script_sets = kzalloc(sizeof(u16), GFP_KERNEL);
> +	*script_sets = fw->data[fw_file_pos] + (fw->data[fw_file_pos + 1] << 8);
> +	dev->data.script_sets = script_sets;
> +
> +	fw_file_pos += 2;
> +
> +	/* FirmwareV2_scripts */
> +	j = 0;
> +	scripts = kzalloc(*script_sets * sizeof(*scripts), GFP_KERNEL);
> +	for (i = 0; i < *script_sets; i++) {
> +		scripts[i].address = fw->data[fw_file_pos + j] +
> +		    (fw->data[fw_file_pos + j + 1] << 8) +
> +		    (fw->data[fw_file_pos + j + 2] << 16) +
> +		    (fw->data[fw_file_pos + j + 3] << 24);
> +
> +		scripts[i].value = fw->data[fw_file_pos + j + 4];
> +		j += 5;
> +	}
> +
> +	dev->data.scripts = scripts;
> +	fw_file_pos += j;
> +
> +	if (chip_v2 && (fw_file_pos == fw->size)) {
> +		info("FW file only include IT9135 v2 firmware");
> +		goto end_of_fw;
> +	} else if (!chip_v2 && (fw_file_pos == partition_len_v1)) {
> +		info("FW file only include IT9135 v1 firmware!");
> +		goto end_of_fw;
> +	}
> +
> +	/*--- Parsing Firmware_Afa_Omega_Script ---*/
> +
> +	dev->data.tuner_script_normal = script_parser(fw, &fw_file_pos,
> +						      &(dev->data.
> +							tuner_script_sets_normal));
> +
> +	if (dev->data.tuner_script_normal == NULL)
> +		return -EPERM;
> +
> +	if (chip_v2 && (fw_file_pos == fw->size)) {
> +		info("~~~ .Fw file only include Omega2 firmware&Omega_Script!!");
> +		goto end_of_fw;
> +	} else if (!chip_v2 && (fw_file_pos == partition_len_v1)) {
> +		info("~~~ .Fw file only include Omega1 firmware&Omega_Script!!");
> +		goto end_of_fw;
> +	}
> +
> +	/*--- Parsing Firmware_Afa_Omega_LNA_Config_1_Script ---*/
> +
> +	dev->data.tuner_script_lna1 =
> +	    script_parser(fw, &fw_file_pos,
> +			  &(dev->data.tuner_script_sets_lna1));
> +
> +	if (dev->data.tuner_script_lna1 == NULL)
> +		return -EPERM;
> +	if (chip_v2 && (fw_file_pos == fw->size)) {
> +		info("~~~ .Fw file only include Omega2 firmware Script1!!");
> +		goto end_of_fw;
> +	} else if (!chip_v2 && (fw_file_pos == partition_len_v1)) {
> +		info("~~~ .Fw file only include Omega1 firmware, Script1!!");
> +		goto end_of_fw;
> +	}
> +
> +	/*--- Parsing Firmware_Afa_Omega_LNA_Config_2_Script_V2 ---*/
> +	dev->data.tuner_script_lna2 =
> +	    script_parser(fw, &fw_file_pos,
> +			  &(dev->data.tuner_script_sets_lna2));
> +
> +	if (dev->data.tuner_script_lna2 == NULL)
> +		return -EPERM;
> +
> +	if (chip_v2 && (fw_file_pos == fw->size)) {
> +		info("~~~ .Fw file only include Omega2 firmware, Scripts1&2!!");
> +		goto end_of_fw;
> +	} else if (!chip_v2 && (fw_file_pos == partition_len_v1)) {
> +		info("~~~ .Fw file only include Omega1 firmware, Scripts1&2!!");
> +		goto end_of_fw;
> +	}
> +
> +end_of_fw:
> +
> +	/**** Init Device first ****/
> +	retval = it9135_device_init(udev, dev, true);
> +	if (retval) {
> +		if (retval)
> +			err("device_init Fail: 0x%08x\n", retval);
> +		return -ENOMEM;
> +	}
> +
> +	for (i = 0; i < it9135_device_count; i++) {
> +		if (dev->architecture == ARCHITECTURE_PIP) {
> +			deb_info("@@@@@@@ adapter == 2");


What does that "@@@@@@" mean?

> +			it9135_properties[i].num_adapters = 2;
> +			it9135_properties[i].caps = DVB_USB_IS_AN_I2C_ADAPTER;
> +		} else {
> +			deb_info("@@@@@@@ adapter == 1");
> +			it9135_properties[i].caps = 0;
> +			it9135_properties[i].num_adapters = 1;
> +		}
> +
> +		/* USB1.1 set smaller buffersize and disable 2nd adapter */
> +		if (udev->speed == USB_SPEED_FULL) {
> +			it9135_properties[i].adapter[0].stream.u.bulk.buffersize
> +			    = (188 * 21);
> +		} else {
> +			it9135_properties[i].adapter[0].stream.u.bulk.buffersize
> +			    = (188 * 348);
> +		}
> +
> +	}
> +
> +	return 0;
> +}
> +
> +static int it9135_power_ctrl(struct dvb_usb_device *d, int onoff)
> +{
> +	return 0;
> +}
> +
> +static int it9135_identify_state(struct usb_device *udev,
> +				 struct dvb_usb_device_properties *props,
> +				 struct dvb_usb_device_description **desc,
> +				 int *cold)
> +{
> +	/* *cold = 0; */
> +	return 0;
> +}
> +
> +static int it9135_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
> +			   int num)
> +{
> +	return 0;
> +}
> +
> +static u32 it9135_i2c_func(struct i2c_adapter *adapter)
> +{
> +	return I2C_FUNC_I2C;
> +}
> +
> +static struct i2c_algorithm it9135_i2c_algo = {
> +	.master_xfer = it9135_i2c_xfer,
> +	.functionality = it9135_i2c_func,
> +};
> +
> +/* Called to attach the possible frontends */
> +static int it9135_frontend_attach(struct dvb_usb_adapter *adap)
> +{
> +	deb_func("Enter %s Function - chip=%d\n", __func__, adap->id);
> +
> +	adap->fe = it9135_attach(adap);
> +
> +	return adap->fe == NULL ? -ENODEV : 0;
> +}
> +
> +static int it9135_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
> +{
> +	deb_func("Enter %s Function - (%s) streaming state for chip=%d\n",
> +		 __func__, onoff ? "ON" : "OFF", adap->id);
> +
> +	return 0;
> +}
> +
> +/* -------------------------------------------------------------------------- */
> +
> +/* ******* IT9135 DVB USB DEVICE ******* */
> +
> +/* Table of devices that work with this driver */
> +struct usb_device_id it9135_usb_id_table[] = {
> +	{USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135)},
> +	{USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005)},
> +	{USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006)},
> +	{0},			/* Terminating entry */
> +};
> +
> +MODULE_DEVICE_TABLE(usb, it9135_usb_id_table);
> +
> +struct dvb_usb_device_properties it9135_properties[] = {
> +	{
> +	 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
> +	 .download_firmware = it9135_download_firmware,
> +	 .firmware = "dvb-usb-it9135.fw",
> +
> +	 .size_of_priv = sizeof(struct it9135_state),
> +	 .i2c_algo = &it9135_i2c_algo,
> +
> +	 .usb_ctrl = DEVICE_SPECIFIC,
> +
> +	 .no_reconnect = 1,
> +	 .power_ctrl = it9135_power_ctrl,
> +	 .identify_state = it9135_identify_state,
> +	 .num_adapters = 2,
> +	 .adapter = {
> +		     {
> +		      .caps =
> +		      DVB_USB_ADAP_HAS_PID_FILTER |
> +		      DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
> +
> +		      .pid_filter_count = 32,
> +		      .pid_filter = it9135_pid_filter,
> +		      .pid_filter_ctrl = it9135_pid_filter_ctrl,
> +		      .frontend_attach = it9135_frontend_attach,
> +		      .streaming_ctrl = it9135_streaming_ctrl,
> +		      .stream = {
> +				 .type = USB_BULK,
> +				 .count = 4,
> +				 .endpoint = 0x84,
> +				 .u = {
> +				       .bulk = {
> +						.buffersize = (188 * 348),
> +						}
> +				       }
> +				 }
> +		      },
> +		     {
> +		      .caps =
> +		      DVB_USB_ADAP_HAS_PID_FILTER |
> +		      DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
> +
> +		      .pid_filter_count = 32,
> +		      .pid_filter = it9135_pid_filter,
> +		      .pid_filter_ctrl = it9135_pid_filter_ctrl,
> +		      .frontend_attach = it9135_frontend_attach,
> +		      .streaming_ctrl = it9135_streaming_ctrl,
> +		      .stream = {
> +				 .type = USB_BULK,
> +				 .count = 4,
> +				 .endpoint = 0x85,
> +				 .u = {
> +				       .bulk = {
> +						.buffersize = (188 * 348),
> +						}
> +				       }
> +				 }
> +		      },
> +		     },

Hmm... from the above code, it seems that remote controller is supported. However, I'm not seeing
it referenced here.

> +	 .num_device_descs = 1,
> +	 .devices = {
> +		     {"ITEtech USB2.0 DVB-T Recevier",
> +		      {&it9135_usb_id_table[0], &it9135_usb_id_table[1],
> +		       &it9135_usb_id_table[2], NULL},
> +		      {NULL},
> +		      },
> +		     {NULL},
> +
> +		     }
> +	 }
> +};
> +
> +int it9135_device_count = ARRAY_SIZE(it9135_properties);
> +
> +/* Register a DVB_USB device and a USB device node end */
> +static int it9135_probe(struct usb_interface *intf,
> +			const struct usb_device_id *id)
> +{
> +	int retval = -ENOMEM;
> +	int i;
> +	struct dvb_usb_device *d = NULL;
> +
> +	if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
> +
> +		if (it9135_device_count > 2)
> +			it9135_device_count = 2;
> +
> +		for (i = 0; i < it9135_device_count; i++) {
> +			retval =
> +			    dvb_usb_device_init(intf, &it9135_properties[i],
> +						THIS_MODULE, &d, adapter_nr);
> +
> +			if (!retval) {
> +				deb_info("dvb_usb_device_init success!!\n");
> +				break;
> +			}
> +			if (retval != -ENODEV)
> +				return retval;
> +		}
> +		if (retval)
> +			return retval;
> +	}
> +
> +	return retval;
> +}
> +
> +static int it9135_suspend(struct usb_interface *intf, pm_message_t state)
> +{
> +	deb_func("Enter %s Function\n", __func__);
> +	return 0;
> +}
> +
> +static int it9135_resume(struct usb_interface *intf)
> +{
> +	deb_func("Enter %s Function\n", __func__);
> +	return 0;
> +}
> +
> +static int it9135_reset_resume(struct usb_interface *intf)
> +{
> +	int retval = -ENOMEM;
> +	int i;
> +	struct it9135_dev_ctx *dev = NULL;
> +	struct usb_device *udev;
> +
> +	deb_func("Enter %s Function\n", __func__);
> +
> +	udev = interface_to_usbdev(intf);
> +	dev = dev_get_drvdata(&udev->dev);
> +
> +	retval = it9135_device_init(udev, dev, 1);
> +	if (retval) {
> +		if (retval)
> +			err("device_init Fail: 0x%08x", retval);
> +		return -ENOMEM;
> +	}
> +
> +	for (i = 0; i < dev->data.chip_num; i++)
> +		it9135_dl_ap_ctrl(dev, i, 1);
> +
> +	return 0;
> +}
> +
> +static void it9135_i2c_exit(struct dvb_usb_device *d)
> +{
> +	struct it9135_state *state = d->priv;
> +
> +	deb_func("%s:\n", __func__);
> +
> +	/* remove 2nd I2C adapter */
> +	if (d->state & DVB_USB_STATE_I2C) {
> +		try_module_get(THIS_MODULE);
> +		i2c_del_adapter(&state->i2c_adap);
> +	}
> +}
> +
> +static void it9135_disconnect(struct usb_interface *intf)
> +{
> +	struct it9135_dev_ctx *dev;
> +	struct usb_device *udev;
> +	int minor = intf->minor;
> +	struct dvb_usb_device *d = usb_get_intfdata(intf);
> +
> +	deb_func("%s:\n", __func__);
> +
> +	udev = interface_to_usbdev(intf);
> +	dev = dev_get_drvdata(&udev->dev);
> +	dev->disconnect = 1;
> +
> +	kfree(dev->data.script_sets);
> +	kfree(dev->data.scripts);
> +	kfree(dev->data.fw_codes);
> +	kfree(dev->data.fw_segs);
> +	kfree(dev->data.tuner_script_normal);
> +	kfree(dev->data.tuner_script_lna1);
> +	kfree(dev->data.tuner_script_lna2);
> +	kfree(dev);
> +
> +	/* remove 2nd I2C adapter */
> +	if (d != NULL && d->desc != NULL)
> +		it9135_i2c_exit(d);
> +
> +	try_module_get(THIS_MODULE);
> +	dvb_usb_device_exit(intf);
> +
> +	deb_info("ITEtech USB #%d now disconnected", minor);
> +}
> +
> +static struct usb_driver it9135_driver = {
> +	.name = "dvb_usb_it9135",
> +	.probe = it9135_probe,
> +	.disconnect = it9135_disconnect,
> +	.id_table = it9135_usb_id_table,
> +	.suspend = it9135_suspend,
> +	.resume = it9135_resume,
> +	.reset_resume = it9135_reset_resume,
> +};
> +
> +/* Insert it9135 module and prepare to register it9135 driver */
> +static int __init it9135_module_init(void)
> +{
> +	int ret;
> +
> +	deb_info("dvb_usb_it9135 Module is loaded\n");
> +
> +	ret = usb_register(&it9135_driver);
> +
> +	if (ret) {
> +		err("usb_register failed. Error number %d", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +/* Deregister this driver with the USB subsystem */
> +static void __exit it9135_module_exit(void)
> +{
> +	deb_info("dvb_usb_it9135 Module is unloaded!\n");
> +	usb_deregister(&it9135_driver);
> +}
> +
> +module_init(it9135_module_init);
> +module_exit(it9135_module_exit);
> +
> +MODULE_AUTHOR("Jason Dong <jason.dong@ite.com.tw>");
> +MODULE_DESCRIPTION("Driver for devices based on ITEtech IT9135");
> +MODULE_VERSION(DRIVER_RELEASE_VERSION);
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/media/dvb/dvb-usb/it9135.h b/drivers/media/dvb/dvb-usb/it9135.h
> new file mode 100644
> index 0000000..d1cf54c
> --- /dev/null
> +++ b/drivers/media/dvb/dvb-usb/it9135.h
> @@ -0,0 +1,155 @@
> +/*
> + * DVB USB Linux driver for IT9135 DVB-T USB2.0 receiver
> + *
> + * Copyright (C) 2011 ITE Technologies, INC.
> + *
> + *    This program is free software; you can redistribute it and/or modify
> + *    it under the terms of the GNU General Public License as published by
> + *    the Free Software Foundation; either version 2 of the License, or
> + *    (at your option) any later version.
> + */
> +
> +#ifndef _IT9135_H_
> +#define _IT9135_H_
> +
> +#define DVB_USB_LOG_PREFIX "IT9135"
> +
> +#include <linux/version.h>
> +
> +#include "dvb-usb.h"
> +#include "it9135-fe.h"
> +
> +#define DRIVER_RELEASE_VERSION	"v11.08.02.1"
> +/* **************** customization **************** */
> +extern int dvb_usb_it9135_debug;
> +
> +#ifdef CONFIG_DVB_USB_IT9135_DEBUG
> +#define deb_func(args...)	printk(KERN_INFO args)
> +#define deb_info(args...)	printk(KERN_INFO args)
> +#define deb_warning(args...)	printk(KERN_INFO args)
> +#define dmg(format, arg...)	printk(KERN_ERR DVB_USB_LOG_PREFIX "::" "%s: " format "\n" , __func__, ## arg)
> +#else
> +#define deb_func(args...)	dprintk(dvb_usb_it9135_debug, 0x01, args)
> +#define deb_info(args...)	dprintk(dvb_usb_it9135_debug, 0x02, args)
> +#define deb_warning(args...)	dprintk(dvb_usb_it9135_debug, 0x04, args)
> +#define dmg(format, arg...)	printk(KERN_ERR DVB_USB_LOG_PREFIX "::" "%s: " format "\n" , __func__, ## arg)
> +#endif
> +/* **************** from device.h **************** */
> +#define IT9135_TS_PACKET_SIZE		188
> +#define IT9135_TS_PACKET_COUNT_HI	348
> +#define IT9135_TS_PACKET_COUNT_FU	21
> +
> +/* **************** from driver.h **************** */
> +#define IT9135_TS_FRAMES_HI		128
> +#define IT9135_TS_FRAMES_FU		128
> +#define IT9135_MAX_USB20_IRP_NUM	5
> +#define IT9135_MAX_USB11_IRP_NUM	2
> +
> +/* **************** from afdrv.h **************** */
> +#define EEPROM_FLB_OFS		8
> +
> +#define EEPROM_IRMODE       (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x10)	/* 00:disabled, 01:HID */
> +#define EEPROM_SELSUSPEND   (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28)	/* Selective Suspend Mode */
> +#define EEPROM_TSMODE       (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+1)	/* 0:one ts, 1:dual ts */
> +#define EEPROM_2WIREADDR    (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+2)	/* MPEG2 2WireAddr */
> +#define EEPROM_SUSPEND      (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+3)	/* Suspend Mode */
> +#define EEPROM_IRTYPE       (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+4)	/* 0:NEC, 1:RC6 */
> +#define EEPROM_SAWBW1       (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+5)
> +#define EEPROM_XTAL1        (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+6)	/* 0:28800, 1:20480 */
> +#define EEPROM_SPECINV1     (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x28+7)
> +#define EEPROM_TUNERID      (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x30+4)
> +#define EEPROM_IFFREQL      (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x30)
> +#define EEPROM_IFFREQH      (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x30+1)
> +#define EEPROM_IF1L         (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x30+2)
> +#define EEPROM_IF1H         (OVA_EEPROM_CFG+EEPROM_FLB_OFS+0x30+3)
> +#define EEPROM_SHIFT        (0x10)	/* EEPROM Addr Shift for slave front end */
> +
> +/* **************** from device.h **************** */
> +struct it9135_state {
> +	struct i2c_adapter i2c_adap;	/* I2C adapter for 2nd FE */
> +	u8 rc_repeat;
> +	u32 rc_keycode;
> +};
> +
> +struct it9135_tuner_info {
> +	int inited;
> +	int setting_freq;
> +	unsigned short id;
> +	int set;
> +	int locked;
> +};
> +
> +struct it9135_filter_ctx_hw {
> +	struct it9135_tuner_info tuner_info;
> +	unsigned long curr_freq;
> +	unsigned short curr_bw;
> +	unsigned long desired_freq;
> +	unsigned short desired_bw;
> +	int timer_on;
> +	int en_pid;
> +	int ap_on;
> +	int reset_ts;
> +	unsigned char ovr_flw_chk;
> +};
> +
> +/* IT9135 device context */
> +struct it9135_dev_ctx {
> +	struct it9135_filter_ctx_hw fc[2];
> +	struct mutex it9135_mutex;
> +	int boot_code;
> +	int ep12_err;
> +	int ep45_err;
> +	int dual_ts;
> +	int ir_tab_load;
> +	int proprietary_ir;
> +	u8 ir_type;		/* EE chose NEC RC5 RC6 table */
> +	int surprise_removal;
> +	int dev_not_resp;
> +	int enter_suspend;
> +	u16 usb_mode;
> +	u16 max_packet_sz;
> +	u32 ts_frames;
> +	u32 ts_frame_sz;
> +	u32 ts_frame_sz_dw;
> +	u32 ts_packet_cnt;
> +	int selective_suspend;
> +	u32 active_filter;
> +	unsigned char architecture;
> +	unsigned char stream_type;
> +	int dca_pip;
> +	int swap_filter;
> +	u8 filter_cnt;
> +	u8 filter_index;
> +	int tuner_pw_off;
> +	u8 usb_ctrl_timeOut;
> +	struct it9135_data data;
> +	int disconnect;
> +	/* patch for Om1 Om2 EE */
> +	unsigned char chip_ver;
> +	int already_nim_reset_seq;
> +	/* Fw versiion */
> +	u32 ofdm_ver;
> +	u32 link_ver;
> +	u8 fw_ver[32];
> +
> +};
> +
> +struct it9135_ofdm_channel {
> +	u32 rf_khz;
> +	u8 bw;
> +	s16 nfft;
> +	s16 guard;
> +	s16 nqam;
> +	s16 vit_hrch;
> +	s16 vit_select_hp;
> +	s16 vit_alpha;
> +	s16 vit_code_rate_hp;
> +	s16 vit_code_rate_lp;
> +	u8 intlv_native;
> +};
> +
> +/**********************************************/
> +
> +extern int it9135_device_count;
> +
> +#endif


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-09-03 13:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-05 10:24 [PATCH 1/1] Add driver support for ITE IT9135 device jasondong
2011-08-06  9:51 ` [PATCH 1/2] IT9135 Add support for KWORLD_UB499_2T_T09 (id 1b80:e409) Malcolm Priestley
2011-08-06  9:52 ` [PATCH 2/2] IT9135 add MFE support to driver Malcolm Priestley
2011-08-24 18:08 ` [PATCH 1/1] Add driver support for ITE IT9135 device Arkadiusz Miskiewicz
2011-08-24 20:27   ` Arkadiusz Miskiewicz
2011-09-03 13:44 ` Mauro Carvalho Chehab

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.