From: jasondong <jason.dong@ite.com.tw>
To: linux-media@vger.kernel.org
Subject: [PATCH 1/1] Add driver support for ITE IT9135 device
Date: Fri, 05 Aug 2011 18:24:55 +0800 [thread overview]
Message-ID: <1312539895.2763.33.camel@Jason-Linux> (raw)
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
next reply other threads:[~2011-08-05 10:32 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-05 10:24 jasondong [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1312539895.2763.33.camel@Jason-Linux \
--to=jason.dong@ite.com.tw \
--cc=linux-media@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).