diff --git a/packages/linux/patches/default/linux-220-tbs-support.patch b/packages/linux/patches/default/linux-220-tbs-support.patch deleted file mode 100644 index a3fd782525..0000000000 --- a/packages/linux/patches/default/linux-220-tbs-support.patch +++ /dev/null @@ -1,60954 +0,0 @@ -From: https://github.com/tbsdtv/linux_media -Date: 13 Dec 2016 00:00:00 -Subject: [PATCH] add TBS DVB card support - -diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c -index fd89314..b824edd 100644 ---- a/drivers/media/dvb-core/dvb_ca_en50221.c -+++ b/drivers/media/dvb-core/dvb_ca_en50221.c -@@ -253,7 +253,7 @@ static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot) - int cam_present_old = (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE); - cam_changed = (cam_present_now != cam_present_old); - } -- -+ - if (cam_changed) { - if (!cam_present_now) { - ca->slot_info[slot].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED; -@@ -1055,7 +1055,6 @@ static int dvb_ca_en50221_thread(void *data) - dvb_ca_en50221_thread_update_delay(ca); - atomic_dec(&ca->slot_info[slot].camchange_count); - } -- - // CAM state machine - switch (ca->slot_info[slot].slot_state) { - case DVB_CA_SLOTSTATE_NONE: -@@ -1772,6 +1771,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, - ret); - goto unregister_device; - } -+ - return 0; - - unregister_device: -diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig -index c841fa1..2a10e95 100644 ---- a/drivers/media/dvb-frontends/Kconfig -+++ b/drivers/media/dvb-frontends/Kconfig -@@ -698,6 +698,14 @@ config DVB_MB86A20S - A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator. - Say Y when you want to support this frontend. - -+config DVB_MTV23X -+ tristate "RAONTECH mtv23x" -+ depends on DVB_CORE && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ help -+ A driver for RAONTECH mtv23x DVB-T/ISDB-T demodulator. -+ Say Y when you want to support this frontend. -+ - comment "ISDB-S (satellite) & ISDB-T (terrestrial) frontends" - depends on DVB_CORE - -@@ -782,6 +790,13 @@ config DVB_ISL6421 - help - An SEC control chip. - -+config DVB_ISL6422 -+ tristate "ISL6422[B] SEC controller" -+ depends on DVB_CORE && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ help -+ A Dual SEC controller chip from Intersil -+ - config DVB_ISL6423 - tristate "ISL6423 SEC controller" - depends on DVB_CORE && I2C -@@ -875,8 +890,52 @@ config DVB_HELENE - help - Say Y when you want to support this frontend. - -+config DVB_TAS2101 -+ tristate "Tmax TAS2101 based" -+ depends on DVB_CORE && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y when you want to support this frontend. -+ -+config DVB_MXL5XX -+ tristate "MaxLinear MXL5XX based" -+ depends on DVB_CORE && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ help -+ A DVB-S demod and tuner module. -+ Say Y when you want to support this frontend. -+ -+config DVB_SI2183 -+ tristate "Silicon Labs Si2183" -+ depends on DVB_CORE && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y when you want to support this frontend. - comment "Tools to develop new frontends" - -+config DVB_STV0910 -+ tristate "STV0910 based" -+ depends on DVB_CORE && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ help -+ DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators. -+ Say Y when you want to support these frontends. -+ -+config DVB_AVL6882 -+ tristate "Availink AVL6882 DVB-T/T2/C/S/S2 demodulator" -+ depends on DVB_CORE && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y when you want to support this frontend. -+ -+config DVB_MN88436 -+ tristate "Panasonic MN88436" -+ depends on DVB_CORE && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ help -+ An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want -+ to support this frontend. -+ - config DVB_DUMMY_FE - tristate "Dummy frontend driver" - depends on DVB_CORE -diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile -index 93921a4..075449f 100644 ---- a/drivers/media/dvb-frontends/Makefile -+++ b/drivers/media/dvb-frontends/Makefile -@@ -97,6 +97,7 @@ obj-$(CONFIG_DVB_STV6110x) += stv6110x.o - obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o - obj-$(CONFIG_DVB_MN88472) += mn88472.o - obj-$(CONFIG_DVB_MN88473) += mn88473.o -+obj-$(CONFIG_DVB_ISL6422) += isl6422.o - obj-$(CONFIG_DVB_ISL6423) += isl6423.o - obj-$(CONFIG_DVB_EC100) += ec100.o - obj-$(CONFIG_DVB_HD29L2) += hd29l2.o -@@ -126,3 +127,10 @@ obj-$(CONFIG_DVB_TC90522) += tc90522.o - obj-$(CONFIG_DVB_HORUS3A) += horus3a.o - obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o - obj-$(CONFIG_DVB_HELENE) += helene.o -+obj-$(CONFIG_DVB_TAS2101) += tas2101.o -+obj-$(CONFIG_DVB_MXL5XX) += mxl5xx.o -+obj-$(CONFIG_DVB_SI2183) += si2183.o -+obj-$(CONFIG_DVB_STV0910) += stv0910.o -+obj-$(CONFIG_DVB_AVL6882) += avl6882.o -+obj-$(CONFIG_DVB_MN88436) += mn88436.o -+obj-$(CONFIG_DVB_MTV23X) += mtv23x.o -diff --git a/drivers/media/dvb-frontends/avl6882.c b/drivers/media/dvb-frontends/avl6882.c -new file mode 100644 -index 0000000..3b723e8 ---- /dev/null -+++ b/drivers/media/dvb-frontends/avl6882.c -@@ -0,0 +1,2392 @@ -+/* -+ * Availink AVL6882 demod driver -+ * -+ * Copyright (C) 2015 Luis Alves -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "dvb_frontend.h" -+#include "avl6882.h" -+#include "avl6882_priv.h" -+ -+#define AVL6882_FIRMWARE "dvb-demod-avl6882.fw" -+ -+static int avl6882_i2c_rd(struct avl6882_priv *priv, u8 *buf, int len) -+{ -+ int ret; -+ struct i2c_msg msg[] = { -+ { -+ .addr = priv->config->demod_address, -+ .flags = 0, -+ .len = 3, -+ .buf = buf, -+ }, -+ { -+ .addr= priv->config->demod_address, -+ .flags= I2C_M_RD, -+ .len = len, -+ .buf = buf, -+ } -+ }; -+ -+ ret = i2c_transfer(priv->i2c, msg, 2); -+ if (ret == 2) { -+ ret = 0; -+ } else { -+ dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d " \ -+ "len=%d\n", KBUILD_MODNAME, ret, len); -+ ret = -EREMOTEIO; -+ } -+ return ret; -+} -+ -+static int avl6882_i2c_wr(struct avl6882_priv *priv, u8 *buf, int len) -+{ -+ int ret; -+ struct i2c_msg msg = { -+ .addr= priv->config->demod_address, -+ .flags = 0, -+ .buf = buf, -+ .len = len, -+ }; -+ -+ ret = i2c_transfer(priv->i2c, &msg, 1); -+ if (ret == 1) { -+ ret = 0; -+ } else { -+ dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d " \ -+ "len=%d\n", KBUILD_MODNAME, ret, len); -+ ret = -EREMOTEIO; -+ } -+ return ret; -+} -+#if 0 -+static int avl6882_i2c_wrm(struct avl6882_priv *priv, u8 *buf, int len) -+{ -+ int ret; -+ struct i2c_msg msg = { -+ .addr= priv->config->demod_address, -+ .flags = 1, /* ?? */ -+ .buf = buf, -+ .len = len, -+ }; -+ -+ ret = i2c_transfer(priv->i2c, &msg, 1); -+ if (ret == 1) { -+ ret = 0; -+ } else { -+ dev_warn(&priv->i2c->dev, "%s: i2c wrm failed=%d " \ -+ "len=%d\n", KBUILD_MODNAME, ret, len); -+ ret = -EREMOTEIO; -+ } -+ return ret; -+} -+#endif -+/* write 32bit words at addr */ -+#define MAX_WORDS_WR_LEN ((MAX_I2C_WRITE_SIZE-3) / 4) -+static int avl6882_i2c_wr_data(struct avl6882_priv *priv, -+ u32 addr, u32 *data, int len) -+{ -+ int ret = 0, this_len; -+ u32 buf[MAX_WORDS_WR_LEN + 1], *p; -+ u8 *b = ((u8*) buf) + 1, i; -+ -+ -+ while (len > 0) { -+ p = buf; -+ *(p++) = cpu_to_be32(addr); -+ -+ this_len = (len > MAX_WORDS_WR_LEN) ? MAX_WORDS_WR_LEN : len; -+ -+ for (i = 0; i < this_len; i++) -+ *(p++) = cpu_to_be32(*data++); -+ -+ ret = avl6882_i2c_wr(priv, b, this_len * 4 + 3); -+ if (ret) -+ break; -+ -+ len -= this_len; -+ if (len) -+ addr += this_len * 4; -+ -+ } -+ return ret; -+} -+ -+static int avl6882_i2c_wr_reg(struct avl6882_priv *priv, -+ u32 addr, u32 data, int reg_size) -+{ -+ u8 buf[3 + 4]; -+ u8 *p = buf; -+ -+ *(p++) = (u8) (addr >> 16); -+ *(p++) = (u8) (addr >> 8); -+ *(p++) = (u8) (addr); -+ -+ switch (reg_size) { -+ case 4: -+ *(p++) = (u8) (data >> 24); -+ *(p++) = (u8) (data >> 16); -+ case 2: -+ *(p++) = (u8) (data >> 8); -+ case 1: -+ default: -+ *(p++) = (u8) (data); -+ break; -+ } -+ -+ return avl6882_i2c_wr(priv, buf, 3 + reg_size); -+} -+ -+#define AVL6882_WR_REG8(_priv, _addr, _data) \ -+ avl6882_i2c_wr_reg(_priv, _addr, _data, 1) -+#define AVL6882_WR_REG16(_priv, _addr, _data) \ -+ avl6882_i2c_wr_reg(_priv, _addr, _data, 2) -+#define AVL6882_WR_REG32(_priv, _addr, _data) \ -+ avl6882_i2c_wr_reg(_priv, _addr, _data, 4) -+ -+static int avl6882_i2c_rd_reg(struct avl6882_priv *priv, -+ u32 addr, u32 *data, int reg_size) -+{ -+ int ret; -+ u8 buf[3 + 4]; -+ u8 *p = buf; -+ -+ *(p++) = (u8) (addr >> 16); -+ *(p++) = (u8) (addr >> 8); -+ *(p++) = (u8) (addr); -+ //ret = avl6882_i2c_wr(priv, buf, 3); -+ ret = avl6882_i2c_rd(priv, buf, reg_size); -+ -+ *data = 0; -+ p = buf; -+ -+ switch (reg_size) { -+ case 4: -+ *data |= (u32) (*(p++)) << 24; -+ *data |= (u32) (*(p++)) << 16; -+ case 2: -+ *data |= (u32) (*(p++)) << 8; -+ case 1: -+ default: -+ *data |= (u32) *(p); -+ break; -+ } -+ return ret; -+} -+ -+#define AVL6882_RD_REG8(_priv, _addr, _data) \ -+ avl6882_i2c_rd_reg(_priv, _addr, _data, 1) -+#define AVL6882_RD_REG16(_priv, _addr, _data) \ -+ avl6882_i2c_rd_reg(_priv, _addr, _data, 2) -+#define AVL6882_RD_REG32(_priv, _addr, _data) \ -+ avl6882_i2c_rd_reg(_priv, _addr, _data, 4) -+ -+inline static int avl6882_gpio_set(struct avl6882_priv *priv, u8 pin, u8 val) -+{ -+ return AVL6882_WR_REG32(priv, AVLREG_GPIO_BASE + pin, val); -+} -+ -+static int avl6882_setup_pll(struct avl6882_priv *priv) -+{ -+ int ret; -+ -+ /* sys_pll */ -+ ret = AVL6882_WR_REG32(priv, AVLREG_PLL_sys_pll_divr, 2); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_sys_pll_divf, 99); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_sys_pll_divq, 7); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_sys_pll_range, 1); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_sys_pll_divq2, 11); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_sys_pll_divq3, 13); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_sys_pll_enable2, 0); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_sys_pll_enable3, 0); -+ -+ /* mpeg_pll */ -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_mpeg_pll_divr, 0); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_mpeg_pll_divf, 35); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_mpeg_pll_divq, 7); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_mpeg_pll_range, 3); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_mpeg_pll_divq2, 11); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_mpeg_pll_divq3, 13); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_mpeg_pll_enable2, 0); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_mpeg_pll_enable3, 0); -+ -+ /* adc_pll */ -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_adc_pll_divr, 2); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_adc_pll_divf, 99); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_adc_pll_divq, 7); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_adc_pll_range, 1); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_adc_pll_divq2, 11); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_adc_pll_divq3, 13); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_adc_pll_enable2, 1); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_adc_pll_enable3, 1); -+ -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_RESET, 0); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_RESET, 1); -+ msleep(20); -+ -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_dll_out_phase, 96); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_dll_rd_phase, 0); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_deglitch_mode, 1); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_dll_init, 1); -+ ret |= AVL6882_WR_REG32(priv, AVLREG_PLL_dll_init, 0); -+ return ret; -+} -+ -+#define DEMOD_WAIT_RETRIES (10) -+#define DEMOD_WAIT_MS (20) -+static int avl6882_wait_demod(struct avl6882_priv *priv) -+{ -+ u32 cmd = 0; -+ int ret, retry = DEMOD_WAIT_RETRIES; -+ -+ do { -+ ret = AVL6882_RD_REG16(priv, 0x200 + rc_fw_command_saddr_offset, &cmd); -+ if ((ret == 0) && (cmd == 0)) -+ return ret; -+ else -+ msleep(DEMOD_WAIT_MS); -+ } while (--retry); -+ ret = -EBUSY; -+ return ret; -+} -+ -+/* TODO remove one of the waits */ -+static int avl6882_exec_n_wait(struct avl6882_priv *priv, u8 cmd) -+{ -+ int ret; -+ -+ ret = avl6882_wait_demod(priv); -+ if (ret) -+ return ret; -+ ret = AVL6882_WR_REG16(priv, 0x200 + rc_fw_command_saddr_offset, (u32) cmd); -+ if (ret) -+ return ret; -+ return avl6882_wait_demod(priv); -+} -+ -+ -+#define DMA_MAX_TRIES (20) -+static int avl6882_patch_demod(struct avl6882_priv *priv, u32 *patch) -+{ -+ int ret = 0; -+ u8 unary_op, binary_op, addr_mode_op; -+ u32 cmd, num_cmd_words, next_cmd_idx, num_cond_words, num_rvs; -+ u32 condition = 0; -+ u32 value = 0; -+ u32 operation; -+ u32 tmp_top_valid, core_rdy_word; -+ u32 exp_crc_val, crc_result; -+ u32 data = 0; -+ u32 type, ref_addr, ref_size; -+ u32 data_section_offset; -+ u32 args_addr, src_addr, dest_addr, data_offset, length; -+ u32 idx, len, i; -+ u32 variable_array[PATCH_VAR_ARRAY_SIZE]; -+ -+ for(i=0; i < PATCH_VAR_ARRAY_SIZE; i++) -+ variable_array[i] = 0; -+ -+ -+ printk("PATCHING---------\n"); -+ -+ //total_patch_len = patch[1]; -+ //standard = patch[2]; -+ idx = 3; -+ args_addr = patch[idx++]; -+ data_section_offset = patch[idx++]; -+ /* reserved length */ -+ len = patch[idx++]; -+ idx += len; -+ /* script length */ -+ len = patch[idx++]; -+ len += idx; -+ -+ while (idx < len) { -+ num_cmd_words = patch[idx++]; -+ next_cmd_idx = idx + num_cmd_words - 1; -+ num_cond_words = patch[idx++]; -+ if (num_cond_words == 0) { -+ condition = 1; -+ } else { -+ for (i = 0; i < num_cond_words; i++) { -+ operation = patch[idx++]; -+ value = patch[idx++]; -+ unary_op = (operation >> 8) & 0xff; -+ binary_op = operation & 0xff; -+ addr_mode_op = ((operation >> 16) & 0x3); -+ -+ if ((addr_mode_op == PATCH_OP_ADDR_MODE_VAR_IDX) && -+ (binary_op != PATCH_OP_BINARY_STORE)) { -+ value = variable_array[value]; //grab variable value -+ } -+ -+ switch(unary_op) { -+ case PATCH_OP_UNARY_LOGICAL_NEGATE: -+ value = !value; -+ break; -+ case PATCH_OP_UNARY_BITWISE_NEGATE: -+ value = ~value; -+ break; -+ default: -+ break; -+ } -+ switch(binary_op) { -+ case PATCH_OP_BINARY_LOAD: -+ condition = value; -+ break; -+ case PATCH_OP_BINARY_STORE: -+ variable_array[value] = condition; -+ break; -+ case PATCH_OP_BINARY_AND: -+ condition = condition && value; -+ break; -+ case PATCH_OP_BINARY_OR: -+ condition = condition || value; -+ break; -+ case PATCH_OP_BINARY_BITWISE_AND: -+ condition = condition & value; -+ break; -+ case PATCH_OP_BINARY_BITWISE_OR: -+ condition = condition | value; -+ break; -+ case PATCH_OP_BINARY_EQUALS: -+ condition = condition == value; -+ break; -+ case PATCH_OP_BINARY_NOT_EQUALS: -+ condition = condition != value; -+ break; -+ default: -+ break; -+ } -+ } -+ } -+ -+ AVL6882_RD_REG32(priv, 0x29A648, &tmp_top_valid); -+ AVL6882_RD_REG32(priv, 0x0A0, &core_rdy_word); -+ -+ if (condition) { -+ cmd = patch[idx++]; -+ switch(cmd) { -+ case PATCH_CMD_PING: -+ ret = avl6882_exec_n_wait(priv, AVL_FW_CMD_PING); -+ num_rvs = patch[idx++]; -+ i = patch[idx]; -+ variable_array[i] = (ret == 0); -+ break; -+ case PATCH_CMD_VALIDATE_CRC: -+ exp_crc_val = patch[idx++]; -+ src_addr = patch[idx++]; -+ length = patch[idx++]; -+ AVL6882_WR_REG32(priv,0x200 + rc_fw_command_args_addr_iaddr_offset, args_addr); -+ AVL6882_WR_REG32(priv,args_addr+0, src_addr); -+ AVL6882_WR_REG32(priv,args_addr+4, length); -+ ret = avl6882_exec_n_wait(priv, AVL_FW_CMD_CALC_CRC); -+ AVL6882_RD_REG32(priv,args_addr+8, &crc_result); -+ num_rvs = patch[idx++]; -+ i = patch[idx]; -+ variable_array[i] = (crc_result == exp_crc_val); -+ break; -+ case PATCH_CMD_LD_TO_DEVICE: -+ length = patch[idx++]; -+ dest_addr = patch[idx++]; -+ data_offset = patch[idx++]; -+ data_offset += data_section_offset; -+ ret = avl6882_i2c_wr_data(priv, dest_addr, &patch[data_offset], length); -+ num_rvs = patch[idx++]; -+ break; -+ case PATCH_CMD_LD_TO_DEVICE_IMM: -+ length = patch[idx++]; -+ dest_addr = patch[idx++]; -+ data = patch[idx++]; -+ ret = avl6882_i2c_wr_reg(priv, dest_addr, data, length); -+ num_rvs = patch[idx++]; -+ break; -+ case PATCH_CMD_RD_FROM_DEVICE: -+ length = patch[idx++]; -+ src_addr = patch[idx++]; -+ num_rvs = patch[idx++]; -+ ret = avl6882_i2c_rd_reg(priv, src_addr, &data, length); -+ i = patch[idx]; -+ variable_array[i] = data; -+ break; -+ case PATCH_CMD_DMA: -+ dest_addr = patch[idx++]; -+ length = patch[idx++]; -+ if (length > 0) -+ ret = avl6882_i2c_wr_data(priv, dest_addr, &patch[idx], length * 3); -+ AVL6882_WR_REG32(priv,0x200 + rc_fw_command_args_addr_iaddr_offset, dest_addr); -+ ret = avl6882_exec_n_wait(priv,AVL_FW_CMD_DMA); -+ idx += length * 3; -+ num_rvs = patch[idx++]; -+ break; -+ case PATCH_CMD_DECOMPRESS: -+ type = patch[idx++]; -+ src_addr = patch[idx++]; -+ dest_addr = patch[idx++]; -+ if(type == PATCH_CMP_TYPE_ZLIB) { -+ ref_addr = patch[idx++]; -+ ref_size = patch[idx++]; -+ } -+ AVL6882_WR_REG32(priv,0x200 + rc_fw_command_args_addr_iaddr_offset, args_addr); -+ AVL6882_WR_REG32(priv,args_addr+0, type); -+ AVL6882_WR_REG32(priv,args_addr+4, src_addr); -+ AVL6882_WR_REG32(priv,args_addr+8, dest_addr); -+ if(type == PATCH_CMP_TYPE_ZLIB) { -+ AVL6882_WR_REG32(priv,args_addr+12, ref_addr); -+ AVL6882_WR_REG32(priv,args_addr+16, ref_size); -+ } -+ ret = avl6882_exec_n_wait(priv,AVL_FW_CMD_DECOMPRESS); -+ num_rvs = patch[idx++]; -+ break; -+ case PATCH_CMD_ASSERT_CPU_RESET: -+ ret |= AVL6882_WR_REG32(priv,0x110840, 1); -+ num_rvs = patch[idx++]; -+ break; -+ case PATCH_CMD_RELEASE_CPU_RESET: -+ AVL6882_WR_REG32(priv, 0x110840, 0); -+ num_rvs = patch[idx++]; -+ break; -+ case PATCH_CMD_DMA_HW: -+ dest_addr = patch[idx++]; -+ length = patch[idx++]; -+ if (length > 0) -+ ret = avl6882_i2c_wr_data(priv, dest_addr, &patch[idx], length * 3); -+ i = 0; -+ do { -+ if (i++ > DMA_MAX_TRIES) -+ return -ENODEV; -+ ret |= AVL6882_RD_REG32(priv, 0x110048, &data); -+ } while (!(0x01 & data)); -+ -+ if (data) -+ ret |= AVL6882_WR_REG32(priv, 0x110050, dest_addr); -+ idx += length * 3; -+ num_rvs = patch[idx++]; -+ break; -+ case PATCH_CMD_SET_COND_IMM: -+ data = patch[idx++]; -+ num_rvs = patch[idx++]; -+ i = patch[idx]; -+ variable_array[i] = data; -+ break; -+ default: -+ return -ENODEV; -+ break; -+ } -+ idx += num_rvs; -+ } else { -+ idx = next_cmd_idx; -+ continue; -+ } -+ } -+ -+ return ret; -+} -+ -+#define DEMOD_WAIT_RETRIES_BOOT (100) -+#define DEMOD_WAIT_MS_BOOT (20) -+static int avl6882_wait_demod_boot(struct avl6882_priv *priv) -+{ -+ int ret, retry = DEMOD_WAIT_RETRIES_BOOT; -+ u32 ready_code = 0; -+ u32 status = 0; -+ -+ do { -+ ret = AVL6882_RD_REG32(priv, 0x110840, &status); -+ ret |= AVL6882_RD_REG32(priv, rs_core_ready_word_iaddr_offset, &ready_code); -+ if ((ret == 0) && (status == 0) && (ready_code == 0x5aa57ff7)) -+ return ret; -+ else -+ msleep(DEMOD_WAIT_MS_BOOT); -+ } while (--retry); -+ ret = -EBUSY; -+ return ret; -+} -+ -+ -+/* firmware loader */ -+static int avl6882_load_firmware(struct avl6882_priv *priv) -+{ -+ struct avl6882_fw *fw; -+ int ret = 0; -+ -+ switch (priv->delivery_system) { -+ case SYS_DVBC_ANNEX_A: -+ fw = &priv->fw[AVL6882_FW_DVBC]; -+ break; -+ case SYS_DVBS: -+ case SYS_DVBS2: -+ fw = &priv->fw[AVL6882_FW_DVBS]; -+ break; -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ default: -+ fw = &priv->fw[AVL6882_FW_DVBT]; -+ break; -+ } -+ -+ ret |= AVL6882_WR_REG32(priv, 0x110010, 1); -+ ret |= avl6882_setup_pll(priv); -+ if (ret) -+ goto err; -+ ret |= AVL6882_WR_REG32(priv, 0x0a4 + rs_core_ready_word_iaddr_offset, 0x00000000); -+ ret |= AVL6882_WR_REG32(priv, 0x110010, 0); -+ -+ /* check patch version - only v1 supported */ -+ if ((fw->data[0] & 0xff) != 1) -+ return -EINVAL; -+ -+ ret |= avl6882_patch_demod(priv, fw->data); -+ if (ret) -+ return ret; -+ ret = avl6882_wait_demod_boot(priv); -+err: -+ return ret; -+} -+ -+ -+ -+int ErrorStatMode_Demod( struct avl6882_priv *priv,AVL_ErrorStatConfig stErrorStatConfig ) -+{ -+ int r = AVL_EC_OK; -+ u64 time_tick_num = 270000 * stErrorStatConfig.uiTimeThresholdMs; -+ -+ r = AVL6882_WR_REG32(priv,0x132050 + esm_mode_offset,(u32) stErrorStatConfig.eErrorStatMode); -+ r |= AVL6882_WR_REG32(priv,0x132050 + tick_type_offset,(u32) stErrorStatConfig.eAutoErrorStatType); -+ -+ r |= AVL6882_WR_REG32(priv,0x132050 + time_tick_low_offset, (u32) (time_tick_num)); -+ r |= AVL6882_WR_REG32(priv,0x132050 + time_tick_high_offset, (u32) (time_tick_num >> 32)); -+ -+ r |= AVL6882_WR_REG32(priv,0x132050 + byte_tick_low_offset, stErrorStatConfig.uiTimeThresholdMs); -+ r |= AVL6882_WR_REG32(priv,0x132050 + byte_tick_high_offset, 0);//high 32-bit is not used -+ -+ if(stErrorStatConfig.eErrorStatMode == AVL_ERROR_STAT_AUTO)//auto mode -+ { -+ //reset auto error stat -+ r |= AVL6882_WR_REG32(priv,0x132050 + tick_clear_offset,0); -+ r |= AVL6882_WR_REG32(priv,0x132050 + tick_clear_offset,1); -+ r |= AVL6882_WR_REG32(priv,0x132050 + tick_clear_offset,0); -+ } -+ -+ return (r); -+} -+ -+ -+int ResetPER_Demod( struct avl6882_priv *priv) -+{ -+ int r = AVL_EC_OK; -+ u32 uiTemp = 0; -+ -+ r |= AVL6882_RD_REG32(priv,0x132050 + esm_cntrl_offset, &uiTemp); -+ uiTemp |= 0x00000001; -+ r |= AVL6882_WR_REG32(priv,0x132050 + esm_cntrl_offset, uiTemp); -+ -+ r |= AVL6882_RD_REG32(priv,0x132050 + esm_cntrl_offset, &uiTemp); -+ uiTemp |= 0x00000008; -+ r |= AVL6882_WR_REG32(priv,0x132050 + esm_cntrl_offset, uiTemp); -+ uiTemp |= 0x00000001; -+ r |= AVL6882_WR_REG32(priv,0x132050 + esm_cntrl_offset, uiTemp); -+ uiTemp &= 0xFFFFFFFE; -+ r |= AVL6882_WR_REG32(priv,0x132050 + esm_cntrl_offset, uiTemp); -+ -+ return r; -+} -+ -+static int InitErrorStat_Demod( struct avl6882_priv *priv ) -+{ -+ int r = AVL_EC_OK; -+ AVL_ErrorStatConfig stErrorStatConfig; -+ -+ stErrorStatConfig.eErrorStatMode = AVL_ERROR_STAT_AUTO; -+ stErrorStatConfig.eAutoErrorStatType = AVL_ERROR_STAT_TIME; -+ stErrorStatConfig.uiTimeThresholdMs = 3000; -+ stErrorStatConfig.uiNumberThresholdByte = 0; -+ -+ r = ErrorStatMode_Demod(priv,stErrorStatConfig); -+ r |= ResetPER_Demod(priv); -+ -+ return r; -+} -+ -+ -+ -+ -+ -+static int avl6882_init_diseqc( struct avl6882_priv *priv,AVL_Diseqc_Para *pDiseqcPara) -+{ -+ int r; -+ u32 i1 = 0; -+ -+ r = AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_srst_offset, 1); -+ -+ r |= AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_samp_frac_n_offset, 2000000); //2M=200*10kHz -+ r |= AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_samp_frac_d_offset, 166666667); //uiDDCFrequencyHz 166666667 -+ -+ r |= AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_tone_frac_n_offset, ((pDiseqcPara->uiToneFrequencyKHz)<<1)); -+ r |= AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_tone_frac_d_offset, (166666667/1000));//uiDDCFrequencyHz 166666667 -+ -+ // Initialize the tx_control -+ r |= AVL6882_RD_REG32(priv,0x16c000 + hw_diseqc_tx_cntrl_offset, &i1); -+ i1 &= 0x00000300; -+ i1 |= 0x20; //reset tx_fifo -+ i1 |= ((u32)(pDiseqcPara->eTXGap) << 6); -+ i1 |= ((u32)(pDiseqcPara->eTxWaveForm) << 4); -+ i1 |= (1<<3); //enable tx gap. -+ r |= AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_tx_cntrl_offset, i1); -+ i1 &= ~(0x20); //release tx_fifo reset -+ r |= AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_tx_cntrl_offset, i1); -+ -+ // Initialize the rx_control -+ i1 = ((u32)(pDiseqcPara->eRxWaveForm) << 2); -+ i1 |= (1<<1); //active the receiver -+ i1 |= (1<<3); //envelop high when tone present -+ r |= AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_rx_cntrl_offset, i1); -+ i1 = (u32)(pDiseqcPara->eRxTimeout); -+ r |= AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_rx_msg_tim_offset, i1); -+ -+ r |= AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_srst_offset, 0); -+ -+ return r; -+} -+ -+ -+static int avl6882_init_dvbs(struct dvb_frontend *fe) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ int ret; -+ AVL_Diseqc_Para stDiseqcConfig; -+ -+ ret = AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_int_mpeg_clk_MHz_saddr_offset,27000); -+ ret |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_int_fec_clk_MHz_saddr_offset,25000); -+ -+ ret |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_int_adc_clk_MHz_saddr_offset,12500);// uiADCFrequencyHz 125000000 -+ ret |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_int_dmd_clk_MHz_saddr_offset,166666667/10000); //uiDDCFrequencyHz 166666667 -+ -+ ret |= AVL6882_WR_REG32(priv, 0xe00 + rc_DVBSx_rfagc_pol_iaddr_offset,AVL_AGC_INVERTED); -+ -+ ret |= AVL6882_WR_REG32(priv, 0xe00 + rc_DVBSx_format_iaddr_offset, AVL_OFFBIN);//Offbin -+ ret |= AVL6882_WR_REG32(priv, 0xe00 + rc_DVBSx_input_iaddr_offset, AVL_ADC_IN);//ADC in -+ -+ ret |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_IF_Offset_10kHz_saddr_offset,0); -+ -+ /* enble agc */ -+ ret |= avl6882_gpio_set(priv, GPIO_AGC_DVBS, GPIO_AGC_ON); -+ -+ stDiseqcConfig.eRxTimeout = AVL_DRT_150ms; -+ stDiseqcConfig.eRxWaveForm = AVL_DWM_Normal; -+ stDiseqcConfig.uiToneFrequencyKHz = 22; -+ stDiseqcConfig.eTXGap = AVL_DTXG_15ms; -+ stDiseqcConfig.eTxWaveForm = AVL_DWM_Normal; -+ -+ ret |= avl6882_init_diseqc(priv, &stDiseqcConfig); -+ return ret; -+} -+ -+ -+static int avl6882_init_dvbc(struct dvb_frontend *fe) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ int ret; -+ -+ ret = AVL6882_WR_REG32(priv, 0x600 + rc_DVBC_dmd_clk_Hz_iaddr_offset, 250000000); -+ ret |= AVL6882_WR_REG32(priv, 0x600 + rc_DVBC_fec_clk_Hz_iaddr_offset, 250000000); -+ ret |= AVL6882_WR_REG8(priv, 0x600 + rc_DVBC_rfagc_pol_caddr_offset,AVL_AGC_NORMAL); -+ ret |= AVL6882_WR_REG32(priv, 0x600 + rc_DVBC_if_freq_Hz_iaddr_offset, 5000000); -+ ret |= AVL6882_WR_REG8(priv, 0x600 + rc_DVBC_adc_sel_caddr_offset, (u8) AVL_IF_Q); -+ ret |= AVL6882_WR_REG32(priv, 0x600 + rc_DVBC_symbol_rate_Hz_iaddr_offset, 6875000); -+ ret |= AVL6882_WR_REG8(priv, 0x600 + rc_DVBC_j83b_mode_caddr_offset, AVL_DVBC_J83A); -+ -+ //DDC configuration -+ ret |= AVL6882_WR_REG8(priv, 0x600 + rc_DVBC_input_format_caddr_offset, AVL_ADC_IN); //ADC in -+ ret |= AVL6882_WR_REG8(priv, 0x600 + rc_DVBC_input_select_caddr_offset, AVL_OFFBIN); //RX_OFFBIN -+ ret |= AVL6882_WR_REG8(priv, 0x600 + rc_DVBC_tuner_type_caddr_offset, AVL_DVBC_IF); //IF -+ -+ //ADC configuration -+ ret |= AVL6882_WR_REG8(priv, 0x600 + rc_DVBC_adc_use_pll_clk_caddr_offset, 0); -+ ret |= AVL6882_WR_REG32(priv, 0x600 + rc_DVBC_sample_rate_Hz_iaddr_offset, 30000000); -+ -+ /* enable agc */ -+ ret |= avl6882_gpio_set(priv, GPIO_AGC_DVBTC, GPIO_AGC_ON); -+ return ret; -+} -+ -+ -+static int avl6882_init_dvbt(struct dvb_frontend *fe) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ int ret; -+ -+ ret = AVL6882_WR_REG32(priv, 0xa00 + rc_DVBTx_sample_rate_Hz_iaddr_offset, 30000000); -+ ret |= AVL6882_WR_REG32(priv, 0xa00 + rc_DVBTx_mpeg_clk_rate_Hz_iaddr_offset, 270000000); -+ -+ /* DDC configuration */ -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_input_format_caddr_offset, AVL_OFFBIN); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_input_select_caddr_offset, AVL_ADC_IN); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_tuner_type_caddr_offset, AVL_DVBTX_REAL_IF); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_rf_agc_pol_caddr_offset, 0); -+ ret |= AVL6882_WR_REG32(priv, 0xa00 + rc_DVBTx_nom_carrier_freq_Hz_iaddr_offset, 5000000); -+ -+ /* ADC configuration */ -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_adc_sel_caddr_offset, (u8)AVL_IF_Q); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_adc_use_pll_clk_caddr_offset, 0); -+ -+ /* enable agc */ -+ ret |= avl6882_gpio_set(priv, GPIO_AGC_DVBTC, GPIO_AGC_ON); -+ return ret; -+} -+ -+ -+static int avl6882_read_status(struct dvb_frontend *fe, enum fe_status *status) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ int ret; -+ u32 reg; -+ -+ *status = 0; -+ -+ switch (priv->delivery_system) { -+ case SYS_DVBC_ANNEX_A: -+ ret = AVL6882_RD_REG32(priv,0x400 + rs_DVBC_mode_status_iaddr_offset, ®); -+ if ((reg & 0xff) == 0x15) -+ reg = 1; -+ else -+ reg = 0; -+ break; -+ case SYS_DVBS: -+ case SYS_DVBS2: -+ ret = AVL6882_RD_REG16(priv, 0xc00 + rs_DVBSx_fec_lock_saddr_offset, ®); -+ break; -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ default: -+ ret = AVL6882_RD_REG8(priv, 0x800 + rs_DVBTx_fec_lock_caddr_offset, ®); -+ break; -+ } -+ if (ret) { -+ *status = 0; -+ return ret; -+ } -+ -+ if (reg) -+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | -+ FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; -+ -+ return ret; -+} -+ -+ -+static int avl6882_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ int ret; -+ -+ dev_dbg(&priv->i2c->dev, "%s: %d\n", __func__, enable); -+ -+ if (enable) { -+ ret = AVL6882_WR_REG32(priv,0x118000 + tuner_i2c_bit_rpt_cntrl_offset, 0x07); -+ } else -+ ret = AVL6882_WR_REG32(priv,0x118000 + tuner_i2c_bit_rpt_cntrl_offset, 0x06); -+ -+ return ret; -+} -+ -+ -+static int avl6882_set_dvbs(struct dvb_frontend *fe) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int ret; -+ -+ //printk("[avl6882_set_dvbs] Freq:%d Mhz,sym:%d Khz\n", c->frequency, c->symbol_rate); -+ -+ ret = AVL6882_WR_REG16(priv, 0xc00 + rs_DVBSx_fec_lock_saddr_offset, 0); -+ ret |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_decode_mode_saddr_offset, 0x14); -+ ret |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_fec_bypass_coderate_saddr_offset, 0); //DVBS auto lock -+ ret |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_iq_mode_saddr_offset, 1); //enable spectrum auto detection -+ ret |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_decode_mode_saddr_offset, 0x14); -+ ret |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_fec_bypass_coderate_saddr_offset, 0); -+ ret |= AVL6882_WR_REG32(priv, 0xe00 + rc_DVBSx_int_sym_rate_MHz_iaddr_offset, c->symbol_rate); -+ ret |= avl6882_exec_n_wait(priv,AVL_FW_CMD_ACQUIRE); -+ return ret; -+} -+ -+ -+static int avl6882_set_dvbc(struct dvb_frontend *fe) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int ret; -+ -+ //printk("[avl6882_set_dvbc] Freq:%d Mhz,sym:%d\n", c->frequency, c->symbol_rate); -+ -+ ret = AVL6882_WR_REG32(priv, 0x600 + rc_DVBC_qam_mode_scan_control_iaddr_offset, 0x0101); -+ ret |= AVL6882_WR_REG32(priv, 0x600 + rc_DVBC_symbol_rate_Hz_iaddr_offset, c->symbol_rate); -+ ret |= avl6882_exec_n_wait(priv, AVL_FW_CMD_ACQUIRE); -+ return ret; -+} -+ -+ -+static int avl6882_set_dvbt(struct dvb_frontend *fe) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ u32 bw_fft; -+ int ret; -+ -+ //printk("[avl6882_set_dvbtx] Freq:%d bw:%d\n", c->frequency, c->bandwidth_hz); -+ -+ /* set bandwidth */ -+ if(c->bandwidth_hz <= 1700000) { -+ bw_fft = 1845070; -+ } else if(c->bandwidth_hz <= 5000000) { -+ bw_fft = 5714285; -+ } else if(c->bandwidth_hz <= 6000000) { -+ bw_fft = 6857143; -+ } else if(c->bandwidth_hz <= 7000000) { -+ bw_fft = 8000000; -+ } else { // if(c->bandwidth_hz <= 8000) { -+ bw_fft = 9142857; -+ } -+ ret = AVL6882_WR_REG32(priv, 0xa00 + rc_DVBTx_fund_rate_Hz_iaddr_offset, bw_fft); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_l1_proc_only_caddr_offset, 0); -+ -+ /* spectrum inversion */ -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_spectrum_invert_caddr_offset, AVL_SPECTRUM_AUTO); -+ -+ switch (c->delivery_system) { -+ case SYS_DVBT: -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_acquire_mode_caddr_offset, (u8) AVL_DVBTx_LockMode_T_ONLY); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_dvbt_layer_select_caddr_offset, 0); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_data_PLP_ID_caddr_offset, 0); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_common_PLP_ID_caddr_offset, 0); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_common_PLP_present_caddr_offset, 0); -+ break; -+ case SYS_DVBT2: -+ default: -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_acquire_mode_caddr_offset, AVL_DVBTx_LockMode_ALL); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_data_PLP_ID_caddr_offset, c->stream_id); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_common_PLP_ID_caddr_offset, 0); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_common_PLP_present_caddr_offset, 2); -+ break; -+ } -+ ret |= avl6882_exec_n_wait(priv, AVL_FW_CMD_ACQUIRE); -+ return ret; -+} -+ -+static int avl6882_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -+{ -+ //printk("%s()\n", __func__); -+ *ucblocks = 0x00; -+ return 0; -+} -+ -+static void avl6882_release(struct dvb_frontend *fe) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ int i; -+ //printk("%s()\n", __func__); -+ for (i = 0; i < AVL6882_FW_COUNT; i++) -+ kfree(priv->fw[i].data); -+ kfree(priv); -+} -+ -+static int avl6882_read_ber(struct dvb_frontend *fe, u32 *ber) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int ret = 0; -+ u32 tmp; -+ -+ switch (c->delivery_system) { -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ default: -+ ret = AVL6882_RD_REG16(priv, -+ 0x800 + rs_DVBTx_post_viterbi_BER_estimate_x10M_iaddr_offset, -+ &tmp); -+ break; -+ case SYS_DVBS: -+ case SYS_DVBS2: -+ ret = AVL6882_RD_REG16(priv, -+ 0xc00 + rs_DVBSx_post_viterbi_BER_estimate_x10M_iaddr_offset, -+ &tmp); -+ break; -+ case SYS_DVBC_ANNEX_A: -+ ret = AVL6882_RD_REG16(priv, -+ 0x400 + rs_DVBC_post_viterbi_BER_estimate_x10M_iaddr_offset, -+ &tmp); -+ break; -+ } -+ -+ *ber = tmp; -+ return ret; -+} -+ -+static int avl6882_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd burst) -+{ -+ //printk("%s()\n", __func__); -+ return 0; -+} -+ -+static int avl6882_set_tone(struct dvb_frontend* fe, enum fe_sec_tone_mode tone) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ int ret; -+ u32 reg; -+ -+ ret = AVL6882_RD_REG32(priv, 0x16c000 + hw_diseqc_tx_cntrl_offset, ®); -+ if (ret) -+ return ret; -+ -+ switch(tone) { -+ case SEC_TONE_ON: -+ reg &= 0xfffffff8; -+ reg |= 0x3; // continuous mode -+ reg |= (1<<10); // on -+ break; -+ case SEC_TONE_OFF: -+ reg &= 0xfffff3ff; -+ break; -+ default: -+ return -EINVAL; -+ } -+ return AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_tx_cntrl_offset, reg); -+} -+ -+static int avl6882_set_voltage(struct dvb_frontend* fe, enum fe_sec_voltage voltage) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ u32 pwr, vol; -+ int ret; -+ -+ switch (voltage) { -+ case SEC_VOLTAGE_OFF: -+ pwr = GPIO_1; -+ vol = GPIO_0; -+ break; -+ case SEC_VOLTAGE_13: -+ pwr = GPIO_0; -+ vol = GPIO_0; -+ break; -+ case SEC_VOLTAGE_18: -+ pwr = GPIO_0; -+ vol = GPIO_Z; -+ break; -+ default: -+ return -EINVAL; -+ } -+ ret = avl6882_gpio_set(priv, GPIO_LNB_PWR, pwr); -+ ret |= avl6882_gpio_set(priv, GPIO_LNB_VOLT, vol); -+ return ret; -+} -+ -+/* diseqc master command */ -+static int avl6882_diseqc_send_master_cmd(struct dvb_frontend *fe, -+ struct dvb_diseqc_master_cmd *d) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ u8 tx_done, tx_remain, continuous_flag = 0; -+ int i, ret, timeout = 0; -+ u32 reg, tmp; -+ -+ if (d->msg_len > 8) -+ return -EINVAL; -+ -+ // reset rx_fifo -+ ret = AVL6882_RD_REG32(priv, 0x16c000 + hw_diseqc_rx_cntrl_offset, &tmp); -+ ret |= AVL6882_WR_REG32(priv, 0x16c000 + hw_diseqc_rx_cntrl_offset, tmp | 1); -+ ret |= AVL6882_WR_REG32(priv, 0x16c000 + hw_diseqc_rx_cntrl_offset, tmp & ~1); -+ -+ ret = AVL6882_RD_REG32(priv,0x16c000 + hw_diseqc_tx_cntrl_offset, ®); -+ if (reg & 0x400) { -+ /* remember tone setting */ -+ continuous_flag = 1; -+ /* turn off tone */ -+ reg &= 0xfffff3ff; -+ } -+ -+ // set to modulation mode and load FIFO -+ reg &= 0xfffffff8; -+ ret |= AVL6882_WR_REG32(priv, 0x16c000 + hw_diseqc_tx_cntrl_offset, reg); -+ for (i = 0; i < d->msg_len; i++) -+ ret |= AVL6882_WR_REG32(priv, 0x16c000 + hw_tx_fifo_map_offset, (u32) d->msg[i]); -+ msleep(20); -+ -+ // start tx -+ reg |= 4; -+ ret |= AVL6882_WR_REG32(priv, 0x16c000 + hw_diseqc_tx_cntrl_offset, reg); -+ do { -+ ret |= AVL6882_RD_REG32(priv, 0x16c000 + hw_diseqc_tx_st_offset, &tmp); -+ tx_done = (u8) ((tmp & 0x00000040) >> 6); -+ tx_remain = (u8) ((tmp & 0x0000003c) >> 2); -+ msleep(20); -+ if (++timeout > 25) -+ ret = -ETIMEDOUT; -+ } while ((tx_done == 0) || ret); -+ -+ if (continuous_flag) { -+ /* restore tone */ -+ reg &= 0xfffffff8; -+ reg |= 0x403; -+ ret |= AVL6882_WR_REG32(priv, 0x16c000 + hw_diseqc_tx_cntrl_offset, reg); -+ } -+ return ret; -+} -+ -+ -+static int avl6882_init(struct dvb_frontend *fe) -+{ -+ return 0; -+} -+ -+ -+#define I2C_RPT_DIV ((0x2A)*(250000)/(240*1000)) //m_CoreFrequency_Hz 250000000 -+ -+static int avl6882_set_dvbmode(struct dvb_frontend *fe, -+ enum fe_delivery_system delsys) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ int ret; -+ u32 reg; -+ -+ /* these modes use the same fw / config */ -+ if (delsys == SYS_DVBS2) -+ delsys = SYS_DVBS; -+ else if (delsys == SYS_DVBT2) -+ delsys = SYS_DVBT; -+ -+ /* already in the requested mode */ -+ if (priv->delivery_system == delsys) -+ return 0; -+ -+ priv->delivery_system = delsys; -+ //printk("initing demod for delsys=%d\n", delsys); -+ -+ ret = avl6882_load_firmware(priv); -+ -+ // Load the default configuration -+ ret |= avl6882_exec_n_wait(priv, AVL_FW_CMD_LD_DEFAULT); -+ ret |= avl6882_exec_n_wait(priv, AVL_FW_CMD_INIT_SDRAM); -+ ret |= avl6882_exec_n_wait(priv, AVL_FW_CMD_INIT_ADC); -+ -+ switch (priv->delivery_system) { -+ case SYS_DVBC_ANNEX_A: -+ ret |= avl6882_init_dvbc(fe); -+ break; -+ case SYS_DVBS: -+ case SYS_DVBS2: -+ ret |= avl6882_init_dvbs(fe); -+ break; -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ default: -+ ret |= avl6882_init_dvbt(fe); -+ break; -+ } -+ -+ /* set gpio / turn off lnb, set 13V */ -+ ret = avl6882_gpio_set(priv, GPIO_LNB_PWR, GPIO_1); -+ ret |= avl6882_gpio_set(priv, GPIO_LNB_VOLT, GPIO_0); -+ -+ /* set TS mode */ -+ ret |= AVL6882_WR_REG8(priv, 0x200 + rc_ts_serial_caddr_offset, AVL_TS_PARALLEL); -+ ret |= AVL6882_WR_REG8(priv, 0x200 + rc_ts_clock_edge_caddr_offset, AVL_MPCM_RISING); -+ ret |= AVL6882_WR_REG8(priv, 0x200 + rc_enable_ts_continuous_caddr_offset, AVL_TS_CONTINUOUS_ENABLE); -+ -+ /* TS serial pin */ -+ ret |= AVL6882_WR_REG8(priv, 0x200 + rc_ts_serial_outpin_caddr_offset, AVL_MPSP_DATA0); -+ /* TS serial order */ -+ ret |= AVL6882_WR_REG8(priv, 0x200 + rc_ts_serial_msb_caddr_offset, AVL_MPBO_MSB); -+ /* TS serial sync pulse */ -+ ret |= AVL6882_WR_REG8(priv, 0x200 + rc_ts_sync_pulse_caddr_offset, AVL_TS_SERIAL_SYNC_1_PULSE); -+ /* TS error pol */ -+ ret |= AVL6882_WR_REG8(priv, 0x200 + rc_ts_error_polarity_caddr_offset, AVL_MPEP_Normal); -+ /* TS valid pol */ -+ ret |= AVL6882_WR_REG8(priv, 0x200 + rc_ts_valid_polarity_caddr_offset, AVL_MPVP_Normal); -+ /* TS packet len */ -+ ret |= AVL6882_WR_REG8(priv, 0x200 + rc_ts_packet_len_caddr_offset, AVL_TS_188); -+ /* TS parallel order */ -+ ret |= AVL6882_WR_REG8(priv, 0x200 + rc_ts_packet_order_caddr_offset, AVL_TS_PARALLEL_ORDER_NORMAL); -+ /* TS parallel phase */ -+ ret |= AVL6882_WR_REG8(priv, 0x200 + ts_clock_phase_caddr_offset, AVL_TS_PARALLEL_PHASE_0); -+ -+ /* TS output enable */ -+ ret |= AVL6882_WR_REG32(priv, AVLREG_TS_OUTPUT, TS_OUTPUT_ENABLE); -+ -+ /* init tuner i2c repeater */ -+ /* hold in reset */ -+ ret |= AVL6882_WR_REG32(priv, 0x118000 + tuner_i2c_srst_offset, 1); -+ /* close gate */ -+ ret |= avl6882_i2c_gate_ctrl(fe, 0); -+ //ret |= AVL6882_WR_REG32(priv, 0x118000 + tuner_i2c_bit_rpt_cntrl_offset, 0x6); -+ ret |= AVL6882_RD_REG32(priv, 0x118000 + tuner_i2c_cntrl_offset, ®); -+ reg &= 0xfffffffe; -+ ret |= AVL6882_WR_REG32(priv, 0x118000 + tuner_i2c_cntrl_offset, reg); -+ /* set bit clock */ -+ ret |= AVL6882_WR_REG32(priv, 0x118000 + tuner_i2c_bit_rpt_clk_div_offset, I2C_RPT_DIV); -+ /* release from reset */ -+ ret |= AVL6882_WR_REG32(priv, 0x118000 + tuner_i2c_srst_offset, 0); -+ -+ ret |= InitErrorStat_Demod(priv); -+ -+ if (ret) { -+ dev_err(&priv->i2c->dev, "%s: demod init failed", -+ KBUILD_MODNAME); -+ } -+ -+ return ret; -+} -+ -+static int avl6882_sleep(struct dvb_frontend *fe) -+{ -+ //printk("%s()\n", __func__); -+ return 0; -+} -+ -+ -+static int avl6882fe_strength(struct dvb_frontend *fe, u16 *signal_strength) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ int ret; -+ u32 tmp; -+ ret = AVL6882_RD_REG16(priv,0x0a4 + rs_rf_agc_saddr_offset, &tmp); -+ -+ *signal_strength = (u16) tmp; -+ return 0; -+} -+ -+static int avl6882fe_snr(struct dvb_frontend *fe, u16 *snr) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int ret = 0; -+ u32 tmp; -+ -+ switch (c->delivery_system) { -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ default: -+ ret = AVL6882_RD_REG16(priv, -+ 0x800 + rs_DVBTx_snr_dB_x100_saddr_offset, -+ &tmp); -+ break; -+ case SYS_DVBS: -+ case SYS_DVBS2: -+ ret = AVL6882_RD_REG32(priv, -+ 0xc00 + rs_DVBSx_int_SNR_dB_iaddr_offset, -+ &tmp); -+ break; -+ case SYS_DVBC_ANNEX_A: -+ //reg = 0x400 + rs_DVBC_snr_dB_x100_saddr_offset; -+ break; -+ } -+ -+ if (tmp > 10000) -+ *snr = 0; -+ else -+ *snr = (u16) (tmp * 10); -+ return ret; -+} -+ -+static int avl6882fe_algo(struct dvb_frontend *fe) -+{ -+ return DVBFE_ALGO_HW; -+} -+ -+static int avl6882_set_frontend(struct dvb_frontend *fe) -+{ -+ struct avl6882_priv *priv = fe->demodulator_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ u32 demod_mode; -+ int ret; -+ -+ //printk("%s() mode=%d\n", __func__, c->delivery_system); -+ -+ /* check that mode is correctly set */ -+ ret = AVL6882_RD_REG32(priv, 0x200 + rs_current_active_mode_iaddr_offset, &demod_mode); -+ if (ret) -+ return ret; -+ -+ /* setup tuner */ -+ if (fe->ops.tuner_ops.set_params) { -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 1); -+ ret = fe->ops.tuner_ops.set_params(fe); -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 0); -+ -+ if (ret) -+ return ret; -+ } -+ //printk("%s() demod_mode=%d\n", __func__, demod_mode); -+ -+ switch (c->delivery_system) { -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ if (demod_mode != AVL_DVBTX) { -+ dev_err(&priv->i2c->dev, "%s: failed to enter DVBTx mode", -+ KBUILD_MODNAME); -+ ret = -EAGAIN; -+ break; -+ } -+ ret = avl6882_set_dvbt(fe); -+ break; -+ case SYS_DVBC_ANNEX_A: -+ if (demod_mode != AVL_DVBC) { -+ dev_err(&priv->i2c->dev, "%s: failed to enter DVBC mode", -+ KBUILD_MODNAME); -+ ret = -EAGAIN; -+ break; -+ } -+ ret = avl6882_set_dvbc(fe); -+ break; -+ case SYS_DVBS: -+ case SYS_DVBS2: -+ if (demod_mode != AVL_DVBSX) { -+ dev_err(&priv->i2c->dev, "%s: failed to enter DVBSx mode", -+ KBUILD_MODNAME); -+ ret = -EAGAIN; -+ break; -+ } -+ ret = avl6882_set_dvbs(fe); -+ break; -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ -+ return ret; -+} -+ -+static int avl6882_tune(struct dvb_frontend *fe, bool re_tune, -+ unsigned int mode_flags, unsigned int *delay, enum fe_status *status) -+{ -+ *delay = HZ / 5; -+ if (re_tune) { -+ int ret = avl6882_set_frontend(fe); -+ if (ret) -+ return ret; -+ } -+ return avl6882_read_status(fe, status); -+} -+ -+static int avl6882_get_frontend(struct dvb_frontend *fe, -+ struct dtv_frontend_properties *c) -+{ -+ return 0; -+} -+ -+static int avl6882_set_property(struct dvb_frontend *fe, -+ struct dtv_property *p) -+{ -+ int ret = 0; -+ -+ switch (p->cmd) { -+ case DTV_DELIVERY_SYSTEM: -+ //printk("DTV_set_prop delsys %d\n", p->u.data); -+ ret = avl6882_set_dvbmode(fe, p->u.data); -+ if (ret) { -+ printk("error set_dvbmode\n"); -+ } -+ switch (p->u.data) { -+ case SYS_DVBC_ANNEX_A: -+ fe->ops.info.frequency_min = 47000000; -+ fe->ops.info.frequency_max = 862000000; -+ fe->ops.info.frequency_stepsize = 62500; -+ break; -+ case SYS_DVBS: -+ case SYS_DVBS2: -+ fe->ops.info.frequency_min = 950000; -+ fe->ops.info.frequency_max = 2150000; -+ fe->ops.info.frequency_stepsize = 0; -+ break; -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ default: -+ fe->ops.info.frequency_min = 174000000; -+ fe->ops.info.frequency_max = 862000000; -+ fe->ops.info.frequency_stepsize = 250000; -+ break; -+ } -+ -+ break; -+ default: -+ break; -+ } -+ -+ return ret; -+} -+ -+static int avl6882_get_property(struct dvb_frontend *fe, -+ struct dtv_property *p) -+{ -+ int ret = 0; -+ u16 tmp; -+ u32 tmp2; -+ -+ switch (p->cmd) { -+ case DTV_STAT_CNR: -+ ret |= avl6882fe_snr(fe, &tmp); -+ p->u.st.stat[0].scale = FE_SCALE_DECIBEL; -+ p->u.st.stat[0].svalue = tmp; -+ -+ if (tmp > 25000) -+ tmp2 = 0xffff; -+ else -+ tmp2 = (tmp * 0xffff) / 25000; -+ p->u.st.stat[1].scale = FE_SCALE_RELATIVE; -+ p->u.st.stat[1].svalue = (u16) tmp2; -+ p->u.st.len = 2; -+ break; -+ default: -+ break; -+ } -+ -+ return ret; -+} -+ -+static struct dvb_frontend_ops avl6882_ops = { -+ .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A, SYS_DVBS, SYS_DVBS2}, -+ .info = { -+ .name = "Availink AVL6882", -+ .frequency_min = 0, -+ .frequency_max = 0, -+ .frequency_stepsize = 0, -+ .frequency_tolerance = 0, -+ .symbol_rate_min = 1000000, -+ .symbol_rate_max = 45000000, -+ .caps = FE_CAN_FEC_1_2 | -+ FE_CAN_FEC_2_3 | -+ FE_CAN_FEC_3_4 | -+ FE_CAN_FEC_4_5 | -+ FE_CAN_FEC_5_6 | -+ FE_CAN_FEC_6_7 | -+ FE_CAN_FEC_7_8 | -+ FE_CAN_FEC_AUTO | -+ FE_CAN_QPSK | -+ FE_CAN_QAM_16 | -+ FE_CAN_QAM_32 | -+ FE_CAN_QAM_64 | -+ FE_CAN_QAM_128 | -+ FE_CAN_QAM_256 | -+ FE_CAN_QAM_AUTO | -+ FE_CAN_TRANSMISSION_MODE_AUTO | -+ FE_CAN_GUARD_INTERVAL_AUTO | -+ FE_CAN_HIERARCHY_AUTO | -+ FE_CAN_MUTE_TS | -+ FE_CAN_2G_MODULATION | -+ FE_CAN_MULTISTREAM | -+ FE_CAN_INVERSION_AUTO -+ }, -+ -+ .release = avl6882_release, -+ .init = avl6882_init, -+ -+ .sleep = avl6882_sleep, -+ .i2c_gate_ctrl = avl6882_i2c_gate_ctrl, -+ -+ .read_status = avl6882_read_status, -+ .read_ber = avl6882_read_ber, -+ .read_signal_strength = avl6882fe_strength, -+ .read_snr = avl6882fe_snr, -+ .read_ucblocks = avl6882_read_ucblocks, -+ .set_tone = avl6882_set_tone, -+ .set_voltage = avl6882_set_voltage, -+ .diseqc_send_master_cmd = avl6882_diseqc_send_master_cmd, -+ .diseqc_send_burst = avl6882_burst, -+ .get_frontend_algo = avl6882fe_algo, -+ .tune = avl6882_tune, -+ -+ .set_property = avl6882_set_property, -+ .get_property = avl6882_get_property, -+ .set_frontend = avl6882_set_frontend, -+ .get_frontend = avl6882_get_frontend, -+}; -+ -+ -+static int avl6882_setup_firmware(struct avl6882_priv *priv) -+{ -+ const struct firmware *fw; -+ struct avl6882_fw *afw = priv->fw; -+ int ret, i; -+ u32 *ptr, size = 0; -+ -+ ret = request_firmware(&fw, AVL6882_FIRMWARE, priv->i2c->dev.parent); -+ if (ret) { -+ dev_err(&priv->i2c->dev, "Error loading firmware: %s " -+ "(timeout or file not found?)\n", AVL6882_FIRMWARE); -+ goto err1; -+ } -+ if (fw->size < AVL6882_FW_HEADER_SIZE) { -+ dev_err(&priv->i2c->dev, "Error loading firmware: %s " -+ "(invalid file size?)\n", AVL6882_FIRMWARE); -+ ret = -EINVAL; -+ goto err2; -+ } -+ -+ ptr = (u32*) fw->data; -+ -+ for (i = 0; i < AVL6882_FW_COUNT; i++) { -+ afw[i].offset = le32_to_cpu(*ptr++); -+ afw[i].size = le32_to_cpu(*ptr++) & 0xfffffffc; -+ size += afw[i].size; -+ } -+ -+ if (size != fw->size - AVL6882_FW_HEADER_SIZE) { -+ dev_err(&priv->i2c->dev, "Error loading firmware: %s " -+ "(invalid fw size?)\n", AVL6882_FIRMWARE); -+ ret = -EINVAL; -+ goto err2; -+ } -+ -+ for (i = 0; i < AVL6882_FW_COUNT; i++) { -+ afw[i].data = kzalloc(afw[i].size, GFP_KERNEL); -+ if (afw[i].data == NULL) { -+ dev_err(&priv->i2c->dev, "Error loading firmware: %s " -+ "(not enough mem)\n", AVL6882_FIRMWARE); -+ ret = -ENOMEM; -+ goto err3; -+ } -+ ptr = (u32*) &fw->data[afw[i].offset]; -+ for (size = 0; size < afw[i].size / 4; size++) -+ afw[i].data[size] = be32_to_cpu(*ptr++); -+ /* check valid FW */ -+ if ((afw[i].data[0] & 0xf0000000) != 0x10000000) { -+ dev_err(&priv->i2c->dev, "Error loading firmware: %s " -+ "(invalid fw)\n", AVL6882_FIRMWARE); -+ ret = -EINVAL; -+ goto err3; -+ } -+ } -+ -+ return ret; -+err3: -+ while (--i >= 0) -+ kfree(afw[i].data); -+err2: -+ release_firmware(fw); -+err1: -+ return ret; -+} -+ -+struct dvb_frontend *avl6882_attach(struct avl6882_config *config, -+ struct i2c_adapter *i2c) -+{ -+ struct avl6882_priv *priv; -+ int ret; -+ u32 id, fid; -+ -+ -+ priv = kzalloc(sizeof(struct avl6882_priv), GFP_KERNEL); -+ if (priv == NULL) -+ goto err; -+ -+ memcpy(&priv->frontend.ops, &avl6882_ops, -+ sizeof(struct dvb_frontend_ops)); -+ -+ priv->frontend.demodulator_priv = priv; -+ priv->config = config; -+ priv->i2c = i2c; -+ priv->g_nChannel_ts_total = 0, -+ priv->delivery_system = -1; -+ -+ /* get chip id */ -+ ret = AVL6882_RD_REG32(priv, 0x108000, &id); -+ /* get chip family id */ -+ ret |= AVL6882_RD_REG32(priv, 0x40000, &fid); -+ if (ret) { -+ dev_err(&priv->i2c->dev, "%s: attach failed reading id", -+ KBUILD_MODNAME); -+ goto err1; -+ } -+ -+ if (fid != 0x68624955) { -+ dev_err(&priv->i2c->dev, "%s: attach failed family id mismatch", -+ KBUILD_MODNAME); -+ goto err1; -+ } -+ -+ dev_info(&priv->i2c->dev, "%s: found id=0x%x " \ -+ "family_id=0x%x", KBUILD_MODNAME, id, fid); -+ -+ /* setup firmware */ -+ if (avl6882_setup_firmware(priv)) -+ goto err1; -+ -+ return &priv->frontend; -+ -+err1: -+ kfree(priv); -+err: -+ return NULL; -+} -+EXPORT_SYMBOL(avl6882_attach); -+ -+MODULE_DESCRIPTION("Availink AVL6882 DVB demodulator driver"); -+MODULE_AUTHOR("Luis Alves (ljalvs@gmail.com)"); -+MODULE_LICENSE("GPL"); -+MODULE_FIRMWARE(AVL6882_FIRMWARE); -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+#if 0 -+static int DVBSx_GetSignalQuality_Demod(struct avl6882_priv *priv, AVL_puint16 puiQuality ) -+{ -+ int r = AVL_EC_OK; -+ u32 uiTemp = 0; -+ -+ r = DVBSx_GetSNR_Demod(priv,&uiTemp); -+ if(uiTemp > 2500) { -+ *puiQuality = 100; -+ } else { -+ *puiQuality = uiTemp*100/2500; -+ } -+ -+ return r; -+} -+ -+int AVL_Demod_GetSQI ( struct avl6882_priv *priv,AVL_puint16 pusSQI) -+{ -+ int r = AVL_EC_OK; -+ -+ *pusSQI = 0; -+ r=DVBSx_GetSignalQuality_Demod(priv,pusSQI); -+ -+ return (r); -+} -+#endif -+ -+ -+ -+ -+ -+#if 0 -+ -+ -+ -+static int AVL_LockChannel_T2(struct avl6882_priv *priv, u32 Freq_Khz, u32 BandWidth_Khz, u8 T2_Profile, AVL_int32 PLP_ID) -+{ -+ int ret; -+ AVL_DVBTxBandWidth nBand = AVL_DVBTx_BW_8M; -+ AVL_DVBTx_LockMode eDVBTxLockMode; -+ AVL_DVBT2_PROFILE eDVTB2Profile = (AVL_DVBT2_PROFILE) T2_Profile; -+ -+ printk("[AVL_LockChannel_T2] Freq:%d Mhz,sym:%d Khz\n",Freq_Khz,BandWidth_Khz); -+ -+ //return_code = r848_lock_n_wait(priv, Freq_Khz, BandWidth_Khz); -+ //AVL_Demod_DVBT2AutoLock(priv, nBand, , PLP_ID); -+ -+ ret = AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_l1_proc_only_caddr_offset, 0); -+ if (eDVTB2Profile == AVL_DVBT2_PROFILE_BASE) { -+ eDVBTxLockMode = AVL_DVBTx_LockMode_T2BASE; -+ } else if (eDVTB2Profile == AVL_DVBT2_PROFILE_LITE) { -+ eDVBTxLockMode = AVL_DVBTx_LockMode_T2LITE; -+ } else { -+ eDVBTxLockMode = AVL_DVBTx_LockMode_ALL; -+ } -+ -+ nBand = Convert2DemodBand(BandWidth_Khz); -+ ret |= DVBTx_SetBandWidth_Demod(priv, nBand); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_acquire_mode_caddr_offset, (u8) eDVBTxLockMode); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_spectrum_invert_caddr_offset, AVL_SPECTRUM_AUTO); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_data_PLP_ID_caddr_offset, PLP_ID); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_common_PLP_ID_caddr_offset, 0); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_common_PLP_present_caddr_offset, 2); -+ ret |= avl6882_exec_n_wait(priv,AVL_FW_CMD_ACQUIRE); -+ if (ret) -+ printk("[AVL_LockChannel_DVBT2] Failed to lock the channel!\n"); -+ return ret; -+} -+ -+ -+static int AVL_LockChannel_T(struct avl6882_priv *priv,u32 Freq_Khz,u16 BandWidth_Khz, AVL_int32 DVBT_layer_info) -+{ -+ int ret; -+ AVL_DVBTxBandWidth nBand = AVL_DVBTx_BW_8M; -+ -+ printk("[AVL_LockChannel_T] Freq is %d MHz, Bandwide is %d MHz, Layer Info is %d (0 : LP; 1 : HP)\n", -+ Freq_Khz/1000, BandWidth_Khz/1000, DVBT_layer_info); -+ -+ //ret = r848_lock_n_wait(priv, Freq_Khz, BandWidth_Khz); -+ nBand = Convert2DemodBand(BandWidth_Khz); -+ //AVL_Demod_DVBTAutoLock -+ ret = AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_l1_proc_only_caddr_offset, 0); -+ ret |= DVBTx_SetBandWidth_Demod(priv, nBand); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_acquire_mode_caddr_offset, (u8) AVL_DVBTx_LockMode_T_ONLY); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_spectrum_invert_caddr_offset, AVL_SPECTRUM_AUTO); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_dvbt_layer_select_caddr_offset, DVBT_layer_info); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_data_PLP_ID_caddr_offset, 0); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_common_PLP_ID_caddr_offset, 0); -+ ret |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_common_PLP_present_caddr_offset, 0); -+ ret |= avl6882_exec_n_wait(priv, AVL_FW_CMD_ACQUIRE); -+ if(ret) -+ printk("[AVL_LockChannel_T] Failed to lock the channel!\n"); -+ -+ return ret; -+} -+ -+ -+ -+ -+static int IBase_SendRxOP_Demod(struct avl6882_priv *priv,u8 cmd) -+{ -+ int ret = avl6882_wait_demod(priv); -+ if (ret) -+ return ret; -+ return AVL6882_WR_REG16(priv, 0x200 + rc_fw_command_saddr_offset, (u32) cmd); -+} -+ -+int TestSDRAM_Demod( struct avl6882_priv *priv,AVL_puint32 puiTestResult, AVL_puint32 puiTestPattern) -+{ -+ int r = AVL_EC_OK; -+ u16 uiTimeDelay = 100; -+ u16 uiMaxRetries = 200; -+ u32 i=0; -+ -+ r = IBase_SendRxOP_Demod(priv,AVL_FW_CMD_SDRAM_TEST); -+ if(AVL_EC_OK == r ) -+ { -+ -+ r |= avl6882_wait_demod(priv); -+/* while (AVL_EC_OK != IBase_GetRxOPStatus_Demod(priv)) -+ { -+ if (uiMaxRetries < i++) -+ { -+ r |= AVL_EC_RUNNING; -+ break; -+ } -+ msleep(uiTimeDelay); -+ }*/ -+ -+ r |= AVL6882_RD_REG32(priv,0x0a4 + rc_sdram_test_return_iaddr_offset, puiTestPattern); -+ r |= AVL6882_RD_REG32(priv,0x0a4 + rc_sdram_test_result_iaddr_offset, puiTestResult); -+ } -+ -+ return r; -+} -+ -+static int avl6882_demod_lock_wait(struct avl6882_priv *priv, u8 *lock_flag) -+{ -+ int ret, retry = 50; -+ enum fe_status locked; -+ do { -+ ret = avl6882_read_status(&priv->frontend, &locked); -+ if (ret) { -+ *lock_flag = 0; -+ break; -+ } -+ if (locked) { -+ *lock_flag = 1; -+ break; -+ } -+ msleep(20); -+ } while (--retry); -+ return ret; -+} -+ -+int AVL_Demod_DVBTxChannelScan(struct avl6882_priv *priv, AVL_DVBTxBandWidth eBandWidth, AVL_DVBTx_LockMode eLockMode) -+{ -+ int r = AVL_EC_OK; -+ -+ r = DVBTx_SetBandWidth_Demod(priv,eBandWidth); -+ r |= AVL6882_WR_REG8(priv,0xa00 + rc_DVBTx_acquire_mode_caddr_offset, eLockMode); -+ r |= AVL6882_WR_REG8(priv, 0xa00 + rc_DVBTx_l1_proc_only_caddr_offset, 1); -+ r |= avl6882_exec_n_wait(priv,AVL_FW_CMD_ACQUIRE); -+ -+ return r; -+} -+ -+ -+int AVL_Demod_DVBTxGetScanInfo(struct avl6882_priv *priv, AVL_DVBTxScanInfo* pstDVBTxScanInfo) -+{ -+ int r = AVL_EC_OK; -+ u32 ucTemp0 = 0; -+ u32 ucTemp1 = 0; -+ enum fe_status ucDemodLockStatus; -+ -+ r = avl6882_read_status(&priv->frontend, &ucDemodLockStatus); -+ if(ucDemodLockStatus == 0) -+ return r; -+ -+ r |= AVL6882_RD_REG8(priv, 0x800 + rs_DVBTx_rx_mode_caddr_offset, -+ &ucTemp0); -+ -+ pstDVBTxScanInfo->eTxStandard = (AVL_DVBTx_Standard)ucTemp0; -+ -+ -+ if(AVL_DVBTx_Standard_T == pstDVBTxScanInfo->eTxStandard) -+ { -+ r |= AVL6882_RD_REG8(priv, 0x8f0 + rs_DVBTx_hierarchy_caddr_offset,&ucTemp0); -+ } -+ else if(AVL_DVBTx_Standard_T2 == pstDVBTxScanInfo->eTxStandard) -+ { -+ r |= AVL6882_RD_REG8(priv,0x800 + rs_DVBTx_P1_S2_field_2_caddr_offset, &ucTemp1); -+ r |= AVL6882_RD_REG8(priv, 0x800 + rs_DVBTx_T2_profile_caddr_offset, &ucTemp0); -+ } -+ -+ pstDVBTxScanInfo->ucTxInfo = ucTemp0; -+ pstDVBTxScanInfo->ucFEFInfo = ucTemp1; -+ -+ return r; -+} -+ -+ -+ -+ -+static int AVL_Demod_DVBT2GetPLPList(struct avl6882_priv *priv, AVL_puchar pucPLPIndexArray, AVL_puchar pucPLPNumber) -+{ -+ int r = AVL_EC_OK; -+ u32 ucTemp = 0; -+ u32 uiPLPBuffer = 0x2912b4; -+ u32 ucPLPID = 0; -+ u32 ucPLPType = 0; -+ u32 ucPLPGroupID = 0; -+ u32 i = 0; -+ u8 ucDataPLPNum = 0; -+ u32 uiDelayMS = 20; -+ u32 uiTimes = 10; //time-out window 10*20 = 200ms -+ enum fe_status ucDemodLockStatus = 0; -+ -+ r = avl6882_read_status(&priv->frontend, &ucDemodLockStatus); -+ if (ucDemodLockStatus == 0) { -+ *pucPLPNumber = 0; -+ return r; -+ } -+ -+ for(i = 0; i < uiTimes; i++) -+ { -+ msleep(uiDelayMS); -+ r |= AVL6882_RD_REG8(priv,0x800 + rs_DVBTx_plp_list_request_caddr_offset, &ucTemp); -+ if(ucTemp == 0) -+ { -+ break; -+ } -+ } -+ -+ if(i == uiTimes) -+ { -+ r |= AVL_EC_GENERAL_FAIL; -+ return (r); -+ } -+ -+ r |= AVL6882_RD_REG8(priv,0x830 + rs_DVBTx_NUM_PLP_caddr_offset, &ucTemp); -+ -+ -+ for(i = 0; ifrequency/1000; -+ u16 BandWidth_Khz = c->bandwidth_hz/1000; -+ -+ int return_code = AVL_EC_OK; -+ AVL_DVBTxScanInfo stDVBTxScanInfo; -+ AVL_DVBTxBandWidth nBand = AVL_DVBTx_BW_8M; -+ u16 cur_index = 0; -+ u8 ucLockFlag = 0; -+ AVL_DVBT2_PROFILE ucT2Profile = AVL_DVBT2_PROFILE_UNKNOWN; -+ u8 ucDataPLPArray[255] = {0}; -+ u8 ucDataPLPNumber = 0; -+ u16 i; -+ -+ printk("[AVL_ChannelScan_Tx] Freq is %d MHz BW is %d MHz \n", -+ Freq_Khz/1000, BandWidth_Khz/1000); -+ -+ priv->g_nChannel_ts_total = 0; -+ -+ //=====Tuner Lock=====// -+ return_code = r848_lock_n_wait(priv, Freq_Khz, c->bandwidth_hz); -+ //=====Demod Lock=====// -+ nBand = Convert2DemodBand(BandWidth_Khz); -+ return_code = AVL_Demod_DVBTxChannelScan(priv, nBand, AVL_DVBTx_LockMode_ALL); -+ //=====Check Lock Status =====// -+ avl6882_demod_lock_wait(priv, &ucLockFlag); -+ -+ if(ucLockFlag == 1) { //DVBTx is locked -+ return_code |= AVL_Demod_DVBTxGetScanInfo(priv, &stDVBTxScanInfo); -+ if(stDVBTxScanInfo.eTxStandard == AVL_DVBTx_Standard_T2) { -+ //get PLP ID list only for DVBT2 signal, not for DVBT -+ cur_index = priv->g_nChannel_ts_total; -+ return_code = AVL_Demod_DVBT2GetPLPList(priv, ucDataPLPArray, &ucDataPLPNumber); -+ -+ for (i = 0; i < ucDataPLPNumber; i++) { -+ printk("[DVB-T2_Scan_Info] DATA PLP ID is %d, profile = %d\n", -+ ucDataPLPArray[i], stDVBTxScanInfo.ucTxInfo); -+ -+ //save channel RF frequency -+ priv->global_channel_ts_table[cur_index].channel_freq_khz = Freq_Khz; -+ // save channel bandwidth -+ priv->global_channel_ts_table[cur_index].channel_bandwith_khz = BandWidth_Khz; -+ // save data plp id -+ priv->global_channel_ts_table[cur_index].data_plp_id = ucDataPLPArray[i]; -+ // 0 - DVBT; 1 - DVBT2. -+ priv->global_channel_ts_table[cur_index].channel_type = AVL_DVBTx_Standard_T2; -+ // 0 - Base profile; 1 - Lite profile. -+ priv->global_channel_ts_table[cur_index].channel_profile = (AVL_DVBT2_PROFILE)stDVBTxScanInfo.ucTxInfo; -+ cur_index++; -+ } -+ priv->g_nChannel_ts_total = cur_index % MAX_CHANNEL_INFO; -+ if (stDVBTxScanInfo.ucFEFInfo == 1) { -+ ucT2Profile = (AVL_DVBT2_PROFILE) stDVBTxScanInfo.ucTxInfo; -+ if (ucT2Profile == AVL_DVBT2_PROFILE_BASE) { -+ //profile is base -+ //If T2 base is locked, try to lock T2 lite -+ AVL_Demod_DVBTxChannelScan(priv, nBand, AVL_DVBTx_LockMode_T2LITE); -+ ucT2Profile = AVL_DVBT2_PROFILE_LITE; -+ } else { -+ //If T2 lite is locked, try to lock T2 base -+ AVL_Demod_DVBTxChannelScan(priv, nBand, AVL_DVBTx_LockMode_T2BASE); -+ ucT2Profile = AVL_DVBT2_PROFILE_BASE; -+ } -+ avl6882_demod_lock_wait(priv, &ucLockFlag); -+ if (ucLockFlag == 1) { -+ //DVBTx is locked -+ cur_index = priv->g_nChannel_ts_total; -+ ucDataPLPNumber = 0; -+ return_code = AVL_Demod_DVBT2GetPLPList(priv, ucDataPLPArray, &ucDataPLPNumber); -+ -+ // data PLP ID and common PLP ID pairing -+ for (i = 0; i < ucDataPLPNumber; i++) { -+ printk("[DVB-T2_Scan_Info] DATA PLP ID is %d, profile = %d\n", -+ ucDataPLPArray[i], ucT2Profile); -+ -+ //save channel RF frequency -+ priv->global_channel_ts_table[cur_index].channel_freq_khz = Freq_Khz; -+ // save channel bandwidth -+ priv->global_channel_ts_table[cur_index].channel_bandwith_khz = BandWidth_Khz; -+ // save data plp id -+ priv->global_channel_ts_table[cur_index].data_plp_id = ucDataPLPArray[i]; -+ // 0 - DVBT; 1 - DVBT2. -+ priv->global_channel_ts_table[cur_index].channel_type = AVL_DVBTx_Standard_T2; -+ // 0 - Base profile; 1 - Lite profile. -+ priv->global_channel_ts_table[cur_index].channel_profile = ucT2Profile; -+ -+ cur_index++; -+ } -+ priv->g_nChannel_ts_total = cur_index % MAX_CHANNEL_INFO; -+ } -+ } else { -+ printk("Lock DVB-T2: No FEFInfo\n"); -+ } -+ } else { -+ // DVBT -+ cur_index = priv->g_nChannel_ts_total; -+ // save channel RF frequency -+ priv->global_channel_ts_table[cur_index].channel_freq_khz = Freq_Khz; -+ // save channel bandwidth -+ priv->global_channel_ts_table[cur_index].channel_bandwith_khz = BandWidth_Khz; -+ // save data plp id(not used for DVBT, set to 0xff) -+ priv->global_channel_ts_table[cur_index].data_plp_id = 0; -+ // 0 - DVBT; 1 - DVBT2. -+ priv->global_channel_ts_table[cur_index].channel_type = AVL_DVBTx_Standard_T; -+ // 0 - Low priority layer, 1 - High priority layer -+ priv->global_channel_ts_table[cur_index].dvbt_hierarchy_layer = 1; -+ cur_index++; -+ -+ if(stDVBTxScanInfo.ucTxInfo == 1) { -+ // for hierarchy -+ // save channel RF frequency -+ priv->global_channel_ts_table[cur_index].channel_freq_khz = Freq_Khz; -+ // save channel bandwidth -+ priv->global_channel_ts_table[cur_index].channel_bandwith_khz = BandWidth_Khz; -+ // save data plp id(not used for DVBT, set to 0xff) -+ priv->global_channel_ts_table[cur_index].data_plp_id = 0; -+ // 0 - DVBT; 1 - DVBT2. -+ priv->global_channel_ts_table[cur_index].channel_type = AVL_DVBTx_Standard_T; -+ // 0 - Low priority layer, 1 - High priority layer -+ priv->global_channel_ts_table[cur_index].dvbt_hierarchy_layer = 0; -+ cur_index++; -+ } -+ priv->g_nChannel_ts_total = cur_index % MAX_CHANNEL_INFO; -+ } -+ } else { -+ // return for unlock -+ printk("[DVBTx_ScanChannel_Tx] DVBTx channel scan is fail,Err.\n"); -+ } -+ -+ /* lock channel */ -+ for(i = 0; i < priv->g_nChannel_ts_total; i++) { -+ ucLockFlag = 0; -+ if(priv->global_channel_ts_table[i].channel_type == AVL_DVBTx_Standard_T) { -+ //DVB-T signal.. -+ AVL_LockChannel_T(priv, Freq_Khz, BandWidth_Khz, priv->global_channel_ts_table[i].dvbt_hierarchy_layer); -+ } else if (priv->global_channel_ts_table[i].channel_type == AVL_DVBTx_Standard_T2) { -+ //DVB-T2 signal, do not process FEF... -+ AVL_LockChannel_T2(priv, Freq_Khz, BandWidth_Khz,priv->global_channel_ts_table[i].channel_profile, priv->global_channel_ts_table[i].data_plp_id); -+ } -+ avl6882_demod_lock_wait(priv, &ucLockFlag); -+ } -+ -+ return return_code; -+} -+ -+ -+ -+ -+int AVL_Demod_DVBSx_Diseqc_SendTone( struct avl6882_priv *priv,u8 ucTone, u8 ucCount) -+{ -+ int r = 0; -+ u32 i1 = 0; -+ u32 i2 = 0; -+ //u8 pucBuffTemp[8] = {0}; -+ u8 Continuousflag = 0; -+ u16 uiTempOutTh = 0; -+ -+ if( ucCount>8 ) -+ { -+ r = AVL_EC_WARNING; -+ } -+ else -+ { -+ if (priv->config->eDiseqcStatus == AVL_DOS_InContinuous) -+ { -+ r |= AVL6882_RD_REG32(priv,0x16c000 + hw_diseqc_tx_cntrl_offset, &i1); -+ if ((i1>>10) & 0x01) -+ { -+ Continuousflag = 1; -+ i1 &= 0xfffff3ff; -+ r |= AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_tx_cntrl_offset, i1); -+ msleep(Diseqc_delay); //delay 20ms -+ } -+ } -+ //No data in the FIFO. -+ r |= AVL6882_RD_REG32(priv,0x16c000 + hw_diseqc_tx_cntrl_offset, &i1); -+ i1 &= 0xfffffff8; //put it into the FIFO load mode. -+ if( 0 == ucTone ) -+ { -+ i1 |= 0x01; -+ } -+ else -+ { -+ i1 |= 0x02; -+ } -+ r |= AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_tx_cntrl_offset, i1); -+ -+ -+ for (i2 = 0; i2 < ucCount; i2++) { -+ r |= AVL6882_WR_REG32(priv, 0x16c000 + hw_tx_fifo_map_offset, 1); -+ } -+#if 0 -+ //trunk address -+ ChunkAddr_Demod(0x16c000 + hw_tx_fifo_map_offset, pucBuffTemp); -+ pucBuffTemp[3] = 0; -+ pucBuffTemp[4] = 0; -+ pucBuffTemp[5] = 0; -+ pucBuffTemp[6] = 1; -+ -+ for( i2=0; i2config->eDiseqcStatus = AVL_DOS_InTone; -+ } -+ do -+ { -+ msleep(1); -+ if (++uiTempOutTh > 500) -+ { -+ r |= AVL_EC_TIMEOUT; -+ return(r); -+ } -+ r = AVL6882_RD_REG32(priv,0x16c000 + hw_diseqc_tx_st_offset, &i1); -+ } while ( 1 != ((i1 & 0x00000040) >> 6) ); -+ -+ msleep(Diseqc_delay); //delay 20ms -+ if (Continuousflag == 1) //resume to send out wave -+ { -+ //No data in FIFO -+ r |= AVL6882_RD_REG32(priv,0x16c000 + hw_diseqc_tx_cntrl_offset, &i1); -+ i1 &= 0xfffffff8; -+ i1 |= 0x03; //switch to continuous mode -+ r |= AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_tx_cntrl_offset, i1); -+ -+ //start to send out wave -+ i1 |= (1<<10); -+ r |= AVL6882_WR_REG32(priv,0x16c000 + hw_diseqc_tx_cntrl_offset, i1); -+ -+ } -+ } -+ return (r); -+} -+ -+ -+ -+ -+ -+#endif -+ -+ -+ -+ -+#if 0 -+ -+ -+ -+ -+ -+ -+ -+int AVL_Demod_DVBSxManualLock( struct avl6882_priv *priv,AVL_DVBSxManualLockInfo *pstManualLockInfo) -+{ -+ int r = AVL_EC_OK; -+ AVL_FunctionalMode eFuncMode = AVL_FuncMode_BlindScan; -+ -+ -+ r = AVL_Demod_DVBSx_GetFunctionalMode(priv,&eFuncMode); -+ if(eFuncMode == AVL_FuncMode_Demod) -+ { -+ r |= AVL6882_WR_REG16(priv,0xc00 + rs_DVBSx_fec_lock_saddr_offset, 0); -+ -+ r |= AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_fec_bypass_coderate_saddr_offset, 1);//DVBS manual lock -+ -+ if (pstManualLockInfo->eDVBSxStandard == AVL_DVBS ) -+ { -+ r |= AVL6882_WR_REG32(priv, 0xe00 + rc_DVBSx_dvbs_fec_coderate_iaddr_offset, pstManualLockInfo->eDVBSCodeRate); -+ } -+ else if(pstManualLockInfo->eDVBSxStandard == AVL_DVBS2 ) -+ { -+ r |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_dvbs2_code_rate_saddr_offset, pstManualLockInfo->eDVBS2CodeRate); -+ r |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_dvbs2_modulation_saddr_offset, pstManualLockInfo->eDVBSxModulationMode); -+ } -+ else -+ { -+ return AVL_EC_NOT_SUPPORTED; -+ } -+ r |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_decode_mode_saddr_offset, pstManualLockInfo->eDVBSxStandard); -+ -+ if(pstManualLockInfo->eDVBSxSpecInversion == AVL_SPECTRUM_AUTO) -+ { -+ r |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_iq_mode_saddr_offset, 1);//enable spectrum auto detection -+ } -+ else -+ { -+ r |= AVL6882_WR_REG32(priv, 0xe00 + rc_DVBSx_specinv_iaddr_offset, pstManualLockInfo->eDVBSxSpecInversion); -+ r |= AVL6882_WR_REG16(priv, 0xe00 + rc_DVBSx_iq_mode_saddr_offset, 0); -+ } -+ -+ r |= AVL6882_WR_REG32(priv, 0xe00 + rc_DVBSx_int_sym_rate_MHz_iaddr_offset, pstManualLockInfo->uiDVBSxSymbolRateSps); -+ -+ r |= avl6882_exec_n_wait(priv,AVL_FW_CMD_ACQUIRE ); -+ } -+ else if(eFuncMode == AVL_FuncMode_BlindScan) -+ { -+ return AVL_EC_NOT_SUPPORTED; -+ } -+ -+ return (r); -+} -+int AVL_Demod_DVBSxGetModulationInfo( struct avl6882_priv *priv,AVL_DVBSxModulationInfo *pstModulationInfo) -+{ -+ int r = AVL_EC_OK; -+ u32 uiTemp = 0; -+ u32 temp_uchar = 0; -+ -+ r = AVL6882_RD_REG32(priv, 0xc00 + rs_DVBSx_pilot_iaddr_offset, &uiTemp); -+ pstModulationInfo->eDVBSxPilot = (AVL_DVBSx_Pilot)(uiTemp); -+ -+ r |= AVL6882_RD_REG32(priv, 0xe00 + rc_DVBSx_internal_decode_mode_iaddr_offset,&uiTemp); -+ pstModulationInfo->eDVBSxStandard = (AVL_DVBSx_Standard)uiTemp; -+ -+ if(AVL_DVBS == (AVL_DVBSx_Standard)uiTemp) -+ { -+ r |= AVL6882_RD_REG32(priv, 0xe00 + rc_DVBSx_dvbs_fec_coderate_iaddr_offset,&uiTemp); -+ pstModulationInfo->eDVBSCodeRate = (AVL_DVBS_CodeRate)(uiTemp); -+ } -+ else -+ { -+ r |= AVL6882_RD_REG8(priv, 0xe00 + rc_DVBSx_dvbs2_fec_coderate_caddr_offset,&temp_uchar); -+ pstModulationInfo->eDVBS2CodeRate = (AVL_DVBS2_CodeRate)(temp_uchar); -+ } -+ -+ r |= AVL6882_RD_REG32(priv, 0xc00 + rs_DVBSx_modulation_iaddr_offset, &uiTemp); -+ pstModulationInfo->eDVBSxModulationMode = (AVL_DVBSx_ModulationMode)(uiTemp); -+ -+ r |= AVL6882_RD_REG32(priv, 0xc00 + rs_DVBSx_detected_alpha_iaddr_offset, &uiTemp); -+ pstModulationInfo->eDVBSxRollOff = (AVL_DVBSx_RollOff)(uiTemp); -+ -+ return (r); -+ -+} -+ -+int AVL_Demod_DVBSx_BlindScan_Start( struct avl6882_priv *priv,AVL_BlindScanPara * pBSPara, u16 uiTunerLPF_100kHz) -+{ -+ int r = AVL_EC_OK; -+ u16 uiCarrierFreq_100kHz = 0; -+ u16 uiMinSymRate = 0; -+ AVL_FunctionalMode enumFunctionalMode = AVL_FuncMode_Demod; -+ -+ r = AVL_Demod_DVBSx_GetFunctionalMode(priv,&enumFunctionalMode); -+ -+ if (enumFunctionalMode == AVL_FuncMode_BlindScan) { -+ r |= AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_tuner_LPF_100kHz_saddr_offset, uiTunerLPF_100kHz); -+ r |= AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_blind_scan_tuner_spectrum_inversion_saddr_offset, pBSPara->m_enumBSSpectrumPolarity); -+ -+ uiMinSymRate = pBSPara->m_uiMinSymRate_kHz - 200; // give some tolerance -+ -+ if (uiMinSymRate < 800) //Blind scan doesn't support symbol rate less then 1M, give 200K margin -+ { -+ uiMinSymRate = 800; -+ } -+ -+ if( pBSPara->m_uiStartFreq_100kHz < pBSPara->m_uiStopFreq_100kHz ) -+ { -+ if( AVL_EC_OK == r ) -+ { -+ uiCarrierFreq_100kHz = ((pBSPara->m_uiStopFreq_100kHz)+(pBSPara->m_uiStartFreq_100kHz))>>1; -+ r |= AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_tuner_frequency_100kHz_saddr_offset, uiCarrierFreq_100kHz); -+ r |= AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_blind_scan_min_sym_rate_kHz_saddr_offset, uiMinSymRate); -+ r |= AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_blind_scan_max_sym_rate_kHz_saddr_offset, (pBSPara->m_uiMaxSymRate_kHz)+200); -+ r |= AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_blind_scan_start_freq_100kHz_saddr_offset, (pBSPara->m_uiStartFreq_100kHz)); -+ r |= AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_blind_scan_end_freq_100kHz_saddr_offset, (pBSPara->m_uiStopFreq_100kHz)); -+ -+ if( AVL_EC_OK == r ) -+ { -+ r = avl6882_exec_n_wait(priv,AVL_FW_CMD_BLIND_SCAN); -+ } -+ } -+ } -+ else -+ { -+ r = AVL_EC_GENERAL_FAIL; -+ } -+ } -+ else -+ { -+ r = AVL_EC_GENERAL_FAIL; -+ } -+ -+ return (r); -+} -+#endif -+ -+#if 0 -+// need fix read data size -+int AVL_Demod_DVBSx_BlindScan_GetStatus( struct avl6882_priv *priv,AVL_BSInfo * pBSInfo) -+{ -+ int r = AVL_EC_OK; -+ -+ r = AVL6882_RD_REG16(priv,0xc00 + rs_DVBSx_blind_scan_progress_saddr_offset, &(pBSInfo->m_uiProgress)); -+ r |= AVL6882_RD_REG16(priv,0xc00 + rs_DVBSx_blind_scan_channel_count_saddr_offset, &(pBSInfo->m_uiChannelCount)); -+ r |= AVL6882_RD_REG16(priv,0xe00 + rc_DVBSx_blind_scan_start_freq_100kHz_saddr_offset, &(pBSInfo->m_uiNextStartFreq_100kHz)); -+ r |= AVL6882_RD_REG16(priv,0xc00 + rs_DVBSx_blind_scan_error_code_saddr_offset, &(pBSInfo->m_uiResultCode)); -+ if( pBSInfo->m_uiProgress > 100 ) -+ { -+ pBSInfo->m_uiProgress = 0; -+ } -+ -+ return(r); -+} -+ -+int AVL_Demod_DVBSx_BlindScan_Cancel( struct avl6882_priv *priv ) -+{ -+ int r; -+ enum AVL_FunctionalMode enumFunctionalMode = AVL_FuncMode_Demod; -+ -+ -+ -+ r = AVL_Demod_DVBSx_GetFunctionalMode(priv,&enumFunctionalMode); -+ -+ if(enumFunctionalMode == AVL_FuncMode_BlindScan) -+ { -+ r |= avl6882_exec_n_wait(priv,AVL_FW_CMD_HALT); -+ } -+ else -+ { -+ r = AVL_EC_GENERAL_FAIL; -+ } -+ -+ return(r); -+} -+ -+ -+int AVL_Demod_DVBSx_BlindScan_ReadChannelInfo( struct avl6882_priv *priv,u16 uiStartIndex, AVL_puint16 pChannelCount, AVL_ChannelInfo * pChannel) -+{ -+ int r = 0; -+ u32 channel_addr = 0; -+ u16 i1 = 0; -+ u16 i2 = 0; -+ u32 uiMinFreq = 0; -+ u16 iMinIdx = 0; -+ AVL_ChannelInfo sTempChannel; -+ -+ -+ -+ r = AVL6882_RD_REG16(priv,0xc00 + rs_DVBSx_blind_scan_channel_count_saddr_offset, &i1); -+ if( (uiStartIndex + (*pChannelCount)) > (i1) ) -+ { -+ *pChannelCount = i1-uiStartIndex; -+ } -+ r |= AVL6882_RD_REG16(priv,0xe00 + rc_DVBSx_blind_scan_channel_info_offset_saddr_offset, &i1); -+ channel_addr = 0x200C00 + uiStartIndex*sizeof(AVL_ChannelInfo); -+ for( i1=0; i1<(*pChannelCount); i1++ ) -+ { -+#if 1 //for some processors which can not read 12 bytes -+ //dump the channel information -+ r |= AVL6882_RD_REG32(priv, channel_addr, &(pChannel[i1].m_uiFrequency_kHz)); -+ channel_addr += 4; -+ r |= AVL6882_RD_REG32(priv, channel_addr, &(pChannel[i1].m_uiSymbolRate_Hz)); -+ channel_addr += 4; -+ r |= AVL6882_RD_REG32(priv, channel_addr, &(pChannel[i1].m_Flags)); -+ channel_addr += 4; -+#endif -+ } -+ -+ // Sort the results -+ for(i1=0; i1<(*pChannelCount); i1++) -+ { -+ iMinIdx = i1; -+ uiMinFreq = pChannel[i1].m_uiFrequency_kHz; -+ for(i2=(i1+1); i2<(*pChannelCount); i2++) -+ { -+ if(pChannel[i2].m_uiFrequency_kHz < uiMinFreq) -+ { -+ uiMinFreq = pChannel[i2].m_uiFrequency_kHz; -+ iMinIdx = i2; -+ } -+ } -+ sTempChannel = pChannel[iMinIdx]; -+ pChannel[iMinIdx] = pChannel[i1]; -+ pChannel[i1] = sTempChannel; -+ } -+ -+ return(r); -+} -+ -+ -+int AVL_Demod_DVBSx_BlindScan_Reset( struct avl6882_priv *priv ) -+{ -+ return AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_blind_scan_reset_saddr_offset, 1); -+} -+ -+ -+int AVL_Demod_DVBSx_SetFunctionalMode( struct avl6882_priv *priv,AVL_FunctionalMode enumFunctionalMode ) -+{ -+ int r = AVL_EC_OK; -+ r = AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_functional_mode_saddr_offset, (u16)enumFunctionalMode); -+ r |= AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_iq_mode_saddr_offset,0); -+ return(r); -+} -+ -+int AVL_Demod_DVBSx_SetDishPointingMode( struct avl6882_priv *priv,AVL_Switch enumOn_Off) -+{ -+ int r = AVL_EC_OK; -+ AVL_FunctionalMode enumFunctionalMode = AVL_FuncMode_BlindScan; -+ -+ r |= AVL_Demod_DVBSx_GetFunctionalMode(priv,&enumFunctionalMode); -+ if(enumFunctionalMode == AVL_FuncMode_Demod) -+ { -+ if(enumOn_Off == AVL_ON) -+ { -+ r |= AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_aagc_acq_gain_saddr_offset, 12); -+ r |= AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_dishpoint_mode_saddr_offset, 1); -+ } -+ else -+ { -+ r |= AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_aagc_acq_gain_saddr_offset, 10); -+ r |= AVL6882_WR_REG16(priv,0xe00 + rc_DVBSx_dishpoint_mode_saddr_offset, 0); -+ } -+ } -+ else -+ { -+ r = AVL_EC_GENERAL_FAIL; -+ } -+ -+ return(r); -+} -+#endif -+ -+ -+ -+ -+ -+ -+ -+ -+ -+#if 0 -+int AVL_Demod_GetVersion( struct avl6882_priv *priv,AVL_DemodVersion *pstDemodVersion) -+{ -+ int r = AVL_EC_OK; -+ u32 uiTemp = 0; -+ u8 ucBuff[4] = {0}; -+ -+ r = AVL6882_RD_REG32(priv,0x40000, &uiTemp); -+ if( AVL_EC_OK == r ) -+ { -+ pstDemodVersion->uiChip = uiTemp; -+ } -+ -+ r |= AVL6882_RD_REG32(priv,0x0a4 + rs_patch_ver_iaddr_offset, &uiTemp); -+ if( AVL_EC_OK == r ) -+ { -+ Chunk32_Demod(uiTemp, ucBuff); -+ pstDemodVersion->stPatch.ucMajor = ucBuff[0]; -+ pstDemodVersion->stPatch.ucMinor = ucBuff[1]; -+ pstDemodVersion->stPatch.usBuild = ucBuff[2]; -+ pstDemodVersion->stPatch.usBuild = ((u16)((pstDemodVersion->stPatch.usBuild)<<8)) + ucBuff[3]; -+ } -+ -+ return r; -+} -+#endif -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/drivers/media/dvb-frontends/avl6882.h b/drivers/media/dvb-frontends/avl6882.h -new file mode 100644 -index 0000000..9ede95d ---- /dev/null -+++ b/drivers/media/dvb-frontends/avl6882.h -@@ -0,0 +1,42 @@ -+/* -+ -+ 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. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ -+*/ -+ -+#ifndef AVL6882_H -+#define AVL6882_H -+ -+ -+struct avl6882_config { -+ /* the demodulator's i2c address */ -+ u8 demod_address; -+}; -+ -+ -+#if defined(CONFIG_DVB_AVL6882) || (defined(CONFIG_DVB_AVL6882_MODULE) && \ -+ defined(MODULE)) -+extern struct dvb_frontend *avl6882_attach(struct avl6882_config *config, -+ struct i2c_adapter *i2c); -+#else -+static inline struct dvb_frontend *avl6882_attach(struct avl6882_config *config, -+ struct i2c_adapter *i2c) -+{ -+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -+ return NULL; -+} -+#endif /* CONFIG_DVB_AVL6882 */ -+ -+#endif /* AVL6882_H */ -diff --git a/drivers/media/dvb-frontends/avl6882_priv.h b/drivers/media/dvb-frontends/avl6882_priv.h -new file mode 100644 -index 0000000..8e4b5e80f ---- /dev/null -+++ b/drivers/media/dvb-frontends/avl6882_priv.h -@@ -0,0 +1,1672 @@ -+#ifndef AVL6882_PRIV_H -+#define AVL6882_PRIV_H -+ -+#include "dvb_frontend.h" -+ -+ -+#define MAX_CHANNEL_INFO 256 -+ -+typedef struct s_DVBTx_Channel_TS -+{ -+ // number, example 474*1000 is RF frequency 474MHz. -+ int channel_freq_khz; -+ // number, example 8000 is 8MHz bandwith channel. -+ int channel_bandwith_khz; -+ -+ u8 channel_type; -+ // 0 - Low priority layer, 1 - High priority layer -+ u8 dvbt_hierarchy_layer; -+ // data PLP id, 0 to 255; for single PLP DVBT2 channel, this ID is 0; for DVBT channel, this ID isn't used. -+ u8 data_plp_id; -+ u8 channel_profile; -+}s_DVBTx_Channel_TS; -+ -+ -+ -+#define AVL6882_FW_DVBC 0 -+#define AVL6882_FW_DVBS 1 -+#define AVL6882_FW_DVBT 2 -+#define AVL6882_FW_ISDBT 3 -+ -+#define AVL6882_FW_COUNT 3 -+#define AVL6882_FW_HEADER_SIZE (8 * AVL6882_FW_COUNT) -+ -+ -+/* i2c */ -+#define MAX_I2C_READ_SIZE 64 -+#define MAX_I2C_WRITE_SIZE 62 -+//64 -+ -+ -+/* registers */ -+/* PLL */ -+#define AVLREG_PLL_RESET 0x00100000 -+#define AVLREG_PLL_dll_init 0x00100008 -+#define AVLREG_PLL_deglitch_mode 0x00100010 -+#define AVLREG_PLL_sys_pll_bypass 0x00100040 -+#define AVLREG_PLL_sys_pll_enable 0x00100044 -+#define AVLREG_PLL_sys_pll_divr 0x00100048 -+#define AVLREG_PLL_sys_pll_divf 0x0010004c -+#define AVLREG_PLL_sys_pll_divq 0x00100050 -+#define AVLREG_PLL_sys_pll_range 0x00100054 -+#define AVLREG_PLL_sys_pll_lock 0x00100058 -+#define AVLREG_PLL_mpeg_pll_bypass 0x0010005c -+#define AVLREG_PLL_mpeg_pll_enable 0x00100060 -+#define AVLREG_PLL_mpeg_pll_divr 0x00100064 -+#define AVLREG_PLL_mpeg_pll_divf 0x00100068 -+#define AVLREG_PLL_mpeg_pll_divq 0x0010006c -+#define AVLREG_PLL_mpeg_pll_range 0x00100070 -+#define AVLREG_PLL_mpeg_pll_lock 0x00100074 -+#define AVLREG_PLL_adc_pll_bypass 0x00100078 -+#define AVLREG_PLL_adc_pll_enable 0x0010007c -+#define AVLREG_PLL_adc_pll_divr 0x00100080 -+#define AVLREG_PLL_adc_pll_divf 0x00100084 -+#define AVLREG_PLL_adc_pll_divq 0x00100088 -+#define AVLREG_PLL_adc_pll_range 0x0010008c -+#define AVLREG_PLL_adc_pll_lock 0x00100090 -+#define AVLREG_PLL_mpeg_pll_reset 0x00100094 -+#define AVLREG_PLL_adc_pll_reset 0x00100098 -+#define AVLREG_PLL_sys_pll_reset 0x0010009c -+#define AVLREG_PLL_sys_pll_enable2 0x001000b4 -+#define AVLREG_PLL_sys_pll_enable3 0x001000b8 -+#define AVLREG_PLL_sys_pll_divq2 0x001000bc -+#define AVLREG_PLL_sys_pll_divq3 0x001000c0 -+#define AVLREG_PLL_mpeg_pll_enable2 0x001000c4 -+#define AVLREG_PLL_mpeg_pll_enable3 0x001000c8 -+#define AVLREG_PLL_mpeg_pll_divq2 0x001000cc -+#define AVLREG_PLL_mpeg_pll_divq3 0x001000d0 -+#define AVLREG_PLL_adc_pll_enable2 0x001000d4 -+#define AVLREG_PLL_adc_pll_enable3 0x001000d8 -+#define AVLREG_PLL_adc_pll_divq2 0x001000dc -+#define AVLREG_PLL_adc_pll_divq3 0x001000e0 -+#define AVLREG_PLL_ddc_clk_sel 0x001000e4 -+#define AVLREG_PLL_sdram_clk_sel 0x001000e8 -+#define AVLREG_PLL_dll_out_phase 0x00000100 -+#define AVLREG_PLL_dll_rd_phase 0x00000104 -+ -+/* TS */ -+#define AVLREG_TS_OUTPUT 0x00130420 -+#define TS_OUTPUT_ENABLE 0x00000000 -+#define TS_OUTPUT_DISABLE 0x00000fff -+ -+/* GPIO */ -+#define AVLREG_GPIO_BASE 0x00120000 -+#define GPIO_AGC_DVBTC (0x00) /* agc1_sel */ -+#define GPIO_AGC_DVBS (0x10) /* agc2_sel */ -+#define GPIO_LNB_VOLT (0x08) /* pin 38 - lnb_ctrl_1_sel */ -+#define GPIO_LNB_PWR (0x0c) /* pin 37 - lnb_ctrl_0_sel */ -+#define GPIO_RD_MASK (0x40) -+#define GPIO_0 (0) -+#define GPIO_1 (1) -+#define GPIO_Z (2) -+#define GPIO_AGC_ON (6) -+ -+ -+ -+//GPIO control -+#define lnb_cntrl_1_sel_offset 0x08 -+#define lnb_cntrl_0_sel_offset 0x0c -+ -+#define lnb_cntrl_1_i_offset 0x48 -+#define lnb_cntrl_0_i_offset 0x4c -+ -+ -+ -+ -+struct avl6882_fw { -+ u32 offset; -+ u32 size; -+ u32 *data; -+}; -+ -+struct avl6882_priv { -+ struct i2c_adapter *i2c; -+ struct avl6882_config *config; -+ struct dvb_frontend frontend; -+ enum fe_delivery_system delivery_system; -+ -+ /* DVB-Tx */ -+ u16 g_nChannel_ts_total; -+ s_DVBTx_Channel_TS global_channel_ts_table[MAX_CHANNEL_INFO]; -+ -+ struct avl6882_fw fw[AVL6882_FW_COUNT]; -+}; -+ -+ -+ -+ -+ -+typedef unsigned char AVL_semaphore; ///< the semaphore data type. -+ -+ -+ -+ -+ -+ -+/* known registers */ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+//SDK Version -+#define AVL_API_VER_MAJOR 0x02 -+#define AVL_API_VER_MINOR 0x03 -+#define AVL_API_VER_BUILD 0x02 -+ -+ -+#define AVL68XX 0x68624955 -+ -+#define AVL_FW_CMD_IDLE 0 -+#define AVL_FW_CMD_LD_DEFAULT 1 -+#define AVL_FW_CMD_ACQUIRE 2 -+#define AVL_FW_CMD_HALT 3 -+#define AVL_FW_CMD_DEBUG 4 -+#define AVL_FW_CMD_SLEEP 7 -+#define AVL_FW_CMD_WAKE 8 -+#define AVL_FW_CMD_BLIND_SCAN 9 -+#define AVL_FW_CMD_SDRAM_TEST 16 -+#define AVL_FW_CMD_INIT_SDRAM 17 -+#define AVL_FW_CMD_INIT_ADC 18 -+#define AVL_FW_CMD_CHANGE_MODE 19 -+ -+#define AVL_FW_CMD_DMA 21 -+#define AVL_FW_CMD_CALC_CRC 22 -+#define AVL_FW_CMD_PING 23 -+#define AVL_FW_CMD_DECOMPRESS 24 -+ -+ -+ -+/* -+ * Patch file stuff -+ */ -+#define PATCH_VAR_ARRAY_SIZE 32 -+ -+#define PATCH_CMD_VALIDATE_CRC 0 -+#define PATCH_CMD_PING 1 -+#define PATCH_CMD_LD_TO_DEVICE 2 -+#define PATCH_CMD_DMA 3 -+#define PATCH_CMD_DECOMPRESS 4 -+#define PATCH_CMD_ASSERT_CPU_RESET 5 -+#define PATCH_CMD_RELEASE_CPU_RESET 6 -+#define PATCH_CMD_LD_TO_DEVICE_IMM 7 -+#define PATCH_CMD_RD_FROM_DEVICE 8 -+#define PATCH_CMD_DMA_HW 9 -+#define PATCH_CMD_SET_COND_IMM 10 -+#define PATCH_CMD_EXIT 11 -+ -+ -+#define PATCH_CMP_TYPE_ZLIB 0 -+#define PATCH_CMP_TYPE_ZLIB_NULL 1 -+#define PATCH_CMP_TYPE_GLIB 2 -+#define PATCH_CMP_TYPE_NONE 3 -+ -+//Addr modes 2 bits -+#define PATCH_OP_ADDR_MODE_VAR_IDX 0 -+#define PATCH_OP_ADDR_MODE_IMMIDIATE 1 -+ -+//Unary operators 6 bits -+#define PATCH_OP_UNARY_NOP 0 -+#define PATCH_OP_UNARY_LOGICAL_NEGATE 1 -+#define PATCH_OP_UNARY_BITWISE_NEGATE 2 -+#define PATCH_OP_UNARY_BITWISE_AND 3 -+#define PATCH_OP_UNARY_BITWISE_OR 4 -+ -+//Binary operators 1 Byte -+#define PATCH_OP_BINARY_LOAD 0 -+#define PATCH_OP_BINARY_AND 1 -+#define PATCH_OP_BINARY_OR 2 -+#define PATCH_OP_BINARY_BITWISE_AND 3 -+#define PATCH_OP_BINARY_BITWISE_OR 4 -+#define PATCH_OP_BINARY_EQUALS 5 -+#define PATCH_OP_BINARY_STORE 6 -+#define PATCH_OP_BINARY_NOT_EQUALS 7 -+ -+#define PATCH_COND_EXIT_AFTER_LD 8 -+ -+ -+ -+ -+#define tuner_i2c_srst_offset 0x0 -+#define tuner_i2c_cntrl_offset 0x4 -+#define tuner_i2c_bit_rpt_clk_div_offset 0x18 -+#define tuner_i2c_bit_rpt_cntrl_offset 0x1C -+ -+#define esm_cntrl_offset 0x4 -+#define bit_error_offset 0x8 -+#define byte_num_offset 0xC -+#define packet_error_offset 0x10 -+#define packet_num_offset 0x14 -+#define tick_clear_offset 0x88 -+#define tick_type_offset 0x8C -+#define time_tick_low_offset 0x90 -+#define time_tick_high_offset 0x94 -+#define byte_tick_low_offset 0x98 -+#define byte_tick_high_offset 0x9C -+#define esm_mode_offset 0xC0 -+ -+#define rs_current_active_mode_iaddr_offset 0x24 -+#define rc_fw_command_saddr_offset 0x00 -+#define rs_core_ready_word_iaddr_offset 0xa0 -+#define rc_sdram_test_return_iaddr_offset 0x3C -+#define rc_sdram_test_result_iaddr_offset 0x40 -+#define rs_rf_agc_saddr_offset 0x44 -+ -+#define rc_fw_command_args_addr_iaddr_offset 0x58 -+ -+#define rc_ts_cntns_clk_frac_d_iaddr_offset 0x0000007c -+#define rc_ts_cntns_clk_frac_n_iaddr_offset 0x00000078 -+#define rc_enable_ts_continuous_caddr_offset 0x0000003a -+#define rc_ts_clock_edge_caddr_offset 0x0000003b -+#define rc_ts_serial_caddr_offset 0x0000003c -+#define rc_ts_serial_outpin_caddr_offset 0x0000003f -+#define rc_ts_serial_msb_caddr_offset 0x0000003e -+#define rc_ts_packet_len_caddr_offset 0x00000039 -+#define rc_ts_packet_order_caddr_offset rc_ts_serial_msb_caddr_offset -+#define rc_ts_error_bit_en_caddr_offset 0x000000000 -+#define rc_ts_error_polarity_caddr_offset 0x00000041 -+#define rc_ts_valid_polarity_caddr_offset 0x00000040 -+#define rc_ts_sync_pulse_caddr_offset 0x00000097 -+#define ts_clock_phase_caddr_offset 0x00000096 -+ -+#define rs_patch_ver_iaddr_offset 0x00000004 -+ -+#define hw_AVL_rx_rf_aagc_gain 0x160888 -+ -+ -+//Define ADC channel selection -+typedef enum AVL_ADC_Channel -+{ -+ AVL_ADC_CHAN2 = 0, -+ AVL_ADC_CHAN1 = 1, -+ AVL_ADC_OFF = 2 -+}AVL_ADC_Channel; -+ -+typedef enum AVL_ADC_Output_format -+{ -+ AVL_2COMP = 0, -+ AVL_OFFBIN = 1 -+}AVL_ADC_Output_format; -+ -+//Input_select enumeration definitions -+typedef enum AVL_DDC_Input -+{ -+ AVL_DIG_IN = 0, -+ AVL_ADC_IN = 1, -+ AVL_VEC_IN = 2, -+ AVL_VEC1x_IN = 3, -+ AVL_DIG1x_IN = 4 -+}AVL_DDC_Input; -+ -+// Defines BER type -+typedef enum AVL_BER_Type -+{ -+ AVL_PRE_VITERBI_BER = 0, // previous viterbi BER will be acquired. -+ AVL_POST_VITERBI_BER = 1, // post viterbi BER will be acquired. -+ AVL_PRE_LDPC_BER = 2, // previous LDPC BER will be acquired. -+ AVL_POST_LDPC_BER = 3, // post LDPC BER will be acquired. -+ AVL_FINAL_BER = 4 // final BER will be acquired. -+}AVL_BER_Type; -+ -+// Defines different standards supported by the demod. -+typedef enum AVL_DemodMode -+{ -+ AVL_DVBC = 0, -+ AVL_DVBSX = 1, -+ AVL_DVBTX = 2, -+ AVL_ISDBT = 3, -+ AVL_DTMB = 4, -+ AVL_ISDBS = 5, -+ AVL_ABSS = 6, -+ AVL_ATSC = 7, -+ AVL_DVBC2 = 8 -+} AVL_DemodMode; -+ -+// Defines the channel lock mode. -+typedef enum AVL_LockMode -+{ -+ AVL_LOCK_MODE_AUTO = 0, // lock channel automatically. -+ AVL_LOCK_MODE_MANUAL = 1 // lock channel manually. -+}AVL_LockMode; -+ -+// Defines channel lock status -+typedef enum AVL_LockStatus -+{ -+ AVL_STATUS_UNLOCK = 0, // channel isn't locked -+ AVL_STATUS_LOCK = 1 // channel is in locked state. -+}AVL_LockStatus; -+ -+typedef enum AVL_TSMode -+{ -+ AVL_TS_PARALLEL = 0, -+ AVL_TS_SERIAL = 1 -+}AVL_TSMode; -+ -+typedef enum AVL_TSClockEdge -+{ -+ AVL_MPCM_FALLING = 0, -+ AVL_MPCM_RISING = 1 -+} AVL_TSClockEdge; -+ -+typedef enum AVL_TSClockMode -+{ -+ AVL_TS_CONTINUOUS_ENABLE = 0, -+ AVL_TS_CONTINUOUS_DISABLE = 1 -+} AVL_TSClockMode; -+ -+typedef enum AVL_TSSerialPin -+{ -+ AVL_MPSP_DATA0 = 0, -+ AVL_MPSP_DATA7 = 1 -+} AVL_TSSerialPin; -+ -+typedef enum AVL_TSSerialOrder -+{ -+ AVL_MPBO_LSB = 0, -+ AVL_MPBO_MSB = 1 -+} AVL_TSSerialOrder; -+ -+typedef enum AVL_TSSerialSyncPulse -+{ -+ AVL_TS_SERIAL_SYNC_8_PULSE = 0, -+ AVL_TS_SERIAL_SYNC_1_PULSE = 1 -+} AVL_TSSerialSyncPulse; -+ -+typedef enum AVL_TSErrorBit -+{ -+ AVL_TS_ERROR_BIT_DISABLE = 0, -+ AVL_TS_ERROR_BIT_ENABLE = 1 -+} AVL_TSErrorBit; -+ -+typedef enum AVL_TSErrorPolarity -+{ -+ AVL_MPEP_Normal = 0, -+ AVL_MPEP_Invert = 1 -+} AVL_TSErrorPolarity; -+ -+typedef enum AVL_TSValidPolarity -+{ -+ AVL_MPVP_Normal = 0, -+ AVL_MPVP_Invert = 1 -+} AVL_TSValidPolarity; -+ -+typedef enum AVL_TSPacketLen -+{ -+ AVL_TS_188 = 0, -+ AVL_TS_204 = 1 -+} AVL_TSPacketLen; -+ -+typedef enum AVL_AGCPola -+{ -+ AVL_AGC_NORMAL = 0, // normal AGC polarity. Used for a tuner whose gain increases with increased AGC voltage. -+ AVL_AGC_INVERTED= 1 // inverted AGC polarity. Used for tuner whose gain decreases with increased AGC voltage. -+}AVL_AGCPola; -+ -+typedef enum AVL_TSParallelOrder -+{ -+ AVL_TS_PARALLEL_ORDER_INVERT = 0, -+ AVL_TS_PARALLEL_ORDER_NORMAL = 1 -+} AVL_TSParallelOrder; -+ -+typedef enum AVL_TSParallelPhase -+{ -+ AVL_TS_PARALLEL_PHASE_0 = 0, -+ AVL_TS_PARALLEL_PHASE_1 = 1, -+ AVL_TSG_PARALLEL_PHASE_2 = 2, -+ AVL_TS_PARALLEL_PHASE_3 = 3 -+}AVL_TSParallelPhase; -+ -+// Stores an unsigned 64-bit integer -+typedef struct AVLuint64 -+{ -+ u32 uiHighWord; // The most significant 32-bits of the unsigned 64-bit integer -+ u32 uiLowWord; // The least significant 32-bits of the unsigned 64-bit integer -+}AVLuint64; -+ -+ -+// Defines whether the feeback bit of the LFSR used to generate the BER/PER test pattern is inverted. -+typedef enum AVL_LFSR_FbBit -+{ -+ AVL_LFSR_FB_NOT_INVERTED = 0, // LFSR feedback bit isn't inverted -+ AVL_LFSR_FB_INVERTED = 1 // LFSR feedback bit is inverted -+}AVL_LFSR_FbBit; -+ -+// Defines the test pattern being used for BER/PER measurements. -+typedef enum AVL_TestPattern -+{ -+ AVL_TEST_LFSR_15 = 0, // BER test pattern is LFSR15 -+ AVL_TEST_LFSR_23 = 1 // BER test pattern is LFSR23 -+}AVL_TestPattern; -+ -+// Defines the type of auto error statistics -+typedef enum AVL_AutoErrorStat_Type -+{ -+ AVL_ERROR_STAT_BYTE = 0, // error statistics will be reset according to the number of received bytes. -+ AVL_ERROR_STAT_TIME = 1 // error statistics will be reset according to time interval. -+}AVL_AutoErrorStat_Type; -+ -+// Defines Error statistics mode -+typedef enum AVL_ErrorStat_Mode -+{ -+ AVL_ERROR_STAT_MANUAL = 0, -+ AVL_ERROR_STAT_AUTO = 1 -+}AVL_ErrorStat_Mode; -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+// Defines the DiSEqC status -+typedef enum AVL_DiseqcStatus -+{ -+ AVL_DOS_Uninitialized = 0, // DiSEqC has not been initialized yet. -+ AVL_DOS_Initialized = 1, // DiSEqC has been initialized. -+ AVL_DOS_InContinuous = 2, // DiSEqC is in continuous mode. -+ AVL_DOS_InTone = 3, // DiSEqC is in tone burst mode. -+ AVL_DOS_InModulation = 4 // DiSEqC is in modulation mode. -+}AVL_DiseqcStatus; -+ -+// Contains variables for storing error statistics used in the BER and PER calculations. -+typedef struct AVL_ErrorStats -+{ -+ u16 usLFSRSynced; // Indicates whether the receiver is synchronized with the transmitter generating the BER test pattern. -+ u16 usLostLock; // Indicates whether the receiver has lost lock since the BER/PER measurement was started. -+ AVLuint64 stSwCntNumBits; // A software counter which stores the number of bits which have been received. -+ AVLuint64 stSwCntBitErrors; // A software counter which stores the number of bit errors which have been detected. -+ AVLuint64 stNumBits; // The total number of bits which have been received. -+ AVLuint64 stBitErrors; // The total number of bit errors which have been detected. -+ AVLuint64 stSwCntNumPkts; // A software counter which stores the number of packets which have been received. -+ AVLuint64 stSwCntPktErrors; // A software counter which stores the number of packet errors which have been detected. -+ AVLuint64 stNumPkts; // The total number of packets which have been received. -+ AVLuint64 stPktErrors; // The total number of packet errors which have been detected. -+ u32 uiBER; // The bit error rate scaled by 1e9. -+ u32 uiPER; // The packet error rate scaled by 1e9. -+}AVL_ErrorStats; -+ -+typedef enum AVL_Demod_Xtal -+{ -+ Xtal_30M = 0, -+ Xtal_16M, -+ Xtal_24M, -+ Xtal_27M -+} AVL_Demod_Xtal; -+ -+typedef enum AVL_InputPath -+{ -+ AVL_IF_I, -+ AVL_IF_Q -+} AVL_InputPath; -+ -+// Contains variables for storing error statistics used in the BER and PER calculations. -+typedef struct AVL_ErrorStatConfig -+{ -+ AVL_ErrorStat_Mode eErrorStatMode; // indicates the error statistics mode. -+ AVL_AutoErrorStat_Type eAutoErrorStatType; // indicates the MPEG data sampling clock mode. -+ u32 uiTimeThresholdMs; // used to set time interval for auto error statistics. -+ u32 uiNumberThresholdByte; // used to set the received byte number threshold for auto error statistics. -+}AVL_ErrorStatConfig; -+ -+// Contains variables for storing error statistics used in the BER and PER calculations. -+typedef struct AVL_BERConfig -+{ -+ AVL_TestPattern eBERTestPattern; // indicates the pattern of LFSR. -+ AVL_LFSR_FbBit eBERFBInversion; // indicates LFSR feedback bit inversion. -+ u32 uiLFSRSynced; // indicates the LFSR synchronization status. -+ u32 uiLFSRStartPos; //set LFSR start byte positon -+}AVL_BERConfig; -+ -+ -+ -+ -+/* -+typedef struct AVL_StandardSpecificFunctions -+{ -+ AVL_Func_Initialize fpRxInitializeFunc; -+ AVL_Func_GetLockStatus fpGetLockStatus; -+ AVL_Func_GetSNR fpGetSNR; -+ AVL_Func_GetSQI fpGetSQI; -+ AVL_Func_GetPrePostBER fpGetPrePostBER; -+}AVL_StandardSpecificFunctions; -+*/ -+typedef struct AVL_DVBTxPara -+{ -+ AVL_InputPath eDVBTxInputPath; -+ u32 uiDVBTxIFFreqHz; -+ AVL_AGCPola eDVBTxAGCPola; -+} AVL_DVBTxPara; -+ -+typedef enum AVL_Diseqc_WaveFormMode -+{ -+ AVL_DWM_Normal = 0, // Normal waveform mode -+ AVL_DWM_Envelope = 1 // Envelope waveform mode -+}AVL_Diseqc_WaveFormMode; -+ -+typedef struct AVL_DVBSxPara -+{ -+ AVL_semaphore semDiseqc; -+ AVL_DiseqcStatus eDiseqcStatus; -+ AVL_AGCPola eDVBSxAGCPola; -+ AVL_Diseqc_WaveFormMode e22KWaveForm; -+}AVL_DVBSxPara; -+ -+typedef enum AVL_ISDBT_BandWidth -+{ -+ AVL_ISDBT_BW_6M = 0, -+ AVL_ISDBT_BW_8M = 1, -+}AVL_ISDBT_BandWidth; -+ -+typedef struct AVL_ISDBTPara -+{ -+ AVL_InputPath eISDBTInputPath; -+ AVL_ISDBT_BandWidth eISDBTBandwidth; -+ u32 uiISDBTIFFreqHz; -+ AVL_AGCPola eISDBTAGCPola; -+} AVL_ISDBTPara; -+ -+typedef struct AVL_DTMBPara -+{ -+ AVL_InputPath eDTMBInputPath; -+ u32 uiDTMBIFFreqHz; -+ u32 uiDTMBSymbolRateHz; -+ AVL_AGCPola eDTMBAGCPola; -+} AVL_DTMBPara; -+ -+typedef enum AVL_DVBC_Standard -+{ -+ AVL_DVBC_J83A = 0, //the J83A standard -+ AVL_DVBC_J83B = 1, //the J83B standard -+ AVL_DVBC_UNKNOWN = 2 -+}AVL_DVBC_Standard; -+ -+typedef struct AVL_DVBCPara -+{ -+ AVL_InputPath eDVBCInputPath; -+ u32 uiDVBCIFFreqHz; -+ u32 uiDVBCSymbolRateSps; -+ AVL_AGCPola eDVBCAGCPola; -+ AVL_DVBC_Standard eDVBCStandard; -+} AVL_DVBCPara; -+ -+/**************************************************/ -+typedef struct AVL_CommonConfig -+{ -+ u16 usI2CAddr; -+ AVL_Demod_Xtal eDemodXtal; -+ AVL_TSMode eTSMode; -+ AVL_TSClockEdge eClockEdge; -+ AVL_TSClockMode eClockMode; -+}AVL_CommonConfig; -+ -+typedef struct AVL_DVBTxConfig -+{ -+ AVL_InputPath eDVBTxInputPath; -+ u32 uiDVBTxIFFreqHz; -+ AVL_AGCPola eDVBTxAGCPola; -+} AVL_DVBTxConfig; -+ -+typedef struct AVL_DVBCConfig -+{ -+ AVL_InputPath eDVBCInputPath; -+ u32 uiDVBCIFFreqHz; -+ u32 uiDVBCSymbolRateSps; -+ AVL_AGCPola eDVBCAGCPola; -+ AVL_DVBC_Standard eDVBCStandard; -+} AVL_DVBCConfig; -+ -+typedef struct AVL_DVBSxConfig -+{ -+ AVL_AGCPola eDVBSxAGCPola; -+ AVL_Diseqc_WaveFormMode e22KWaveForm; -+} AVL_DVBSxConfig; -+ -+typedef struct AVL_DTMBConfig -+{ -+ AVL_InputPath eDTMBInputPath; -+ u32 uiDTMBIFFreqHz; -+ u32 uiDTMBSymbolRateHz; -+ AVL_AGCPola eDTMBAGCPola; -+} AVL_DTMBConfig; -+ -+typedef struct AVL_ISDBTConfig -+{ -+ AVL_InputPath eISDBTInputPath; -+ AVL_ISDBT_BandWidth eISDBTBandwidth; -+ u32 uiISDBTIFFreqHz; -+ AVL_AGCPola eISDBTAGCPola; -+} AVL_ISDBTConfig; -+ -+typedef struct AVL_TSConfig -+{ -+ AVL_TSMode eMode; -+ AVL_TSClockEdge eClockEdge; -+ AVL_TSClockMode eClockMode; -+ AVL_TSSerialPin eSerialPin; -+ AVL_TSSerialOrder eSerialOrder; -+ AVL_TSSerialSyncPulse eSerialSyncPulse; -+ AVL_TSErrorBit eErrorBit; -+ AVL_TSErrorPolarity eErrorPolarity; -+ AVL_TSValidPolarity eValidPolarity; -+ AVL_TSPacketLen ePacketLen; -+ AVL_TSParallelOrder eParallelOrder; -+ u32 guiDVBTxSerialTSContinuousHz; -+ u32 guiDVBSxSerialTSContinuousHz; -+ u32 guiISDBTSerialTSContinuousHz; -+ u32 guiDTMBSerialTSContinuousHz; -+ u32 guiDVBCSerialTSContinuousHz; -+}AVL_TSConfig; -+ -+ -+ -+// The Availink version structure. -+typedef struct AVL_Version -+{ -+ u8 ucMajor; // The major version number. -+ u8 ucMinor; // The minor version number. -+ u16 usBuild; // The build version number. -+}AVL_Version; -+ -+// Stores AVLEM61 device version information. -+typedef struct AVL_DemodVersion -+{ -+ u32 uiChip; // Hardware version information. 0xYYYYMMDD -+ AVL_Version stPatch; // The version of the internal patch. -+} AVL_DemodVersion; -+ -+ -+#define Diseqc_delay 20 -+ -+#define AVL_EC_OK 0 // There is no error. -+#define AVL_EC_WARNING 1 // There is warning. -+#define AVL_EC_GENERAL_FAIL 2 // A general failure has occurred. -+#define AVL_EC_I2C_FAIL 4 // An I2C operation failed during communication with the AVLEM61 through the BSP. -+#define AVL_EC_I2C_REPEATER_FAIL 8 // An error ocurred during communication between AVLEM61 I2C master and tuner. This error code is defined by enum AVLEM61_MessageType_II2C_Repeater_Status. -+#define AVL_EC_RUNNING 16 // The AVLEM61 device is busy processing a previous receiver/i2c repeater command. -+#define AVL_EC_TIMEOUT 32 // Operation failed in a given time period -+#define AVL_EC_SLEEP 64 // Demod in sleep mode -+#define AVL_EC_NOT_SUPPORTED 128 // Specified operation isn't support in current senario -+#define AVL_EC_BSP_ERROR1 256 // BSP Error 1, if it's used, need to be customized -+#define AVL_EC_BSP_ERROR2 512 // BSP Error 2, if it's used, need to be customized -+ -+#define AVL_CONSTANT_10_TO_THE_9TH 1000000000 //10e9 -+ -+ -+ -+ -+ -+ -+ -+ -+/* DVBS header file */ -+#define rc_DVBSx_rfagc_pol_iaddr_offset 0x00000000 -+#define rc_DVBSx_internal_decode_mode_iaddr_offset 0x0000000c -+#define rc_DVBSx_format_iaddr_offset 0x00000010 -+#define rc_DVBSx_input_iaddr_offset 0x00000014 -+#define rc_DVBSx_specinv_iaddr_offset 0x00000034 -+#define rc_DVBSx_dvbs_fec_coderate_iaddr_offset 0x00000044 -+#define rc_DVBSx_int_sym_rate_MHz_iaddr_offset 0x00000054 -+#define rc_DVBSx_aagc_acq_gain_saddr_offset 0x000000fe -+#define rc_DVBSx_Max_LowIF_sps_iaddr_offset 0x000000a4 -+#define rc_DVBSx_int_dmd_clk_MHz_saddr_offset 0x00000164 -+#define rc_DVBSx_int_mpeg_clk_MHz_saddr_offset 0x00000168 -+#define rc_DVBSx_int_fec_clk_MHz_saddr_offset 0x0000016a -+#define rc_DVBSx_fec_bypass_coderate_saddr_offset 0x0000019a -+#define rc_DVBSx_tuner_frequency_100kHz_saddr_offset 0x000001c0 -+#define rc_DVBSx_tuner_LPF_100kHz_saddr_offset 0x000001c6 -+#define rc_DVBSx_blind_scan_start_freq_100kHz_saddr_offset 0x000001cc -+#define rc_DVBSx_blind_scan_min_sym_rate_kHz_saddr_offset 0x000001d0 -+#define rc_DVBSx_blind_scan_end_freq_100kHz_saddr_offset 0x000001d2 -+#define rc_DVBSx_blind_scan_channel_info_offset_saddr_offset 0x000001d4 -+#define rc_DVBSx_blind_scan_max_sym_rate_kHz_saddr_offset 0x000001d6 -+#define rc_DVBSx_decode_mode_saddr_offset 0x00000204 -+#define rc_DVBSx_iq_mode_saddr_offset 0x0000020a -+#define rc_DVBSx_dishpoint_mode_saddr_offset 0x0000020e -+#define rc_DVBSx_blind_scan_reset_saddr_offset 0x00000210 -+#define rc_DVBSx_functional_mode_saddr_offset 0x00000212 -+#define rc_DVBSx_blind_scan_tuner_spectrum_inversion_saddr_offset 0x00000226 -+#define rc_DVBSx_IF_Offset_10kHz_saddr_offset 0x00000234 -+#define rc_DVBSx_dvbs2_fec_coderate_caddr_offset 0x0000023f -+#define rc_DVBSx_adc_Q_chan_sel_caddr_offset 0x00000246 -+#define rc_DVBSx_adc_I_chan_sel_caddr_offset 0x00000247 -+#define rc_DVBSx_dvbs2_code_rate_saddr_offset 0x00000258 -+#define rc_DVBSx_dvbs2_modulation_saddr_offset 0x0000025a -+#define rc_DVBSx_int_adc_clk_MHz_saddr_offset 0x000002a0 -+ -+#define rs_DVBSx_modulation_iaddr_offset 0x0000000c -+#define rs_DVBSx_pilot_iaddr_offset 0x00000010 -+#define rs_DVBSx_int_SNR_dB_iaddr_offset 0x00000020 -+#define rs_DVBSx_blind_scan_channel_count_saddr_offset 0x000000b0 -+#define rs_DVBSx_blind_scan_error_code_saddr_offset 0x000000b4 -+#define rs_DVBSx_blind_scan_progress_saddr_offset 0x000000b6 -+#define rs_DVBSx_post_viterbi_BER_estimate_x10M_iaddr_offset 0x000000c4 -+#define rs_DVBSx_post_LDPC_BER_estimate_x10M_iaddr_offset 0x000000c8 -+#define rs_DVBSx_pre_LDPC_BER_estimate_x10M_iaddr_offset 0x000000cc -+#define rs_DVBSx_detected_alpha_iaddr_offset 0x000000d0 -+#define rs_DVBSx_int_carrier_freq_100kHz_saddr_offset 0x00000078 -+#define rs_DVBSx_fec_lock_saddr_offset 0x0000009e -+ -+ -+#define hw_diseqc_tx_cntrl_offset 0x0 -+#define hw_diseqc_tone_frac_n_offset 0x4 -+#define hw_diseqc_tone_frac_d_offset 0x8 -+#define hw_diseqc_tx_st_offset 0xC -+#define hw_diseqc_rx_parity_offset 0x10 -+#define hw_diseqc_rx_msg_tim_offset 0x14 -+#define hw_diseqc_rx_st_offset 0x18 -+#define hw_diseqc_rx_cntrl_offset 0x1C -+#define hw_diseqc_srst_offset 0x20 -+#define hw_diseqc_samp_frac_n_offset 0x28 -+#define hw_diseqc_samp_frac_d_offset 0x2C -+#define hw_rx_fifo_map_offset 0x40 -+#define hw_tx_fifo_map_offset 0x80 -+ -+/// Represents the code rate. The Availink device can automatically detect the code rate of the input signal. -+typedef enum AVL_DVBS_CodeRate -+{ -+ AVL_DVBS_CR_1_2 = 0, -+ AVL_DVBS_CR_2_3 = 1, -+ AVL_DVBS_CR_3_4 = 2, -+ AVL_DVBS_CR_5_6 = 3, -+ AVL_DVBS_CR_6_7 = 4, -+ AVL_DVBS_CR_7_8 = 5 -+}AVL_DVBS_CodeRate; -+ -+ -+typedef enum AVL_DVBS2_CodeRate -+{ -+ AVL_DVBS2_CR_1_4 = 0, -+ AVL_DVBS2_CR_1_3 = 1, -+ AVL_DVBS2_CR_2_5 = 2, -+ AVL_DVBS2_CR_1_2 = 3, -+ AVL_DVBS2_CR_3_5 = 4, -+ AVL_DVBS2_CR_2_3 = 5, -+ AVL_DVBS2_CR_3_4 = 6, -+ AVL_DVBS2_CR_4_5 = 7, -+ AVL_DVBS2_CR_5_6 = 8, -+ AVL_DVBS2_CR_8_9 = 9, -+ AVL_DVBS2_CR_9_10 = 10 -+}AVL_DVBS2_CodeRate; -+ -+typedef enum AVL_DVBSx_Pilot -+{ -+ AVL_DVBSx_Pilot_OFF = 0, // Pilot off -+ AVL_DVBSx_Pilot_ON = 1 // Pilot on -+}AVL_DVBSx_Pilot; -+ -+typedef enum AVL_DVBSx_ModulationMode -+{ -+ AVL_DVBSx_QPSK = 0, // QPSK -+ AVL_DVBSx_8PSK = 1, // 8-PSK -+ AVL_DVBSx_16APSK = 2, // 16-APSK -+ AVL_DVBSx_32APSK = 3 // 32-APSK -+}AVL_DVBSx_ModulationMode; -+ -+ -+typedef enum AVL_DVBSx_RollOff -+{ -+ AVL_DVBSx_RollOff_20 = 0, // Roll off is 0.20 -+ AVL_DVBSx_RollOff_25 = 1, // Roll off is 0.25 -+ AVL_DVBSx_RollOff_35 = 2 // Roll off is 0.35 -+}AVL_DVBSx_RollOff; -+ -+typedef enum AVL_DVBSx_Standard -+{ -+ AVL_DVBS = 0, // DVBS standard -+ AVL_DVBS2 = 1 // DVBS2 standard -+}AVL_DVBSx_Standard; -+ -+// Defines the AVL device spectrum inversion mode -+typedef enum AVL_SpectrumInversion -+{ -+ AVL_SPECTRUM_NORMAL = 0, // Signal spectrum in normal. -+ AVL_SPECTRUM_INVERTED = 1, // Signal spectrum in inverted. -+ AVL_SPECTRUM_AUTO = 2 // Signal spectrum isn't known. -+}AVL_SpectrumInversion; -+ -+// Defines the ON/OFF options for the AVLEM61 device. -+typedef enum AVL_Switch -+{ -+ AVL_ON = 0, // switched on -+ AVL_OFF = 1 // switched off -+}AVL_Switch; -+ -+// Defines the device functional mode. -+typedef enum AVL_FunctionalMode -+{ -+ AVL_FuncMode_Demod = 0, // The device is in demod mode. -+ AVL_FuncMode_BlindScan = 1 // The device is in blind scan mode. -+}AVL_FunctionalMode; -+ -+typedef enum AVL_Diseqc_TxGap -+{ -+ AVL_DTXG_15ms = 0, // The gap is 15 ms. -+ AVL_DTXG_20ms = 1, // The gap is 20 ms. -+ AVL_DTXG_25ms = 2, // The gap is 25 ms. -+ AVL_DTXG_30ms = 3 // The gap is 30 ms. -+}AVL_Diseqc_TxGap; -+ -+typedef enum AVL_Diseqc_TxMode -+{ -+ AVL_DTM_Modulation = 0, // Use modulation mode. -+ AVL_DTM_Tone0 = 1, // Send out tone 0. -+ AVL_DTM_Tone1 = 2, // Send out tone 1. -+ AVL_DTM_Continuous = 3 // Continuously send out pulses. -+}AVL_Diseqc_TxMode; -+ -+typedef enum AVL_Diseqc_RxTime -+{ -+ AVL_DRT_150ms = 0, // Wait 150 ms for receive data and then close the input FIFO. -+ AVL_DRT_170ms = 1, // Wait 170 ms for receive data and then close the input FIFO. -+ AVL_DRT_190ms = 2, // Wait 190 ms for receive data and then close the input FIFO. -+ AVL_DRT_210ms = 3 // Wait 210 ms for receive data and then close the input FIFO. -+}AVL_Diseqc_RxTime; -+ -+// Stores blind scan info -+typedef struct AVL_BSInfo -+{ -+ u16 m_uiProgress; // The percentage completion of the blind scan procedure. A value of 100 indicates that the blind scan is finished. -+ u16 m_uiChannelCount; // The number of channels detected thus far by the blind scan operation. The Availink device can store up to 120 detected channels. -+ u16 m_uiNextStartFreq_100kHz; // The start frequency of the next scan in units of 100kHz. -+ u16 m_uiResultCode; // The result of the blind scan operation. Possible values are: 0 - blind scan operation normal; 1 -- more than 120 channels have been detected. -+}AVL_BSInfo; -+ -+// Stores channel info -+typedef struct AVL_ChannelInfo -+{ -+ u32 m_uiFrequency_kHz; // The channel carrier frequency in units of kHz. -+ u32 m_uiSymbolRate_Hz; // The symbol rate in units of Hz. -+ u32 m_Flags; // Contains bit-mapped fields which store additional channel configuration information. -+}AVL_ChannelInfo; -+ -+typedef struct AVL_DVBSxModulationInfo -+{ -+ AVL_DVBSx_ModulationMode eDVBSxModulationMode; -+ AVL_DVBS_CodeRate eDVBSCodeRate; -+ AVL_DVBS2_CodeRate eDVBS2CodeRate; -+ AVL_DVBSx_Pilot eDVBSxPilot; -+ AVL_DVBSx_RollOff eDVBSxRollOff; -+ AVL_DVBSx_Standard eDVBSxStandard; -+}AVL_DVBSxModulationInfo; -+ -+typedef struct AVL_DVBSxManualLockInfo -+{ -+ AVL_DVBSx_ModulationMode eDVBSxModulationMode; -+ AVL_DVBS_CodeRate eDVBSCodeRate; -+ AVL_DVBS2_CodeRate eDVBS2CodeRate; -+ AVL_DVBSx_Pilot eDVBSxPilot; -+ AVL_SpectrumInversion eDVBSxSpecInversion; -+ AVL_DVBSx_Standard eDVBSxStandard; -+ u32 uiDVBSxSymbolRateSps; -+}AVL_DVBSxManualLockInfo; -+ -+// Defines the device spectrum polarity setting. -+typedef enum AVL_BlindSanSpectrumPolarity -+{ -+ AVL_Spectrum_Invert = 0, -+ AVL_Spectrum_Normal = 1 -+}AVL_BlindSanSpectrumPolarity; -+ -+/// Stores the blind scan parameters which are passed to the blind scan function. -+typedef struct AVL_BlindScanPara -+{ -+ u16 m_uiStartFreq_100kHz; // The start scan frequency in units of 100kHz. The minimum value depends on the tuner specification. -+ u16 m_uiStopFreq_100kHz; // The stop scan frequency in units of 100kHz. The maximum value depends on the tuner specification. -+ u16 m_uiMinSymRate_kHz; // The minimum symbol rate to be scanned in units of kHz. The minimum value is 1000 kHz. -+ u16 m_uiMaxSymRate_kHz; // The maximum symbol rate to be scanned in units of kHz. The maximum value is 45000 kHz. -+ AVL_BlindSanSpectrumPolarity m_enumBSSpectrumPolarity; -+}AVL_BlindScanPara; -+ -+// Stores DiSEqC operation parameters -+typedef struct AVL_Diseqc_Para -+{ -+ u16 uiToneFrequencyKHz;// The DiSEqC bus speed in units of kHz. Normally, it is 22kHz. -+ AVL_Diseqc_TxGap eTXGap; // Transmit gap -+ AVL_Diseqc_WaveFormMode eTxWaveForm; // Transmit waveform format -+ AVL_Diseqc_RxTime eRxTimeout; // Receive time frame window -+ AVL_Diseqc_WaveFormMode eRxWaveForm; // Receive waveform format -+}AVL_Diseqc_Para; -+ -+// Stores the DiSEqC transmitter status. -+typedef struct AVL_Diseqc_TxStatus -+{ -+ u8 m_TxDone; // Indicates whether the transmission is complete (1 - transmission is finished, 0 - transmission is still in progress). -+ u8 m_TxFifoCount; // The number of bytes remaining in the transmit FIFO -+}AVL_Diseqc_TxStatus; -+ -+// Stores the DiSEqC receiver status -+typedef struct AVL_Diseqc_RxStatus -+{ -+ u8 m_RxFifoCount; // The number of bytes in the DiSEqC receive FIFO. -+ u8 m_RxFifoParChk; // The parity check result of the received data. This is a bit-mapped field in which each bit represents the parity check result for each each byte in the receive FIFO. The upper bits without corresponding data are undefined. If a bit is 1, the corresponding byte in the FIFO has good parity. For example, if three bytes are in the FIFO, and the parity check value is 0x03 (value of bit 2 is zero), then the first and the second bytes in the receive FIFO are good. The third byte had bad parity. -+ u8 m_RxDone; // 1 if the receiver window is turned off, 0 if it is still in receiving state. -+}AVL_Diseqc_RxStatus; -+ -+ -+ -+ -+ -+ -+/* DVBC */ -+//DVBC config registers offset address -+#define rc_DVBC_symbol_rate_Hz_iaddr_offset 0x00000000 -+#define rc_DVBC_sample_rate_Hz_iaddr_offset 0x00000004 -+#define rc_DVBC_dmd_clk_Hz_iaddr_offset 0x00000008 -+#define rc_DVBC_j83b_mode_caddr_offset 0x00000017 -+#define rc_DVBC_tuner_type_caddr_offset 0x00000024 -+#define rc_DVBC_input_format_caddr_offset 0x00000025 -+#define rc_DVBC_spectrum_invert_caddr_offset 0x00000026 -+#define rc_DVBC_input_select_caddr_offset 0x00000027 -+#define rc_DVBC_if_freq_Hz_iaddr_offset 0x00000028 -+#define rc_DVBC_qam_mode_iaddr_offset 0x0000002c -+#define rc_DVBC_rfagc_pol_caddr_offset 0x00000049 -+#define rc_DVBC_fec_clk_Hz_iaddr_offset 0x00000050 -+#define rc_DVBC_get_btr_crl_iaddr_offset 0x00000080 -+#define rc_DVBC_qam_mode_scan_control_iaddr_offset 0x00000090 -+#define rc_DVBC_adc_sel_caddr_offset 0x000001ef -+#define rc_DVBC_adc_use_pll_clk_caddr_offset 0x000001ee -+ -+ -+ -+//DVBC status registers offset address -+#define rs_DVBC_mode_status_iaddr_offset 0x00000004 -+#define rs_DVBC_snr_dB_x100_saddr_offset 0x0000000e -+#define rs_DVBC_j83b_il_mode_caddr_offset 0x0000001d -+#define rs_DVBC_post_viterbi_BER_estimate_x10M_iaddr_offset 0x0000004c -+ -+typedef enum AVL_DVBC_TunerType -+{ -+ AVL_DVBC_IF = 0, -+ AVL_DVBC_BASEBAND = 1 -+}AVL_DVBC_TunerType; -+ -+typedef enum AVL_DVBC_ChannelType -+{ -+ AVL_DVBC_I_CHANNEL = 0, -+ AVL_DVBC_Q_CHANNEL = 1 -+}AVL_DVBC_ChannelType; -+ -+typedef enum AVL_DVBCQAMMode -+{ -+ AVL_DVBC_16QAM = 0, -+ AVL_DVBC_32QAM = 1, -+ AVL_DVBC_64QAM = 2, -+ AVL_DVBC_128QAM = 3, -+ AVL_DVBC_256QAM = 4 -+}AVL_DVBCQAMMode; -+ -+// Defines the symbol interleave mode of the received DVBC signal, only used for J.83B. -+typedef enum AVL_DVBCInterleaveMode -+{ -+ AVL_DVBC_INTERLEAVE_128_1_0 = 0, -+ AVL_DVBC_INTERLEAVE_128_1_1 = 1, -+ AVL_DVBC_INTERLEAVE_128_2 = 2, -+ AVL_DVBC_INTERLEAVE_64_2 = 3, -+ AVL_DVBC_INTERLEAVE_128_3 = 4, -+ AVL_DVBC_INTERLEAVE_32_4 = 5, -+ AVL_DVBC_INTERLEAVE_128_4 = 6, -+ AVL_DVBC_INTERLEAVE_16_8 = 7, -+ AVL_DVBC_INTERLEAVE_128_5 = 8, -+ AVL_DVBC_INTERLEAVE_8_16 = 9, -+ AVL_DVBC_INTERLEAVE_128_6 = 10, -+ AVL_DVBC_INTERLEAVE_128_7 = 12, -+ AVL_DVBC_INTERLEAVE_128_8 = 14 -+}AVL_DVBCInterleaveMode; -+ -+ -+typedef struct AVL_DVBCModulationInfo -+{ -+ AVL_DVBCQAMMode eQAMMode; -+ AVL_DVBCInterleaveMode eInterleaveMode; -+}AVL_DVBCModulationInfo; -+ -+ typedef struct AVL_DVBC_SQI_CN_Table_Element -+ { -+ AVL_DVBC_Standard eStandard; -+ AVL_DVBCQAMMode modulation; -+ u32 CN_Test_Result_x100_db; -+ }AVL_DVBC_SQI_CN_Table_Element; -+ -+ -+/* DVBT2 */ -+ -+#define rc_DVBTx_fund_rate_Hz_iaddr_offset 0x00000004 -+#define rc_DVBTx_sample_rate_Hz_iaddr_offset 0x00000008 -+#define rc_DVBTx_rf_agc_pol_caddr_offset 0x0000000f -+#define rc_DVBTx_tuner_type_caddr_offset 0x00000040 -+#define rc_DVBTx_input_format_caddr_offset 0x00000041 -+#define rc_DVBTx_spectrum_invert_caddr_offset 0x00000042 -+#define rc_DVBTx_input_select_caddr_offset 0x00000043 -+#define rc_DVBTx_nom_carrier_freq_Hz_iaddr_offset 0x00000044 -+#define rc_DVBTx_l1_proc_only_caddr_offset 0x00000054 -+#define rc_DVBTx_common_PLP_present_caddr_offset 0x00000055 -+#define rc_DVBTx_common_PLP_ID_caddr_offset 0x00000056 -+#define rc_DVBTx_data_PLP_ID_caddr_offset 0x00000057 -+#define rc_DVBTx_dvbt_layer_select_caddr_offset 0x0000006a -+#define rc_DVBTx_acquire_mode_caddr_offset 0x0000006b -+#define rc_DVBTx_mpeg_clk_rate_Hz_iaddr_offset 0x0000006c -+#define rc_DVBTx_adc_sel_caddr_offset 0x00000077 -+#define rc_DVBTx_adc_use_pll_clk_caddr_offset 0x00000076 -+ -+ -+#define rs_DVBTx_rx_mode_caddr_offset 0x000000d0 -+#define rs_DVBTx_fec_lock_caddr_offset 0x000000d2 -+#define rs_DVBTx_snr_dB_x100_saddr_offset 0x000000d6 -+#define rs_DVBTx_post_viterbi_BER_estimate_x10M_iaddr_offset 0x00000114 -+#define rs_DVBTx_post_LDPC_BER_estimate_x1B_iaddr_offset 0x00000118 -+#define rs_DVBTx_pre_LDPC_BER_estimate_x10M_iaddr_offset 0x0000011c -+#define rs_DVBTx_plp_list_request_caddr_offset 0x00000133 -+ -+#define rs_DVBTx_data_PLP_ID_caddr_offset 0x00000000 -+#define rs_DVBTx_data_PLP_TYPE_caddr_offset 0x00000001 -+#define rs_DVBTx_data_PLP_COD_caddr_offset 0x00000007 -+#define rs_DVBTx_data_PLP_MOD_caddr_offset 0x00000008 -+#define rs_DVBTx_data_PLP_ROTATION_caddr_offset 0x00000009 -+#define rs_DVBTx_data_PLP_FEC_TYPE_caddr_offset 0x0000000b -+ -+#define rs_DVBTx_common_PLP_ID_caddr_offset 0x00000000 -+#define rs_DVBTx_common_PLP_COD_caddr_offset 0x00000007 -+#define rs_DVBTx_common_PLP_MOD_caddr_offset 0x00000008 -+#define rs_DVBTx_common_PLP_ROTATION_caddr_offset 0x00000009 -+#define rs_DVBTx_common_PLP_FEC_TYPE_caddr_offset 0x0000000b -+ -+#define rs_DVBTx_P1_S2_field_2_caddr_offset 0x00000003 -+#define rs_DVBTx_MISO_SISO_caddr_offset 0x00000005 -+#define rs_DVBTx_T2_profile_caddr_offset 0x00000006 -+#define rs_DVBTx_FFT_size_caddr_offset 0x00000007 -+ -+#define rs_DVBTx_NUM_PLP_caddr_offset 0x00000002 -+ -+#define rs_DVBTx_constellation_caddr_offset 0x00000001 -+#define rs_DVBTx_hierarchy_caddr_offset 0x00000002 -+#define rs_DVBTx_HP_code_rate_caddr_offset 0x00000003 -+#define rs_DVBTx_LP_code_rate_caddr_offset 0x00000004 -+#define rs_DVBTx_guard_interval_caddr_offset 0x00000005 -+#define rs_DVBTx_transmission_mode_caddr_offset 0x00000006 -+ -+#define rs_DVBTx_BWT_EXT_caddr_offset 0x00000001 -+#define rs_DVBTx_GUARD_INTERVAL_caddr_offset 0x00000005 -+#define rs_DVBTx_PAPR_caddr_offset 0x00000006 -+#define rs_DVBTx_L1_MOD_caddr_offset 0x00000007 -+#define rs_DVBTx_PILOT_PATTERN_caddr_offset 0x00000014 -+#define rs_DVBTx_CELL_ID_saddr_offset 0x00000016 -+#define rs_DVBTx_NETWORK_ID_saddr_offset 0x00000018 -+#define rs_DVBTx_T2_SYSTEM_ID_saddr_offset 0x0000001a -+#define rs_DVBTx_NUM_T2_FRAMES_caddr_offset 0x0000001d -+#define rs_DVBTx_NUM_DATA_SYMBOLS_saddr_offset 0x0000001e -+ -+#define rs_DVBTx_Signal_Presence_iaddr_offset 0x00000150 -+ -+typedef enum AVL_DVBTx_TunerType -+{ -+ AVL_DVBTX_REAL_IF = 0, -+ AVL_DVBTX_COMPLEX_BASEBAND = 1, -+ AVL_DVBTX_REAL_IF_FROM_Q = 2 -+}AVL_DVBTx_TunerType; -+ -+typedef enum AVL_DVBT2_PLP_Type -+{ -+ AVL_DVBT2_SINGLE_PLP = 0, -+ AVL_DVBT2_MULTIPLE_PLP = 1 -+}AVL_DVBT2_PLP_Type; -+ -+typedef enum AVL_DVBTxBandWidth -+{ -+ AVL_DVBTx_BW_1M7 = 0, -+ AVL_DVBTx_BW_5M = 1, -+ AVL_DVBTx_BW_6M = 2, -+ AVL_DVBTx_BW_7M = 3, -+ AVL_DVBTx_BW_8M = 4 -+}AVL_DVBTxBandWidth; -+ -+typedef enum AVL_DVBTx_LockMode -+{ -+ AVL_DVBTx_LockMode_T2BASE_T = 0, -+ AVL_DVBTx_LockMode_T2LITE_T = 1, -+ AVL_DVBTx_LockMode_T2BASE = 2, -+ AVL_DVBTx_LockMode_T2LITE = 3, -+ AVL_DVBTx_LockMode_T_ONLY = 4, -+ AVL_DVBTx_LockMode_ALL = 5 -+}AVL_DVBTx_LockMode; -+ -+typedef enum AVL_DVBT_Layer -+{ -+ AVL_DVBT_LAYER_LP = 0, -+ AVL_DVBT_LAYER_HP = 1 -+}AVL_DVBT_Layer; -+ -+typedef enum AVL_DVBT_FFTSize -+{ -+ AVL_DVBT_FFT_2K = 0, -+ AVL_DVBT_FFT_8K = 1, -+ AVL_DVBT_FFT_UNKNOWN = 2 -+}AVL_DVBT_FFTSize; -+ -+typedef enum AVL_DVBT_GuardInterval -+{ -+ AVL_DVBT_GUARD_1_32 = 0, -+ AVL_DVBT_GUARD_1_16 = 1, -+ AVL_DVBT_GUARD_1_8 = 2, -+ AVL_DVBT_GUARD_1_4 = 3 -+}AVL_DVBT_GuardInterval; -+ -+typedef enum AVL_DVBT_ModulationMode -+{ -+ AVL_DVBT_QPSK = 0, -+ AVL_DVBT_16QAM = 1, -+ AVL_DVBT_64QAM = 2, -+ AVL_DVBT_MOD_UNKNOWN = 3 -+}AVL_DVBT_ModulationMode; -+ -+typedef enum AVL_DVBT_Hierarchy -+{ -+ AVL_DVBT_HIER_NONE = 0, -+ AVL_DVBT_HIER_ALPHA_1 = 1, -+ AVL_DVBT_HIER_ALPHA_2 = 2, -+ AVL_DVBT_HIER_ALPHA_4 = 3 -+}AVL_DVBT_Hierarchy; -+ -+typedef enum AVL_DVBT_CodeRate -+{ -+ AVL_DVBT_CR_1_2 = 0, -+ AVL_DVBT_CR_2_3 = 1, -+ AVL_DVBT_CR_3_4 = 2, -+ AVL_DVBT_CR_5_6 = 3, -+ AVL_DVBT_CR_7_8 = 4 -+}AVL_DVBT_CodeRate; -+ -+typedef enum AVL_DVBT2_FFTSize -+{ -+ AVL_DVBT2_FFT_1K = 0, -+ AVL_DVBT2_FFT_2K = 1, -+ AVL_DVBT2_FFT_4K = 2, -+ AVL_DVBT2_FFT_8K = 3, -+ AVL_DVBT2_FFT_16K = 4, -+ AVL_DVBT2_FFT_32K = 5 -+}AVL_DVBT2_FFTSize; -+ -+typedef enum AVL_DVBT2_MISO_SISO -+{ -+ AVL_DVBT2_SISO = 0, -+ AVL_DVBT2_MISO = 1 -+}AVL_DVBT2_MISO_SISO; -+ -+ -+typedef enum AVL_DVBT2_PROFILE -+{ -+ AVL_DVBT2_PROFILE_BASE = 0, -+ AVL_DVBT2_PROFILE_LITE = 1, -+ AVL_DVBT2_PROFILE_UNKNOWN = 2 -+}AVL_DVBT2_PROFILE; -+ -+typedef enum AVL_DVBT2_PILOT_PATTERN -+{ -+ AVL_DVBT2_PP_PP1 = 0, -+ AVL_DVBT2_PP_PP2 = 1, -+ AVL_DVBT2_PP_PP3 = 2, -+ AVL_DVBT2_PP_PP4 = 3, -+ AVL_DVBT2_PP_PP5 = 4, -+ AVL_DVBT2_PP_PP6 = 5, -+ AVL_DVBT2_PP_PP7 = 6, -+ AVL_DVBT2_PP_PP8 = 7, -+ AVL_DVBT2_PP_DVBT = 8, -+ AVL_DVBT2_PP_DVBT_REVERSE = 9, -+ AVL_DVBT2_PP_UNKNOWN = 10 -+}AVL_DVBT2_PILOT_PATTERN; -+ -+typedef enum AVL_DVBT2_DATA_PLP_TYPE -+{ -+ AVL_DVBT2_DATA_PLP_TYPE1 = 1, -+ AVL_DVBT2_DATA_PLP_TYPE2 = 2 -+}AVL_DVBT2_DATA_PLP_TYPE; -+ -+typedef enum AVL_DVBT2_CodeRate -+{ -+ AVL_DVBT2_CR_1_2 = 0, -+ AVL_DVBT2_CR_3_5 = 1, -+ AVL_DVBT2_CR_2_3 = 2, -+ AVL_DVBT2_CR_3_4 = 3, -+ AVL_DVBT2_CR_4_5 = 4, -+ AVL_DVBT2_CR_5_6 = 5, -+ AVL_DVBT2_CR_1_3 = 6, -+ AVL_DVBT2_CR_2_5 = 7 -+}AVL_DVBT2_CodeRate; -+ -+typedef enum AVL_DVBT2_PLP_ModulationMode -+{ -+ AVL_DVBT2_QPSK = 0, -+ AVL_DVBT2_16QAM = 1, -+ AVL_DVBT2_64QAM = 2, -+ AVL_DVBT2_256QAM = 3 -+}AVL_DVBT2_PLP_ModulationMode; -+ -+typedef enum AVL_DVBT2_L1_Modulation -+{ -+ AVL_DVBT2_L1_BPSK = 0, -+ AVL_DVBT2_L1_QPSK = 1, -+ AVL_DVBT2_L1_16QAM = 2, -+ AVL_DVBT2_L1_64QAM = 3 -+}AVL_DVBT2_L1_Modulation; -+ -+typedef enum AVL_DVBT2_PLP_Constellation_Rotation -+{ -+ AVL_DVBT2_PLP_NOT_ROTATION = 0, -+ AVL_DVBT2_PLP_ROTATION = 1 -+}AVL_DVBT2_PLP_Constellation_Rotation; -+ -+typedef enum AVL_DVBT2_PLP_FEC_Type -+{ -+ AVL_DVBT2_FEC_LDPC16K = 0, -+ AVL_DVBT2_FEC_LDPC64K = 1 -+}AVL_DVBT2_PLP_FEC_Type; -+ -+typedef enum AVL_DVBTx_Standard -+{ -+ AVL_DVBTx_Standard_T = 0, //the DVB-T standard -+ AVL_DVBTx_Standard_T2 = 1 //the DVB-T2 standard -+}AVL_DVBTx_Standard; -+ -+typedef enum AVL_DVBT2_PAPR -+{ -+ AVL_DVBT2_PAPR_NONE = 0, -+ AVL_DVBT2_PAPR_ACE = 1, -+ AVL_DVBT2_PAPR_TR = 2, -+ AVL_DVBT2_PAPR_BOTH = 3 -+}AVL_DVBT2_PAPR; -+ -+typedef enum AVL_DVBT2_GUARD_INTERVAL -+{ -+ AVL_DVBT2_GI_1_32 = 0, -+ AVL_DVBT2_GI_1_16 = 1, -+ AVL_DVBT2_GI_1_8 = 2, -+ AVL_DVBT2_GI_1_4 = 3, -+ AVL_DVBT2_GI_1_128 = 4, -+ AVL_DVBT2_GI_19_128 = 5, -+ AVL_DVBT2_GI_19_256 = 6 -+}AVL_DVBT2_GUARD_INTERVAL; -+ -+ -+ -+typedef struct AVL_DVBT_RF_Table_Element -+{ -+ AVL_DVBT_ModulationMode modulation; -+ AVL_DVBT_CodeRate code_rate; -+ int Nordig_RF_Ref_dbm; -+}AVL_DVBT_RF_Table_Element; -+ -+typedef struct AVL_DVBT_BERSQI_List -+{ -+ u32 m_ber; -+ u32 m_ber_sqi; -+}AVL_DVBT_BERSQI_List; -+ -+typedef struct AVL_DVBT_Non_Hierarchical_CN_Table_Element -+{ -+ AVL_DVBT_ModulationMode modulation; -+ AVL_DVBT_CodeRate hp_code_rate; -+ int CN_NordigP1_x100_db; -+}AVL_DVBT_Non_Hierarchical_CN_Table_Element; -+ -+typedef struct AVL_DVBT_Hierarchical_CN_Table_Element -+{ -+ AVL_DVBT_Layer selected_layer; -+ AVL_DVBT_ModulationMode modulation; -+ AVL_DVBT_CodeRate code_rate; -+ AVL_DVBT_Hierarchy hierarchy; -+ int CN_NordigP1_x100_db; -+}AVL_DVBT_Hierarchical_CN_Table_Element; -+ -+typedef struct DVBT2_CN_Table_Element -+{ -+ AVL_DVBT2_PLP_ModulationMode modulation; -+ AVL_DVBT2_CodeRate code_rate; -+ int CN_NordigP1_x100_db; -+}DVBT2_CN_Table_Element; -+ -+// DVBT2 pilot boosting correct CN table -+typedef struct DVBT2_PBC_CN_Table_Element -+{ -+ AVL_DVBT2_FFTSize fft_size; -+ AVL_DVBT2_PILOT_PATTERN pilot_pattern; -+ int PCB_CN; -+}DVBT2_PBC_CN_Table_Element; -+typedef struct AVL_DVBT2_RF_Table_Element -+{ -+ AVL_DVBT2_PLP_ModulationMode modulation; -+ AVL_DVBT2_CodeRate code_rate; -+ int Nordig_RF_Ref_dbm; -+}AVL_DVBT2_RF_Table_Element; -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+AVL_DVBC_SQI_CN_Table_Element AVL_DVBC_CN_Table[]= -+{ -+ //profile 1, AWGN -+ {AVL_DVBC_J83A, AVL_DVBC_16QAM , 1700}, -+ {AVL_DVBC_J83A, AVL_DVBC_32QAM , 1980}, -+ {AVL_DVBC_J83A, AVL_DVBC_64QAM , 2300}, -+ {AVL_DVBC_J83A, AVL_DVBC_128QAM , 2600}, -+ {AVL_DVBC_J83A, AVL_DVBC_256QAM , 2920}, -+ -+ {AVL_DVBC_J83B, AVL_DVBC_64QAM , 2180}, -+ {AVL_DVBC_J83B, AVL_DVBC_256QAM , 2810} -+}; -+ -+AVL_DVBT_Non_Hierarchical_CN_Table_Element AVL_DVBT_Non_Hierarchical_CN_Table[]= -+{ -+ //profile 1, Gaussian -+ {AVL_DVBT_QPSK, AVL_DVBT_CR_1_2, 510}, -+ {AVL_DVBT_QPSK, AVL_DVBT_CR_2_3, 690}, -+ {AVL_DVBT_QPSK, AVL_DVBT_CR_3_4, 790}, -+ {AVL_DVBT_QPSK, AVL_DVBT_CR_5_6, 890}, -+ {AVL_DVBT_QPSK, AVL_DVBT_CR_7_8, 970}, -+ -+ {AVL_DVBT_16QAM, AVL_DVBT_CR_1_2, 1080}, -+ {AVL_DVBT_16QAM, AVL_DVBT_CR_2_3, 1310}, -+ {AVL_DVBT_16QAM, AVL_DVBT_CR_3_4, 1460}, -+ {AVL_DVBT_16QAM, AVL_DVBT_CR_5_6, 1560}, -+ {AVL_DVBT_16QAM, AVL_DVBT_CR_7_8, 1600}, -+ -+ {AVL_DVBT_64QAM, AVL_DVBT_CR_1_2, 1650}, -+ {AVL_DVBT_64QAM, AVL_DVBT_CR_2_3, 1870}, -+ {AVL_DVBT_64QAM, AVL_DVBT_CR_3_4, 2020}, -+ {AVL_DVBT_64QAM, AVL_DVBT_CR_5_6, 2160}, -+ {AVL_DVBT_64QAM, AVL_DVBT_CR_7_8, 2250} -+}; -+ -+ -+ -+AVL_DVBT_Hierarchical_CN_Table_Element AVL_DVBT_Hierarchical_CN_Table[]= -+{ -+ //profile 1, Gaussian -+ //For HP, only QPSK is used -+ -+ //64QAM -+ {AVL_DVBT_LAYER_HP, AVL_DVBT_64QAM, AVL_DVBT_CR_1_2,AVL_DVBT_HIER_ALPHA_1,1090}, -+ {AVL_DVBT_LAYER_LP, AVL_DVBT_64QAM, AVL_DVBT_CR_1_2,AVL_DVBT_HIER_ALPHA_1,1670}, -+ -+ {AVL_DVBT_LAYER_HP, AVL_DVBT_64QAM, AVL_DVBT_CR_2_3,AVL_DVBT_HIER_ALPHA_1,1410}, -+ {AVL_DVBT_LAYER_LP, AVL_DVBT_64QAM, AVL_DVBT_CR_2_3,AVL_DVBT_HIER_ALPHA_1,1910}, -+ -+ {AVL_DVBT_LAYER_HP, AVL_DVBT_64QAM, AVL_DVBT_CR_3_4,AVL_DVBT_HIER_ALPHA_1,1570}, -+ {AVL_DVBT_LAYER_LP, AVL_DVBT_64QAM, AVL_DVBT_CR_3_4,AVL_DVBT_HIER_ALPHA_1,2090}, -+ -+ -+ {AVL_DVBT_LAYER_HP, AVL_DVBT_64QAM, AVL_DVBT_CR_1_2,AVL_DVBT_HIER_ALPHA_2,850}, -+ {AVL_DVBT_LAYER_LP, AVL_DVBT_64QAM, AVL_DVBT_CR_1_2,AVL_DVBT_HIER_ALPHA_2,1850}, -+ -+ {AVL_DVBT_LAYER_HP, AVL_DVBT_64QAM, AVL_DVBT_CR_2_3,AVL_DVBT_HIER_ALPHA_2,1100}, -+ {AVL_DVBT_LAYER_LP, AVL_DVBT_64QAM, AVL_DVBT_CR_2_3,AVL_DVBT_HIER_ALPHA_2,2120}, -+ -+ {AVL_DVBT_LAYER_HP, AVL_DVBT_64QAM, AVL_DVBT_CR_3_4,AVL_DVBT_HIER_ALPHA_2,1280}, -+ {AVL_DVBT_LAYER_LP, AVL_DVBT_64QAM, AVL_DVBT_CR_3_4,AVL_DVBT_HIER_ALPHA_2,2360}, -+ -+ //16QAM -+ {AVL_DVBT_LAYER_HP, AVL_DVBT_16QAM, AVL_DVBT_CR_1_2,AVL_DVBT_HIER_ALPHA_2,680}, -+ {AVL_DVBT_LAYER_LP, AVL_DVBT_16QAM, AVL_DVBT_CR_1_2,AVL_DVBT_HIER_ALPHA_2,1500}, -+ -+ {AVL_DVBT_LAYER_HP, AVL_DVBT_16QAM, AVL_DVBT_CR_2_3,AVL_DVBT_HIER_ALPHA_2,910}, -+ {AVL_DVBT_LAYER_LP, AVL_DVBT_16QAM, AVL_DVBT_CR_2_3,AVL_DVBT_HIER_ALPHA_2,1720}, -+ -+ {AVL_DVBT_LAYER_HP, AVL_DVBT_16QAM, AVL_DVBT_CR_3_4,AVL_DVBT_HIER_ALPHA_2,1040}, -+ {AVL_DVBT_LAYER_LP, AVL_DVBT_16QAM, AVL_DVBT_CR_3_4,AVL_DVBT_HIER_ALPHA_2,1840}, -+ -+ -+ {AVL_DVBT_LAYER_HP, AVL_DVBT_16QAM, AVL_DVBT_CR_1_2,AVL_DVBT_HIER_ALPHA_4,580}, -+ {AVL_DVBT_LAYER_LP, AVL_DVBT_16QAM, AVL_DVBT_CR_1_2,AVL_DVBT_HIER_ALPHA_4,1950}, -+ -+ {AVL_DVBT_LAYER_HP, AVL_DVBT_16QAM, AVL_DVBT_CR_2_3,AVL_DVBT_HIER_ALPHA_4,790}, -+ {AVL_DVBT_LAYER_LP, AVL_DVBT_16QAM, AVL_DVBT_CR_2_3,AVL_DVBT_HIER_ALPHA_4,2140}, -+ -+ {AVL_DVBT_LAYER_HP, AVL_DVBT_16QAM, AVL_DVBT_CR_3_4,AVL_DVBT_HIER_ALPHA_4,910}, -+ {AVL_DVBT_LAYER_LP, AVL_DVBT_16QAM, AVL_DVBT_CR_3_4,AVL_DVBT_HIER_ALPHA_4,2250} -+}; -+ -+ -+DVBT2_CN_Table_Element DVBT2_RAW_CN_Table[]= -+{ -+ //profile 1, Gaussian -+ {AVL_DVBT2_QPSK, AVL_DVBT2_CR_1_3, -120}, //from DVB-S2 std -+ {AVL_DVBT2_QPSK, AVL_DVBT2_CR_2_5, -030}, //from DVB-S2 std -+ {AVL_DVBT2_QPSK, AVL_DVBT2_CR_1_2, 100}, -+ {AVL_DVBT2_QPSK, AVL_DVBT2_CR_3_5, 220}, -+ {AVL_DVBT2_QPSK, AVL_DVBT2_CR_2_3, 310}, -+ {AVL_DVBT2_QPSK, AVL_DVBT2_CR_3_4, 410}, -+ {AVL_DVBT2_QPSK, AVL_DVBT2_CR_4_5, 470}, -+ {AVL_DVBT2_QPSK, AVL_DVBT2_CR_5_6, 520}, -+ -+ {AVL_DVBT2_16QAM, AVL_DVBT2_CR_1_3, 370}, -+ {AVL_DVBT2_16QAM, AVL_DVBT2_CR_2_5, 490}, -+ {AVL_DVBT2_16QAM, AVL_DVBT2_CR_1_2, 620}, -+ {AVL_DVBT2_16QAM, AVL_DVBT2_CR_3_5, 760}, -+ {AVL_DVBT2_16QAM, AVL_DVBT2_CR_2_3, 890}, -+ {AVL_DVBT2_16QAM, AVL_DVBT2_CR_3_4, 1000}, -+ {AVL_DVBT2_16QAM, AVL_DVBT2_CR_4_5, 1080}, -+ {AVL_DVBT2_16QAM, AVL_DVBT2_CR_5_6, 1130}, -+ -+ {AVL_DVBT2_64QAM, AVL_DVBT2_CR_1_3, 760}, -+ {AVL_DVBT2_64QAM, AVL_DVBT2_CR_2_5, 920}, -+ {AVL_DVBT2_64QAM, AVL_DVBT2_CR_1_2, 1050}, -+ {AVL_DVBT2_64QAM, AVL_DVBT2_CR_3_5, 1230}, -+ {AVL_DVBT2_64QAM, AVL_DVBT2_CR_2_3, 1360}, -+ {AVL_DVBT2_64QAM, AVL_DVBT2_CR_3_4, 1510}, -+ {AVL_DVBT2_64QAM, AVL_DVBT2_CR_4_5, 1610}, -+ {AVL_DVBT2_64QAM, AVL_DVBT2_CR_5_6, 1670}, -+ -+ {AVL_DVBT2_256QAM, AVL_DVBT2_CR_1_3, 1110}, -+ {AVL_DVBT2_256QAM, AVL_DVBT2_CR_2_5, 1290}, -+ {AVL_DVBT2_256QAM, AVL_DVBT2_CR_1_2, 1440}, -+ {AVL_DVBT2_256QAM, AVL_DVBT2_CR_3_5, 1670}, -+ {AVL_DVBT2_256QAM, AVL_DVBT2_CR_2_3, 1810}, -+ {AVL_DVBT2_256QAM, AVL_DVBT2_CR_3_4, 2000}, -+ {AVL_DVBT2_256QAM, AVL_DVBT2_CR_4_5, 2130}, -+ {AVL_DVBT2_256QAM, AVL_DVBT2_CR_5_6, 2200} -+}; -+ -+ -+DVBT2_PBC_CN_Table_Element DVBT2_PCB_CN_Table[]= -+{ -+ {AVL_DVBT2_FFT_1K, AVL_DVBT2_PP_PP1, 34}, -+ {AVL_DVBT2_FFT_1K, AVL_DVBT2_PP_PP2, 32}, -+ {AVL_DVBT2_FFT_1K, AVL_DVBT2_PP_PP3, 44}, -+ {AVL_DVBT2_FFT_1K, AVL_DVBT2_PP_PP4, 42}, -+ {AVL_DVBT2_FFT_1K, AVL_DVBT2_PP_PP5, 48}, -+ {AVL_DVBT2_FFT_1K, AVL_DVBT2_PP_PP6, 0}, -+ {AVL_DVBT2_FFT_1K, AVL_DVBT2_PP_PP7, 29}, -+ {AVL_DVBT2_FFT_1K, AVL_DVBT2_PP_PP8, 0}, -+ -+ {AVL_DVBT2_FFT_2K, AVL_DVBT2_PP_PP1, 35}, -+ {AVL_DVBT2_FFT_2K, AVL_DVBT2_PP_PP2, 33}, -+ {AVL_DVBT2_FFT_2K, AVL_DVBT2_PP_PP3, 43}, -+ {AVL_DVBT2_FFT_2K, AVL_DVBT2_PP_PP4, 42}, -+ {AVL_DVBT2_FFT_2K, AVL_DVBT2_PP_PP5, 47}, -+ {AVL_DVBT2_FFT_2K, AVL_DVBT2_PP_PP6, 0}, -+ {AVL_DVBT2_FFT_2K, AVL_DVBT2_PP_PP7, 29}, -+ {AVL_DVBT2_FFT_2K, AVL_DVBT2_PP_PP8, 0}, -+ -+ {AVL_DVBT2_FFT_4K, AVL_DVBT2_PP_PP1, 39}, -+ {AVL_DVBT2_FFT_4K, AVL_DVBT2_PP_PP2, 37}, -+ {AVL_DVBT2_FFT_4K, AVL_DVBT2_PP_PP3, 47}, -+ {AVL_DVBT2_FFT_4K, AVL_DVBT2_PP_PP4, 45}, -+ {AVL_DVBT2_FFT_4K, AVL_DVBT2_PP_PP5, 51}, -+ {AVL_DVBT2_FFT_4K, AVL_DVBT2_PP_PP6, 0}, -+ {AVL_DVBT2_FFT_4K, AVL_DVBT2_PP_PP7, 34}, -+ {AVL_DVBT2_FFT_4K, AVL_DVBT2_PP_PP8, 0}, -+ -+ {AVL_DVBT2_FFT_8K, AVL_DVBT2_PP_PP1, 41}, -+ {AVL_DVBT2_FFT_8K, AVL_DVBT2_PP_PP2, 39}, -+ {AVL_DVBT2_FFT_8K, AVL_DVBT2_PP_PP3, 49}, -+ {AVL_DVBT2_FFT_8K, AVL_DVBT2_PP_PP4, 48}, -+ {AVL_DVBT2_FFT_8K, AVL_DVBT2_PP_PP5, 53}, -+ {AVL_DVBT2_FFT_8K, AVL_DVBT2_PP_PP6, 0}, -+ {AVL_DVBT2_FFT_8K, AVL_DVBT2_PP_PP7, 37}, -+ {AVL_DVBT2_FFT_8K, AVL_DVBT2_PP_PP8, 37}, -+ -+ {AVL_DVBT2_FFT_16K, AVL_DVBT2_PP_PP1, 41}, -+ {AVL_DVBT2_FFT_16K, AVL_DVBT2_PP_PP2, 38}, -+ {AVL_DVBT2_FFT_16K, AVL_DVBT2_PP_PP3, 49}, -+ {AVL_DVBT2_FFT_16K, AVL_DVBT2_PP_PP4, 47}, -+ {AVL_DVBT2_FFT_16K, AVL_DVBT2_PP_PP5, 52}, -+ {AVL_DVBT2_FFT_16K, AVL_DVBT2_PP_PP6, 49}, -+ {AVL_DVBT2_FFT_16K, AVL_DVBT2_PP_PP7, 33}, -+ {AVL_DVBT2_FFT_16K, AVL_DVBT2_PP_PP8, 35}, -+ -+ {AVL_DVBT2_FFT_32K, AVL_DVBT2_PP_PP1, 0}, -+ {AVL_DVBT2_FFT_32K, AVL_DVBT2_PP_PP2, 37}, -+ {AVL_DVBT2_FFT_32K, AVL_DVBT2_PP_PP3, 48}, -+ {AVL_DVBT2_FFT_32K, AVL_DVBT2_PP_PP4, 45}, -+ {AVL_DVBT2_FFT_32K, AVL_DVBT2_PP_PP5, 0}, -+ {AVL_DVBT2_FFT_32K, AVL_DVBT2_PP_PP6, 48}, -+ {AVL_DVBT2_FFT_32K, AVL_DVBT2_PP_PP7, 33}, -+ {AVL_DVBT2_FFT_32K, AVL_DVBT2_PP_PP8, 35}, -+}; -+ -+AVL_DVBT_BERSQI_List DVBT_BERSQI_Table[]= -+{ -+ {100 , 40 }, -+ {178 , 45 }, -+ {316 , 50 }, -+ {562 , 55 }, -+ {1000 , 60 }, -+ {1000 , 60 }, -+ {1778 , 65 }, -+ {3162 , 70 }, -+ {5623 , 75 }, -+ {10000 , 80 }, -+ {17783 , 85 }, -+ {31623 , 90 }, -+ {56234 , 95 }, -+ {100000 , 100 }, -+ {177828 , 105 }, -+ {316228 , 110 }, -+ {562341 , 115 }, -+ {1000000 , 120 }, -+ {1778279 , 125 }, -+ {3162278 , 130 }, -+ {5623413 , 135 }, -+ {10000000 , 140 } -+}; -+ -+ -+ -+AVL_DVBT_RF_Table_Element AVL_DVBT_RF_TABLE[]= -+{ -+ {AVL_DVBT_QPSK,AVL_DVBT_CR_1_2,-93}, -+ {AVL_DVBT_QPSK,AVL_DVBT_CR_2_3,-91}, -+ {AVL_DVBT_QPSK,AVL_DVBT_CR_3_4,-90}, -+ {AVL_DVBT_QPSK,AVL_DVBT_CR_5_6,-89}, -+ {AVL_DVBT_QPSK,AVL_DVBT_CR_7_8,-88}, -+ -+ {AVL_DVBT_16QAM,AVL_DVBT_CR_1_2,-87}, -+ {AVL_DVBT_16QAM,AVL_DVBT_CR_2_3,-85}, -+ {AVL_DVBT_16QAM,AVL_DVBT_CR_3_4,-84}, -+ {AVL_DVBT_16QAM,AVL_DVBT_CR_5_6,-83}, -+ {AVL_DVBT_16QAM,AVL_DVBT_CR_7_8,-82}, -+ -+ {AVL_DVBT_64QAM,AVL_DVBT_CR_1_2,-82}, -+ {AVL_DVBT_64QAM,AVL_DVBT_CR_2_3,-80}, -+ {AVL_DVBT_64QAM,AVL_DVBT_CR_3_4,-78}, -+ {AVL_DVBT_64QAM,AVL_DVBT_CR_5_6,-77}, -+ {AVL_DVBT_64QAM,AVL_DVBT_CR_7_8,-76} -+}; -+ -+AVL_DVBT2_RF_Table_Element AVL_DVBT2_RF_TABLE[]= -+{ -+ {AVL_DVBT2_QPSK,AVL_DVBT2_CR_1_3,-101}, -+ {AVL_DVBT2_QPSK,AVL_DVBT2_CR_2_5,-100}, -+ {AVL_DVBT2_QPSK,AVL_DVBT2_CR_1_2,-96}, -+ {AVL_DVBT2_QPSK,AVL_DVBT2_CR_3_5,-95}, -+ {AVL_DVBT2_QPSK,AVL_DVBT2_CR_2_3,-94}, -+ {AVL_DVBT2_QPSK,AVL_DVBT2_CR_3_4,-93}, -+ {AVL_DVBT2_QPSK,AVL_DVBT2_CR_4_5,-92}, -+ {AVL_DVBT2_QPSK,AVL_DVBT2_CR_5_6,-92}, -+ -+ {AVL_DVBT2_16QAM,AVL_DVBT2_CR_1_3,-96}, -+ {AVL_DVBT2_16QAM,AVL_DVBT2_CR_2_5,-95}, -+ {AVL_DVBT2_16QAM,AVL_DVBT2_CR_1_2,-91}, -+ {AVL_DVBT2_16QAM,AVL_DVBT2_CR_3_5,-89}, -+ {AVL_DVBT2_16QAM,AVL_DVBT2_CR_2_3,-88}, -+ {AVL_DVBT2_16QAM,AVL_DVBT2_CR_3_4,-87}, -+ {AVL_DVBT2_16QAM,AVL_DVBT2_CR_4_5,-86}, -+ {AVL_DVBT2_16QAM,AVL_DVBT2_CR_5_6,-86}, -+ -+ {AVL_DVBT2_64QAM,AVL_DVBT2_CR_1_3,-93}, -+ {AVL_DVBT2_64QAM,AVL_DVBT2_CR_2_5,-92}, -+ {AVL_DVBT2_64QAM,AVL_DVBT2_CR_1_2,-86}, -+ {AVL_DVBT2_64QAM,AVL_DVBT2_CR_3_5,-85}, -+ {AVL_DVBT2_64QAM,AVL_DVBT2_CR_2_3,-83}, -+ {AVL_DVBT2_64QAM,AVL_DVBT2_CR_3_4,-82}, -+ {AVL_DVBT2_64QAM,AVL_DVBT2_CR_4_5,-81}, -+ {AVL_DVBT2_64QAM,AVL_DVBT2_CR_5_6,-80}, -+ -+ {AVL_DVBT2_256QAM,AVL_DVBT2_CR_1_3,-89}, -+ {AVL_DVBT2_256QAM,AVL_DVBT2_CR_2_5,-88}, -+ {AVL_DVBT2_256QAM,AVL_DVBT2_CR_1_2,-82}, -+ {AVL_DVBT2_256QAM,AVL_DVBT2_CR_3_5,-80}, -+ {AVL_DVBT2_256QAM,AVL_DVBT2_CR_2_3,-78}, -+ {AVL_DVBT2_256QAM,AVL_DVBT2_CR_3_4,-76}, -+ {AVL_DVBT2_256QAM,AVL_DVBT2_CR_4_5,-75}, -+ {AVL_DVBT2_256QAM,AVL_DVBT2_CR_5_6,-74} -+}; -+ -+ -+ -+ -+ -+#endif -+ -diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c -index e105532..2e67aac 100644 ---- a/drivers/media/dvb-frontends/cx24116.c -+++ b/drivers/media/dvb-frontends/cx24116.c -@@ -705,6 +705,9 @@ static int cx24116_read_status(struct dvb_frontend *fe, enum fe_status *status) - if (lock & CX24116_HAS_SYNCLOCK) - *status |= FE_HAS_SYNC | FE_HAS_LOCK; - -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, *status & FE_HAS_LOCK); -+ - return 0; - } - -@@ -1113,6 +1116,10 @@ static void cx24116_release(struct dvb_frontend *fe) - { - struct cx24116_state *state = fe->demodulator_priv; - dprintk("%s\n", __func__); -+ -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, 0); -+ - kfree(state); - } - -@@ -1198,6 +1205,9 @@ static int cx24116_sleep(struct dvb_frontend *fe) - - dprintk("%s()\n", __func__); - -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, 0); -+ - /* Firmware CMD 36: Power config */ - cmd.args[0x00] = CMD_TUNERSLEEP; - cmd.args[0x01] = 1; -diff --git a/drivers/media/dvb-frontends/cx24116.h b/drivers/media/dvb-frontends/cx24116.h -index 9ff8df8d..887249a 100644 ---- a/drivers/media/dvb-frontends/cx24116.h -+++ b/drivers/media/dvb-frontends/cx24116.h -@@ -38,6 +38,9 @@ struct cx24116_config { - - /* max bytes I2C provider can write at once */ - u16 i2c_wr_max; -+ -+ /* Hook for Lock LED */ -+ void (*set_lock_led)(struct dvb_frontend *fe, int offon); - }; - - #if IS_REACHABLE(CONFIG_DVB_CX24116) -diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c -index d37cb77..213d457 100644 ---- a/drivers/media/dvb-frontends/cx24117.c -+++ b/drivers/media/dvb-frontends/cx24117.c -@@ -195,7 +195,7 @@ struct cx24117_cmd { - - /* common to both fe's */ - struct cx24117_priv { -- u8 demod_address; -+ struct cx24117_config *cfg; - struct i2c_adapter *i2c; - u8 skip_fw_load; - struct mutex fe_lock; -@@ -265,11 +265,17 @@ static struct cx24117_modfec { - */ - }; - -+struct i2c_adapter *cx24117_get_i2c_adapter(struct dvb_frontend *fe) -+{ -+ struct cx24117_state *state = fe->demodulator_priv; -+ return state->priv->i2c; -+} -+EXPORT_SYMBOL_GPL(cx24117_get_i2c_adapter); - - static int cx24117_writereg(struct cx24117_state *state, u8 reg, u8 data) - { - u8 buf[] = { reg, data }; -- struct i2c_msg msg = { .addr = state->priv->demod_address, -+ struct i2c_msg msg = { .addr = state->priv->cfg->demod_address, - .flags = 0, .buf = buf, .len = 2 }; - int ret; - -@@ -301,7 +307,7 @@ static int cx24117_writecmd(struct cx24117_state *state, - buf[0] = CX24117_REG_COMMAND; - memcpy(&buf[1], cmd->args, cmd->len); - -- msg.addr = state->priv->demod_address; -+ msg.addr = state->priv->cfg->demod_address; - msg.flags = 0; - msg.len = cmd->len+1; - msg.buf = buf; -@@ -320,9 +326,9 @@ static int cx24117_readreg(struct cx24117_state *state, u8 reg) - int ret; - u8 recv = 0; - struct i2c_msg msg[] = { -- { .addr = state->priv->demod_address, .flags = 0, -+ { .addr = state->priv->cfg->demod_address, .flags = 0, - .buf = ®, .len = 1 }, -- { .addr = state->priv->demod_address, .flags = I2C_M_RD, -+ { .addr = state->priv->cfg->demod_address, .flags = I2C_M_RD, - .buf = &recv, .len = 1 } - }; - -@@ -345,9 +351,9 @@ static int cx24117_readregN(struct cx24117_state *state, - { - int ret; - struct i2c_msg msg[] = { -- { .addr = state->priv->demod_address, .flags = 0, -+ { .addr = state->priv->cfg->demod_address, .flags = 0, - .buf = ®, .len = 1 }, -- { .addr = state->priv->demod_address, .flags = I2C_M_RD, -+ { .addr = state->priv->cfg->demod_address, .flags = I2C_M_RD, - .buf = buf, .len = len } - }; - -@@ -624,7 +630,7 @@ static int cx24117_load_firmware(struct dvb_frontend *fe, - memcpy(&buf[1], fw->data, fw->size); - - /* prepare i2c message to send */ -- msg.addr = state->priv->demod_address; -+ msg.addr = state->priv->cfg->demod_address; - msg.flags = 0; - msg.len = fw->size + 1; - msg.buf = buf; -@@ -910,7 +916,7 @@ static int cx24117_set_voltage(struct dvb_frontend *fe, - { - struct cx24117_state *state = fe->demodulator_priv; - struct cx24117_cmd cmd; -- int ret; -+ int ret = 0; - u8 reg = (state->demod == 0) ? 0x10 : 0x20; - - dev_dbg(&state->priv->i2c->dev, "%s() demod%d %s\n", -@@ -919,6 +925,9 @@ static int cx24117_set_voltage(struct dvb_frontend *fe, - voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : - "SEC_VOLTAGE_OFF"); - -+ if (state->priv->cfg->lnb_power) -+ state->priv->cfg->lnb_power(fe, state->demod, 1); -+ - /* Prepare a set GPIO logic level CMD */ - cmd.args[0] = CMD_SET_GPIOOUT; - cmd.args[2] = reg; /* mask */ -@@ -950,8 +959,12 @@ static int cx24117_set_voltage(struct dvb_frontend *fe, - msleep(20); - } else { - /* power off LNB */ -- cmd.args[1] = 0x00; -- ret = cx24117_cmd_execute(fe, &cmd); -+ if (state->priv->cfg->lnb_power) { -+ state->priv->cfg->lnb_power(fe, state->demod, 0); -+ } else { -+ cmd.args[1] = 0x00; -+ ret = cx24117_cmd_execute(fe, &cmd); -+ } - } - - return ret; -@@ -1166,7 +1179,7 @@ static void cx24117_release(struct dvb_frontend *fe) - - static const struct dvb_frontend_ops cx24117_ops; - --struct dvb_frontend *cx24117_attach(const struct cx24117_config *config, -+struct dvb_frontend *cx24117_attach(struct cx24117_config *config, - struct i2c_adapter *i2c) - { - struct cx24117_state *state = NULL; -@@ -1186,7 +1199,7 @@ struct dvb_frontend *cx24117_attach(const struct cx24117_config *config, - case 1: - /* new priv instance */ - priv->i2c = i2c; -- priv->demod_address = config->demod_address; -+ priv->cfg = config; - mutex_init(&priv->fe_lock); - break; - default: -diff --git a/drivers/media/dvb-frontends/cx24117.h b/drivers/media/dvb-frontends/cx24117.h -index 445f13f..d72c1f8 100644 ---- a/drivers/media/dvb-frontends/cx24117.h -+++ b/drivers/media/dvb-frontends/cx24117.h -@@ -27,15 +27,19 @@ - struct cx24117_config { - /* the demodulator's i2c address */ - u8 demod_address; -+ -+ /* lnb power control */ -+ void (*lnb_power)(struct dvb_frontend *fe, int demod, int onoff); - }; - - #if IS_REACHABLE(CONFIG_DVB_CX24117) -+struct i2c_adapter *cx24117_get_i2c_adapter(struct dvb_frontend *fe); - extern struct dvb_frontend *cx24117_attach( -- const struct cx24117_config *config, -+ struct cx24117_config *config, - struct i2c_adapter *i2c); - #else - static inline struct dvb_frontend *cx24117_attach( -- const struct cx24117_config *config, -+ struct cx24117_config *config, - struct i2c_adapter *i2c) - { - dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__); -diff --git a/drivers/media/dvb-frontends/cxd2820r.h b/drivers/media/dvb-frontends/cxd2820r.h -index f3ff8f6..9bf399f 100644 ---- a/drivers/media/dvb-frontends/cxd2820r.h -+++ b/drivers/media/dvb-frontends/cxd2820r.h -@@ -57,6 +57,7 @@ struct cxd2820r_platform_data { - bool spec_inv; - int **gpio_chip_base; - -+ void (*set_lock_led)(struct dvb_frontend *fe, int offon); - struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *); - /* private: For legacy media attach wrapper. Do not set value. */ - bool attach_in_use; -@@ -94,6 +95,9 @@ struct cxd2820r_config { - * Values: 0, 1 - */ - bool spec_inv; -+ -+ /* Hook for Lock LED */ -+ void (*set_lock_led)(struct dvb_frontend *fe, int offon); - }; - - -diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c -index 95267c6..e887582 100644 ---- a/drivers/media/dvb-frontends/cxd2820r_core.c -+++ b/drivers/media/dvb-frontends/cxd2820r_core.c -@@ -180,6 +180,10 @@ static int cxd2820r_read_status(struct dvb_frontend *fe, enum fe_status *status) - ret = -EINVAL; - break; - } -+ -+ if (priv->set_lock_led) -+ priv->set_lock_led(fe, *status & FE_HAS_LOCK); -+ - return ret; - } - -@@ -284,6 +288,9 @@ static int cxd2820r_sleep(struct dvb_frontend *fe) - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret; - -+ if (priv->set_lock_led) -+ priv->set_lock_led(fe, 0); -+ - dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); - - switch (c->delivery_system) { -@@ -415,6 +422,9 @@ static void cxd2820r_release(struct dvb_frontend *fe) - - dev_dbg(&client->dev, "\n"); - -+ if (priv->set_lock_led) -+ priv->set_lock_led(fe, 0); -+ - i2c_unregister_device(client); - - return; -@@ -536,6 +546,7 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *config, - pdata.ts_clk_inv = config->ts_clock_inv; - pdata.if_agc_polarity = config->if_agc_polarity; - pdata.spec_inv = config->spec_inv; -+ pdata.set_lock_led = config->set_lock_led; - pdata.gpio_chip_base = &gpio_chip_base; - pdata.attach_in_use = true; - -@@ -620,6 +631,7 @@ static int cxd2820r_probe(struct i2c_client *client, - priv->ts_clk_inv = pdata->ts_clk_inv; - priv->if_agc_polarity = pdata->if_agc_polarity; - priv->spec_inv = pdata->spec_inv; -+ priv->set_lock_led = pdata->set_lock_led; - gpio_chip_base = *pdata->gpio_chip_base; - priv->regmap[0] = regmap_init_i2c(priv->client[0], ®map_config0); - if (IS_ERR(priv->regmap[0])) { -diff --git a/drivers/media/dvb-frontends/cxd2820r_priv.h b/drivers/media/dvb-frontends/cxd2820r_priv.h -index 0d09620..2e827d4 100644 ---- a/drivers/media/dvb-frontends/cxd2820r_priv.h -+++ b/drivers/media/dvb-frontends/cxd2820r_priv.h -@@ -47,6 +47,7 @@ struct cxd2820r_priv { - bool ts_clk_inv; - bool if_agc_polarity; - bool spec_inv; -+ void (*set_lock_led)(struct dvb_frontend *fe, int offon); - - u64 post_bit_error_prev_dvbv3; - u64 post_bit_error; -diff --git a/drivers/media/dvb-frontends/isl6422.c b/drivers/media/dvb-frontends/isl6422.c -new file mode 100644 -index 0000000..4a230f0 ---- /dev/null -+++ b/drivers/media/dvb-frontends/isl6422.c -@@ -0,0 +1,317 @@ -+/* -+ Intersil ISL6422 SEC and LNB Power supply controller -+ -+ Created based on isl6423 from Manu Abraham -+ -+ Copyright (C) Luis Alves -+ -+ 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. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dvb_frontend.h" -+#include "isl6422.h" -+ -+static unsigned int verbose; -+module_param(verbose, int, 0644); -+MODULE_PARM_DESC(verbose, "Set Verbosity level"); -+ -+#define FE_ERROR 0 -+#define FE_NOTICE 1 -+#define FE_INFO 2 -+#define FE_DEBUG 3 -+#define FE_DEBUGREG 4 -+ -+#define dprintk(__y, __z, format, arg...) do { \ -+ if (__z) { \ -+ if ((verbose > FE_ERROR) && (verbose > __y)) \ -+ printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ -+ else if ((verbose > FE_NOTICE) && (verbose > __y)) \ -+ printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ -+ else if ((verbose > FE_INFO) && (verbose > __y)) \ -+ printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ -+ else if ((verbose > FE_DEBUG) && (verbose > __y)) \ -+ printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ -+ } else { \ -+ if (verbose > __y) \ -+ printk(format, ##arg); \ -+ } \ -+} while (0) -+ -+struct isl6422_dev { -+ const struct isl6422_config *config; -+ struct i2c_adapter *i2c; -+ -+ u8 reg_3; -+ u8 reg_4; -+ -+ unsigned int verbose; -+}; -+ -+static int isl6422_write(struct isl6422_dev *isl6422, u8 reg) -+{ -+ struct i2c_adapter *i2c = isl6422->i2c; -+ u8 addr = isl6422->config->addr; -+ int err = 0; -+ -+ struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = ®, .len = 1 }; -+ -+ dprintk(FE_DEBUG, 1, "write reg %02X", reg); -+ err = i2c_transfer(i2c, &msg, 1); -+ if (err < 0) -+ goto exit; -+ return 0; -+ -+exit: -+ dprintk(FE_ERROR, 1, "I/O error <%d>", err); -+ return err; -+} -+ -+static int isl6422_set_modulation(struct dvb_frontend *fe) -+{ -+ struct isl6422_dev *isl6422 = (struct isl6422_dev *) fe->sec_priv; -+ const struct isl6422_config *config = isl6422->config; -+ int err = 0; -+ u8 reg_2 = 0; -+ -+ reg_2 = 0x01 << 5; -+ -+ if (config->mod_extern) -+ reg_2 |= (1 << 3); -+ else -+ reg_2 |= (1 << 4); -+ -+ err = isl6422_write(isl6422, reg_2 | ((config->id & 1) << 7)); -+ if (err < 0) -+ goto exit; -+ return 0; -+ -+exit: -+ dprintk(FE_ERROR, 1, "I/O error <%d>", err); -+ return err; -+} -+ -+static int isl6422_voltage_boost(struct dvb_frontend *fe, long arg) -+{ -+ struct isl6422_dev *isl6422 = (struct isl6422_dev *) fe->sec_priv; -+ const struct isl6422_config *config = isl6422->config; -+ u8 reg_3 = isl6422->reg_3; -+ u8 reg_4 = isl6422->reg_4; -+ int err = 0; -+ -+ if (arg) { -+ /* EN = 1, VSPEN = 1, VBOT = 1 */ -+ reg_4 |= (1 << 4); -+ reg_4 |= 0x1; -+ reg_3 |= (1 << 3); -+ } else { -+ /* EN = 1, VSPEN = 1, VBOT = 0 */ -+ reg_4 |= (1 << 4); -+ reg_4 &= ~0x1; -+ reg_3 |= (1 << 3); -+ } -+ err = isl6422_write(isl6422, reg_3 | ((config->id & 1) << 7)); -+ if (err < 0) -+ goto exit; -+ -+ err = isl6422_write(isl6422, reg_4 | ((config->id & 1) << 7)); -+ if (err < 0) -+ goto exit; -+ -+ isl6422->reg_3 = reg_3; -+ isl6422->reg_4 = reg_4; -+ -+ return 0; -+exit: -+ dprintk(FE_ERROR, 1, "I/O error <%d>", err); -+ return err; -+} -+ -+ -+static int isl6422_set_voltage(struct dvb_frontend *fe, -+ enum fe_sec_voltage voltage) -+{ -+ struct isl6422_dev *isl6422 = (struct isl6422_dev *) fe->sec_priv; -+ const struct isl6422_config *config = isl6422->config; -+ u8 reg_3 = isl6422->reg_3; -+ u8 reg_4 = isl6422->reg_4; -+ int err = 0; -+ -+ switch (voltage) { -+ case SEC_VOLTAGE_OFF: -+ /* EN = 0 */ -+ reg_4 &= ~(1 << 4); -+ break; -+ -+ case SEC_VOLTAGE_13: -+ /* EN = 1, VSPEN = 1, VTOP = 0, VBOT = 0 */ -+ reg_4 |= (1 << 4); -+ reg_4 &= ~0x3; -+ reg_3 |= (1 << 3); -+ break; -+ -+ case SEC_VOLTAGE_18: -+ /* EN = 1, VSPEN = 1, VTOP = 1, VBOT = 0 */ -+ reg_4 |= (1 << 4); -+ reg_4 |= 0x2; -+ reg_4 &= ~0x1; -+ reg_3 |= (1 << 3); -+ break; -+ -+ default: -+ break; -+ } -+ err = isl6422_write(isl6422, reg_3 | ((config->id & 1) << 7)); -+ if (err < 0) -+ goto exit; -+ -+ err = isl6422_write(isl6422, reg_4 | ((config->id & 1) << 7)); -+ if (err < 0) -+ goto exit; -+ -+ isl6422->reg_3 = reg_3; -+ isl6422->reg_4 = reg_4; -+ -+ return 0; -+exit: -+ dprintk(FE_ERROR, 1, "I/O error <%d>", err); -+ return err; -+} -+ -+static int isl6422_set_current(struct dvb_frontend *fe) -+{ -+ struct isl6422_dev *isl6422 = (struct isl6422_dev *) fe->sec_priv; -+ u8 reg_3 = isl6422->reg_3; -+ const struct isl6422_config *config = isl6422->config; -+ int err = 0; -+ -+ reg_3 &= ~0x7; -+ -+ switch (config->current_max) { -+ case SEC_CURRENT_305m: -+ /* 305mA */ -+ /* ISELR = 0, ISELH = X, ISELL = X */ -+ break; -+ -+ case SEC_CURRENT_388m: -+ /* 388mA */ -+ /* ISELR = 1, ISELH = 0, ISELL = 0 */ -+ reg_3 |= 0x4; -+ break; -+ -+ case SEC_CURRENT_570m: -+ /* 570mA */ -+ /* ISELR = 1, ISELH = 0, ISELL = 1 */ -+ reg_3 |= 0x5; -+ break; -+ -+ case SEC_CURRENT_705m: -+ /* 705mA */ -+ /* ISELR = 1, ISELH = 1, ISELL = 0 */ -+ reg_3 |= 0x6; -+ break; -+ -+ case SEC_CURRENT_890m: -+ /* 890mA */ -+ /* ISELR = 1, ISELH = 1, ISELL = 1 */ -+ reg_3 |= 0x7; -+ break; -+ } -+ -+ err = isl6422_write(isl6422, reg_3 | ((config->id & 1) << 7)); -+ if (err < 0) -+ goto exit; -+ -+ switch (config->curlim) { -+ case SEC_CURRENT_LIM_ON: -+ /* DCL = 0 */ -+ reg_3 &= ~0x10; -+ break; -+ -+ case SEC_CURRENT_LIM_OFF: -+ /* DCL = 1 */ -+ reg_3 |= 0x10; -+ break; -+ } -+ -+ err = isl6422_write(isl6422, reg_3 | ((config->id & 1) << 7)); -+ if (err < 0) -+ goto exit; -+ -+ isl6422->reg_3 = reg_3; -+ -+ return 0; -+exit: -+ dprintk(FE_ERROR, 1, "I/O error <%d>", err); -+ return err; -+} -+ -+static void isl6422_release(struct dvb_frontend *fe) -+{ -+ isl6422_set_voltage(fe, SEC_VOLTAGE_OFF); -+ -+ kfree(fe->sec_priv); -+ fe->sec_priv = NULL; -+} -+ -+struct dvb_frontend *isl6422_attach(struct dvb_frontend *fe, -+ struct i2c_adapter *i2c, -+ const struct isl6422_config *config) -+{ -+ struct isl6422_dev *isl6422; -+ -+ isl6422 = kzalloc(sizeof(struct isl6422_dev), GFP_KERNEL); -+ if (!isl6422) -+ return NULL; -+ -+ isl6422->config = config; -+ isl6422->i2c = i2c; -+ fe->sec_priv = isl6422; -+ -+ /* SR3H = 0, SR3M = 1, SR3L = 0 */ -+ isl6422->reg_3 = 0x02 << 5; -+ /* SR4H = 0, SR4M = 1, SR4L = 1 */ -+ isl6422->reg_4 = 0x03 << 5; -+ -+ if (isl6422_set_current(fe)) -+ goto exit; -+ -+ if (isl6422_set_modulation(fe)) -+ goto exit; -+ -+ fe->ops.release_sec = isl6422_release; -+ fe->ops.set_voltage = isl6422_set_voltage; -+ fe->ops.enable_high_lnb_voltage = isl6422_voltage_boost; -+ isl6422->verbose = verbose; -+ -+ return fe; -+ -+exit: -+ kfree(isl6422); -+ fe->sec_priv = NULL; -+ return NULL; -+} -+EXPORT_SYMBOL(isl6422_attach); -+ -+MODULE_DESCRIPTION("ISL6422 SEC"); -+MODULE_AUTHOR("Luis Alves"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/dvb-frontends/isl6422.h b/drivers/media/dvb-frontends/isl6422.h -new file mode 100644 -index 0000000..3ce414c ---- /dev/null -+++ b/drivers/media/dvb-frontends/isl6422.h -@@ -0,0 +1,67 @@ -+/* -+ Intersil ISL6422 SEC and LNB Power supply controller -+ -+ Created based on isl6423 from Manu Abraham -+ -+ Copyright (C) Luis Alves -+ -+ 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. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+*/ -+ -+#ifndef __ISL_6422_H -+#define __ISL_6422_H -+ -+#include -+ -+enum isl6422_current { -+ SEC_CURRENT_305m = 0, -+ SEC_CURRENT_388m, -+ SEC_CURRENT_570m, -+ SEC_CURRENT_705m, -+ SEC_CURRENT_890m, -+}; -+ -+enum isl6422_curlim { -+ SEC_CURRENT_LIM_ON = 1, -+ SEC_CURRENT_LIM_OFF -+}; -+ -+struct isl6422_config { -+ enum isl6422_current current_max; -+ enum isl6422_curlim curlim; -+ u8 addr; -+ u8 mod_extern; -+ int id; -+}; -+ -+#if IS_ENABLED(CONFIG_DVB_ISL6422) -+ -+ -+extern struct dvb_frontend *isl6422_attach(struct dvb_frontend *fe, -+ struct i2c_adapter *i2c, -+ const struct isl6422_config *config); -+ -+#else -+static inline struct dvb_frontend *isl6422_attach(struct dvb_frontend *fe, -+ struct i2c_adapter *i2c, -+ const struct isl6422_config *config) -+{ -+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -+ return NULL; -+} -+ -+#endif /* CONFIG_DVB_ISL6422 */ -+ -+#endif /* __ISL_6422_H */ -diff --git a/drivers/media/dvb-frontends/m88ds3103.h b/drivers/media/dvb-frontends/m88ds3103.h -index 04b355a..f2d3566 100644 ---- a/drivers/media/dvb-frontends/m88ds3103.h -+++ b/drivers/media/dvb-frontends/m88ds3103.h -@@ -168,6 +168,8 @@ struct m88ds3103_config { - * 0: pin high to disable, pin low to enable. - */ - u8 lnb_en_pol:1; -+ /* Hook for Lock LED */ -+ void (*set_lock_led)(struct dvb_frontend *fe, int offon); - }; - - #if defined(CONFIG_DVB_M88DS3103) || \ -diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c -index ce6c21d..131f9fe 100644 ---- a/drivers/media/dvb-frontends/m88rs2000.c -+++ b/drivers/media/dvb-frontends/m88rs2000.c -@@ -459,6 +459,10 @@ static int m88rs2000_sleep(struct dvb_frontend *fe) - { - struct m88rs2000_state *state = fe->demodulator_priv; - int ret; -+ -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, 0); -+ - /* Shutdown the frondend */ - ret = m88rs2000_tab_set(state, m88rs2000_shutdown); - return ret; -@@ -478,6 +482,10 @@ static int m88rs2000_read_status(struct dvb_frontend *fe, - if (state->config->set_ts_params) - state->config->set_ts_params(fe, CALL_IS_READ); - } -+ -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, *status & FE_HAS_LOCK); -+ - return 0; - } - -@@ -749,6 +757,10 @@ static int m88rs2000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) - static void m88rs2000_release(struct dvb_frontend *fe) - { - struct m88rs2000_state *state = fe->demodulator_priv; -+ -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, 0); -+ - kfree(state); - } - -diff --git a/drivers/media/dvb-frontends/m88rs2000.h b/drivers/media/dvb-frontends/m88rs2000.h -index 1a313b0..1e487f4 100644 ---- a/drivers/media/dvb-frontends/m88rs2000.h -+++ b/drivers/media/dvb-frontends/m88rs2000.h -@@ -33,6 +33,9 @@ struct m88rs2000_config { - int min_delay_ms; - - int (*set_ts_params)(struct dvb_frontend *, int); -+ -+ /* Hook for Lock LED */ -+ void (*set_lock_led)(struct dvb_frontend *fe, int offon); - }; - - enum { -diff --git a/drivers/media/dvb-frontends/mn88436.c b/drivers/media/dvb-frontends/mn88436.c -new file mode 100644 -index 0000000..91de093 ---- /dev/null -+++ b/drivers/media/dvb-frontends/mn88436.c -@@ -0,0 +1,1467 @@ -+#include "mn88436_priv.h" -+ -+static u8 DMD_REG_ATSC[]={ -+0 ,0x0 ,0x50 , -+0 ,0x1 ,0x0 , -+0 ,0x2 ,0xC0 , -+0 ,0x3 ,0x0 , -+0 ,0x4 ,0x0 , -+0 ,0x5 ,0x0 , -+0 ,0x6 ,0x0 , -+0 ,0x7 ,0x0 , -+0 ,0x8 ,0x0 , -+0 ,0x9 ,0x0 , -+0 ,0xA ,0x1E , -+0 ,0xB ,0x35 , -+0 ,0xC ,0x56 , -+0 ,0xD ,0x8E , -+0 ,0xE ,0xB9 , -+0 ,0xF ,0x72 , -+0 ,0x10 ,0x0 , -+0 ,0x11 ,0x14 , -+0 ,0x12 ,0xE3 , -+0 ,0x13 ,0x4E , -+0 ,0x14 ,0x8 , -+0 ,0x15 ,0x5 , -+0 ,0x16 ,0x63 , -+0 ,0x17 ,0x0 , -+0 ,0x18 ,0x0 , -+0 ,0x19 ,0x0 , -+0 ,0x1A ,0x0 , -+0 ,0x1B ,0x0 , -+0 ,0x1C ,0x0 , -+0 ,0x1D ,0x0 , -+0 ,0x1E ,0x0 , -+0 ,0x1F ,0x0 , -+0 ,0x20 ,0x0 , -+0 ,0x21 ,0x50 , -+0 ,0x22 ,0x60 , -+0 ,0x23 ,0x36 , -+0 ,0x24 ,0x2 , -+0 ,0x25 ,0x0 , -+0 ,0x26 ,0x0 , -+0 ,0x27 ,0x0 , -+0 ,0x28 ,0x0 , -+0 ,0x29 ,0x0 , -+0 ,0x2A ,0x20 , -+0 ,0x2B ,0xC0 , -+0 ,0x2C ,0x23 , -+0 ,0x2D ,0x3F , -+0 ,0x2E ,0x3F , -+0 ,0x2F ,0x0 , -+0 ,0x30 ,0x2E , -+0 ,0x31 ,0x0 , -+0 ,0x32 ,0x0 , -+0 ,0x33 ,0x81 , -+0 ,0x34 ,0x0 , -+0 ,0x35 ,0x26 , -+0 ,0x36 ,0x21 , -+0 ,0x37 ,0x88 , -+0 ,0x38 ,0x3 , -+0 ,0x39 ,0x19 , -+0 ,0x3A ,0x85 , -+0 ,0x3B ,0x5 , -+0 ,0x3C ,0xC9 , -+0 ,0x3D ,0x2 , -+0 ,0x3E ,0x30 , -+0 ,0x3F ,0x69 , -+0 ,0x40 ,0x1F , -+0 ,0x41 ,0xF0 , -+0 ,0x42 ,0x0 , -+0 ,0x43 ,0x96 , -+0 ,0x44 ,0x72 , -+0 ,0x45 ,0x1B , -+0 ,0x46 ,0x2D , -+0 ,0x47 ,0x1A , -+0 ,0x48 ,0x31 , -+0 ,0x49 ,0xFE , -+0 ,0x4A ,0x96 , -+0 ,0x4B ,0x7 , -+0 ,0x4C ,0x26 , -+0 ,0x4D ,0xE3 , -+0 ,0x4E ,0x22 , -+0 ,0x4F ,0x1B , -+0 ,0x50 ,0x26 , -+0 ,0x51 ,0x12 , -+0 ,0x52 ,0x40 , -+0 ,0x53 ,0x50 , -+0 ,0x54 ,0x60 , -+0 ,0x55 ,0x40 , -+0 ,0x56 ,0xED , -+0 ,0x57 ,0x96 , -+0 ,0x58 ,0x4A , -+0 ,0x59 ,0xDE , -+0 ,0x5A ,0x88 , -+0 ,0x5B ,0xC8 , -+0 ,0x5C ,0x2D , -+0 ,0x5D ,0x1 , -+0 ,0x5E ,0x0 , -+0 ,0x5F ,0xB8 , -+0 ,0x60 ,0x40 , -+0 ,0x61 ,0x14 , -+0 ,0x62 ,0x13 , -+0 ,0x63 ,0x30 , -+0 ,0x64 ,0x59 , -+0 ,0x65 ,0x7 , -+0 ,0x66 ,0xF0 , -+0 ,0x67 ,0x47 , -+0 ,0x68 ,0xA1 , -+0 ,0x69 ,0x80 , -+0 ,0x6A ,0x0 , -+0 ,0x6B ,0x0 , -+0 ,0x6C ,0xC0 , -+0 ,0x6D ,0x0 , -+0 ,0x6E ,0x0 , -+0 ,0x6F ,0x0 , -+0 ,0x70 ,0x0 , -+0 ,0x71 ,0x0 , -+0 ,0x72 ,0x0 , -+0 ,0x73 ,0x0 , -+0 ,0x74 ,0x2F , -+0 ,0x75 ,0x0 , -+0 ,0x76 ,0x0 , -+0 ,0x77 ,0x0 , -+0 ,0x78 ,0x0 , -+0 ,0x79 ,0x40 , -+0 ,0x7A ,0x20 , -+0 ,0x7B ,0x40 , -+0 ,0x7C ,0x80 , -+0 ,0x7D ,0xFF , -+0 ,0x7E ,0x20 , -+0 ,0x7F ,0x40 , -+0 ,0x80 ,0x10 , -+0 ,0x81 ,0x0 , -+0 ,0x82 ,0xE5 , -+0 ,0x83 ,0xC4 , -+0 ,0x84 ,0xE9 , -+0 ,0x85 ,0x52 , -+0 ,0x86 ,0x5F , -+0 ,0x87 ,0x53 , -+0 ,0x88 ,0x20 , -+0 ,0x89 ,0x43 , -+0 ,0x8A ,0x11 , -+0 ,0x8B ,0x8 , -+0 ,0x8C ,0x43 , -+0 ,0x8D ,0x11 , -+0 ,0x8E ,0x8 , -+0 ,0x8F ,0x0 , -+0 ,0x90 ,0x60 , -+0 ,0x91 ,0x5B , -+0 ,0x92 ,0x80 , -+0 ,0x93 ,0xE4 , -+0 ,0x94 ,0x34 , -+0 ,0x95 ,0x0 , -+0 ,0x96 ,0x0 , -+0 ,0x97 ,0x7 , -+0 ,0x98 ,0x0 , -+0 ,0x99 ,0xB0 , -+0 ,0x9A ,0x68 , -+0 ,0x9B ,0x50 , -+0 ,0x9C ,0x84 , -+0 ,0x9D ,0xA9 , -+0 ,0x9E ,0x11 , -+0 ,0x9F ,0x4 , -+0 ,0xA0 ,0x44 , -+0 ,0xA1 ,0x14 , -+0 ,0xA2 ,0x9C , -+0 ,0xA3 ,0x15 , -+0 ,0xA4 ,0xF6 , -+0 ,0xA5 ,0x36 , -+0 ,0xA6 ,0x16 , -+0 ,0xA7 ,0x3F , -+0 ,0xA8 ,0x1 , -+0 ,0xA9 ,0x8 , -+0 ,0xAA ,0x0 , -+0 ,0xAB ,0x0 , -+0 ,0xAC ,0x0 , -+0 ,0xAD ,0x65 , -+0 ,0xAE ,0x87 , -+0 ,0xAF ,0x56 , -+0 ,0xB0 ,0x52 , -+0 ,0xB1 ,0x55 , -+0 ,0xB2 ,0x35 , -+0 ,0xB3 ,0x13 , -+0 ,0xB4 ,0x88 , -+0 ,0xB5 ,0x23 , -+0 ,0xB6 ,0x28 , -+0 ,0xB7 ,0x3C , -+0 ,0xB8 ,0x1 , -+0 ,0xB9 ,0x5B , -+0 ,0xBA ,0x0 , -+0 ,0xBB ,0x0 , -+0 ,0xBC ,0x0 , -+0 ,0xBD ,0x0 , -+0 ,0xBE ,0x0 , -+0 ,0xBF ,0x0 , -+0 ,0xC0 ,0x0 , -+0 ,0xC1 ,0x0 , -+0 ,0xC2 ,0x0 , -+0 ,0xC3 ,0x0 , -+0 ,0xC4 ,0x0 , -+0 ,0xC5 ,0x0 , -+0 ,0xC6 ,0x0 , -+0 ,0xC7 ,0x0 , -+0 ,0xC8 ,0x0 , -+0 ,0xC9 ,0x0 , -+0 ,0xCA ,0x0 , -+0 ,0xCB ,0x0 , -+0 ,0xCC ,0x0 , -+0 ,0xCD ,0x0 , -+0 ,0xCE ,0x0 , -+0 ,0xCF ,0x0 , -+0 ,0xD0 ,0x0 , -+0 ,0xD1 ,0x0 , -+0 ,0xD2 ,0x0 , -+0 ,0xD3 ,0x0 , -+0 ,0xD4 ,0x0 , -+0 ,0xD5 ,0x0 , -+0 ,0xD6 ,0x0 , -+0 ,0xD7 ,0x0 , -+0 ,0xD8 ,0x0 , -+0 ,0xD9 ,0xA0 , -+0 ,0xDA ,0x0 , -+0 ,0xDB ,0x0 , -+0 ,0xDC ,0x0 , -+0 ,0xDD ,0x0 , -+0 ,0xDE ,0x0 , -+0 ,0xDF ,0x9 , -+0 ,0xE0 ,0x8 , -+0 ,0xE1 ,0x8 , -+0 ,0xE2 ,0xA8 , -+0 ,0xE3 ,0x0 , -+0 ,0xE4 ,0x0 , -+0 ,0xE5 ,0x0 , -+0 ,0xE6 ,0x0 , -+0 ,0xE7 ,0xB4 , -+0 ,0xE8 ,0xA , -+0 ,0xE9 ,0x0 , -+0 ,0xEA ,0x0 , -+0 ,0xEB ,0x0 , -+0 ,0xEC ,0x0 , -+0 ,0xED ,0x0 , -+0 ,0xEE ,0x0 , -+0 ,0xEF ,0xB4 , -+0 ,0xF0 ,0x91 , -+0 ,0xF1 ,0x0 , -+0 ,0xF2 ,0x0 , -+0 ,0xF3 ,0x0 , -+0 ,0xF4 ,0x0 , -+0 ,0xF5 ,0x0 , -+0 ,0xF6 ,0x0 , -+0 ,0xF7 ,0x0 , -+0 ,0xF8 ,0x0 , -+0 ,0xF9 ,0x0 , -+0 ,0xFA ,0x0 , -+0 ,0xFB ,0x80 , -+0 ,0xFC ,0x10 , -+0 ,0xFD ,0x2 , -+0 ,0xFE ,0x20 , -+0 ,0xFF ,0xAA , -+1 ,0x9 ,0x0 , -+1 ,0xA ,0x0 , -+1 ,0xB ,0x0 , -+1 ,0xC ,0x8 , -+1 ,0xD ,0x0 , -+1 ,0x14 ,0x8 , -+1 ,0x5A ,0x3C , -+1 ,0x5B ,0x0 , -+1 ,0x5C ,0x0 , -+1 ,0x5D ,0x0 , -+1 ,0x5E ,0x0 , -+1 ,0x5F ,0x0 , -+1 ,0x60 ,0x0 , -+1 ,0x61 ,0xAC , -+1 ,0x62 ,0x24 , -+1 ,0x63 ,0x0 , -+1 ,0x64 ,0x0 , -+1 ,0x65 ,0x0 , -+1 ,0x66 ,0x0 , -+1 ,0x67 ,0x0 , -+1 ,0x68 ,0x0 , -+1 ,0x69 ,0x0 , -+1 ,0x6A ,0x0 , -+1 ,0x6B ,0x0 , -+1 ,0x74 ,0x0 , -+1 ,0x79 ,0x0 , -+1 ,0x80 ,0x5 , -+1 ,0x81 ,0x0 , -+1 ,0x82 ,0x40 , -+1 ,0x83 ,0x0 , -+1 ,0x84 ,0x40 , -+1 ,0x85 ,0x37 , -+1 ,0x86 ,0x2 , -+1 ,0x87 ,0x20 , -+1 ,0x88 ,0x0 , -+1 ,0x89 ,0x20 , -+1 ,0x8A ,0x0 , -+1 ,0x8B ,0x3 , -+1 ,0x8C ,0x60 , -+1 ,0x8D ,0x30 , -+1 ,0x8E ,0x88 , -+1 ,0x8F ,0x11 , -+1 ,0x90 ,0x0 , -+1 ,0x91 ,0x0 , -+1 ,0x92 ,0x76 , -+1 ,0x93 ,0xA6 , -+1 ,0x94 ,0x19 , -+1 ,0x95 ,0x52 , -+1 ,0x96 ,0x73 , -+1 ,0x97 ,0x96 , -+1 ,0x98 ,0x9E , -+1 ,0x99 ,0x69 , -+1 ,0x9A ,0xFA , -+1 ,0x9B ,0x8F , -+1 ,0x9C ,0x2E , -+1 ,0x9D ,0x8E , -+1 ,0x9E ,0x0 , -+1 ,0x9F ,0x0 , -+1 ,0xA0 ,0xFD , -+1 ,0xA1 ,0x6D , -+1 ,0xA2 ,0x63 , -+1 ,0xA3 ,0x52 , -+1 ,0xFF ,0x55 , -+0xff,0xff,0xff}; -+ -+// Mode : QAM_B_64QAM -+static u8 DMD_REG_QAM_64QAM[]={ -+0 ,0x0 ,0x51 , -+0 ,0x1 ,0x0 , -+0 ,0x2 ,0xC0 , -+0 ,0x3 ,0x0 , -+0 ,0x4 ,0x0 , -+0 ,0x5 ,0x0 , -+0 ,0x6 ,0x0 , -+0 ,0x7 ,0x0 , -+0 ,0x8 ,0x0 , -+0 ,0x9 ,0x0 , -+0 ,0xA ,0x16 , -+0 ,0xB ,0x35 , -+0 ,0xC ,0x56 , -+0 ,0xD ,0x97 , -+0 ,0xE ,0xDE , -+0 ,0xF ,0xD8 , -+0 ,0x10 ,0x0 , -+0 ,0x11 ,0x14 , -+0 ,0x12 ,0xE4 , -+0 ,0x13 ,0x74 , -+0 ,0x14 ,0x8 , -+0 ,0x15 ,0x5 , -+0 ,0x16 ,0x63 , -+0 ,0x17 ,0x0 , -+0 ,0x18 ,0x0 , -+0 ,0x19 ,0x0 , -+0 ,0x1A ,0x0 , -+0 ,0x1B ,0x0 , -+0 ,0x1C ,0x0 , -+0 ,0x1D ,0x0 , -+0 ,0x1E ,0x0 , -+0 ,0x1F ,0x0 , -+0 ,0x20 ,0x0 , -+0 ,0x21 ,0x50 , -+0 ,0x22 ,0x60 , -+0 ,0x23 ,0x36 , -+0 ,0x24 ,0x2 , -+0 ,0x25 ,0x0 , -+0 ,0x26 ,0x0 , -+0 ,0x27 ,0x0 , -+0 ,0x28 ,0x0 , -+0 ,0x29 ,0x0 , -+0 ,0x2A ,0x20 , -+0 ,0x2B ,0xC0 , -+0 ,0x2C ,0x23 , -+0 ,0x2D ,0x3F , -+0 ,0x2E ,0x3F , -+0 ,0x2F ,0x0 , -+0 ,0x30 ,0x2E , -+0 ,0x31 ,0x0 , -+0 ,0x32 ,0x0 , -+0 ,0x33 ,0x81 , -+0 ,0x34 ,0x0 , -+0 ,0x35 ,0x26 , -+0 ,0x36 ,0x21 , -+0 ,0x37 ,0x88 , -+0 ,0x38 ,0x3 , -+0 ,0x39 ,0x19 , -+0 ,0x3A ,0x85 , -+0 ,0x3B ,0x5 , -+0 ,0x3C ,0xC9 , -+0 ,0x3D ,0x2 , -+0 ,0x3E ,0x30 , -+0 ,0x3F ,0x69 , -+0 ,0x40 ,0x1F , -+0 ,0x41 ,0xF0 , -+0 ,0x42 ,0x0 , -+0 ,0x43 ,0x96 , -+0 ,0x44 ,0x72 , -+0 ,0x45 ,0x1B , -+0 ,0x46 ,0x2D , -+0 ,0x47 ,0x1A , -+0 ,0x48 ,0x31 , -+0 ,0x49 ,0xFE , -+0 ,0x4A ,0x96 , -+0 ,0x4B ,0x7 , -+0 ,0x4C ,0x26 , -+0 ,0x4D ,0xE3 , -+0 ,0x4E ,0x22 , -+0 ,0x4F ,0x1B , -+0 ,0x50 ,0x26 , -+0 ,0x51 ,0x12 , -+0 ,0x52 ,0x40 , -+0 ,0x53 ,0x50 , -+0 ,0x54 ,0x60 , -+0 ,0x55 ,0x40 , -+0 ,0x56 ,0xED , -+0 ,0x57 ,0x96 , -+0 ,0x58 ,0x4A , -+0 ,0x59 ,0xDE , -+0 ,0x5A ,0x88 , -+0 ,0x5B ,0xC8 , -+0 ,0x5C ,0x2D , -+0 ,0x5D ,0x1 , -+0 ,0x5E ,0x0 , -+0 ,0x5F ,0xB8 , -+0 ,0x60 ,0x40 , -+0 ,0x61 ,0x14 , -+0 ,0x62 ,0x13 , -+0 ,0x63 ,0x30 , -+0 ,0x64 ,0x59 , -+0 ,0x65 ,0x7 , -+0 ,0x66 ,0xF0 , -+0 ,0x67 ,0x47 , -+0 ,0x68 ,0xA1 , -+0 ,0x69 ,0x80 , -+0 ,0x6A ,0x0 , -+0 ,0x6B ,0x0 , -+0 ,0x6C ,0xC0 , -+0 ,0x6D ,0x0 , -+0 ,0x6E ,0x0 , -+0 ,0x6F ,0x0 , -+0 ,0x70 ,0x0 , -+0 ,0x71 ,0x0 , -+0 ,0x72 ,0x0 , -+0 ,0x73 ,0x0 , -+0 ,0x74 ,0x2F , -+0 ,0x75 ,0x0 , -+0 ,0x76 ,0x0 , -+0 ,0x77 ,0x0 , -+0 ,0x78 ,0x0 , -+0 ,0x79 ,0x40 , -+0 ,0x7A ,0x20 , -+0 ,0x7B ,0x40 , -+0 ,0x7C ,0x80 , -+0 ,0x7D ,0xFF , -+0 ,0x7E ,0x20 , -+0 ,0x7F ,0x40 , -+0 ,0x80 ,0x10 , -+0 ,0x81 ,0x0 , -+0 ,0x82 ,0xE5 , -+0 ,0x83 ,0xC4 , -+0 ,0x84 ,0xE9 , -+0 ,0x85 ,0x52 , -+0 ,0x86 ,0x5F , -+0 ,0x87 ,0x53 , -+0 ,0x88 ,0x20 , -+0 ,0x89 ,0x43 , -+0 ,0x8A ,0x11 , -+0 ,0x8B ,0x8 , -+0 ,0x8C ,0x43 , -+0 ,0x8D ,0x11 , -+0 ,0x8E ,0x8 , -+0 ,0x8F ,0x0 , -+0 ,0x90 ,0x60 , -+0 ,0x91 ,0x5B , -+0 ,0x92 ,0x80 , -+0 ,0x93 ,0xE4 , -+0 ,0x94 ,0x34 , -+0 ,0x95 ,0x0 , -+0 ,0x96 ,0x0 , -+0 ,0x97 ,0x7 , -+0 ,0x98 ,0x0 , -+0 ,0x99 ,0xB0 , -+0 ,0x9A ,0x68 , -+0 ,0x9B ,0x50 , -+0 ,0x9C ,0x84 , -+0 ,0x9D ,0xA9 , -+0 ,0x9E ,0x11 , -+0 ,0x9F ,0x4 , -+0 ,0xA0 ,0x44 , -+0 ,0xA1 ,0x14 , -+0 ,0xA2 ,0x9C , -+0 ,0xA3 ,0x15 , -+0 ,0xA4 ,0xF6 , -+0 ,0xA5 ,0x36 , -+0 ,0xA6 ,0x16 , -+0 ,0xA7 ,0x3F , -+0 ,0xA8 ,0x1 , -+0 ,0xA9 ,0x8 , -+0 ,0xAA ,0x0 , -+0 ,0xAB ,0x0 , -+0 ,0xAC ,0x0 , -+0 ,0xAD ,0x65 , -+0 ,0xAE ,0x87 , -+0 ,0xAF ,0x56 , -+0 ,0xB0 ,0x52 , -+0 ,0xB1 ,0x55 , -+0 ,0xB2 ,0x35 , -+0 ,0xB3 ,0x13 , -+0 ,0xB4 ,0x88 , -+0 ,0xB5 ,0x23 , -+0 ,0xB6 ,0x28 , -+0 ,0xB7 ,0x3C , -+0 ,0xB8 ,0x1 , -+0 ,0xB9 ,0x5B , -+0 ,0xBA ,0x0 , -+0 ,0xBB ,0x0 , -+0 ,0xBC ,0x0 , -+0 ,0xBD ,0x0 , -+0 ,0xBE ,0x0 , -+0 ,0xBF ,0x0 , -+0 ,0xC0 ,0x0 , -+0 ,0xC1 ,0x0 , -+0 ,0xC2 ,0x0 , -+0 ,0xC3 ,0x0 , -+0 ,0xC4 ,0x0 , -+0 ,0xC5 ,0x0 , -+0 ,0xC6 ,0x0 , -+0 ,0xC7 ,0x0 , -+0 ,0xC8 ,0x0 , -+0 ,0xC9 ,0x0 , -+0 ,0xCA ,0x0 , -+0 ,0xCB ,0x0 , -+0 ,0xCC ,0x0 , -+0 ,0xCD ,0x0 , -+0 ,0xCE ,0x0 , -+0 ,0xCF ,0x0 , -+0 ,0xD0 ,0x0 , -+0 ,0xD1 ,0x0 , -+0 ,0xD2 ,0x0 , -+0 ,0xD3 ,0x0 , -+0 ,0xD4 ,0x0 , -+0 ,0xD5 ,0x0 , -+0 ,0xD6 ,0x0 , -+0 ,0xD7 ,0x0 , -+0 ,0xD8 ,0x0 , -+0 ,0xD9 ,0xA0 , -+0 ,0xDA ,0x0 , -+0 ,0xDB ,0x0 , -+0 ,0xDC ,0x0 , -+0 ,0xDD ,0x0 , -+0 ,0xDE ,0x0 , -+0 ,0xDF ,0x9 , -+0 ,0xE0 ,0x8 , -+0 ,0xE1 ,0x8 , -+0 ,0xE2 ,0xA8 , -+0 ,0xE3 ,0x0 , -+0 ,0xE4 ,0x0 , -+0 ,0xE5 ,0x0 , -+0 ,0xE6 ,0x0 , -+0 ,0xE7 ,0xB4 , -+0 ,0xE8 ,0xA , -+0 ,0xE9 ,0x0 , -+0 ,0xEA ,0x0 , -+0 ,0xEB ,0x0 , -+0 ,0xEC ,0x0 , -+0 ,0xED ,0x0 , -+0 ,0xEE ,0x0 , -+0 ,0xEF ,0xB4 , -+0 ,0xF0 ,0x91 , -+0 ,0xF1 ,0x0 , -+0 ,0xF2 ,0x0 , -+0 ,0xF3 ,0x0 , -+0 ,0xF4 ,0x0 , -+0 ,0xF5 ,0x0 , -+0 ,0xF6 ,0x0 , -+0 ,0xF7 ,0x0 , -+0 ,0xF8 ,0x0 , -+0 ,0xF9 ,0x0 , -+0 ,0xFA ,0x0 , -+0 ,0xFB ,0x80 , -+0 ,0xFC ,0x10 , -+0 ,0xFD ,0x2 , -+0 ,0xFE ,0x20 , -+0 ,0xFF ,0xAA , -+1 ,0x9 ,0x0 , -+1 ,0xA ,0x0 , -+1 ,0xB ,0x0 , -+1 ,0xC ,0x8 , -+1 ,0xD ,0x0 , -+1 ,0x14 ,0x8 , -+1 ,0x5A ,0x3C , -+1 ,0x5B ,0x0 , -+1 ,0x5C ,0x0 , -+1 ,0x5D ,0x0 , -+1 ,0x5E ,0x0 , -+1 ,0x5F ,0x0 , -+1 ,0x60 ,0x0 , -+1 ,0x61 ,0xAC , -+1 ,0x62 ,0x24 , -+1 ,0x63 ,0x0 , -+1 ,0x64 ,0x0 , -+1 ,0x65 ,0x0 , -+1 ,0x66 ,0x0 , -+1 ,0x67 ,0x0 , -+1 ,0x68 ,0x0 , -+1 ,0x69 ,0x0 , -+1 ,0x6A ,0x0 , -+1 ,0x6B ,0x0 , -+1 ,0x74 ,0x0 , -+1 ,0x79 ,0x0 , -+1 ,0x80 ,0x5 , -+1 ,0x81 ,0x0 , -+1 ,0x82 ,0x40 , -+1 ,0x83 ,0x0 , -+1 ,0x84 ,0x40 , -+1 ,0x85 ,0x37 , -+1 ,0x86 ,0x2 , -+1 ,0x87 ,0x20 , -+1 ,0x88 ,0x0 , -+1 ,0x89 ,0x20 , -+1 ,0x8A ,0x0 , -+1 ,0x8B ,0x3 , -+1 ,0x8C ,0x60 , -+1 ,0x8D ,0x30 , -+1 ,0x8E ,0x88 , -+1 ,0x8F ,0x11 , -+1 ,0x90 ,0x0 , -+1 ,0x91 ,0x0 , -+1 ,0x92 ,0x71 , -+1 ,0x93 ,0xE7 , -+1 ,0x94 ,0x23 , -+1 ,0x95 ,0x52 , -+1 ,0x96 ,0x73 , -+1 ,0x97 ,0x96 , -+1 ,0x98 ,0xA5 , -+1 ,0x99 ,0x3 , -+1 ,0x9A ,0xBA , -+1 ,0x9B ,0x95 , -+1 ,0x9C ,0x25 , -+1 ,0x9D ,0xD4 , -+1 ,0x9E ,0x0 , -+1 ,0x9F ,0x0 , -+1 ,0xA0 ,0xFD , -+1 ,0xA1 ,0x6D , -+1 ,0xA2 ,0x63 , -+1 ,0xA3 ,0x52 , -+1 ,0xFF ,0x55 , -+0xff,0xff,0xff}; -+ -+ -+// Mode : QAM_B_256QAM -+static u8 DMD_REG_QAM_256QAM[]={ -+0 ,0x0 ,0x53 , -+0 ,0x1 ,0x0 , -+0 ,0x2 ,0xC0 , -+0 ,0x3 ,0x0 , -+0 ,0x4 ,0x0 , -+0 ,0x5 ,0x0 , -+0 ,0x6 ,0x0 , -+0 ,0x7 ,0x0 , -+0 ,0x8 ,0x0 , -+0 ,0x9 ,0x0 , -+0 ,0xA ,0x16 , -+0 ,0xB ,0x35 , -+0 ,0xC ,0x56 , -+0 ,0xD ,0x8F , -+0 ,0xE ,0x44 , -+0 ,0xF ,0xED , -+0 ,0x10 ,0x0 , -+0 ,0x11 ,0x14 , -+0 ,0x12 ,0xE4 , -+0 ,0x13 ,0x74 , -+0 ,0x14 ,0x8 , -+0 ,0x15 ,0x5 , -+0 ,0x16 ,0x63 , -+0 ,0x17 ,0x0 , -+0 ,0x18 ,0x0 , -+0 ,0x19 ,0x0 , -+0 ,0x1A ,0x0 , -+0 ,0x1B ,0x0 , -+0 ,0x1C ,0x0 , -+0 ,0x1D ,0x0 , -+0 ,0x1E ,0x0 , -+0 ,0x1F ,0x0 , -+0 ,0x20 ,0x0 , -+0 ,0x21 ,0x50 , -+0 ,0x22 ,0x60 , -+0 ,0x23 ,0x36 , -+0 ,0x24 ,0x2 , -+0 ,0x25 ,0x0 , -+0 ,0x26 ,0x0 , -+0 ,0x27 ,0x0 , -+0 ,0x28 ,0x0 , -+0 ,0x29 ,0x0 , -+0 ,0x2A ,0x20 , -+0 ,0x2B ,0xC0 , -+0 ,0x2C ,0x23 , -+0 ,0x2D ,0x3F , -+0 ,0x2E ,0x3F , -+0 ,0x2F ,0x0 , -+0 ,0x30 ,0x2E , -+0 ,0x31 ,0x0 , -+0 ,0x32 ,0x0 , -+0 ,0x33 ,0x81 , -+0 ,0x34 ,0x0 , -+0 ,0x35 ,0x26 , -+0 ,0x36 ,0x21 , -+0 ,0x37 ,0x88 , -+0 ,0x38 ,0x3 , -+0 ,0x39 ,0x19 , -+0 ,0x3A ,0x85 , -+0 ,0x3B ,0x5 , -+0 ,0x3C ,0xC9 , -+0 ,0x3D ,0x2 , -+0 ,0x3E ,0x30 , -+0 ,0x3F ,0x69 , -+0 ,0x40 ,0x1F , -+0 ,0x41 ,0xF0 , -+0 ,0x42 ,0x0 , -+0 ,0x43 ,0x96 , -+0 ,0x44 ,0x72 , -+0 ,0x45 ,0x1B , -+0 ,0x46 ,0x2D , -+0 ,0x47 ,0x1A , -+0 ,0x48 ,0x31 , -+0 ,0x49 ,0xFE , -+0 ,0x4A ,0x96 , -+0 ,0x4B ,0x7 , -+0 ,0x4C ,0x26 , -+0 ,0x4D ,0xE3 , -+0 ,0x4E ,0x22 , -+0 ,0x4F ,0x1B , -+0 ,0x50 ,0x26 , -+0 ,0x51 ,0x12 , -+0 ,0x52 ,0x40 , -+0 ,0x53 ,0x50 , -+0 ,0x54 ,0x60 , -+0 ,0x55 ,0x40 , -+0 ,0x56 ,0xED , -+0 ,0x57 ,0x96 , -+0 ,0x58 ,0x4A , -+0 ,0x59 ,0xDE , -+0 ,0x5A ,0x88 , -+0 ,0x5B ,0xC8 , -+0 ,0x5C ,0x2D , -+0 ,0x5D ,0x1 , -+0 ,0x5E ,0x0 , -+0 ,0x5F ,0xB8 , -+0 ,0x60 ,0x40 , -+0 ,0x61 ,0x14 , -+0 ,0x62 ,0x13 , -+0 ,0x63 ,0x30 , -+0 ,0x64 ,0x59 , -+0 ,0x65 ,0x7 , -+0 ,0x66 ,0xF0 , -+0 ,0x67 ,0x47 , -+0 ,0x68 ,0xA1 , -+0 ,0x69 ,0x80 , -+0 ,0x6A ,0x0 , -+0 ,0x6B ,0x0 , -+0 ,0x6C ,0xC0 , -+0 ,0x6D ,0x0 , -+0 ,0x6E ,0x0 , -+0 ,0x6F ,0x0 , -+0 ,0x70 ,0x0 , -+0 ,0x71 ,0x0 , -+0 ,0x72 ,0x0 , -+0 ,0x73 ,0x0 , -+0 ,0x74 ,0x2F , -+0 ,0x75 ,0x0 , -+0 ,0x76 ,0x0 , -+0 ,0x77 ,0x0 , -+0 ,0x78 ,0x0 , -+0 ,0x79 ,0x40 , -+0 ,0x7A ,0x20 , -+0 ,0x7B ,0x40 , -+0 ,0x7C ,0x80 , -+0 ,0x7D ,0xFF , -+0 ,0x7E ,0x20 , -+0 ,0x7F ,0x40 , -+0 ,0x80 ,0x10 , -+0 ,0x81 ,0x0 , -+0 ,0x82 ,0xE5 , -+0 ,0x83 ,0xC4 , -+0 ,0x84 ,0xE9 , -+0 ,0x85 ,0x52 , -+0 ,0x86 ,0x5F , -+0 ,0x87 ,0x53 , -+0 ,0x88 ,0x20 , -+0 ,0x89 ,0x43 , -+0 ,0x8A ,0x11 , -+0 ,0x8B ,0x8 , -+0 ,0x8C ,0x43 , -+0 ,0x8D ,0x11 , -+0 ,0x8E ,0x8 , -+0 ,0x8F ,0x0 , -+0 ,0x90 ,0x60 , -+0 ,0x91 ,0x5B , -+0 ,0x92 ,0x80 , -+0 ,0x93 ,0xE4 , -+0 ,0x94 ,0x34 , -+0 ,0x95 ,0x0 , -+0 ,0x96 ,0x0 , -+0 ,0x97 ,0x7 , -+0 ,0x98 ,0x0 , -+0 ,0x99 ,0xB0 , -+0 ,0x9A ,0x68 , -+0 ,0x9B ,0x50 , -+0 ,0x9C ,0x84 , -+0 ,0x9D ,0xA9 , -+0 ,0x9E ,0x11 , -+0 ,0x9F ,0x4 , -+0 ,0xA0 ,0x44 , -+0 ,0xA1 ,0x14 , -+0 ,0xA2 ,0x9C , -+0 ,0xA3 ,0x15 , -+0 ,0xA4 ,0xF6 , -+0 ,0xA5 ,0x36 , -+0 ,0xA6 ,0x16 , -+0 ,0xA7 ,0x3F , -+0 ,0xA8 ,0x1 , -+0 ,0xA9 ,0x8 , -+0 ,0xAA ,0x0 , -+0 ,0xAB ,0x0 , -+0 ,0xAC ,0x0 , -+0 ,0xAD ,0x65 , -+0 ,0xAE ,0x87 , -+0 ,0xAF ,0x56 , -+0 ,0xB0 ,0x52 , -+0 ,0xB1 ,0x55 , -+0 ,0xB2 ,0x35 , -+0 ,0xB3 ,0x13 , -+0 ,0xB4 ,0x88 , -+0 ,0xB5 ,0x23 , -+0 ,0xB6 ,0x28 , -+0 ,0xB7 ,0x3C , -+0 ,0xB8 ,0x1 , -+0 ,0xB9 ,0x5B , -+0 ,0xBA ,0x0 , -+0 ,0xBB ,0x0 , -+0 ,0xBC ,0x0 , -+0 ,0xBD ,0x0 , -+0 ,0xBE ,0x0 , -+0 ,0xBF ,0x0 , -+0 ,0xC0 ,0x0 , -+0 ,0xC1 ,0x0 , -+0 ,0xC2 ,0x0 , -+0 ,0xC3 ,0x0 , -+0 ,0xC4 ,0x0 , -+0 ,0xC5 ,0x0 , -+0 ,0xC6 ,0x0 , -+0 ,0xC7 ,0x0 , -+0 ,0xC8 ,0x0 , -+0 ,0xC9 ,0x0 , -+0 ,0xCA ,0x0 , -+0 ,0xCB ,0x0 , -+0 ,0xCC ,0x0 , -+0 ,0xCD ,0x0 , -+0 ,0xCE ,0x0 , -+0 ,0xCF ,0x0 , -+0 ,0xD0 ,0x0 , -+0 ,0xD1 ,0x0 , -+0 ,0xD2 ,0x0 , -+0 ,0xD3 ,0x0 , -+0 ,0xD4 ,0x0 , -+0 ,0xD5 ,0x0 , -+0 ,0xD6 ,0x0 , -+0 ,0xD7 ,0x0 , -+0 ,0xD8 ,0x0 , -+0 ,0xD9 ,0xA0 , -+0 ,0xDA ,0x0 , -+0 ,0xDB ,0x0 , -+0 ,0xDC ,0x0 , -+0 ,0xDD ,0x0 , -+0 ,0xDE ,0x0 , -+0 ,0xDF ,0x9 , -+0 ,0xE0 ,0x8 , -+0 ,0xE1 ,0x8 , -+0 ,0xE2 ,0xA8 , -+0 ,0xE3 ,0x0 , -+0 ,0xE4 ,0x0 , -+0 ,0xE5 ,0x0 , -+0 ,0xE6 ,0x0 , -+0 ,0xE7 ,0xB4 , -+0 ,0xE8 ,0xA , -+0 ,0xE9 ,0x0 , -+0 ,0xEA ,0x0 , -+0 ,0xEB ,0x0 , -+0 ,0xEC ,0x0 , -+0 ,0xED ,0x0 , -+0 ,0xEE ,0x0 , -+0 ,0xEF ,0xB4 , -+0 ,0xF0 ,0x91 , -+0 ,0xF1 ,0x0 , -+0 ,0xF2 ,0x0 , -+0 ,0xF3 ,0x0 , -+0 ,0xF4 ,0x0 , -+0 ,0xF5 ,0x0 , -+0 ,0xF6 ,0x0 , -+0 ,0xF7 ,0x0 , -+0 ,0xF8 ,0x0 , -+0 ,0xF9 ,0x0 , -+0 ,0xFA ,0x0 , -+0 ,0xFB ,0x80 , -+0 ,0xFC ,0x10 , -+0 ,0xFD ,0x2 , -+0 ,0xFE ,0x20 , -+0 ,0xFF ,0xAA , -+1 ,0x9 ,0x0 , -+1 ,0xA ,0x0 , -+1 ,0xB ,0x0 , -+1 ,0xC ,0x8 , -+1 ,0xD ,0x0 , -+1 ,0x14 ,0x8 , -+1 ,0x5A ,0x3C , -+1 ,0x5B ,0x0 , -+1 ,0x5C ,0x0 , -+1 ,0x5D ,0x0 , -+1 ,0x5E ,0x0 , -+1 ,0x5F ,0x0 , -+1 ,0x60 ,0x0 , -+1 ,0x61 ,0xAC , -+1 ,0x62 ,0x24 , -+1 ,0x63 ,0x0 , -+1 ,0x64 ,0x0 , -+1 ,0x65 ,0x0 , -+1 ,0x66 ,0x0 , -+1 ,0x67 ,0x0 , -+1 ,0x68 ,0x0 , -+1 ,0x69 ,0x0 , -+1 ,0x6A ,0x0 , -+1 ,0x6B ,0x0 , -+1 ,0x74 ,0x0 , -+1 ,0x79 ,0x0 , -+1 ,0x80 ,0x5 , -+1 ,0x81 ,0x0 , -+1 ,0x82 ,0x40 , -+1 ,0x83 ,0x0 , -+1 ,0x84 ,0x40 , -+1 ,0x85 ,0x37 , -+1 ,0x86 ,0x2 , -+1 ,0x87 ,0x20 , -+1 ,0x88 ,0x0 , -+1 ,0x89 ,0x20 , -+1 ,0x8A ,0x0 , -+1 ,0x8B ,0x3 , -+1 ,0x8C ,0x60 , -+1 ,0x8D ,0x30 , -+1 ,0x8E ,0x88 , -+1 ,0x8F ,0x11 , -+1 ,0x90 ,0x0 , -+1 ,0x91 ,0x0 , -+1 ,0x92 ,0x76 , -+1 ,0x93 ,0xA6 , -+1 ,0x94 ,0x19 , -+1 ,0x95 ,0x4F , -+1 ,0x96 ,0x27 , -+1 ,0x97 ,0x49 , -+1 ,0x98 ,0xA5 , -+1 ,0x99 ,0x3 , -+1 ,0x9A ,0xBA , -+1 ,0x9B ,0x95 , -+1 ,0x9C ,0x25 , -+1 ,0x9D ,0xD4 , -+1 ,0x9E ,0x0 , -+1 ,0x9F ,0x0 , -+1 ,0xA0 ,0xFD , -+1 ,0xA1 ,0x6D , -+1 ,0xA2 ,0x63 , -+1 ,0xA3 ,0x52 , -+1 ,0xFF ,0x55 , -+0xff,0xff,0xff}; -+ -+static u32 MN88436_REG_AUTOCTRL_SIZE = 673; -+ -+static u8 MN88436_REG_AUTOCTRL[] = { -+ 0x10 ,0x00 ,0xc0 ,0x02 ,0xa1 ,0x10 ,0x25 ,0x20 -+ ,0x4b ,0x10 ,0x1b ,0x20 ,0x51 ,0x10 ,0x64 ,0x20 -+ ,0xf7 ,0x10 ,0x0a ,0x20 ,0xeb ,0x30 ,0xc4 ,0x70 -+ ,0x60 ,0x90 ,0x00 ,0x78 ,0x82 ,0x00 ,0x1f ,0x10 -+ ,0x0c ,0x20 ,0xeb ,0x30 ,0xec ,0x70 ,0xbf ,0x20 -+ ,0xec ,0x30 ,0x5b ,0x70 ,0x40 ,0x14 ,0x30 ,0xec -+ ,0x75 ,0x20 ,0xec ,0x30 ,0xc4 ,0x70 ,0x02 ,0x90 -+ ,0x00 ,0x05 ,0x0d ,0x82 ,0x00 ,0x73 ,0x82 ,0x00 -+ ,0x41 ,0x30 ,0xc4 ,0x70 ,0x01 ,0xb0 ,0x00 ,0x1f -+ ,0xc4 ,0x02 ,0xa5 ,0x68 ,0x88 ,0x90 ,0x00 ,0x63 -+ ,0x80 ,0x00 ,0x53 ,0x10 ,0x88 ,0xc0 ,0x02 ,0xa5 -+ ,0x20 ,0x5b ,0x30 ,0xec ,0x70 ,0xbf ,0x20 ,0xec -+ ,0x80 ,0x00 ,0x1f ,0x10 ,0xc8 ,0xc0 ,0x02 ,0xa5 -+ ,0x20 ,0x5b ,0x30 ,0xec ,0x74 ,0x40 ,0x20 ,0xec -+ ,0x80 ,0x00 ,0x1f ,0x08 ,0xb0 ,0x00 ,0x73 ,0x01 -+ ,0x10 ,0x58 ,0x20 ,0xb9 ,0x30 ,0xed ,0x70 ,0xfc -+ ,0x20 ,0xed ,0x82 ,0x01 ,0x54 ,0x10 ,0x07 ,0x20 -+ ,0x4b ,0x10 ,0x12 ,0x20 ,0x51 ,0x10 ,0x5b ,0x20 -+ ,0xb9 ,0x10 ,0x01 ,0x20 ,0xeb ,0x10 ,0x00 ,0xc0 -+ ,0x02 ,0xa0 ,0x20 ,0x5e ,0x10 ,0x94 ,0x20 ,0x5d -+ ,0x10 ,0x00 ,0xc0 ,0x02 ,0xa4 ,0x82 ,0x02 ,0x3c -+ ,0x0c ,0x82 ,0x02 ,0x2c ,0x09 ,0x82 ,0x01 ,0x77 -+ ,0xc4 ,0x02 ,0xa4 ,0x40 ,0xc0 ,0x02 ,0xa4 ,0x14 -+ ,0x10 ,0x3c ,0x69 ,0xb0 ,0x00 ,0xa5 ,0x82 ,0x01 -+ ,0x2a ,0x10 ,0x02 ,0x20 ,0xeb ,0xc4 ,0x02 ,0xa0 -+ ,0x68 ,0x0f ,0xc0 ,0x02 ,0xa0 ,0x20 ,0x5e ,0x10 -+ ,0x94 ,0x20 ,0x5d ,0x10 ,0x00 ,0xc0 ,0x02 ,0xa4 -+ ,0x82 ,0x02 ,0x3c ,0x0c ,0x82 ,0x02 ,0x2c ,0x09 -+ ,0x82 ,0x01 ,0x77 ,0xc4 ,0x02 ,0xa4 ,0x40 ,0xc0 -+ ,0x02 ,0xa4 ,0x14 ,0x10 ,0x3c ,0x69 ,0xb0 ,0x00 -+ ,0xd8 ,0x82 ,0x01 ,0x2a ,0x10 ,0x04 ,0x20 ,0xeb -+ ,0xc4 ,0x02 ,0xa0 ,0x60 ,0x1e ,0xc0 ,0x02 ,0xa0 -+ ,0x20 ,0x5e ,0x10 ,0x94 ,0x20 ,0x5d ,0x10 ,0x00 -+ ,0xc0 ,0x02 ,0xa4 ,0x82 ,0x02 ,0x3c ,0x0c ,0x82 -+ ,0x02 ,0x2c ,0x09 ,0x82 ,0x01 ,0x77 ,0xc4 ,0x02 -+ ,0xa4 ,0x40 ,0xc0 ,0x02 ,0xa4 ,0x14 ,0x10 ,0x3c -+ ,0x69 ,0xb0 ,0x01 ,0x0b ,0x82 ,0x01 ,0x2a ,0x80 -+ ,0x00 ,0x91 ,0x30 ,0xea ,0xc0 ,0x02 ,0xa2 ,0x10 -+ ,0x04 ,0x20 ,0xba ,0x10 ,0x47 ,0x20 ,0x60 ,0x10 -+ ,0x05 ,0x20 ,0xba ,0x30 ,0xbd ,0x70 ,0x20 ,0xc0 -+ ,0x02 ,0xa3 ,0x30 ,0xea ,0xc5 ,0x02 ,0xa2 ,0x69 -+ ,0xb0 ,0x01 ,0x2a ,0xc4 ,0x02 ,0xa3 ,0x60 ,0x00 -+ ,0xb0 ,0x01 ,0xed ,0x01 ,0x10 ,0x05 ,0x20 ,0xeb -+ ,0x10 ,0x10 ,0x20 ,0xac ,0x10 ,0xf4 ,0x20 ,0xe7 -+ ,0x10 ,0x04 ,0x20 ,0xaa ,0x10 ,0x0 ,0xc0 ,0x02 -+ ,0xa0 ,0x20 ,0x5e ,0x10 ,0x94 ,0x20 ,0x5d ,0x30 -+ ,0xc4 ,0x70 ,0x01 ,0x90 ,0x00 ,0x05 ,0x01 ,0x82 -+ ,0x01 ,0x7f ,0x08 ,0xb0 ,0x01 ,0x77 ,0x01 ,0x30 -+ ,0xea ,0xc0 ,0x02 ,0xa2 ,0x10 ,0x5b ,0x20 ,0xb9 -+ ,0x10 ,0x04 ,0x20 ,0xba ,0x10 ,0x47 ,0x20 ,0x60 -+ ,0x10 ,0x05 ,0x20 ,0xba ,0x30 ,0xbd ,0x70 ,0x20 -+ ,0xc0 ,0x02 ,0xa3 ,0x30 ,0xea ,0xc5 ,0x02 ,0xa2 -+ ,0x69 ,0xb0 ,0x01 ,0x7f ,0xc4 ,0x02 ,0xa3 ,0x60 -+ ,0x00 ,0x90 ,0x01 ,0xaf ,0xb0 ,0x01 ,0xce ,0x10 -+ ,0x10 ,0x20 ,0xac ,0x10 ,0xf4 ,0x20 ,0xe7 ,0x10 -+ ,0x04 ,0x20 ,0xaa ,0x30 ,0xc6 ,0xc0 ,0x02 ,0xa1 -+ ,0x70 ,0x04 ,0x90 ,0x00 ,0x05 ,0x30 ,0xed ,0x70 -+ ,0xfb ,0x74 ,0x00 ,0x20 ,0xed ,0x01 ,0x10 ,0x10 -+ ,0x20 ,0xac ,0x10 ,0x90 ,0x20 ,0xe7 ,0x10 ,0x04 -+ ,0x20 ,0xaa ,0x30 ,0xc6 ,0xc0 ,0x02 ,0xa1 ,0x70 -+ ,0x04 ,0x90 ,0x00 ,0x05 ,0x30 ,0xed ,0x70 ,0xfb -+ ,0x74 ,0x04 ,0x20 ,0xed ,0x01 ,0x30 ,0x5e ,0x70 -+ ,0xff ,0x92 ,0x02 ,0x11 ,0x30 ,0x5e ,0x70 ,0x80 -+ ,0xb2 ,0x02 ,0x1a ,0x30 ,0x5e ,0x68 ,0x0f ,0x92 -+ ,0x02 ,0x23 ,0x30 ,0xeb ,0x74 ,0xf0 ,0x20 ,0xeb -+ ,0x82 ,0x01 ,0x7f ,0x82 ,0x02 ,0x3c ,0x80 ,0x02 -+ ,0x02 ,0x30 ,0xed ,0x70 ,0xfc ,0x74 ,0x01 ,0x20 -+ ,0xed ,0x01 ,0x30 ,0xed ,0x70 ,0xfc ,0x74 ,0x02 -+ ,0x20 ,0xed ,0x01 ,0x30 ,0xed ,0x70 ,0xfc ,0x74 -+ ,0x03 ,0x20 ,0xed ,0x01 ,0x30 ,0xc6 ,0xc0 ,0x02 -+ ,0xa1 ,0x70 ,0x04 ,0x90 ,0x00 ,0x05 ,0x08 ,0xb0 -+ ,0x02 ,0x2c ,0x09 ,0x01 ,0x30 ,0xeb ,0x74 ,0x10 -+ ,0x20 ,0xeb ,0x30 ,0xd8 ,0x14 ,0x70 ,0x07 ,0x90 -+ ,0x02 ,0x51 ,0x11 ,0x68 ,0x05 ,0x90 ,0x02 ,0x51 -+ ,0x01 ,0x30 ,0xcf ,0xc0 ,0x02 ,0xa6 ,0xc4 ,0x02 -+ ,0xa6 ,0x70 ,0xf8 ,0x90 ,0x02 ,0x61 ,0xb0 ,0x02 -+ ,0x7e ,0xc4 ,0x02 ,0xa6 ,0x4c ,0x4c ,0x4c ,0x4c -+ ,0x4c ,0xc0 ,0x02 ,0xa6 ,0x30 ,0xd0 ,0x48 ,0x48 -+ ,0x48 ,0x14 ,0xc4 ,0x02 ,0xa6 ,0x61 ,0xc0 ,0x02 -+ ,0xa6 ,0x20 ,0xee ,0x80 ,0x02 ,0x88 ,0x10 ,0xff -+ ,0xc0 ,0x02 ,0xa6 ,0x20 ,0xee ,0x80 ,0x02 ,0x88 -+ ,0xc4 ,0x02 ,0xa6 ,0x14 ,0x30 ,0xef ,0x69 ,0x88 -+ ,0x02 ,0x93 ,0x01 ,0x30 ,0xa3 ,0x70 ,0x07 ,0x74 -+ ,0x28 ,0x20 ,0xa3 ,0x70 ,0x07 ,0x20 ,0xa3 ,0x01 -+ ,0x72}; -+ -+static const struct dvb_frontend_ops mn88436_ops; -+ -+static int log10_easy( u32 cnr ) -+{ -+ u32 c; -+ s32 ret; -+ s32 logtbl[] = { -+ 0 ,-1000,-699 ,-523,-398, -+ -301,-222 ,-155 ,-97 ,-46 , -+ 0 ,41 ,79 ,114 ,146 , -+ 176 ,204 ,230 ,255 , -+ 279 ,301 ,322 ,342 , -+ 362 ,380 ,398 ,415 , -+ 431 ,447 ,462 ,477 , -+ 491 ,505 ,519 ,531 , -+ 544 ,556 ,568 ,580 , -+ 591 ,602 ,613 ,623 , -+ 633 ,643 ,653 ,663 , -+ 672 ,681 ,690 ,699 , -+ 708 ,716 ,724 ,732 , -+ 740 ,748 ,756 ,763 , -+ 771 ,778 ,785 ,792 , -+ 799 ,806 ,813 ,820 , -+ 826 ,833 ,839 ,845 , -+ 851 ,857 ,863 ,869 , -+ 875 ,881 ,886 ,892 , -+ 898 ,903 ,908 ,914 , -+ 919 ,924 ,929 ,934 , -+ 940 ,944 ,949 ,954 , -+ 959 ,964 ,968 ,973 , -+ 978 ,982 ,987 ,991 , -+ 996 ,1000}; -+ c = 0; -+ -+ while( cnr > 100 ){ -+ cnr = cnr / 10; -+ c++; -+ } -+ ret = logtbl[cnr] + c*1000 + 1000; -+ -+ return ret; -+} -+ -+static int DMD_send_registers(struct i2c_client *client,u8*regset) -+{ -+ struct mn88436_dev*dev = i2c_get_clientdata(client); -+ int ret; -+ u32 i; -+ for(i=0;;) -+ { -+ if(regset[i]==0xff)break; -+ ret=regmap_write(dev->regmap[regset[i]],regset[i+1],regset[i+2]); -+ i=i+3; -+ } -+ return ret; -+} -+ -+static int mn88436_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct mn88436_dev *dev = i2c_get_clientdata(client); -+ u32 ifagc = 0; -+ int IF1,IF2; -+ -+ regmap_read(dev->regmap[1], DMD_USR_IFAGCMON1 , &IF1 ); -+ regmap_read(dev->regmap[1], DMD_USR_IFAGCMON2 , &IF2 ); -+ -+ ifagc = IF1 * 256 + IF2; -+ if ( ifagc < AGC_MIN ) -+ { -+ *strength = 0; -+ } -+ else if ( ifagc > AGC_MAX ) -+ { -+ *strength = 100; -+ } -+ else -+ { -+ *strength = (ifagc-AGC_MIN)*100/AGC_RANGE; -+ } -+ -+ -+ return 0; -+} -+ -+static int mn88436_read_status(struct dvb_frontend *fe,enum fe_status *status) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct mn88436_dev *dev = i2c_get_clientdata(client); -+ -+ int ret; -+ int utemp; -+ int i =0; -+ for(i=0;i<50;i++) -+ { -+ ret = regmap_read(dev->regmap[0],DMD_MAIN_STSMON1,&utemp); -+ if(utemp&0x1){ -+ *status = FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; -+ break; -+ } -+ else -+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; -+ -+ msleep(1); -+ } -+ -+ return ret; -+ -+} -+static int mn88436_init(struct dvb_frontend *fe) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct mn88436_dev *dev = i2c_get_clientdata(client); -+ int ret; -+ int utemp; -+ u32 i; -+ /*Demod LSI init*/ -+ ret = DMD_send_registers(client,DMD_REG_ATSC); -+ if(ret) -+ goto err; -+ ret = regmap_write(dev->regmap[0],DMD_MAIN_PSEQSET,0x03); -+ if(ret) -+ goto err; -+ for(i=0;iregmap[0],DMD_MAIN_PSEQPRG,MN88436_REG_AUTOCTRL[i]); -+ -+ -+ ret |= regmap_read(dev->regmap[0],DMD_MAIN_PSEQSET,&utemp); -+ if(utemp&0x20) -+ { -+ printk("ERROR : PSEQ Parity \n"); -+ } -+ else -+ ret |= regmap_write(dev->regmap[0],DMD_MAIN_PSEQSET,0x00); -+ -+ if(ret) -+ goto err; -+ -+ ret = regmap_read(dev->regmap[0],DMD_MAIN_TCBSET,&utemp); -+ utemp |=0x7f &0x53; -+ utemp &=(0x7f^0xff)|0x53; -+ ret = regmap_write(dev->regmap[0],DMD_MAIN_TCBSET,utemp); -+ -+ ret = regmap_write(dev->regmap[0],DMD_MAIN_TCBADR,0x00); -+ if(ret) -+ goto err; -+ -+ -+ /*set TS mode*/ -+ utemp = dev->ts_mode ?0xc0 :0xc1; -+ ret = regmap_write(dev->regmap[0],DMD_MAIN_CPOSET2,utemp); -+ -+ utemp = dev->ts_mode ?0xc0 :0xff; -+ ret |= regmap_write(dev->regmap[0],DMD_MAIN_GPSET1,utemp); -+ -+ if(!dev->ts_mode) -+ ret |= regmap_write(dev->regmap[0],DMD_MAIN_CPOSET1,0x01); -+ -+ if(ret) -+ goto err; -+ -+ dev_dbg(&client->dev,"mn88436 init successfully."); -+ -+ return ret; -+err: -+ dev_err(&client->dev,"failed =%d",ret); -+ return ret; -+ -+} -+static int mn88436_set_frontend(struct dvb_frontend *fe) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct mn88436_dev *dev = i2c_get_clientdata(client); -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int ret; -+ int utemp; -+ u32 tuner_status; -+ -+ dev_dbg(&client->dev,"delivery_system=%u modulation=%u ,frequency=%d \n",c->delivery_system, -+ c->modulation,c->frequency); -+ switch(c->modulation){ -+ default: -+ case VSB_8: -+ ret = DMD_send_registers(client,DMD_REG_ATSC); -+ dev->mode = DMD_E_ATSC; -+ break; -+ case QAM_64: -+ ret = DMD_send_registers(client,DMD_REG_QAM_64QAM); -+ dev->mode = DMD_E_QAMB_64QAM; -+ break; -+ case QAM_256: -+ ret = DMD_send_registers(client,DMD_REG_QAM_256QAM); -+ dev->mode = DMD_E_QAMB_256QAM; -+ break; -+ } -+ /*set TS again*/ -+ utemp = dev->ts_mode ?0xc0 :0xc1; -+ ret = regmap_write(dev->regmap[0],DMD_MAIN_CPOSET2,utemp); -+ -+ utemp = dev->ts_mode ?0xc0 :0xff; -+ ret |= regmap_write(dev->regmap[0],DMD_MAIN_GPSET1,utemp); -+ -+ if(!dev->ts_mode) -+ ret |= regmap_write(dev->regmap[0],DMD_MAIN_CPOSET1,0x01); -+ -+ ret |= regmap_write(dev->regmap[0],DMD_MAIN_VEQSET2,0xe0); -+ if(ret) -+ goto err; -+ -+ /*set tuner*/ -+ if(fe->ops.tuner_ops.set_params){ -+ ret = fe->ops.tuner_ops.set_params(fe); -+ if(ret) -+ goto err; -+ } -+ if(fe->ops.tuner_ops.get_status){ -+ ret = fe->ops.tuner_ops.get_status(fe,&tuner_status); -+ } -+ msleep(5); -+ -+ ret = regmap_write(dev->regmap[0],DMD_MAIN_RSTSET1,0x77); -+ if(ret) -+ goto err; -+ -+ return ret; -+err: -+ dev_err(&client->dev,"failed = %d" ,ret); -+ return ret; -+} -+static int mn88436_read_snr(struct dvb_frontend* fe, u16* snr) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct mn88436_dev *dev = i2c_get_clientdata(client); -+ int rd; -+ u32 cni,cnd; -+ u32 x,y; -+ -+ regmap_read(dev->regmap[1], DMD_USR_CNMON1 , &rd ); -+ x = 0x100 * rd; -+ regmap_read(dev->regmap[1], DMD_USR_CNMON2 , &rd ); -+ x += rd; -+ regmap_read(dev->regmap[1], DMD_USR_CNMON3 , &rd ); -+ y = 0x100 * rd; -+ regmap_read(dev->regmap[1], DMD_USR_CNMON4 , &rd ); -+ y += rd; -+ if( dev->mode == DMD_E_ATSC ) -+ { -+ //after EQ -+ *snr = 4634 - log10_easy( y ); -+ -+ } -+ else -+ { -+ if( y != 0 ) -+ *snr = log10_easy( (8*x) / y ); -+ else -+ *snr = 0; -+ -+ } -+ -+ return 0; -+} -+ -+static const struct dvb_frontend_ops mn88436_ops = { -+ .delsys = {SYS_ATSC,SYS_DVBC_ANNEX_B}, -+ .info = { -+ .name = "MN88436 ATSC/QAMB frontend", -+ .frequency_min = 44000000, -+ .frequency_max = 1002000000, -+ .frequency_stepsize = 62500, -+ .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB -+ -+ }, -+ .init = mn88436_init, -+ .set_frontend = mn88436_set_frontend, -+ .read_status = mn88436_read_status, -+ .read_signal_strength = mn88436_read_signal_strength, -+ .read_snr = mn88436_read_snr, -+}; -+static int mn88436_probe(struct i2c_client *client , -+ const struct i2c_device_id *id) -+{ -+ struct mn88436_config *cfg = client->dev.platform_data; -+ struct mn88436_dev *dev; -+ int ret; -+ int utmp; -+ static const struct regmap_config regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ }; -+ dev = kzalloc(sizeof(*dev),GFP_KERNEL); -+ if(!dev){ -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ dev->i2c_write_max = cfg->i2c_wr_max ?cfg->i2c_wr_max : ~0; -+ dev->ts_mode = cfg->ts_mode; -+ dev->mode = DMD_E_ATSC; -+ dev->client[0] = client; -+ dev->regmap[0] = regmap_init_i2c(dev->client[0],®map_config); -+ if(IS_ERR(dev->regmap[0])){ -+ ret = PTR_ERR(dev->regmap[0]); -+ goto err_kfree; -+ } -+ /*check demod i2c*/ -+ ret = regmap_read(dev->regmap[0],0xff,&utmp); -+ if(ret) -+ goto err_regmap_0_regmap_exit; -+ -+ ret = regmap_write(dev->regmap[0],0xff,0x99); -+ if(ret) -+ goto err_regmap_0_regmap_exit; -+ -+ ret = regmap_read(dev->regmap[0],0xff,&utmp); -+ if(utmp!=0x99) -+ goto err_regmap_0_regmap_exit; -+ -+ /*chip has two IIC address for different register bank, 0x18 and 0x10,so we need register a dummy clients */ -+ dev->client[1] = i2c_new_dummy(client->adapter,0x10); -+ if(!dev->client[1]){ -+ ret = -ENODEV; -+ dev_err(&client->dev,"I2C registeration failed\n"); -+ if(ret) -+ goto err_regmap_0_regmap_exit; -+ } -+ -+ -+ dev->regmap[1] = regmap_init_i2c(dev->client[1],®map_config); -+ if(IS_ERR(dev->regmap[1])){ -+ ret = PTR_ERR(dev->regmap[1]); -+ goto err_client_1_i2c_unregister_device; -+ } -+ i2c_set_clientdata(dev->client[1],dev); -+ -+ /*test the dummy i2c*/ -+ ret = regmap_write(dev->regmap[1],0xff,0x88); -+ if(ret) -+ goto err_regmap_1_regmap_exit; -+ ret = regmap_read(dev->regmap[1],0xff,&utmp); -+ if(ret) -+ goto err_regmap_1_regmap_exit; -+ if(utmp!=0x88) -+ goto err_regmap_1_regmap_exit; -+ -+ /*Create dvb frontend*/ -+ -+ memcpy(&dev->fe.ops,&mn88436_ops,sizeof(struct dvb_frontend_ops)); -+ dev->fe.demodulator_priv = client; -+ *cfg->fe = &dev->fe; -+ i2c_set_clientdata(client,dev); -+ -+ dev_info(&client->dev, "Panasonic MN88436 successfully identified\n"); -+ -+ return 0; -+ -+err_regmap_1_regmap_exit: -+ regmap_exit(dev->regmap[1]); -+err_client_1_i2c_unregister_device : -+ i2c_unregister_device(dev->client[1]); -+err_regmap_0_regmap_exit: -+ regmap_exit(dev->regmap[0]); -+ -+err_kfree: -+ kfree(dev); -+err : -+ dev_err(&client->dev,"__failed = %d___\n",ret); -+ return ret; -+} -+static int mn88436_remove(struct i2c_client *client) -+{ -+ struct mn88436_dev *dev = i2c_get_clientdata(client); -+ -+ regmap_exit(dev->regmap[1]); -+ i2c_unregister_device(dev->client[1]); -+ -+ regmap_exit(dev->regmap[0]); -+ -+ kfree(dev); -+ -+ return 0; -+ -+} -+static const struct i2c_device_id mn88436_id_table[] = { -+ {"mn88436",0}, -+ {} -+ -+}; -+ -+MODULE_DEVICE_TABLE(i2c,mn88436_id_table); -+ -+static struct i2c_driver mn88436_driver = { -+ .driver ={ -+ .name = "mn88436", -+ }, -+ .probe = mn88436_probe, -+ .remove = mn88436_remove, -+ .id_table = mn88436_id_table, -+ -+}; -+ -+module_i2c_driver(mn88436_driver); -+ -+MODULE_AUTHOR("Davin "); -+MODULE_DESCRIPTION("Panasonic MN88436 ATSC/QAMB demodulator driver"); -+MODULE_LICENSE("GPL"); -+ -diff --git a/drivers/media/dvb-frontends/mn88436.h b/drivers/media/dvb-frontends/mn88436.h -new file mode 100644 -index 0000000..ae9922f ---- /dev/null -+++ b/drivers/media/dvb-frontends/mn88436.h -@@ -0,0 +1,14 @@ -+#ifndef MN88436_H -+#define MN88436_H -+#include -+ -+struct mn88436_config{ -+#define DMD_E_TSOUT_PARALLEL_FIXED_CLOCK 0 -+#define DMD_E_TSOUT_SERIAL_VARIABLE_CLOCK 1 -+ int ts_mode; -+ -+ u16 i2c_wr_max; -+ -+ struct dvb_frontend **fe; -+}; -+#endif -diff --git a/drivers/media/dvb-frontends/mn88436_priv.h b/drivers/media/dvb-frontends/mn88436_priv.h -new file mode 100644 -index 0000000..6ceee47 ---- /dev/null -+++ b/drivers/media/dvb-frontends/mn88436_priv.h -@@ -0,0 +1,370 @@ -+#ifndef MN88436_PRIV_H -+#define MN88436_PRIV_H -+ -+#include "dvb_frontend.h" -+#include "mn88436.h" -+#include -+ -+typedef enum{ -+ DMD_E_ATSC, -+ DMD_E_QAMB_64QAM, -+ DMD_E_QAMB_256QAM, -+ -+}DMD_SYSTEM_t; -+ -+struct mn88436_dev { -+ struct i2c_client *client[2]; -+ struct regmap *regmap[2]; -+ struct dvb_frontend fe; -+ u16 i2c_write_max; -+ -+ unsigned int ts_mode; -+ -+ DMD_SYSTEM_t mode; -+ -+}; -+ -+#define AGC_MIN 801 //-90dBm -+#define AGC_MAX 3338 //0dBm -+#define AGC_RANGE (AGC_MAX - AGC_MIN) -+ -+ -+#define DMD_INFORMATION_MAX 512 -+#define DMD_INFO_VALUE_MAX 32 -+ -+#define DMD_MAX_DEVICE 4 -+#define DMD_REG_BANK 2 -+ -+#define DMD_NOT_SUPPORT 0 -+#define DMD_SYSTEM_MAX 15 -+#define DMD_TCB_DATA_MAX 256 -+#define DMD_REGISTER_MAX 2048 -+#define DMD_I2C_MAXSIZE 127 -+ -+ -+ -+//For Main -+#define DMD_MAIN_IBMOD 0x0 -+#define DMD_MAIN_CPOSET1 0x1 -+#define DMD_MAIN_CPOSET2 0x2 -+#define DMD_MAIN_HIZSET 0x3 -+#define DMD_MAIN_INVSET 0x4 -+#define DMD_MAIN_GPSET1 0x5 -+#define DMD_MAIN_GPSET2 0x6 -+#define DMD_MAIN_GPSET3 0x7 -+#define DMD_MAIN_MDADATL 0x8 -+#define DMD_MAIN_MDADATU 0x9 -+#define DMD_MAIN_IQDSET 0xA -+#define DMD_MAIN_FOFFSET1U 0xB -+#define DMD_MAIN_FOFFSET1L 0xC -+#define DMD_MAIN_SRATEIN1 0xD -+#define DMD_MAIN_SRATEIN2 0xE -+#define DMD_MAIN_SRATEIN3 0xF -+#define DMD_MAIN_RSTSET1 0x10 -+#define DMD_MAIN_RSTSET2 0x11 -+#define DMD_MAIN_FOFFSET2U 0x12 -+#define DMD_MAIN_FOFFSET2L 0x13 -+#define DMD_MAIN_I2CSET 0x14 -+#define DMD_MAIN_TCBSET 0x15 -+#define DMD_MAIN_TCBRT 0x16 -+#define DMD_MAIN_TCBADR 0x17 -+#define DMD_MAIN_TCBDT0 0x18 -+#define DMD_MAIN_TCBDT1 0x19 -+#define DMD_MAIN_TCBDT2 0x1A -+#define DMD_MAIN_TCBDT3 0x1B -+#define DMD_MAIN_TCBDT4 0x1C -+#define DMD_MAIN_TCBDT5 0x1D -+#define DMD_MAIN_TCBDT6 0x1E -+#define DMD_MAIN_TCBDT7 0x1F -+#define DMD_MAIN_TCBCOM 0x20 -+#define DMD_MAIN_VAGCREF 0x21 -+#define DMD_MAIN_QAGCREF 0x22 -+#define DMD_MAIN_AGCCO1 0x23 -+#define DMD_MAIN_AGCSET1 0x24 -+#define DMD_MAIN_VAGCDLY1L 0x25 -+#define DMD_MAIN_VQAGCDLY1U 0x26 -+#define DMD_MAIN_QAGCDLY1L 0x27 -+#define DMD_MAIN_ERRCNTTHU 0x28 -+#define DMD_MAIN_ERRCNTTHL 0x29 -+#define DMD_MAIN_ALCSET1 0x2A -+#define DMD_MAIN_ALCSET2 0x2B -+#define DMD_MAIN_ALCSET3 0x2C -+#define DMD_MAIN_CLIPVUL 0x2D -+#define DMD_MAIN_CLIPVL 0x2E -+#define DMD_MAIN_PIRETH2U 0x2F -+#define DMD_MAIN_PIRETH2L 0x30 -+#define DMD_MAIN_PIRETH3U 0x31 -+#define DMD_MAIN_PIRETH3L 0x32 -+#define DMD_MAIN_PAFCSGSET1 0x33 -+#define DMD_MAIN_PAFCSGSET2 0x34 -+#define DMD_MAIN_PAFCLPFSET1 0x35 -+#define DMD_MAIN_PAFCLPFSETA2 0x36 -+#define DMD_MAIN_PAFCLPFSETA3 0x37 -+#define DMD_MAIN_PAFCLPFSETA4 0x38 -+#define DMD_MAIN_PAFCLPFSETB2 0x39 -+#define DMD_MAIN_PAFCLPFSETB3 0x3A -+#define DMD_MAIN_PAFCLPFSETB4 0x3B -+#define DMD_MAIN_AFCSET1 0x3C -+#define DMD_MAIN_AFCCO 0x3D -+#define DMD_MAIN_AFCADD 0x3E -+#define DMD_MAIN_APCSET1 0x3F -+#define DMD_MAIN_APCSET2 0x40 -+#define DMD_MAIN_APCSET4 0x41 -+#define DMD_MAIN_APCSET5 0x42 -+#define DMD_MAIN_APCCO1 0x43 -+#define DMD_MAIN_APCCO2 0x44 -+#define DMD_MAIN_APCCO3 0x45 -+#define DMD_MAIN_APCCO4 0x46 -+#define DMD_MAIN_VCKRSET1 0x47 -+#define DMD_MAIN_VCKRSET2 0x48 -+#define DMD_MAIN_VCKRCOUL 0x49 -+#define DMD_MAIN_VCKRCOL 0x4A -+#define DMD_MAIN_VFCKSET1 0x4B -+#define DMD_MAIN_VFCKSET2 0x4C -+#define DMD_MAIN_VFCKBWUL 0x4D -+#define DMD_MAIN_VFCKBWLK 0x4E -+#define DMD_MAIN_VFCKATUL 0x4F -+#define DMD_MAIN_VFCKATLK 0x50 -+#define DMD_MAIN_VTCKSET1 0x51 -+#define DMD_MAIN_VTCKSET2 0x52 -+#define DMD_MAIN_VDAGCREF 0x53 -+#define DMD_MAIN_QDAGCREF 0x54 -+#define DMD_MAIN_GMIN 0x55 -+#define DMD_MAIN_DAGCCO 0x56 -+#define DMD_MAIN_CKRCO1 0x57 -+#define DMD_MAIN_CKRCO2 0x58 -+#define DMD_MAIN_CKRSET1 0x59 -+#define DMD_MAIN_CKRSET2 0x5A -+#define DMD_MAIN_PNTSET 0x5B -+#define DMD_MAIN_PNTCO 0x5C -+#define DMD_MAIN_NRFMODE 0x5D -+#define DMD_MAIN_FDATSC 0x5E -+#define DMD_MAIN_FLTBW1 0x5F -+#define DMD_MAIN_NRFRSEL 0x60 -+#define DMD_MAIN_SYNCSET1 0x61 -+#define DMD_MAIN_SYNCSET2 0x62 -+#define DMD_MAIN_SYNCSET6 0x63 -+#define DMD_MAIN_QDETREF 0x64 -+#define DMD_MAIN_QDETSET1 0x65 -+#define DMD_MAIN_QDETSET2 0x66 -+#define DMD_MAIN_EQSET 0x67 -+#define DMD_MAIN_VEQSET1 0x68 -+#define DMD_MAIN_VEQSET2 0x69 -+#define DMD_MAIN_VEQSET3 0x6A -+#define DMD_MAIN_VEQSET4 0x6B -+#define DMD_MAIN_VEQSET5 0x6C -+#define DMD_MAIN_VEQSET6 0x6D -+#define DMD_MAIN_VEQSET7 0x6E -+#define DMD_MAIN_VEQSET8 0x6F -+#define DMD_MAIN_VEQSET9 0x70 -+#define DMD_MAIN_AGCMON 0x71 -+#define DMD_MAIN_CKRFEMON 0x72 -+#define DMD_MAIN_DAGCMON 0x73 -+#define DMD_MAIN_QEQSET 0x74 -+#define DMD_MAIN_PAFCPILOT 0x75 -+#define DMD_MAIN_VCKRSYM 0x76 -+#define DMD_MAIN_APCMON 0x77 -+#define DMD_MAIN_PNTMON 0x78 -+#define DMD_MAIN_VEQSET10 0x79 -+#define DMD_MAIN_VEQSET11 0x7A -+#define DMD_MAIN_VEQSET12 0x7B -+#define DMD_MAIN_VEQSET13 0x7C -+#define DMD_MAIN_VEQSET14 0x7D -+#define DMD_MAIN_VEQSET15 0x7E -+#define DMD_MAIN_VEQSET16 0x7F -+#define DMD_MAIN_VEQSET17 0x80 -+#define DMD_MAIN_VEQSET18 0x81 -+#define DMD_MAIN_VEQSET19 0x82 -+#define DMD_MAIN_VEQSET20 0x83 -+#define DMD_MAIN_VEQSET21 0x84 -+#define DMD_MAIN_VEQSET22 0x85 -+#define DMD_MAIN_PLOCKTH1 0x86 -+#define DMD_MAIN_PLOCKTH2 0x87 -+#define DMD_MAIN_PLOCKTH3 0x88 -+#define DMD_MAIN_CRCDIVASET1 0x89 -+#define DMD_MAIN_CRCDIVASET2 0x8A -+#define DMD_MAIN_CRCDIVASET3 0x8B -+#define DMD_MAIN_CRCDIVBSET1 0x8C -+#define DMD_MAIN_CRCDIVBSET2 0x8D -+#define DMD_MAIN_CRCDIVBSET3 0x8E -+#define DMD_MAIN_CRCDIVSMV 0x8F -+#define DMD_MAIN_CRCDIVTIM 0x90 -+#define DMD_MAIN_PNDETSET1 0x91 -+#define DMD_MAIN_PNDETSET2 0x92 -+#define DMD_MAIN_PREIDETSET1 0x93 -+#define DMD_MAIN_PREQDETSET1 0x94 -+#define DMD_MAIN_PNDETSET3 0x95 -+#define DMD_MAIN_PNDETSET4 0x96 -+#define DMD_MAIN_PNSMSET1 0x97 -+#define DMD_MAIN_PNSMSET2 0x98 -+#define DMD_MAIN_PNSMSET3 0x99 -+#define DMD_MAIN_PNSMSET4 0x9A -+#define DMD_MAIN_PNSMSET5 0x9B -+#define DMD_MAIN_PNSMSET6 0x9C -+#define DMD_MAIN_PNSMSET7 0x9D -+#define DMD_MAIN_PNSMSET8 0x9E -+#define DMD_MAIN_PNSMSET9 0x9F -+#define DMD_MAIN_PNSMSET10 0xA0 -+#define DMD_MAIN_PNSMSET11 0xA1 -+#define DMD_MAIN_PNSMSET12 0xA2 -+#define DMD_MAIN_PNSMSET13 0xA3 -+#define DMD_MAIN_PNREGSET1 0xA4 -+#define DMD_MAIN_PNREGSET2 0xA5 -+#define DMD_MAIN_PNREGSET3 0xA6 -+#define DMD_MAIN_PNREGSET4 0xA7 -+#define DMD_MAIN_PNREGSET5 0xA8 -+#define DMD_MAIN_PNREGSET6 0xA9 -+#define DMD_MAIN_FREQSET 0xAA -+#define DMD_MAIN_FREQU 0xAB -+#define DMD_MAIN_FREQL 0xAC -+#define DMD_MAIN_PNREGSET10 0xAD -+#define DMD_MAIN_PNREGSET11 0xAE -+#define DMD_MAIN_PNREGSET12 0xAF -+#define DMD_MAIN_PNREGSET13 0xB0 -+#define DMD_MAIN_PNREGSET14 0xB1 -+#define DMD_MAIN_PNREGSET15 0xB2 -+#define DMD_MAIN_PNREGSET16 0xB3 -+#define DMD_MAIN_PNREGSET17 0xB4 -+#define DMD_MAIN_PNREGSET18 0xB5 -+#define DMD_MAIN_PNREGSET19 0xB6 -+#define DMD_MAIN_PNREGSET20 0xB7 -+#define DMD_MAIN_PNREGSET21 0xB8 -+#define DMD_MAIN_NTCWTH1 0xB9 -+#define DMD_MAIN_IBTGSET 0xBA -+#define DMD_MAIN_AFCMON 0xBB -+#define DMD_MAIN_CKRMON 0xBC -+#define DMD_MAIN_NRFRDAT 0xBD -+#define DMD_MAIN_MEANFERR 0xBE -+#define DMD_MAIN_MEANMAGERR 0xBF -+#define DMD_MAIN_PAFCSGGATE 0xC0 -+#define DMD_MAIN_AFCMONB 0xC1 -+#define DMD_MAIN_PLOCKMONAU 0xC2 -+#define DMD_MAIN_PLOCKMONAL 0xC3 -+#define DMD_MAIN_STSMON1 0xC4 -+#define DMD_MAIN_STSMON2 0xC5 -+#define DMD_MAIN_SYNCRD2 0xC6 -+#define DMD_MAIN_SYNCRD3 0xC7 -+#define DMD_MAIN_PLOCKMONBU 0xC8 -+#define DMD_MAIN_PLOCKMONBL 0xC9 -+#define DMD_MAIN_PNDETU 0xCA -+#define DMD_MAIN_PNDETL 0xCB -+#define DMD_MAIN_PIBETAU 0xCC -+#define DMD_MAIN_PIBETAL 0xCD -+#define DMD_MAIN_EQMNSET 0xCE -+#define DMD_MAIN_EQERR1 0xCF -+#define DMD_MAIN_EQERR2 0xD0 -+#define DMD_MAIN_RFAGCMON1P 0xD1 -+#define DMD_MAIN_RFAGCMON2P 0xD2 -+#define DMD_MAIN_IFAGCMON1P 0xD3 -+#define DMD_MAIN_IFAGCMON2P 0xD4 -+#define DMD_MAIN_PLOCKSTATE 0xD5 -+#define DMD_MAIN_PIBETAQU 0xD6 -+#define DMD_MAIN_PIBETAQL 0xD7 -+#define DMD_MAIN_PNDETSTATE 0xD8 -+#define DMD_MAIN_CNSETP 0xD9 -+#define DMD_MAIN_CNFLGP 0xDA -+#define DMD_MAIN_CNMON1P 0xDB -+#define DMD_MAIN_CNMON2P 0xDC -+#define DMD_MAIN_CNMON3P 0xDD -+#define DMD_MAIN_CNMON4P 0xDE -+#define DMD_MAIN_FECSET 0xDF -+#define DMD_MAIN_BERDSETP 0xE0 -+#define DMD_MAIN_BERTSET1P 0xE1 -+#define DMD_MAIN_BERTSET2P 0xE2 -+#define DMD_MAIN_BERFLGP 0xE3 -+#define DMD_MAIN_BERMON1P 0xE4 -+#define DMD_MAIN_BERMON2P 0xE5 -+#define DMD_MAIN_BERMON3P 0xE6 -+#define DMD_MAIN_NTCWTH2 0xE7 -+#define DMD_MAIN_PWDSET1 0xE8 -+#define DMD_MAIN_PWDSET2 0xE9 -+#define DMD_MAIN_PSEQOP1 0xEA -+#define DMD_MAIN_PSEQOP2 0xEB -+#define DMD_MAIN_PSEQOP3 0xEC -+#define DMD_MAIN_PSEQOP4 0xED -+#define DMD_MAIN_PSEQOP5 0xEE -+#define DMD_MAIN_PSEQOP6 0xEF -+#define DMD_MAIN_PSEQSET 0xF0 -+#define DMD_MAIN_PSEQPRG 0xF1 -+#define DMD_MAIN_PSEQSEL 0xF2 -+#define DMD_MAIN_PSEQDBG 0xF3 -+#define DMD_MAIN_PSEQOP7 0xF4 -+#define DMD_MAIN_PSEQOP8 0xF5 -+#define DMD_MAIN_PSEQOP9 0xF6 -+#define DMD_MAIN_PSEQOP10 0xF7 -+#define DMD_MAIN_PSEQADRU 0xF8 -+#define DMD_MAIN_PSEQADRL 0xF9 -+#define DMD_MAIN_PSEQDT 0xFA -+#define DMD_MAIN_TESTSET3 0xFB -+#define DMD_MAIN_CLKGSET 0xFC -+#define DMD_MAIN_TPLLSET1 0xFD -+#define DMD_MAIN_TPLLSET2 0xFE -+#define DMD_MAIN_RDCHK 0xFF -+ -+ -+//For USR -+#define DMD_USR_INTDEFR 0x9 -+#define DMD_USR_INTDEFF 0xA -+#define DMD_USR_INTSET 0xB -+#define DMD_USR_INTCNT 0xC -+#define DMD_USR_INTCND 0xD -+#define DMD_USR_I2CSET 0x14 -+#define DMD_USR_CNSET 0x5A -+#define DMD_USR_CNFLG 0x5B -+#define DMD_USR_CNMON1 0x5C -+#define DMD_USR_CNMON2 0x5D -+#define DMD_USR_CNMON3 0x5E -+#define DMD_USR_CNMON4 0x5F -+#define DMD_USR_BERTSET1 0x60 -+#define DMD_USR_BERTSET2 0x61 -+#define DMD_USR_BERPSET1 0x62 -+#define DMD_USR_BERPSET2 0x63 -+#define DMD_USR_BERFLG 0x64 -+#define DMD_USR_BERMON1 0x65 -+#define DMD_USR_BERMON2 0x66 -+#define DMD_USR_BERMON3 0x67 -+#define DMD_USR_RFAGCMON1 0x68 -+#define DMD_USR_RFAGCMON2 0x69 -+#define DMD_USR_IFAGCMON1 0x6A -+#define DMD_USR_IFAGCMON2 0x6B -+#define DMD_USR_IMON 0x74 -+#define DMD_USR_QMON 0x79 -+#define DMD_USR_SDCC 0x80 -+#define DMD_USR_VSAGCREFU 0x81 -+#define DMD_USR_VSAGCREFL 0x82 -+#define DMD_USR_QSAGCREFU 0x83 -+#define DMD_USR_QSAGCREFL 0x84 -+#define DMD_USR_SAGCCO 0x85 -+#define DMD_USR_SAGCSET 0x86 -+#define DMD_USR_VPWMSET1 0x87 -+#define DMD_USR_VPWMDAT1 0x88 -+#define DMD_USR_QPWMSET1 0x89 -+#define DMD_USR_QPWMDAT1 0x8A -+#define DMD_USR_QFECSET1 0x8B -+#define DMD_USR_QFECSET4 0x8C -+#define DMD_USR_QFECSET5 0x8D -+#define DMD_USR_TSCSETV1 0x8E -+#define DMD_USR_TSCSETQ1 0x8F -+#define DMD_USR_TSCSET2 0x90 -+#define DMD_USR_TSCSET4 0x91 -+#define DMD_USR_FAD064U 0x92 -+#define DMD_USR_FAD064M 0x93 -+#define DMD_USR_FAD064L 0x94 -+#define DMD_USR_FAD256U 0x95 -+#define DMD_USR_FAD256M 0x96 -+#define DMD_USR_FAD256L 0x97 -+#define DMD_USR_FAD188U 0x98 -+#define DMD_USR_FAD188M 0x99 -+#define DMD_USR_FAD188L 0x9A -+#define DMD_USR_FAD208U 0x9B -+#define DMD_USR_FAD208M 0x9C -+#define DMD_USR_FAD208L 0x9D -+#define DMD_USR_TESTSET1 0x9E -+#define DMD_USR_TESTSET2 0x9F -+#define DMD_USR_AD10SET1 0xA0 -+#define DMD_USR_AD10SET2 0xA1 -+#define DMD_USR_AD10SET3 0xA2 -+#define DMD_USR_AD10SET4 0xA3 -+#define DMD_USR_RDCHK 0xFF -+ -+#endif -diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c -index 961b9a2..8ce8682 100644 ---- a/drivers/media/dvb-frontends/mt312.c -+++ b/drivers/media/dvb-frontends/mt312.c -@@ -471,6 +471,9 @@ static int mt312_read_status(struct dvb_frontend *fe, enum fe_status *s) - if (status[0] & 0x01) - *s |= FE_HAS_LOCK; /* qpsk lock */ - -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, *s & FE_HAS_LOCK); -+ - return 0; - } - -@@ -703,6 +706,9 @@ static int mt312_sleep(struct dvb_frontend *fe) - int ret; - u8 config; - -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, 0); -+ - /* reset all registers to defaults */ - ret = mt312_reset(state, 1); - if (ret < 0) -@@ -744,6 +750,10 @@ static int mt312_get_tune_settings(struct dvb_frontend *fe, - static void mt312_release(struct dvb_frontend *fe) - { - struct mt312_state *state = fe->demodulator_priv; -+ -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, 0); -+ - kfree(state); - } - -diff --git a/drivers/media/dvb-frontends/mt312.h b/drivers/media/dvb-frontends/mt312.h -index 386939a..aef92c0 100644 ---- a/drivers/media/dvb-frontends/mt312.h -+++ b/drivers/media/dvb-frontends/mt312.h -@@ -34,6 +34,9 @@ struct mt312_config { - - /* inverted voltage setting */ - unsigned int voltage_inverted:1; -+ -+ /* Hook for Lock LED */ -+ void (*set_lock_led)(struct dvb_frontend *fe, int offon); - }; - - #if IS_REACHABLE(CONFIG_DVB_MT312) -diff --git a/drivers/media/dvb-frontends/mtv23x.c b/drivers/media/dvb-frontends/mtv23x.c -new file mode 100644 -index 0000000..06a2555 ---- /dev/null -+++ b/drivers/media/dvb-frontends/mtv23x.c -@@ -0,0 +1,2294 @@ -+#include "mtv23x_priv.h" -+ -+static unsigned int GetSNR_LP_Mode(u8 mod, int val) -+{ -+ unsigned int cn_a = 0; -+ unsigned int cn_b = 0; -+ -+ if (mod == 1) { -+ /* QPSK */ -+ if (val > 270000) { -+ cn_a = 0; -+ cn_b = 0; -+ return 0; -+ } else if (val > 258000) { /* 0~ */ -+ cn_a = 0; -+ cn_b = (270000 - val)/1300; -+ } else if (val > 246000) { /* 1~ */ -+ cn_a = 1; -+ cn_b = (258000 - val)/1300; -+ } else if (val > 226000) { /* 2~ */ -+ cn_a = 2; -+ cn_b = (246000 - val)/2100; -+ } else if (val > 206500) { /* 3~ */ -+ cn_a = 3; -+ cn_b = (226000 - val)/2100; -+ } else if (val > 186500) { /* 4~ */ -+ cn_a = 4; -+ cn_b = (206500 - val)/2200; -+ } else if (val > 163500) { /* 5~ */ -+ cn_a = 5; -+ cn_b = (186500 - val)/2400; -+ } else if (val > 142000) { /* 6~ */ -+ cn_a = 6; -+ cn_b = (163500 - val)/2300; -+ } else if (val > 121000) { /* 7~ */ -+ cn_a = 7; -+ cn_b = (142000 - val)/2300; -+ } else if (val > 100500) { /* 8~ */ -+ cn_a = 8; -+ cn_b = (121000 - val)/2200; -+ } else if (val > 83500) { -+ cn_a = 9; -+ cn_b = (100500 - val)/1800; -+ } else if (val > 69000) { -+ cn_a = 10; -+ cn_b = (83500 - val)/1550; -+ } else if (val > 57200) { -+ cn_a = 11; -+ cn_b = (69000 - val)/1250; -+ } else if (val > 47900) { -+ cn_a = 12; -+ cn_b = (57200 - val)/1000; -+ } else if (val > 40100) { -+ cn_a = 13; -+ cn_b = (47900 - val)/830; -+ } else if (val > 33700) { -+ cn_a = 14; -+ cn_b = (40100 - val)/680; -+ } else if (val > 29000) { -+ cn_a = 15; -+ cn_b = (33700 - val)/500; -+ } else if (val > 25600) { -+ cn_a = 16; -+ cn_b = (29000 - val)/360; -+ } else if (val > 22200) { -+ cn_a = 17; -+ cn_b = (25600 - val)/360; -+ } else if (val > 19700) { -+ cn_a = 18; -+ cn_b = (22200 - val)/265; -+ } else if (val > 18000) { -+ cn_a = 19; -+ cn_b = (19700 - val)/180; -+ } else if (val > 16500) { -+ cn_a = 20; -+ cn_b = (18000 - val)/160; -+ } else if (val > 15200) { -+ cn_a = 21; -+ cn_b = (16500 - val)/140; -+ } else if (val > 14100) { -+ cn_a = 22; -+ cn_b = (15200 - val)/120; -+ } else if (val > 13550) { -+ cn_a = 23; -+ cn_b = (14100 - val)/60; -+ } else if (val > 12800) { -+ cn_a = 24; -+ cn_b = (13550 - val)/80; -+ } else if (val > 12300) { -+ cn_a = 25; -+ cn_b = (12800 - val)/53; -+ } else if (val > 11900) { -+ cn_a = 26; -+ cn_b = (12300 - val)/42; -+ } else if (val > 11600) { -+ cn_a = 27; -+ cn_b = (11900 - val)/31; -+ } else if (val > 11300) { -+ cn_a = 28; -+ cn_b = (11600 - val)/31; -+ } else if (val > 11000) { -+ cn_a = 29; -+ cn_b = (11300 - val)/31; -+ } else if (val > 0) { -+ cn_a = 30; -+ cn_b = 0; -+ } -+ } else if (mod == 2) { -+ /* 16 QAM */ -+ if (val > 353500) { -+ cn_a = 0; -+ cn_b = 0; -+ } else if (val > 353500) { /* 0~ */ -+ cn_a = 0; -+ cn_b = (365000 - val)/124; -+ } else if (val > 344200) { /* 1~ */ -+ cn_a = 1; -+ cn_b = (353500 - val)/101; -+ } else if (val > 333200) { /* 2~ */ -+ cn_a = 2; -+ cn_b = (344200 - val)/120; -+ } else if (val > 325000) { /* 3~ */ -+ cn_a = 3; -+ cn_b = (333200 - val)/90; -+ } else if (val > 316700) { /* 4~ */ -+ cn_a = 4; -+ cn_b = (325000 - val)/91; -+ } else if (val > 308200) { /* 5~ */ -+ cn_a = 5; -+ cn_b = (316700 - val)/93; -+ } else if (val > 299000) { /* 6~ */ -+ cn_a = 6; -+ cn_b = (308200 - val)/98; -+ } else if (val > 295000) { /* 7~ */ -+ cn_a = 7; -+ cn_b = (299000 - val)/1050; -+ } else if (val > 280500) { /* 8~ */ -+ cn_a = 8; -+ cn_b = (295000 - val)/1550; -+ } else if (val > 264000) { -+ cn_a = 9; -+ cn_b = (280500 - val)/1750; -+ } else if (val > 245000) { -+ cn_a = 10; -+ cn_b = (264000 - val)/2050; -+ } else if (val > 222000) { -+ cn_a = 11; -+ cn_b = (245000 - val)/2450; -+ } else if (val > 197000) { -+ cn_a = 12; -+ cn_b = (222000 - val)/2650; -+ } else if (val > 172000) { -+ cn_a = 13; -+ cn_b = (197000 - val)/2650; -+ } else if (val > 147000) { -+ cn_a = 14; -+ cn_b = (172000 - val)/2650; -+ } else if (val > 125000) { -+ cn_a = 15; -+ cn_b = (147000 - val)/2350; -+ } else if (val > 105000) { -+ cn_a = 16; -+ cn_b = (125000 - val)/2150; -+ } else if (val > 88000) { -+ cn_a = 17; -+ cn_b = (105000 - val)/1800; -+ } else if (val > 75000) { -+ cn_a = 18; -+ cn_b = (88000 - val)/1400; -+ } else if (val > 64000) { -+ cn_a = 19; -+ cn_b = (75000 - val)/1180; -+ } else if (val > 55000) { -+ cn_a = 20; -+ cn_b = (64000 - val)/980; -+ } else if (val > 48000) { -+ cn_a = 21; -+ cn_b = (55000 - val)/750; -+ } else if (val > 42000) { -+ cn_a = 22; -+ cn_b = (48000 - val)/640; -+ } else if (val > 38000) { -+ cn_a = 23; -+ cn_b = (42000 - val)/420; -+ } else if (val > 34900) { -+ cn_a = 24; -+ cn_b = (38000 - val)/330; -+ } else if (val > 32000) { -+ cn_a = 25; -+ cn_b = (34900 - val)/310; -+ } else if (val > 29500) { -+ cn_a = 26; -+ cn_b = (32000 - val)/265; -+ } else if (val > 27100) { -+ cn_a = 27; -+ cn_b = (29500 - val)/250; -+ } else if (val > 26000) { -+ cn_a = 28; -+ cn_b = (27100 - val)/118; -+ } else if (val > 25200) { -+ cn_a = 29; -+ cn_b = (26000 - val)/85; -+ } else if (val > 0) { -+ cn_a = 30; -+ cn_b = 0; -+ } -+ } else { -+ cn_a = 0; -+ cn_b = 0; -+ return 0; -+ } -+ -+ if (cn_b > 1000) -+ return (cn_a*1000) + cn_b; -+ else if (cn_b > 100) -+ return (cn_a*1000) + (cn_b*10); -+ else -+ return (cn_a*1000) + (cn_b*100); -+} -+static unsigned int GetSNR_FULL_Mode(u8 mod, int val) -+{ -+ unsigned int cn_a = 0; -+ unsigned int cn_b = 0; -+ -+ if (mod == 1) { -+ /* QPSK */ -+ if (val > 32500) { -+ cn_a = 0; -+ cn_b = 0; -+ return 0; -+ } else if (val > 31400) { /* 0~ */ -+ cn_a = 0; -+ cn_b = (32500 - val)/118; -+ } else if (val > 29800) { /* 1~ */ -+ cn_a = 1; -+ cn_b = (31400 - val)/170; -+ } else if (val > 27900) { /* 2~ */ -+ cn_a = 2; -+ cn_b = (29800 - val)/205; -+ } else if (val > 25500) { /* 3~ */ -+ cn_a = 3; -+ cn_b = (27900 - val)/258; -+ } else if (val > 23000) { /* 4~ */ -+ cn_a = 4; -+ cn_b = (25500 - val)/268; -+ } else if (val > 20300) { /* 5~ */ -+ cn_a = 5; -+ cn_b = (23000 - val)/290; -+ } else if (val > 17500) { /* 6~ */ -+ cn_a = 6; -+ cn_b = (20300 - val)/300; -+ } else if (val > 14600) { /* 7~ */ -+ cn_a = 7; -+ cn_b = (17500 - val)/310; -+ } else if (val > 12000) { /* 8~ */ -+ cn_a = 8; -+ cn_b = (14600 - val)/280; -+ } else if (val > 9750) { -+ cn_a = 9; -+ cn_b = (12000 - val)/240; -+ } else if (val > 7600) { -+ cn_a = 10; -+ cn_b = (9750 - val)/230; -+ } else if (val > 6100) { -+ cn_a = 11; -+ cn_b = (7600 - val)/160; -+ } else if (val > 5000) { -+ cn_a = 12; -+ cn_b = (6100 - val)/118; -+ } else if (val > 3950) { -+ cn_a = 13; -+ cn_b = (5000 - val)/112; -+ } else if (val > 3200) { -+ cn_a = 14; -+ cn_b = (3950 - val)/80; -+ } else if (val > 2580) { -+ cn_a = 15; -+ cn_b = (3200 - val)/65; -+ } else if (val > 2100) { -+ cn_a = 16; -+ cn_b = (2580 - val)/51; -+ } else if (val > 1720) { -+ cn_a = 17; -+ cn_b = (2100 - val)/40; -+ } else if (val > 1390) { -+ cn_a = 18; -+ cn_b = (1720 - val)/35; -+ } else if (val > 1160) { -+ cn_a = 19; -+ cn_b = (1390 - val)/24; -+ } else if (val > 980) { -+ cn_a = 20; -+ cn_b = (1160 - val)/19; -+ } else if (val > 820) { -+ cn_a = 21; -+ cn_b = (980 - val)/17; -+ } else if (val > 700) { -+ cn_a = 22; -+ cn_b = (820 - val)/13; -+ } else if (val > 600) { -+ cn_a = 23; -+ cn_b = (700 - val)/11; -+ } else if (val > 520) { -+ cn_a = 24; -+ cn_b = (600 - val)/8; -+ } else if (val > 450) { -+ cn_a = 25; -+ cn_b = (520 - val)/7; -+ } else if (val > 410) { -+ cn_a = 26; -+ cn_b = (450 - val)/4; -+ } else if (val > 380) { -+ cn_a = 27; -+ cn_b = (410 - val)/3; -+ } else if (val > 350) { -+ cn_a = 28; -+ cn_b = (380 - val)/3; -+ } else if (val > 330) { -+ cn_a = 29; -+ cn_b = (350 - val)/2; -+ } else if (val > 0) { -+ cn_a = 30; -+ cn_b = 0; -+ } -+ } else if (mod == 2) { -+ /* 16 QAM */ -+ if (val > 42000) { -+ cn_a = 0; -+ cn_b = 0; -+ } else if (val > 40500) { /* 0~ */ -+ cn_a = 0; -+ cn_b = (42000 - val)/160; -+ } else if (val > 39000) { /* 1~ */ -+ cn_a = 1; -+ cn_b = (40500 - val)/160; -+ } else if (val > 38000) { /* 2~ */ -+ cn_a = 2; -+ cn_b = (39000 - val)/108; -+ } else if (val > 37000) { -+ cn_a = 3; -+ cn_b = (38000 - val)/108; -+ } else if (val > 36000) { -+ cn_a = 4; -+ cn_b = (37000 - val)/108; -+ } else if (val > 35000) { -+ cn_a = 5; -+ cn_b = (36000 - val)/108; -+ } else if (val > 34000) { -+ cn_a = 6; -+ cn_b = (35000 - val)/108; -+ } else if (val > 32900) { -+ cn_a = 7; -+ cn_b = (34000 - val)/118; -+ } else if (val > 31800) { -+ cn_a = 8; -+ cn_b = (32900 - val)/118; -+ } else if (val > 29500) { -+ cn_a = 9; -+ cn_b = (31800 - val)/248; -+ } else if (val > 27000) { -+ cn_a = 10; -+ cn_b = (29500 - val)/270; -+ } else if (val > 24300) { -+ cn_a = 11; -+ cn_b = (27000 - val)/290; -+ } else if (val > 21400) { -+ cn_a = 12; -+ cn_b = (24300 - val)/315; -+ } else if (val > 18500) { -+ cn_a = 13; -+ cn_b = (21400 - val)/315; -+ } else if (val > 15600) { -+ cn_a = 14; -+ cn_b = (18500 - val)/315; -+ } else if (val > 13000) { -+ cn_a = 15; -+ cn_b = (15600 - val)/280; -+ } else if (val > 10600) { -+ cn_a = 16; -+ cn_b = (13000 - val)/260; -+ } else if (val > 8700) { -+ cn_a = 17; -+ cn_b = (10600 - val)/206; -+ } else if (val > 7200) { -+ cn_a = 18; -+ cn_b = (8700 - val)/160; -+ } else if (val > 6100) { -+ cn_a = 19; -+ cn_b = (7200 - val)/118; -+ } else if (val > 5050) { -+ cn_a = 20; -+ cn_b = (6100 - val)/112; -+ } else if (val > 4100) { -+ cn_a = 21; -+ cn_b = (5050 - val)/102; -+ } else if (val > 3600) { -+ cn_a = 22; -+ cn_b = (4100 - val)/53; -+ } else if (val > 3100) { -+ cn_a = 23; -+ cn_b = (3600 - val)/53; -+ } else if (val > 2650) { -+ cn_a = 24; -+ cn_b = (3100 - val)/48; -+ } else if (val > 2400) { -+ cn_a = 25; -+ cn_b = (2650 - val)/27; -+ } else if (val > 2200) { -+ cn_a = 26; -+ cn_b = (2400 - val)/22; -+ } else if (val > 2000) { -+ cn_a = 27; -+ cn_b = (2200 - val)/22; -+ } else if (val > 1820) { -+ cn_a = 28; -+ cn_b = (2000 - val)/19; -+ } else if (val > 1750) { -+ cn_a = 29; -+ cn_b = (1820 - val)/7; -+ } else if (val > 0) { -+ cn_a = 30; -+ cn_b = 0; -+ } -+ } else if (mod == 3) { -+ /* 64 QAM */ -+ if (val > 43000) { -+ cn_a = 0; -+ cn_b = 0; -+ } else if (val > 40700) { /* 0~ */ -+ cn_a = 0; -+ cn_b = (43000 - val)/250; -+ } else if (val > 40000) { /* 1~ */ -+ cn_a = 1; -+ cn_b = (40700 - val)/75; -+ } else if (val > 38600) { -+ cn_a = 2; -+ cn_b = (40000 - val)/150; -+ } else if (val > 37500) { -+ cn_a = 3; -+ cn_b = (38600 - val)/118; -+ } else if (val > 36800) { -+ cn_a = 4; -+ cn_b = (37500 - val)/74; -+ } else if (val > 36100) { -+ cn_a = 5; -+ cn_b = (36800 - val)/74; -+ } else if (val > 35500) { -+ cn_a = 6; -+ cn_b = (36100 - val)/64; -+ } else if (val > 35000) { -+ cn_a = 7; -+ cn_b = (35500 - val)/53; -+ } else if (val > 34600) { -+ cn_a = 8; -+ cn_b = (35000 - val)/43; -+ } else if (val > 34050) { -+ cn_a = 9; -+ cn_b = (34600 - val)/59; -+ } else if (val > 33500) { -+ cn_a = 10; -+ cn_b = (34050 - val)/59; -+ } else if (val > 32900) { -+ cn_a = 11; -+ cn_b = (33500 - val)/64; -+ } else if (val > 32100) { -+ cn_a = 12; -+ cn_b = (32900 - val)/85; -+ } else if (val > 31200) { -+ cn_a = 13; -+ cn_b = (32100 - val)/96; -+ } else if (val > 30400) { -+ cn_a = 14; -+ cn_b = (31200 - val)/85; -+ } else if (val > 29200) { -+ cn_a = 15; -+ cn_b = (30400 - val)/128; -+ } else if (val > 27800) { -+ cn_a = 16; -+ cn_b = (29200 - val)/150; -+ } else if (val > 25900) { -+ cn_a = 17; -+ cn_b = (27800 - val)/205; -+ } else if (val > 23800) { -+ cn_a = 18; -+ cn_b = (25900 - val)/228; -+ } else if (val > 21500) { -+ cn_a = 19; -+ cn_b = (23800 - val)/248; -+ } else if (val > 19300) { -+ cn_a = 20; -+ cn_b = (21500 - val)/235; -+ } else if (val > 17300) { -+ cn_a = 21; -+ cn_b = (19300 - val)/215; -+ } else if (val > 15300) { -+ cn_a = 22; -+ cn_b = (17300 - val)/215; -+ } else if (val > 13500) { -+ cn_a = 23; -+ cn_b = (15300 - val)/190; -+ } else if (val > 11800) { -+ cn_a = 24; -+ cn_b = (13500 - val)/182; -+ } else if (val > 10500) { -+ cn_a = 25; -+ cn_b = (11800 - val)/140; -+ } else if (val > 9300) { -+ cn_a = 26; -+ cn_b = (10500 - val)/130; -+ } else if (val > 8500) { -+ cn_a = 27; -+ cn_b = (9300 - val)/86; -+ } else if (val > 8000) { -+ cn_a = 28; -+ cn_b = (8500 - val)/53; -+ } else if (val > 7500) { -+ cn_a = 29; -+ cn_b = (8000 - val)/53; -+ } else if (val > 0) { -+ cn_a = 30; -+ cn_b = 0; -+ } -+ } else { -+ cn_a = 0; -+ cn_b = 0; -+ return 0; -+ } -+ -+ if (cn_b > 1000) -+ return (cn_a*1000) + cn_b; -+ else if (cn_b > 100) -+ return (cn_a*1000) + (cn_b*10); -+ else -+ return (cn_a*1000) + (cn_b*100); -+} -+ -+ -+static int mtv_rf_init(struct mtv23x_dev*dev) -+{ -+ int ret,nNumTbalEntry = 0,i=0; -+ struct RTV_REG_INIT_INFO t_mtv23x_INIT[] = { -+ {0x25, 0xF8}, -+ {0x26, 0x00}, -+ {0x28, 0xDD}, -+ {0x29, 0xC4}, -+ {0x2C, 0x1D}, -+ {0x2D, 0x90}, -+ {0x2F, 0x06}, -+ {0x30, 0xDF}, -+ {0x33, 0x11}, -+ {0x36, 0x09}, -+ {0x38, 0xF0}, -+ {0x39, 0x00}, -+ {0x3A, 0xAA}, -+ {0x3E, 0x2D}, -+ {0x47, 0x59}, -+ {0x48, 0x28}, -+ {0x49, 0x41}, -+ {0x4A, 0x70}, -+ {0x4B, 0x65}, -+ {0x4E, 0x4B}, -+ {0x50, 0x6F}, -+ {0x51, 0x3C}, -+ {0x53, 0x65}, -+ {0x54, 0xC0}, -+ {0x5D, 0x01}, -+ {0x5E, 0x70}, -+ {0x5F, 0x75}, -+ {0x60, 0x62}, -+ {0x61, 0x80}, -+ {0x69, 0x0E}, -+ {0x6A, 0x14}, -+ {0x6B, 0x18}, -+ {0x6C, 0xFF}, -+ {0x6D, 0xFD}, -+ {0x6E, 0x19}, -+ {0x70, 0x80}, -+ {0x71, 0x6E}, -+ {0x74, 0x15}, -+ {0x75, 0xA4}, -+ {0x77, 0x69}, -+ {0x78, 0x3D}, -+ {0x7D, 0x28}, -+ {0x81, 0x9C}, -+ {0x83, 0x9F}, -+ {0x85, 0x40}, -+ {0x86, 0x87}, -+ {0x87, 0x84}, -+ {0x88, 0x22}, -+ {0x89, 0x20}, -+ {0x8A, 0xF6}, -+ {0x8B, 0xB5}, -+ {0x8C, 0xFC}, -+ {0x8D, 0xFF}, -+ {0x8E, 0xFE}, -+ {0x8F, 0xFD}, -+ {0x90, 0xFD}, -+ {0x91, 0xFC}, -+ {0x92, 0x0E}, -+ {0x93, 0x0D}, -+ {0x94, 0x09}, -+ {0x95, 0xA3}, -+ {0x96, 0xF0}, -+ {0x97, 0x19}, -+ {0x99, 0x42}, -+ {0x9A, 0x6C}, -+ {0x9B, 0x10}, -+ {0x9C, 0x8E}, -+ {0x9D, 0x3C}, -+ {0x9E, 0x30}, -+ {0x9F, 0x63}, -+ {0xA1, 0x40}, -+ {0xA2, 0x5C}, -+ {0xA3, 0x1C}, -+ {0xA4, 0x85}, -+ {0xA5, 0xB4}, -+ {0xA6, 0x30}, -+ {0xA7, 0x00}, -+ {0xA9, 0x00}, -+ {0xAA, 0x04}, -+ {0xAB, 0x30}, -+ {0xAC, 0x00}, -+ {0xAD, 0x14}, -+ {0xAE, 0x30}, -+ {0xAF, 0x00}, -+ {0xB1, 0x00}, -+ {0xB2, 0x04}, -+ {0xB3, 0x30}, -+ {0xB4, 0x00}, -+ {0xB5, 0xB1}, -+ {0xB7, 0x05}, -+ {0xBC, 0x1F}, -+ {0xBD, 0x1F}, -+ {0xBE, 0x5F}, -+ {0xBF, 0x1F}, -+ {0xC0, 0x1F}, -+ {0xC1, 0x5F}, -+ {0xC2, 0x1F}, -+ {0xC3, 0x1F}, -+ {0xC4, 0x5F}, -+ {0xC6, 0x4A}, -+ {0xC7, 0x4A}, -+ {0xCA, 0xCA}, -+ {0xCB, 0x4A}, -+ {0xCC, 0x4F}, -+ {0xCF, 0x80}, -+ {0xD0, 0x20}, -+ {0xD4, 0x1F}, -+ {0xD7, 0x80}, -+ {0xD8, 0x00}, -+ {0xDA, 0xA4}, -+ {0xDF, 0x01}, -+ {0xE2, 0x24}, -+ {0xE5, 0xA8}, -+ {0xE6, 0xA6}, -+ {0xE7, 0x64} -+ }; -+ nNumTbalEntry = sizeof(t_mtv23x_INIT)/sizeof(struct RTV_REG_INIT_INFO ); -+ -+ do { -+ ret = regmap_write(dev->regmap,t_mtv23x_INIT[i].bReg,t_mtv23x_INIT[i].bVal); -+ i++; -+ } -+ while(--nNumTbalEntry); -+ -+ -+ return ret; -+ -+} -+static int mtv_configTS(struct mtv23x_dev*dev) -+{ -+ u8 REG9F; -+ int temp; -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,FEC_PAGE); -+ regmap_read(dev->regmap,0x9F,&temp); -+ REG9F = temp & 0x55; -+ switch(dev->ts_mode){ -+ case 0: /* EN_high, CLK_rising */ -+ regmap_write(dev->regmap,0x9F, (REG9F | 0x00)); -+ regmap_write(dev->regmap,0xA6, 0x88); -+ regmap_write(dev->regmap,0xA7, 0x48); -+ break; -+ case 1: /* EN_high, CLK_falling */ -+ regmap_write(dev->regmap,0x9F, (REG9F | 0x00)); -+ regmap_write(dev->regmap,0xA6, 0x88); -+ regmap_write(dev->regmap,0xA7, 0x40); -+ break; -+ case 2: /* EN_low, CLK_rising */ -+ regmap_write(dev->regmap,0x9F, (REG9F | 0x20)); -+ regmap_write(dev->regmap,0xA6, 0x88); -+ regmap_write(dev->regmap,0xA7, 0x48); -+ break; -+ case 3: /* EN_low, CLK_falling */ -+ regmap_write(dev->regmap,0x9F, (REG9F | 0x20)); -+ regmap_write(dev->regmap,0xA6, 0x88); -+ regmap_write(dev->regmap,0xA7, 0x40); -+ break; -+ case 4: /* EN_high, CLK_rising + 1CLK add */ -+ regmap_write(dev->regmap,0x9F, (REG9F | 0x00)); -+ regmap_write(dev->regmap,0xA6, 0x88); -+ regmap_write(dev->regmap,0xA7, 0x4C); -+ break; -+ case 5: /* EN_high, CLK_falling + 1CLK add */ -+ regmap_write(dev->regmap,0x9F, (REG9F | 0x00)); -+ regmap_write(dev->regmap,0xA6, 0x88); -+ regmap_write(dev->regmap,0xA7, 0x44); -+ break; -+ case 6: /* Parallel: EN_high, CLK_rising*/ -+ regmap_write(dev->regmap,0x9F, (REG9F | 0x00)); -+ regmap_write(dev->regmap,0xA6, 0x80); -+ regmap_write(dev->regmap,0xA7, 0x48); -+ break; -+ case 7: /* Parallel: EN_high, CLK_falling */ -+ regmap_write(dev->regmap,0x9F, (REG9F | 0x00)); -+ regmap_write(dev->regmap,0xA6, 0x80); -+ regmap_write(dev->regmap,0xA7, 0x40); -+ break; -+ default: -+ printk("Code not present\n"); -+ break; -+ } -+ regmap_update_bits(dev->regmap,0xA4, 0x01, 0x01); /* TEI Enable */ -+ -+ regmap_write(dev->regmap,0xA8, 0x87); -+ regmap_write(dev->regmap,0xA9, (0xB8|0x01/*TS speed*/)); //set TS speed 1:30M 0:60M -+ -+ regmap_write(dev->regmap,0xAB, 0x87); -+ -+ return 0; -+} -+static int rtv_softReset(struct mtv23x_dev*dev) -+{ -+ if(dev->rtv_1seglpmode) -+ regmap_write(dev->regmap,MAP_SEL_REG,LPOFDM_PAGE); -+ else -+ regmap_write(dev->regmap,MAP_SEL_REG,OFDM_PAGE); -+ -+ regmap_update_bits(dev->regmap,0x10, 0x01, 0x01); -+ regmap_update_bits(dev->regmap,0x10, 0x01, 0x00); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,FEC_PAGE); -+ regmap_update_bits(dev->regmap,0xFB, 0x01, 0x01); -+ regmap_update_bits(dev->regmap,0xFB, 0x01, 0x00); -+ -+ return 0; -+ -+} -+static int mtv23x_init(struct dvb_frontend *fe) -+{ -+ struct i2c_client*client = fe->demodulator_priv; -+ struct mtv23x_dev*dev = i2c_get_clientdata(client); -+ int ret,i,temp,read0,read1 ; -+ enum E_RTV_BANDWIDTH_TYPE bandwidth = RTV_BW_MODE_6MHZ; -+ u8 rev_num; -+ u8 ALDO_OUT = 6,DLDO_OUT = 1; -+ -+ ret = regmap_write(dev->regmap,MAP_SEL_REG,TOP_PAGE); -+ ret |= regmap_write(dev->regmap,0x0C,0xC3); -+ for(i = 0; i < 100 ; i++){ -+ regmap_read(dev->regmap,0x00,&read0); -+ regmap_read(dev->regmap,0x01,&read1); -+ -+ if(read0 == 0xC6) -+ goto RTV_POWER_ON_SUCCESS; -+ msleep(5); -+ } -+ dev_err(&client->dev,"MTV23x Power on failed!!\n"); -+ return -1; -+ -+RTV_POWER_ON_SUCCESS: -+ ret = regmap_write(dev->regmap,MAP_SEL_REG,RF_PAGE); -+ ret |= regmap_read(dev->regmap,0x10,&temp); -+ rev_num = (temp&0xF0)>>4; -+ if(rev_num>=0x05){ -+ regmap_update_bits(dev->regmap,0x3B, 0x01, 0x01); -+ regmap_update_bits(dev->regmap,0x32, 0x01, 0x01); -+ } -+ ret = regmap_write(dev->regmap,MAP_SEL_REG,RF_PAGE); -+ ret |= regmap_update_bits(dev->regmap,0xC8, 0x80, ((ALDO_OUT & 0x04) << 5)); -+ ret |= regmap_update_bits(dev->regmap,0xD1, 0x80, ((ALDO_OUT & 0x02) << 6)); -+ ret |= regmap_update_bits(dev->regmap,0xD2, 0x80, ((ALDO_OUT & 0x01) << 7)); -+ ret |= regmap_update_bits(dev->regmap,0xD3, 0x80, ((DLDO_OUT & 0x04) << 5)); -+ ret |= regmap_update_bits(dev->regmap,0xD5, 0x80, ((DLDO_OUT & 0x02) << 6)); -+ ret |= regmap_update_bits(dev->regmap,0xD6, 0x80, ((DLDO_OUT & 0x01) << 7)); -+ if(ret) -+ goto err; -+ -+ msleep(10); -+ regmap_update_bits(dev->regmap,0xC9, 0x80, 0x80); -+ -+ /*Internal LDO mode*/ -+ ret = regmap_write(dev->regmap,0xCD, 0x4F); -+ ret = regmap_write(dev->regmap,0xCE, 0x35); -+ if(ret) -+ goto err; -+ -+ /*init mtv_RF*/ -+ ret = mtv_rf_init(dev); -+ if(ret) -+ goto err; -+ /*init demod*/ -+ regmap_write(dev->regmap,MAP_SEL_REG,TOP_PAGE); -+ regmap_write(dev->regmap,0x09, 0x00); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,HOST_PAGE); -+ regmap_write(dev->regmap,0x28, 0x70); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,LPOFDM_PAGE); -+// regmap_write(dev->regmap,0x71, 0xAA); -+// regmap_write(dev->regmap,0x8E, 0x0A); -+ -+ regmap_write(dev->regmap,0x34, 0x9F); -+ regmap_write(dev->regmap,0x35, 0xFF); -+ regmap_write(dev->regmap,0x36, 0x01); -+ -+ regmap_write(dev->regmap,0x71, 0xAA); -+ regmap_write(dev->regmap,0x8E, 0x15); -+ -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,OFDM_PAGE); -+ -+ regmap_write(dev->regmap,0xB3, 0x31); -+ regmap_write(dev->regmap,0xCA, 0x10); -+ regmap_update_bits(dev->regmap,0x7E, 0x60, 0x60); -+ -+ regmap_write(dev->regmap,0x81, 0xFF); -+ regmap_write(dev->regmap,0x82, 0xFF); -+ -+ regmap_write(dev->regmap,0x6D, 0x4A); -+ regmap_write(dev->regmap,0xB8, 0xA8); -+// regmap_write(dev->regmap,0xC6, 0x78); -+ regmap_write(dev->regmap,0xC6, 0xFF); -+ -+ -+ regmap_write(dev->regmap,0x6F, 0x21); -+ regmap_write(dev->regmap,0xC9, 0x80); -+ regmap_write(dev->regmap,0x5F, 0x10); -+ -+ regmap_write(dev->regmap,0x58, 0x5A); -+ regmap_write(dev->regmap,0x5E, 0x10); -+ regmap_write(dev->regmap,0xCB, 0x02); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,DATA_PAGE); -+ regmap_write(dev->regmap,0x8C, 0x80); -+ regmap_write(dev->regmap,0x8F, 0x40); -+ regmap_write(dev->regmap,0xDB, 0x01); -+ regmap_write(dev->regmap,0xD8, 0x10); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,FEC_PAGE); -+ regmap_write(dev->regmap,0x44, 0x68); -+ regmap_write(dev->regmap,0x47, 0x40); -+ -+ regmap_write(dev->regmap,0x16, 0xFF); -+ regmap_write(dev->regmap,0x17, 0xFF); -+ regmap_write(dev->regmap,0x18, 0xFF); -+ regmap_write(dev->regmap,0x19, 0xFF); -+ regmap_write(dev->regmap,0xA7, 0x40); -+ regmap_write(dev->regmap,0xA8, 0x80); -+ regmap_write(dev->regmap,0xA9, 0xB9); -+ regmap_write(dev->regmap,0xAA, 0x80); -+ regmap_write(dev->regmap,0xAB, 0x80); -+ -+ regmap_write(dev->regmap,0x5C, 0x10); -+ regmap_write(dev->regmap,0x5F, 0x10); -+ -+ regmap_write(dev->regmap,0xFC, 0x83); -+ regmap_write(dev->regmap,0xFF, 0x03); -+ -+ mtv_configTS(dev); -+ rtv_softReset(dev); -+ -+ return 0; -+ -+ -+err: -+ dev_err(&client->dev,"Failed = %d\n",ret); -+ return ret; -+ -+} -+ -+static int rtvRF_LockCheck(struct mtv23x_dev*dev,u8 bCheckBlock) -+{ -+ int temp, i = 0,ret = 0; -+ -+ u8 nLockCheck = 0; -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,RF_PAGE); -+ -+ switch (bCheckBlock) { -+ case 0: /* O == RF Lock Check */ -+ for (i = 0; i < 10; i++) { -+ regmap_read(dev->regmap,0x1B,&temp); -+ nLockCheck = temp & 0x02; -+ if (nLockCheck) -+ break; -+ else -+ printk("[rtvRF_LockCheck]VCheck(%d)\n", i); -+ -+ msleep(1); -+ } -+ -+ if (i == 10) { -+ printk("[rtvRF_LockCheck] VCO Pll unlocked!\n"); -+ ret = -3; -+ } -+ break; -+ -+ case 1: /* CLK Synth Lock Check */ -+ for (i = 0; i < 10; i++) { -+ regmap_read(dev->regmap,0x1B,&temp); -+ nLockCheck = temp & 0x01; -+ if (nLockCheck) -+ break; -+ else -+ printk("[rtvRF_LockCheck]SCheck(%d)\n", i); -+ msleep(1); -+ } -+ -+ if (i == 10) { -+ printk("[rtvRF_LockCheck] ADC clock unlocked!\n"); -+ ret = -2; -+ } -+ break; -+ } -+ -+ return ret; -+} -+ -+static int rtvRF_SetOfdmPara(struct mtv23x_dev*dev,enum E_RTV_SERVICE_TYPE eServiceType, -+ enum E_RTV_BANDWIDTH_TYPE eLpfBwType, u32 dwChFreqKHz) -+{ -+ int nRet = 0; -+ int nNumAdcType = 0; -+ const struct RTV_ADC_CFG_INFO *ptOfdmCfgTbl = NULL; -+ -+ struct RTV_ADC_CFG_INFO g_atAdcCfgTbl_ISDBT_6MHz[] = { -+ /*8*/ {0x00, 0x06, 0x48, 0x2E, 0x29,0x10410410,0x1B6C8B43,0x208208,0x41}, -+ /*9*/ {0x00, 0x04, 0x36, 0x2E, 0x29,0x0E72AE47,0x18607BCA,0x1CE55C,0x39}, -+ /*19.2*/ {0x08, 0x05, 0x48, 0x2E, 0x29,0x6C5C1B17,0x00000000,0x0D8B83,0x1B}, -+ /*20.0*/ {0x08, 0x05, 0x4B, 0x2E, 0x29,0x68068068,0x00000000,0x0D00D0,0x1A}, -+ /*20.48*/{0x08, 0x19, 0x80, 0x6E, 0x29,0x65965965,0x00000000,0x0CB2CB,0x19} -+ }; -+ struct RTV_ADC_CFG_INFO g_atAdcCfgTbl_ISDBT_7MHz[] = { -+ /*8*/ {0x00, 0x06, 0x48, 0x2E, 0x29,0x12F684BD,0x1B6C8B43,0x25ED09,0x4B}, -+ /*9*/ {0x00, 0x04, 0x36, 0x2E, 0x29,0x10DB20A8,0x18607BCA,0x21B641,0x43}, -+ /*19.2*/ {0x08, 0x05, 0x48, 0x2E, 0x29,0x7E6B74F0,0x00000000,0x0FCD6E,0x1F}, -+ /*20.0*/ {0x08, 0x05, 0x4B, 0x2E, 0x29,0x795CEB24,0x00000000,0x0F2B9D,0x1E}, -+ /*20.48*/{0x08, 0x19, 0x80, 0x6E, 0x29,0x7684BDA1,0x00000000,0x0ED097,0x1D} -+ }; -+ struct RTV_ADC_CFG_INFO g_atAdcCfgTbl_ISDBT_8MHz[] = { -+ /*8*/ {0x00, 0x06, 0x48, 0x2E, 0x29,0x15AC056B,0x1B6C8B43,0x2B580A,0x56}, -+ /*9*/ {0x00, 0x04, 0x36, 0x2E, 0x29,0x13439309,0x18607BCA,0x268726,0x4D}, -+ /*19.2*/ {0x08, 0x05, 0x48, 0x2E, 0x29,0x907ACEC9,0x00000000,0x120F59,0x24}, -+ /*20.0*/ {0x08, 0x05, 0x4B, 0x2E, 0x29,0x8AB355E0,0x00000000,0x11566A,0x22}, -+ /*20.48*/{0x08, 0x19, 0x80, 0x6E, 0x29,0x877321DC,0x00000000,0x10EE64,0x21} -+ }; -+ switch (eServiceType) { -+ case RTV_SERVICE_UHF_ISDBT_1seg: -+ nNumAdcType = 1; /* ADC 9MHz */ -+ switch (eLpfBwType) { -+ case RTV_BW_MODE_6MHZ: -+ case RTV_BW_MODE_430KHZ: -+ if ((dwChFreqKHz == 485143) || (dwChFreqKHz == 503143) -+ || (dwChFreqKHz == 539143) || (dwChFreqKHz == 647143) -+ || (dwChFreqKHz == 665143) || (dwChFreqKHz == 683143) -+ || (dwChFreqKHz == 755143)) -+ nNumAdcType = 0; /* ADC 8MHz */ -+ -+ ptOfdmCfgTbl = &g_atAdcCfgTbl_ISDBT_6MHz[nNumAdcType]; -+ break; -+ -+ case RTV_BW_MODE_7MHZ: -+ case RTV_BW_MODE_500KHZ: -+ ptOfdmCfgTbl = &g_atAdcCfgTbl_ISDBT_7MHz[nNumAdcType]; -+ break; -+ -+ case RTV_BW_MODE_8MHZ: -+ case RTV_BW_MODE_571KHZ: -+ ptOfdmCfgTbl = &g_atAdcCfgTbl_ISDBT_8MHz[nNumAdcType]; -+ break; -+ default: -+ printk("[rtvRF_SetOfdmPara] Unsupport 1seg BW\n"); -+ return -9; -+ } -+ break; -+ -+ case RTV_SERVICE_VHF_ISDBTmm_1seg: -+ nNumAdcType = 0; /* ADC 8MHz */ -+ switch (eLpfBwType) { -+ case RTV_BW_MODE_6MHZ: -+ case RTV_BW_MODE_430KHZ: -+ ptOfdmCfgTbl = &g_atAdcCfgTbl_ISDBT_6MHz[nNumAdcType]; -+ break; -+ default: -+ printk("[rtvRF_SetOfdmPara] Unsupport Tmm1seg\n"); -+ return -9; -+ } -+ break; -+ -+ case RTV_SERVICE_VHF_ISDBTsb_1seg: -+ nNumAdcType = 1; /* ADC 9MHz */ -+ switch (eLpfBwType) { -+ case RTV_BW_MODE_6MHZ: -+ case RTV_BW_MODE_430KHZ: -+ ptOfdmCfgTbl = &g_atAdcCfgTbl_ISDBT_6MHz[nNumAdcType]; -+ break; -+ default: -+ printk("[rtvRF_SetOfdmPara] Unsupport Tsb1seg\n"); -+ return -9; -+ } -+ break; -+ -+ case RTV_SERVICE_VHF_ISDBTsb_3seg: -+ printk("[rtvRF_SetOfdmPara] Unsupport Tsb3seg\n"); -+ return -9; -+ -+ case RTV_SERVICE_VHF_ISDBTmm_13seg: -+ nNumAdcType = 4; /* ADC 20.48MHz */ -+ ptOfdmCfgTbl = &g_atAdcCfgTbl_ISDBT_6MHz[nNumAdcType]; -+ break; -+ -+ case RTV_SERVICE_UHF_ISDBT_13seg: -+ if ((dwChFreqKHz == 551143) || (dwChFreqKHz == 581143) || -+ (dwChFreqKHz == 611143) || (dwChFreqKHz == 617143) || -+ (dwChFreqKHz == 647143) || (dwChFreqKHz == 677143) || -+ (dwChFreqKHz == 707143) || (dwChFreqKHz == 737143) || -+ (dwChFreqKHz == 767143) || (dwChFreqKHz == 797143)) -+ nNumAdcType = 2; /* ADC 19.2MHz */ -+ else if ((dwChFreqKHz == 491143) || (dwChFreqKHz == 521143)) -+ nNumAdcType = 3; /* ADC 20.0MHz */ -+ else -+ nNumAdcType = 4; /* ADC 20.48MHz */ -+ -+ switch (eLpfBwType) { -+ case RTV_BW_MODE_6MHZ: -+ ptOfdmCfgTbl = &g_atAdcCfgTbl_ISDBT_6MHz[nNumAdcType]; -+ break; -+ case RTV_BW_MODE_7MHZ: -+ ptOfdmCfgTbl = &g_atAdcCfgTbl_ISDBT_7MHz[nNumAdcType]; -+ break; -+ case RTV_BW_MODE_8MHZ: -+ ptOfdmCfgTbl = &g_atAdcCfgTbl_ISDBT_8MHz[nNumAdcType]; -+ break; -+ default: -+ printk("[rtvRF_SetOfdmPara] Unsupport 13seg\n"); -+ return -9; -+ } -+ break; -+ default: -+ printk("[rtvRF_SetOfdmPara] Invaild Service Type\n"); -+ return -9; -+ } -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,RF_PAGE); -+ regmap_write(dev->regmap,0x2A, ptOfdmCfgTbl->bData2A); -+ regmap_write(dev->regmap,0x6E, ptOfdmCfgTbl->bData6E); -+ regmap_write(dev->regmap,0x70, ptOfdmCfgTbl->bData70); -+ regmap_write(dev->regmap,0x71, ptOfdmCfgTbl->bData71); -+ regmap_update_bits(dev->regmap,0x75, 0xFC, (ptOfdmCfgTbl->bData75 << 2)); -+ -+ if (rtvRF_LockCheck(dev,1) != 0) -+ return -2; -+ -+ if ((eServiceType == RTV_SERVICE_UHF_ISDBT_1seg) || -+ (eServiceType == RTV_SERVICE_VHF_ISDBTmm_1seg) || -+ (eServiceType == RTV_SERVICE_VHF_ISDBTsb_1seg) || -+ (eServiceType == RTV_SERVICE_VHF_ISDBTsb_3seg)) { -+ regmap_write(dev->regmap,MAP_SEL_REG,LPOFDM_PAGE); -+ regmap_write(dev->regmap,0x14, (u8)((ptOfdmCfgTbl->dwTNCO >> 0) & 0xFF)); -+ regmap_write(dev->regmap,0x15, (u8)((ptOfdmCfgTbl->dwTNCO >> 8) & 0xFF)); -+ regmap_write(dev->regmap,0x16, (u8)((ptOfdmCfgTbl->dwTNCO >> 16) & 0xFF)); -+ regmap_write(dev->regmap,0x17, (u8)((ptOfdmCfgTbl->dwTNCO >> 24) & 0xFF)); -+ -+ regmap_write(dev->regmap,0x18, (u8)((ptOfdmCfgTbl->dwPNCO >> 0) & 0xFF)); -+ regmap_write(dev->regmap,0x19, (u8)((ptOfdmCfgTbl->dwPNCO >> 8) & 0xFF)); -+ regmap_write(dev->regmap,0x1A, (u8)((ptOfdmCfgTbl->dwPNCO >> 16) & 0xFF)); -+ regmap_write(dev->regmap,0x1B, (u8)((ptOfdmCfgTbl->dwPNCO >> 24) & 0xFF)); -+ -+ regmap_write(dev->regmap,0x1C, (u8)((ptOfdmCfgTbl->dwGAIN) & 0xFF)); -+ -+ regmap_write(dev->regmap,0x1D, (u8)((ptOfdmCfgTbl->dwCFREQGAIN>>0) & 0xFF)); -+ regmap_write(dev->regmap,0x1E, (u8)((ptOfdmCfgTbl->dwCFREQGAIN>>8) & 0xFF)); -+ regmap_write(dev->regmap,0x1F, (u8)((ptOfdmCfgTbl->dwCFREQGAIN>>16) & 0xFF)); -+ } else { -+ regmap_write(dev->regmap,MAP_SEL_REG,OFDM_PAGE); -+ switch (eLpfBwType) { -+ case RTV_BW_MODE_5MHZ: -+ regmap_update_bits(dev->regmap,0x11, 0x01, 0x00); -+ regmap_update_bits(dev->regmap,0x10, 0xE0, 0xB0); -+ regmap_update_bits(dev->regmap,0x1F, 0xC0, 0xC0); -+ break; -+ case RTV_BW_MODE_6MHZ: -+ regmap_update_bits(dev->regmap,0x11, 0x01, 0x00); -+ regmap_update_bits(dev->regmap,0x10, 0xE0, 0xC0); -+ regmap_update_bits(dev->regmap,0x1F, 0xC0, 0x80); -+ break; -+ case RTV_BW_MODE_7MHZ: -+ regmap_update_bits(dev->regmap,0x11, 0x01, 0x00); -+ regmap_update_bits(dev->regmap,0x10, 0xE0, 0xE0); -+ regmap_update_bits(dev->regmap,0x1F, 0xC0, 0x40); -+ break; -+ case RTV_BW_MODE_8MHZ: -+ regmap_update_bits(dev->regmap,0x11, 0x01, 0x01); -+ regmap_update_bits(dev->regmap,0x10, 0xE0, 0x00); -+ regmap_update_bits(dev->regmap,0x1F, 0xC0, 0x00); -+ break; -+ default: -+ printk("[rtvRF_SetFrequency] Unsupported BW\n"); -+ return -9; -+ break; -+ } -+ -+ regmap_write(dev->regmap,0x34, (u8)((ptOfdmCfgTbl->dwTNCO>>0) & 0xFF)); -+ regmap_write(dev->regmap,0x35, (u8)((ptOfdmCfgTbl->dwTNCO>>8) & 0xFF)); -+ regmap_write(dev->regmap,0x36, (u8)((ptOfdmCfgTbl->dwTNCO>>16) & 0xFF)); -+ regmap_write(dev->regmap,0x37, (u8)((ptOfdmCfgTbl->dwTNCO>>24) & 0xFF)); -+ -+ regmap_write(dev->regmap,0x38, (u8) (ptOfdmCfgTbl->dwPNCO>>0)); -+ regmap_write(dev->regmap,0x39, (u8) (ptOfdmCfgTbl->dwPNCO>>8)); -+ regmap_write(dev->regmap,0x3A, (u8) (ptOfdmCfgTbl->dwPNCO>>16)); -+ regmap_write(dev->regmap,0x3B, (u8) (ptOfdmCfgTbl->dwPNCO>>24)); -+ -+ regmap_write(dev->regmap,0x3D, (u8)((ptOfdmCfgTbl->dwCFREQGAIN>>0) & 0xFF)); -+ regmap_write(dev->regmap,0x3E, (u8)((ptOfdmCfgTbl->dwCFREQGAIN>>8) & 0xFF)); -+ regmap_write(dev->regmap,0x3F, (u8)((ptOfdmCfgTbl->dwCFREQGAIN>>16) & 0xFF)); -+ -+ regmap_update_bits(dev->regmap,0x55, 0xC0, (ptOfdmCfgTbl->dwGAIN & 0x03)); -+ regmap_write(dev->regmap,0x56, (ptOfdmCfgTbl->dwGAIN>>2) & 0xFF); -+ } -+ -+ return nRet; -+} -+ -+static int rtvRF_ConfigureClkCKSYN(struct mtv23x_dev*dev,enum E_RTV_BANDWIDTH_TYPE eBwType) -+{ -+ int temp; -+ u8 WR6D = 0, WR6E = 0, WR70 = 0, WR71 = 0; -+ u8 WR2A = 0, WR72 = 0, WR73 = 0, WR74 = 0, WR75 = 0; -+ -+ const u16 g_atBW_TABLE_CKSYN[MAX_NUM_RTV_BW_MODE_TYPE][9] = -+ { -+ /*RTV_BW_MODE_5MHZ*/ {0x19,0x180,0x01,0x01,0x2E,0x13,0x0E,0x01,0x29}, -+ /*RTV_BW_MODE_6MHZ*/ {0x19,0x180,0x01,0x01,0x2E,0x13,0x0E,0x01,0x29}, -+ /*RTV_BW_MODE_7MHZ*/ {0x19,0x180,0x01,0x01,0x2E,0x13,0x0E,0x01,0x29}, -+ /*RTV_BW_MODE_8MHZ*/ {0x19,0x180,0x01,0x01,0x2E,0x13,0x0E,0x01,0x29}, -+ /*RTV_BW_MODE_430KHZ*/ {0x04,0x36, 0x01,0x00,0x2E,0x13,0x0E,0x01,0x29}, -+ /*RTV_BW_MODE_500KHZ*/ {0x0A,0x7B, 0x01,0x00,0x2E,0x13,0x0E,0x01,0x29}, -+ /*RTV_BW_MODE_571KHZ*/ {0x14,0xAB, 0x00,0x00,0x2E,0x13,0x0E,0x01,0x29}, -+ /*RTV_BW_MODE_768KHZ*/ {0x06,0x48, 0x01,0x00,0x2E,0x13,0x0E,0x01,0x29}, -+ /*RTV_BW_MODE_1290KHZ*/ {0x05,0x24, 0x00,0x00,0x2E,0x13,0x0E,0x01,0x29} -+ }; -+ -+ -+ regmap_read(dev->regmap,0x6D,&temp); -+ WR6D = temp & 0xFC; -+ regmap_read(dev->regmap,0x6E,&temp); -+ WR6E = temp & 0x00; -+ regmap_read(dev->regmap,0x70,&temp); -+ WR70 = temp & 0x00; -+ regmap_read(dev->regmap,0x2A,&temp); -+ WR2A = temp & 0xF7; -+ regmap_read(dev->regmap,0x71,&temp); -+ WR71 = temp & 0x00; -+ regmap_read(dev->regmap,0x72,&temp); -+ WR72 = temp & 0x03; -+ regmap_read(dev->regmap,0x73,&temp); -+ WR73 = temp & 0x03; -+ regmap_read(dev->regmap,0x74,&temp); -+ WR74 = temp & 0x0F; -+ regmap_read(dev->regmap,0x75,&temp); -+ WR75 = temp & 0x03; -+ -+ regmap_write(dev->regmap,0x6D, WR6D | (u8)g_atBW_TABLE_CKSYN[eBwType][2]); -+ regmap_write(dev->regmap,0x6E, WR6E | (u8)g_atBW_TABLE_CKSYN[eBwType][0]); -+ regmap_write(dev->regmap,0x70, WR70 | (u8)(g_atBW_TABLE_CKSYN[eBwType][1] & 0xFF)); -+ regmap_write(dev->regmap,0x2A, WR2A | (u8)(g_atBW_TABLE_CKSYN[eBwType][3] << 3)); -+ regmap_write(dev->regmap,0x71, WR71 | (u8)(((g_atBW_TABLE_CKSYN[eBwType][1] & 0x300) >> 2) -+ | g_atBW_TABLE_CKSYN[eBwType][4])); -+ regmap_write(dev->regmap,0x72, WR72 | (u8)(g_atBW_TABLE_CKSYN[eBwType][6] << 2)); -+ regmap_write(dev->regmap,0x73, WR73 | (u8)(g_atBW_TABLE_CKSYN[eBwType][5] << 2)); -+ regmap_write(dev->regmap,0x74, WR74 | (u8)(g_atBW_TABLE_CKSYN[eBwType][7] << 4)); -+ regmap_write(dev->regmap,0x75, WR75 | (u8)(g_atBW_TABLE_CKSYN[eBwType][8] << 2)); -+ -+ if (rtvRF_LockCheck(dev,1) != 0) -+ return 1; -+ -+ return 0; -+} -+ -+static rtvRF_ConfigureIIRFilter(struct mtv23x_dev*dev,enum E_RTV_BANDWIDTH_TYPE eBwType) -+{ -+ int temp; -+ u8 WR95 = 0; -+ int g_atBW_TABLE_IIR[MAX_NUM_RTV_BW_MODE_TYPE][14] = -+ { -+ /*RTV_BW_MODE_5MHZ*/ {0x02,0xBB83E,0x436A1,0xC12C0,0xC3472,0x43762,0xC1CD3,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x398FD}, -+ /*RTV_BW_MODE_6MHZ*/ {0x02,0x3F019,0x43426,0xC108E,0xC3063,0x43405,0xC1C85,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x3B1B1}, -+ /*RTV_BW_MODE_7MHZ*/ {0x02,0x416DF,0x43084,0xBFBDC,0xC1331,0x41CF0,0xC1C18,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x3B78B}, //19.2MHz -+ /*RTV_BW_MODE_8MHZ*/ {0x02,0x41F50,0x41B43,0xBF8A5,0xBF1E8,0x413E4,0xC1BEC,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x3BDB2}, //19.2MHz IIR -+ /*RTV_BW_MODE_430KHZ*/ {0x02,0x43721,0x43400,0xBFDE1,0x3D238,0x4329D,0xC1965,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x371E2}, -+ /*RTV_BW_MODE_500KHZ*/ {0x03,0x435CF,0x43466,0xC1185,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x3B27E}, -+ /*RTV_BW_MODE_571KHZ*/ {0x02,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000}, -+ /*RTV_BW_MODE_768KHZ*/ {0x02,0xC17A9,0x437A7,0xC1414,0xC38C3,0x439AA,0xC1DD4,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x3B394}, -+ /*RTV_BW_MODE_1290KHZ*/ {0x02,0xC37D0,0x43989,0xC1523,0xBF6D4,0x43B26,0xC1DFB,0x43000,0x43000,0x43000,0x43000,0x43000,0x43000,0x3732E} -+ }; -+ -+ regmap_read(dev->regmap,0x95,&temp); -+ WR95 = temp & 0xC0; -+ -+ regmap_write(dev->regmap,0x95, (WR95 | (u8)((g_atBW_TABLE_IIR[eBwType][0]<<4) | ((g_atBW_TABLE_IIR[eBwType][1]&0xF0000)>>16)))); -+ regmap_write(dev->regmap,0x96, ((g_atBW_TABLE_IIR[eBwType][1] & 0x0FF00)>>8)); -+ regmap_write(dev->regmap,0x97, ((g_atBW_TABLE_IIR[eBwType][1] & 0x000FF)>>0)); -+ regmap_write(dev->regmap,0x98, ((g_atBW_TABLE_IIR[eBwType][2] & 0xFF000)>>12)); -+ regmap_write(dev->regmap,0x99, ((g_atBW_TABLE_IIR[eBwType][2] & 0x00FF0)>>4)); -+ regmap_write(dev->regmap,0x9A, (u8)((((g_atBW_TABLE_IIR[eBwType][2] & 0x0000F)>>0) << 4) | -+ ((g_atBW_TABLE_IIR[eBwType][3] & 0xF0000)>>16))); -+ regmap_write(dev->regmap,0x9B, (u8)((g_atBW_TABLE_IIR[eBwType][3] & 0x0FF00)>>8)); -+ regmap_write(dev->regmap,0x9C, (u8)((g_atBW_TABLE_IIR[eBwType][3] & 0x000FF)>>0)); -+ regmap_write(dev->regmap,0x9D, (u8)((((g_atBW_TABLE_IIR[eBwType][13] & 0xF0000)>>16) << 4) | -+ (u8)((g_atBW_TABLE_IIR[eBwType][4] & 0xF0000)>>16))); -+ regmap_write(dev->regmap,0x9E, (u8)((g_atBW_TABLE_IIR[eBwType][4] & 0x0FF00)>>8)); -+ regmap_write(dev->regmap,0x9F, (u8)((g_atBW_TABLE_IIR[eBwType][4] & 0x000FF)>>0)); -+ regmap_write(dev->regmap,0xA0, (u8)((g_atBW_TABLE_IIR[eBwType][5] & 0xFF000)>>12)); -+ regmap_write(dev->regmap,0xA1, (u8)((g_atBW_TABLE_IIR[eBwType][5] & 0x00FF0)>>4)); -+ regmap_write(dev->regmap,0xA2, (u8)((((g_atBW_TABLE_IIR[eBwType][5] & 0x0000F)>>0) << 4) | -+ ((g_atBW_TABLE_IIR[eBwType][6] & 0xF0000)>>16))); -+ regmap_write(dev->regmap,0xA3, (u8)((g_atBW_TABLE_IIR[eBwType][6] & 0x0FF00)>>8)); -+ regmap_write(dev->regmap,0xA4, (u8)((g_atBW_TABLE_IIR[eBwType][6] & 0x000FF)>>0)); -+ regmap_write(dev->regmap,0xA5, (u8)((((g_atBW_TABLE_IIR[eBwType][13] & 0x0F000)>>12) << 4) | -+ (u8)((g_atBW_TABLE_IIR[eBwType][7] & 0xF0000)>>16))); -+ regmap_write(dev->regmap,0xA6, (u8)((g_atBW_TABLE_IIR[eBwType][7] & 0x0FF00)>>8)); -+ regmap_write(dev->regmap,0xA7, (u8)((g_atBW_TABLE_IIR[eBwType][7] & 0x000FF)>>0)); -+ regmap_write(dev->regmap,0xA8, (u8)((g_atBW_TABLE_IIR[eBwType][8] & 0xFF000)>>12)); -+ regmap_write(dev->regmap,0xA9, (u8)((g_atBW_TABLE_IIR[eBwType][8] & 0x00FF0)>>4)); -+ regmap_write(dev->regmap,0xAA, (u8)((((g_atBW_TABLE_IIR[eBwType][8] & 0x0000F)>>0) << 4) | -+ ((g_atBW_TABLE_IIR[eBwType][9] & 0xF0000)>>16))); -+ regmap_write(dev->regmap,0xAB, (u8)((g_atBW_TABLE_IIR[eBwType][9] & 0x0FF00)>>8)); -+ regmap_write(dev->regmap,0xAC, (u8)((g_atBW_TABLE_IIR[eBwType][9] & 0x000FF)>>0)); -+ regmap_write(dev->regmap,0xAD, (u8)((((g_atBW_TABLE_IIR[eBwType][13] & 0x00F00)>>8) << 4) | -+ (u8)((g_atBW_TABLE_IIR[eBwType][10] & 0xF0000)>>16))); -+ regmap_write(dev->regmap,0xAE, (u8)((g_atBW_TABLE_IIR[eBwType][10] & 0x0FF00)>>8)); -+ regmap_write(dev->regmap,0xAF, (u8)((g_atBW_TABLE_IIR[eBwType][10] & 0x000FF)>>0)); -+ regmap_write(dev->regmap,0xB0, (u8)((g_atBW_TABLE_IIR[eBwType][11] & 0xFF000)>>12)); -+ regmap_write(dev->regmap,0xB1, (u8)((g_atBW_TABLE_IIR[eBwType][11] & 0x00FF0)>>4)); -+ regmap_write(dev->regmap,0xB2, (u8)((((g_atBW_TABLE_IIR[eBwType][11] & 0x0000F)>>0) << 4) | -+ ((g_atBW_TABLE_IIR[eBwType][12] & 0xF0000)>>16))); -+ regmap_write(dev->regmap,0xB3, (u8)((g_atBW_TABLE_IIR[eBwType][12] & 0x0FF00)>>8)); -+ regmap_write(dev->regmap,0xB4, (u8)((g_atBW_TABLE_IIR[eBwType][12] & 0x000FF)>>0)); -+ regmap_write(dev->regmap,0xB5, (u8)((g_atBW_TABLE_IIR[eBwType][13] & 0x000FF)>>0)); -+ -+ return 0; -+ -+ -+} -+static int rtvRF_ConfigureBBA(struct mtv23x_dev*dev,enum E_RTV_BANDWIDTH_TYPE eBwType) -+{ -+ int temp; -+ u8 WR3E = 0, WR3F = 0, WR50 = 0, WR51 = 0, WR4F = 0, WR4E = 0, WR77 = 0; -+ int g_atBW_TABLE_BBA[MAX_NUM_RTV_BW_MODE_TYPE][7] = -+ { -+ /*RTV_BW_MODE_5MHZ*/ {0x2D,0x20,0x03,0x03,0x02,0x02,0x01}, -+ /*RTV_BW_MODE_6MHZ*/ {0x2D,0x20,0x03,0x03,0x02,0x02,0x01}, -+ /*RTV_BW_MODE_7MHZ*/ {0x28,0x19,0x03,0x03,0x02,0x02,0x02}, -+ /*RTV_BW_MODE_8MHZ*/ {0x22,0x13,0x03,0x03,0x02,0x02,0x03}, -+ /*RTV_BW_MODE_430KHZ*/ {0x9C,0x15,0x00,0x03,0x00,0x00,0x00}, -+ /*RTV_BW_MODE_500KHZ*/ {0xBF,0x20,0x03,0x03,0x02,0x02,0x00}, -+ /*RTV_BW_MODE_571KHZ*/ {0xBF,0x20,0x03,0x03,0x02,0x02,0x00}, -+ /*RTV_BW_MODE_768KHZ*/ {0xBF,0x20,0x03,0x03,0x02,0x02,0x00}, -+ /*RTV_BW_MODE_1290KHZ*/ {0xBF,0x20,0x03,0x03,0x02,0x02,0x00} -+ }; -+ regmap_read(dev->regmap,0x3E,&temp); -+ WR3E = temp & 0x00; -+ regmap_read(dev->regmap,0x3F,&temp); -+ WR3F = temp & 0x03; -+ regmap_read(dev->regmap,0x50,&temp); -+ WR50 = temp & 0x1F; -+ regmap_read(dev->regmap,0x51,&temp); -+ WR51 = temp & 0x8F; -+ regmap_read(dev->regmap,0x4F,&temp); -+ WR4F = temp & 0x1F; -+ regmap_read(dev->regmap,0x4E,&temp); -+ WR4E = temp & 0x1F; -+ regmap_read(dev->regmap,0x77,&temp); -+ WR77 = temp & 0xFC; -+ -+ regmap_write(dev->regmap,0x3E, WR3E | g_atBW_TABLE_BBA[eBwType][0]); -+ regmap_write(dev->regmap,0x3F, WR3F | (u8)(g_atBW_TABLE_BBA[eBwType][1] << 2)); -+ regmap_write(dev->regmap,0x50, WR50 | (u8)(g_atBW_TABLE_BBA[eBwType][2] << 5)); -+ regmap_write(dev->regmap,0x51, WR51 | (u8)(g_atBW_TABLE_BBA[eBwType][3] << 4)); -+ regmap_write(dev->regmap,0x4F, WR4F | (u8)(g_atBW_TABLE_BBA[eBwType][4] << 5)); -+ regmap_write(dev->regmap,0x4E, WR4E | (u8)(g_atBW_TABLE_BBA[eBwType][5] << 5)); -+ regmap_write(dev->regmap,0x77, WR77 | (u8)(g_atBW_TABLE_BBA[eBwType][6] << 0)); -+ -+ return 0; -+} -+ -+static int rtvRF_ConfigureADC(struct mtv23x_dev*dev,enum E_RTV_BANDWIDTH_TYPE eBwType) -+{ -+ int temp; -+ u8 WRB7 = 0, WRC8 = 0, WRC9 = 0, WRCA = 0, WRCB = 0, WRCC = 0; -+ u8 WRCD = 0, WRCE = 0; -+ u8 WRD1 = 0, WRD2 = 0, WRD3 = 0, WRD5 = 0, WRD6 = 0, WRD7 = 0; -+ u8 WRD8 = 0, WRD9 = 0, WRDA = 0; -+ u8 g_atBW_TABLE_ADC[MAX_NUM_RTV_BW_MODE_TYPE][47] = -+ { -+ /*RTV_BW_MODE_5MHZ*/ {0x00,0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x0A,0x20,0x1F,0x12,0x20,0x13,0x20,0x00,0x00,0x00,0x02,0x35,0x49,0x49,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x12,0x10,0x1F,0x1F,0x1F,0x10,0x1F,0x1F,0x1F,0x10,0x1F,0x1F,0x1F,0x30,0x30,0x30,0x18,0x00,0x00}, -+ /*RTV_BW_MODE_6MHZ*/ {0x00,0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x0A,0x20,0x1F,0x12,0x20,0x13,0x20,0x00,0x00,0x00,0x02,0x35,0x4F,0x4F,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x12,0x10,0x1F,0x1F,0x1F,0x10,0x1F,0x1F,0x1F,0x10,0x1F,0x1F,0x1F,0x30,0x30,0x30,0x18,0x00,0x00}, -+ /*RTV_BW_MODE_7MHZ*/ {0x00,0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x0A,0x20,0x1F,0x12,0x20,0x13,0x20,0x00,0x00,0x00,0x02,0x35,0x4F,0x4F,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x12,0x10,0x1F,0x1F,0x1F,0x10,0x1F,0x1F,0x1F,0x10,0x1F,0x1F,0x1F,0x30,0x30,0x30,0x18,0x00,0x00}, -+ /*RTV_BW_MODE_8MHZ*/ {0x00,0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x0A,0x20,0x1F,0x12,0x20,0x13,0x20,0x00,0x00,0x00,0x02,0x35,0x4F,0x4F,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x12,0x10,0x1F,0x1F,0x1F,0x10,0x1F,0x1F,0x1F,0x10,0x1F,0x1F,0x1F,0x30,0x30,0x30,0x18,0x00,0x00}, -+ /*RTV_BW_MODE_430KHZ*/ {0x00,0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x08,0x20,0x03,0x08,0x20,0x08,0x20,0x00,0x00,0x00,0x00,0x09,0x23,0x23,0x21,0x21,0x21,0x21,0x21,0x21,0x12,0x10,0x0E,0x0E,0x0E,0x10,0x0E,0x0E,0x0E,0x10,0x0E,0x0E,0x0E,0x30,0x30,0x30,0x18,0x00,0x00}, -+ /*RTV_BW_MODE_500KHZ*/ {0x00,0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x08,0x20,0x03,0x08,0x20,0x08,0x20,0x00,0x00,0x00,0x00,0x06,0x20,0x20,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x12,0x10,0x0D,0x0D,0x0D,0x10,0x0D,0x0D,0x0D,0x10,0x0D,0x0D,0x0D,0x30,0x30,0x30,0x18,0x00,0x00}, -+ /*RTV_BW_MODE_571KHZ*/ {0x00,0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x0B,0x20,0x05,0x0B,0x20,0x0B,0x20,0x00,0x00,0x00,0x00,0x0F,0x2B,0x2B,0x29,0x29,0x29,0x29,0x29,0x29,0x12,0x10,0x11,0x11,0x11,0x10,0x11,0x11,0x11,0x10,0x11,0x11,0x11,0x30,0x30,0x30,0x18,0x00,0x00}, -+ /*RTV_BW_MODE_768KHZ*/ {0x00,0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x08,0x20,0x03,0x08,0x20,0x08,0x20,0x00,0x00,0x00,0x00,0x06,0x20,0x20,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x12,0x10,0x0D,0x0D,0x0D,0x10,0x0D,0x0D,0x0D,0x10,0x0D,0x0D,0x0D,0x30,0x30,0x30,0x18,0x00,0x00}, -+ /*RTV_BW_MODE_1290KHZ*/ {0x00,0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x08,0x20,0x04,0x08,0x20,0x08,0x20,0x00,0x00,0x00,0x00,0x03,0x1F,0x1F,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x12,0x10,0x0C,0x0C,0x0C,0x10,0x0C,0x0C,0x0C,0x10,0x0C,0x0C,0x0C,0x30,0x30,0x30,0x18,0x00,0x00} -+ }; -+ regmap_read(dev->regmap,0xB7,&temp); -+ WRB7 = temp& 0x07; -+ regmap_read(dev->regmap,0xC8,&temp); -+ WRC8 = temp & 0x80; -+ regmap_read(dev->regmap,0xC9,&temp); -+ WRC9 = temp & 0x80; -+ regmap_read(dev->regmap,0xCA,&temp); -+ WRCA = temp & 0x80; -+ regmap_read(dev->regmap,0xCB,&temp); -+ WRCB = temp & 0x80; -+ regmap_read(dev->regmap,0xCC,&temp); -+ WRCC = temp & 0x80; -+ regmap_read(dev->regmap,0xCD,&temp); -+ WRCD = temp & 0x80; -+ regmap_read(dev->regmap,0xCE,&temp); -+ WRCE = temp & 0x80; -+ regmap_read(dev->regmap,0xD1,&temp); -+ WRD1 = temp & 0x80; -+ regmap_read(dev->regmap,0xD2,&temp); -+ WRD2 = temp & 0x80; -+ regmap_read(dev->regmap,0xD3,&temp); -+ WRD3 = temp & 0x80; -+ regmap_read(dev->regmap,0xD5,&temp); -+ WRD5 = temp & 0x80; -+ regmap_read(dev->regmap,0xD6,&temp); -+ WRD6 = temp & 0x80; -+ regmap_read(dev->regmap,0xD7,&temp); -+ WRD7 = temp & 0x80; -+ regmap_read(dev->regmap,0xD8,&temp); -+ WRD8 = temp & 0x80; -+ regmap_read(dev->regmap,0xD9,&temp); -+ WRD9 = temp & 0xC0; -+ regmap_read(dev->regmap,0xDA,&temp); -+ WRDA = temp & 0xC0; -+ -+ regmap_write(dev->regmap,0xB7, (WRB7 | (g_atBW_TABLE_ADC[eBwType][45] << 6) | -+ (g_atBW_TABLE_ADC[eBwType][46] << 5))); -+ regmap_write(dev->regmap,0xB8, (g_atBW_TABLE_ADC[eBwType][44])); -+ regmap_write(dev->regmap,0xB9, (g_atBW_TABLE_ADC[eBwType][43])); -+ regmap_write(dev->regmap,0xBA, (g_atBW_TABLE_ADC[eBwType][42])); -+ regmap_write(dev->regmap,0xBB, (g_atBW_TABLE_ADC[eBwType][41])); -+ regmap_write(dev->regmap,0xBC, ((g_atBW_TABLE_ADC[eBwType][37] & 0x03) << 6) | -+ g_atBW_TABLE_ADC[eBwType][40]); -+ regmap_write(dev->regmap,0xBD, (((g_atBW_TABLE_ADC[eBwType][37] & 0x0C) >> 2) << 6) | -+ g_atBW_TABLE_ADC[eBwType][39]); -+ regmap_write(dev->regmap,0xBE, (((g_atBW_TABLE_ADC[eBwType][37] & 0x30) >> 4) << 6) | -+ g_atBW_TABLE_ADC[eBwType][38]); -+ regmap_write(dev->regmap,0xBF, ((g_atBW_TABLE_ADC[eBwType][33] & 0x03) << 6) | -+ (g_atBW_TABLE_ADC[eBwType][36])); -+ regmap_write(dev->regmap,0xC0, (((g_atBW_TABLE_ADC[eBwType][33] & 0x0C) >> 2) << 6) | -+ (g_atBW_TABLE_ADC[eBwType][35])); -+ regmap_write(dev->regmap,0xC1, (((g_atBW_TABLE_ADC[eBwType][33] & 0x30) >> 4) << 6) | -+ (g_atBW_TABLE_ADC[eBwType][34])); -+ regmap_write(dev->regmap,0xC2, ((g_atBW_TABLE_ADC[eBwType][29] & 0x03) << 6) | -+ (g_atBW_TABLE_ADC[eBwType][32])); -+ regmap_write(dev->regmap,0xC3, (((g_atBW_TABLE_ADC[eBwType][29] & 0x0C) >> 2) << 6) | -+ (g_atBW_TABLE_ADC[eBwType][31])); -+ regmap_write(dev->regmap,0xC4, (((g_atBW_TABLE_ADC[eBwType][29] & 0x30) >> 4) << 6) | -+ (g_atBW_TABLE_ADC[eBwType][30])); -+ regmap_write(dev->regmap,0xC5, (g_atBW_TABLE_ADC[eBwType][28])); -+ regmap_write(dev->regmap,0xC6, (g_atBW_TABLE_ADC[eBwType][27])); -+ regmap_write(dev->regmap,0xC7, (g_atBW_TABLE_ADC[eBwType][26])); -+ regmap_write(dev->regmap,0xC8, (WRC8 | (g_atBW_TABLE_ADC[eBwType][25]))); -+ regmap_write(dev->regmap,0xC9, (WRC9 | (g_atBW_TABLE_ADC[eBwType][24]))); -+ regmap_write(dev->regmap,0xCA, (WRCA | (g_atBW_TABLE_ADC[eBwType][23]))); -+ regmap_write(dev->regmap,0xCB, (WRCB | (g_atBW_TABLE_ADC[eBwType][22]))); -+ regmap_write(dev->regmap,0xCC, (WRCC | (g_atBW_TABLE_ADC[eBwType][21]))); -+ regmap_write(dev->regmap,0xCD, (WRCD | (g_atBW_TABLE_ADC[eBwType][20]))); -+ regmap_write(dev->regmap,0xCE, (WRCE | (g_atBW_TABLE_ADC[eBwType][19]))); -+ regmap_write(dev->regmap,0xCF, (g_atBW_TABLE_ADC[eBwType][18] << 6) | -+ (g_atBW_TABLE_ADC[eBwType][17] << 4) | -+ (g_atBW_TABLE_ADC[eBwType][16] << 2) | -+ (g_atBW_TABLE_ADC[eBwType][15] << 0)); -+ regmap_write(dev->regmap,0xD0, (g_atBW_TABLE_ADC[eBwType][14])); -+ regmap_write(dev->regmap,0xD1, (WRD1 | (g_atBW_TABLE_ADC[eBwType][13]))); -+ regmap_write(dev->regmap,0xD2, (WRD2 | (g_atBW_TABLE_ADC[eBwType][12]))); -+ regmap_write(dev->regmap,0xD3, (WRD3 | (g_atBW_TABLE_ADC[eBwType][11]))); -+ regmap_write(dev->regmap,0xD4, (g_atBW_TABLE_ADC[eBwType][10])); -+ regmap_write(dev->regmap,0xD5, (WRD5 | (g_atBW_TABLE_ADC[eBwType][9]))); -+ regmap_write(dev->regmap,0xD6, (WRD6 | (g_atBW_TABLE_ADC[eBwType][8]))); -+ regmap_write(dev->regmap,0xD7, (WRD7 | (g_atBW_TABLE_ADC[eBwType][7]))); -+ regmap_write(dev->regmap,0xD8, (WRD8 | (g_atBW_TABLE_ADC[eBwType][6]))); -+ regmap_write(dev->regmap,0xD9, (WRD9 | (g_atBW_TABLE_ADC[eBwType][5]))); -+ regmap_write(dev->regmap,0xDA, (WRDA | (g_atBW_TABLE_ADC[eBwType][4]))); -+ regmap_write(dev->regmap,0xDB, ((g_atBW_TABLE_ADC[eBwType][3]) << 4) | -+ (g_atBW_TABLE_ADC[eBwType][2])); -+ regmap_write(dev->regmap,0xDC, ((g_atBW_TABLE_ADC[eBwType][1]) << 4) | -+ (g_atBW_TABLE_ADC[eBwType][0])); -+ -+ return 0; -+} -+ -+static int rtvRF_Lna_Tuning(struct mtv23x_dev*dev,u32 dwLoFreq) -+{ -+ u8 nidx = 0; -+ u8 WR50 = 0, WR73 = 0, WR4E = 0, WR69 = 0, WR88 = 0, WR89 = 0; -+ u8 WR8A = 0, WR8B = 0; -+ u8 WR6C = 0, WR6D = 0, WR6A = 0, WR6B = 0, WR8C = 0, WR8D = 0; -+ u8 WR8E = 0, WR8F = 0; -+ u8 WR90 = 0, WR91 = 0, WR92 = 0, WR87 = 0, WR93 = 0, WR94 = 0; -+ int temp; -+ const u8 g_atLNA_TABLE[20][29] = -+ { -+ /* 80 - 90*/ {0x07,0x02,0x0A,0x03,0x03,0x07,0x00,0x00,0x0F,0x00,0x03,0x03,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00}, -+ /* 90 - 100*/{0x07,0x02,0x0A,0x03,0x02,0x07,0x00,0x00,0x0F,0x00,0x03,0x03,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00}, -+ /*100 - 110*/{0x07,0x02,0x0A,0x03,0x02,0x07,0x00,0x00,0x0F,0x00,0x02,0x03,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00}, -+ /*170 - 180*/{0x0B,0x02,0x10,0x03,0x05,0x00,0x05,0x02,0x07,0x00,0x03,0x04,0x3F,0x08,0x1F,0x2F,0x3F,0x12,0x14,0x02,0x3F,0x0C,0x1F,0x0F,0x03,0x3F,0x0F,0x0F,0x01}, -+ /*180 - 190*/{0x0B,0x02,0x10,0x03,0x04,0x00,0x04,0x02,0x06,0x00,0x03,0x04,0x3F,0x08,0x1F,0x14,0x3F,0x12,0x14,0x02,0x3F,0x0C,0x1F,0x0F,0x03,0x3F,0x0F,0x0F,0x01}, -+ /*190 - 200*/{0x0B,0x02,0x10,0x03,0x04,0x00,0x03,0x01,0x04,0x00,0x02,0x04,0x3F,0x08,0x1F,0x14,0x1F,0x0F,0x0F,0x02,0x14,0x07,0x1F,0x0F,0x03,0x3F,0x0F,0x0F,0x01}, -+ /*200 - 210*/{0x0B,0x02,0x10,0x03,0x03,0x00,0x03,0x01,0x02,0x00,0x02,0x04,0x3F,0x0A,0x1F,0x11,0x1F,0x0F,0x0F,0x02,0x14,0x07,0x1F,0x0F,0x03,0x3F,0x0F,0x0F,0x01}, -+ /*210 - 220*/{0x09,0x02,0x10,0x03,0x03,0x00,0x02,0x01,0x00,0x00,0x01,0x04,0x1E,0x0C,0x1F,0x0D,0x19,0x0C,0x03,0x02,0x14,0x07,0x1F,0x0F,0x03,0x3F,0x0F,0x0F,0x01}, -+ /*220 - 230*/{0x09,0x02,0x10,0x03,0x03,0x00,0x02,0x01,0x00,0x00,0x01,0x04,0x1E,0x0C,0x1F,0x0D,0x19,0x0C,0x03,0x02,0x14,0x07,0x1F,0x0F,0x03,0x3F,0x0F,0x0F,0x01}, -+ /*230 - 240*/{0x09,0x02,0x10,0x03,0x02,0x00,0x01,0x01,0x0F,0x00,0x01,0x04,0x12,0x0C,0x1F,0x0C,0x19,0x0C,0x03,0x02,0x14,0x07,0x1F,0x0F,0x03,0x3F,0x0F,0x0F,0x01}, -+ /*240 - 250*/{0x09,0x02,0x10,0x03,0x02,0x00,0x01,0x01,0x0E,0x00,0x01,0x04,0x12,0x0C,0x1F,0x0C,0x19,0x0C,0x03,0x02,0x14,0x07,0x1F,0x0F,0x03,0x3F,0x0F,0x0F,0x01}, -+ /*250 - 320*/{0x09,0x02,0x10,0x03,0x02,0x00,0x00,0x01,0x0E,0x00,0x01,0x04,0x12,0x0C,0x1F,0x0C,0x19,0x0C,0x03,0x02,0x14,0x07,0x1F,0x0F,0x03,0x3F,0x0F,0x0F,0x01}, -+ /*470 - 510*/{0x1F/*0x0F*/,0x02,0x0B,0x03,0x01,0x00,0x01,0x00,0x00/*0x0F*/,0x06,0x0B,0x05,0x3F,0x3F,0x00/*0x0A*/,0x00/*0x06*/,0x3F,0x3F,0x07,0x03,0x3F,0x3F,0x05,0x03,0x3F,0x3F,0x05,0x02,0x02}, -+ /*510 - 540*/{0x1F/*0x0F*/,0x02,0x0B,0x03,0x00,0x00,0x00,0x00,0x00/*0x07*/,0x06,0x07,0x05,0x3F,0x2F,0x00/*0x0A*/,0x00/*0x05*/,0x3F,0x3F,0x07,0x03,0x3F,0x3F,0x04,0x03,0x3F,0x3F,0x04,0x02,0x02}, -+ /*540 - 560*/{0x1F/*0x0F*/,0x02,0x0B,0x03,0x00,0x00,0x00,0x00,0x00/*0x05*/,0x06,0x03,0x05,0x3F,0x1F,0x00/*0x0A*/,0x00/*0x04*/,0x3F,0x0F,0x03,0x02,0x3F,0x3F,0x04,0x03,0x0F,0x0F,0x03,0x01,0x02}, -+ /*560 - 600*/{0x1F/*0x0D*/,0x02,0x0B,0x03,0x00,0x00,0x00,0x00,0x00/*0x03*/,0x06,0x03,0x05,0x2F,0x16,0x00/*0x09*/,0x00/*0x02*/,0x3F,0x0F,0x03,0x02,0x1F,0x08,0x02,0x00,0x0F,0x0F,0x02,0x00,0x02}, -+ /*600 - 630*/{0x1F/*0x0D*/,0x02,0x0B,0x03,0x00,0x00,0x00,0x00,0x00/*0x01*/,0x06,0x00,0x05,0x1F,0x0C,0x00/*0x08*/,0x00/*0x00*/,0x3F,0x00,0x00,0x00,0x1F,0x08,0x02,0x00,0x00,0x10,0x01,0x00,0x02}, -+ /*630 - 710*/{0x1F/*0x0D*/,0x02,0x10,0x03,0x00,0x00,0x00,0x00,0x00/*0x00*/,0x06,0x00,0x05,0x15,0x00,0x00/*0x06*/,0x00/*0x00*/,0x3F,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x02}, -+ /*710 - 810*/{0x1F/*0x0F*/,0x02,0x10,0x03,0x00,0x00,0x00,0x00,0x00/*0x00*/,0x06,0x00,0x05,0x15,0x00,0x00/*0x00*/,0x00/*0x00*/,0x3F,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x02}, -+ /*810 - 880*/{0x1F/*0x14*/,0x02,0x16,0x03,0x00,0x00,0x00,0x00,0x00/*0x00*/,0x06,0x00,0x05,0x09,0x00,0x00/*0x00*/,0x00/*0x00*/,0x3F,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x02} -+ }; -+ -+ if (75000 < dwLoFreq && 90000 >= dwLoFreq) -+ nidx = 0; -+ else if (90000 < dwLoFreq && 100000 >= dwLoFreq) -+ nidx = 1; -+ else if (100000 < dwLoFreq && 115000 >= dwLoFreq) -+ nidx = 2; -+ else if (115000 < dwLoFreq && 180000 >= dwLoFreq) -+ nidx = 3; -+ else if (180000 < dwLoFreq && 190000 >= dwLoFreq) -+ nidx = 4; -+ else if (190000 < dwLoFreq && 200000 >= dwLoFreq) -+ nidx = 5; -+ else if (200000 < dwLoFreq && 210000 >= dwLoFreq) -+ nidx = 6; -+ else if (210000 < dwLoFreq && 220000 >= dwLoFreq) -+ nidx = 7; -+ else if (220000 < dwLoFreq && 230000 >= dwLoFreq) -+ nidx = 8; -+ else if (230000 < dwLoFreq && 240000 >= dwLoFreq) -+ nidx = 9; -+ else if (240000 < dwLoFreq && 250000 >= dwLoFreq) -+ nidx = 10; -+ else if (250000 < dwLoFreq && 320000 >= dwLoFreq) -+ nidx = 11; -+ else if (320000 < dwLoFreq && 510000 >= dwLoFreq) -+ nidx = 12; -+ else if (510000 < dwLoFreq && 540000 >= dwLoFreq) -+ nidx = 13; -+ else if (540000 < dwLoFreq && 560000 >= dwLoFreq) -+ nidx = 14; -+ else if (560000 < dwLoFreq && 600000 >= dwLoFreq) -+ nidx = 15; -+ else if (600000 < dwLoFreq && 630000 >= dwLoFreq) -+ nidx = 16; -+ else if (630000 < dwLoFreq && 710000 >= dwLoFreq) -+ nidx = 17; -+ else if (710000 < dwLoFreq && 810000 >= dwLoFreq) -+ nidx = 18; -+ else if (810000 < dwLoFreq && 880000 >= dwLoFreq) -+ nidx = 19; -+ else -+ return -5; -+ -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,RF_PAGE); -+ regmap_read(dev->regmap,0x50,&temp); -+ WR50 = temp & 0xE0; -+ regmap_read(dev->regmap,0x73,&temp); -+ WR73 = temp & 0xFC; -+ regmap_read(dev->regmap,0x4E,&temp); -+ WR4E = temp & 0xE0; -+ regmap_read(dev->regmap,0x69,&temp); -+ WR69 = temp & 0x80; -+ regmap_read(dev->regmap,0x88,&temp); -+ WR88 = temp & 0x03; -+ regmap_read(dev->regmap,0x89,&temp); -+ WR89 = temp & 0x03; -+ regmap_read(dev->regmap,0x8A,&temp); -+ WR8A = temp & 0x00; -+ regmap_read(dev->regmap,0x8B,&temp); -+ WR8B = temp & 0x00; -+ regmap_read(dev->regmap,0x6C,&temp); -+ WR6C = temp & 0x03; -+ regmap_read(dev->regmap,0x6D,&temp); -+ WR6D = temp & 0x03; -+ regmap_read(dev->regmap,0x6A,&temp); -+ WR6A = temp & 0xC1; -+ regmap_read(dev->regmap,0x6B,&temp); -+ WR6B = temp & 0x03; -+ regmap_read(dev->regmap,0x8C,&temp); -+ WR8C = temp & 0x00; -+ regmap_read(dev->regmap,0x8D,&temp); -+ WR8D = temp & 0x00; -+ regmap_read(dev->regmap,0x8E,&temp); -+ WR8E = temp & 0x00; -+ regmap_read(dev->regmap,0x8F,&temp); -+ WR8F = temp & 0x00; -+ regmap_read(dev->regmap,0x90,&temp); -+ WR90 = temp & 0x00; -+ regmap_read(dev->regmap,0x91,&temp); -+ WR91 = temp & 0x00; -+ regmap_read(dev->regmap,0x92,&temp); -+ WR92 = temp & 0x00; -+ regmap_read(dev->regmap,0x87,&temp); -+ WR87 = temp & 0xFB; -+ regmap_read(dev->regmap,0x93,&temp); -+ WR93 = temp & 0x03; -+ regmap_read(dev->regmap,0x94,&temp); -+ WR94 = temp & 0x03; -+ -+ regmap_write(dev->regmap,0x50, WR50 | g_atLNA_TABLE[nidx][0]); -+ regmap_write(dev->regmap,0x73, WR73 | g_atLNA_TABLE[nidx][1]); -+ regmap_write(dev->regmap,0x4E, WR4E | g_atLNA_TABLE[nidx][2]); -+ regmap_write(dev->regmap,0x69, WR69 | (g_atLNA_TABLE[nidx][3] << 2) -+ | g_atLNA_TABLE[nidx][28]); -+ -+ regmap_write(dev->regmap,0x88, WR88 | (g_atLNA_TABLE[nidx][4] << 5) -+ | (g_atLNA_TABLE[nidx][5] << 2)); -+ -+ regmap_write(dev->regmap,0x89, WR89 | (g_atLNA_TABLE[nidx][6] << 5) -+ | (g_atLNA_TABLE[nidx][7] << 2)); -+ -+ regmap_write(dev->regmap,0x8A, WR8A | (g_atLNA_TABLE[nidx][8] << 4) -+ | g_atLNA_TABLE[nidx][9]); -+ -+ regmap_write(dev->regmap,0x8B, WR8B | (g_atLNA_TABLE[nidx][10] << 4) -+ | g_atLNA_TABLE[nidx][11]); -+ -+ regmap_write(dev->regmap,0x6C, WR6C | (g_atLNA_TABLE[nidx][12] << 2)); -+ regmap_write(dev->regmap,0x6D, WR6D | (g_atLNA_TABLE[nidx][13] << 2)); -+ regmap_write(dev->regmap,0x6A, WR6A | (g_atLNA_TABLE[nidx][14] << 1)); -+ regmap_write(dev->regmap,0x6B, WR6B | (g_atLNA_TABLE[nidx][15] << 2)); -+ regmap_write(dev->regmap,0x8C, WR8C | (g_atLNA_TABLE[nidx][16] << 2) -+ | ((g_atLNA_TABLE[nidx][18] & 0x18) >> 3)); -+ -+ regmap_write(dev->regmap,0x8D, WR8D | (g_atLNA_TABLE[nidx][20] << 2) -+ | ((g_atLNA_TABLE[nidx][18] & 0x06) >> 1)); -+ -+ regmap_write(dev->regmap,0x8E, WR8E | (g_atLNA_TABLE[nidx][24] << 2) -+ | ((g_atLNA_TABLE[nidx][18] & 0x01) << 1) -+ | ((g_atLNA_TABLE[nidx][22] & 0x10) >> 4)); -+ -+ regmap_write(dev->regmap,0x8F, WR8F | (g_atLNA_TABLE[nidx][17] << 2) -+ | ((g_atLNA_TABLE[nidx][22] & 0x0C) >> 2)); -+ -+ regmap_write(dev->regmap,0x90, WR90 | (g_atLNA_TABLE[nidx][21] << 2) -+ | ((g_atLNA_TABLE[nidx][22] & 0x03) >> 0)); -+ -+ regmap_write(dev->regmap,0x91, WR91 | (g_atLNA_TABLE[nidx][25] << 2) -+ | ((g_atLNA_TABLE[nidx][26] & 0x18) >> 3)); -+ -+ regmap_write(dev->regmap,0x92, WR92 | (g_atLNA_TABLE[nidx][19] << 2) -+ | ((g_atLNA_TABLE[nidx][26] & 0x06) >> 1)); -+ -+ regmap_write(dev->regmap,0x87, WR87 | ((g_atLNA_TABLE[nidx][26] & 0x01) << 2)); -+ regmap_write(dev->regmap,0x93, WR93 | (g_atLNA_TABLE[nidx][23] << 2)); -+ regmap_write(dev->regmap,0x94, WR94 | (g_atLNA_TABLE[nidx][27] << 2)); -+ -+ -+ -+ return 0; -+} -+ -+static int rtvRF_SetUpVCO(struct mtv23x_dev*dev,u32 dwLoFreq, u32 *dwPllfreq) -+{ -+ int nRet = 0; -+ int nVcoDivRate = 0; -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,RF_PAGE); -+ -+ if (dwLoFreq < 107500) { -+ nVcoDivRate = 5; -+ regmap_update_bits(dev->regmap,0x78, 0x0F, 0x0F); -+ } else if (dwLoFreq >= 107500 && dwLoFreq < 215000) { -+ nVcoDivRate = 4; -+ regmap_update_bits(dev->regmap,0x78, 0x0F, 0x0E); -+ } else if (dwLoFreq >= 215000 && dwLoFreq < 430000) { -+ nVcoDivRate = 3; -+ regmap_update_bits(dev->regmap,0x78, 0x0F, 0x0E); -+ } else { -+ nVcoDivRate = 2; -+ regmap_update_bits(dev->regmap,0x78, 0x0F, 0x0D); -+ } -+ -+ *dwPllfreq = dwLoFreq * (1<regmap,0x28, 0x03, ((nVcoDivRate & 0x06)>>1)); -+ regmap_update_bits(dev->regmap,0x29, 0x08, (nVcoDivRate & 0x01)<<3); -+ -+ if (*dwPllfreq >= 1720000 && *dwPllfreq < 1892000) { -+ regmap_update_bits(dev->regmap,0x94, 0x02, 0x00); -+ regmap_update_bits(dev->regmap,0x78, 0x70, 0x40); -+ regmap_update_bits(dev->regmap,0xEA, 0x60, 0x00); -+ } else if (*dwPllfreq >= 1892000 && *dwPllfreq < 3440000) { -+ regmap_update_bits(dev->regmap,0x94, 0x02, 0x00); -+ regmap_update_bits(dev->regmap,0x78, 0x70, 0x30); -+ regmap_update_bits(dev->regmap,0xEA, 0x60, 0x00); -+ } else -+ nRet = -5; -+ -+ return nRet; -+} -+ -+static int rtvRF_SelectService(struct mtv23x_dev*dev,enum E_RTV_SERVICE_TYPE eServiceType) -+{ -+ int nRet = 0; -+ -+ switch (eServiceType) { -+ case RTV_SERVICE_UHF_ISDBT_1seg: -+ case RTV_SERVICE_VHF_ISDBTmm_1seg: -+ case RTV_SERVICE_VHF_ISDBTsb_1seg: -+ regmap_write(dev->regmap,MAP_SEL_REG,HOST_PAGE); -+ regmap_write(dev->regmap,0x0B, 0x36); -+ -+ regmap_write(dev->regmap,0x12, 0x08); -+ regmap_write(dev->regmap,0x21, 0x01); -+ regmap_write(dev->regmap,0x26, 0x00); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,FEC_PAGE); -+ regmap_write(dev->regmap,0x20, 0x0C); -+ -+ regmap_write(dev->regmap,0x23, 0xF0); /* Layer A */ -+ regmap_write(dev->regmap,0x24, 0x31); -+ regmap_write(dev->regmap,0x4F, 0x1F); -+ regmap_write(dev->regmap,0x44, 0x68); -+ regmap_write(dev->regmap,0x47, 0x40); -+ -+ regmap_write(dev->regmap,0x53, 0x3E); -+ regmap_write(dev->regmap,0x21, 0x00); -+ regmap_write(dev->regmap,0x22, 0x00); -+ regmap_write(dev->regmap,0x5C, 0x10); -+ regmap_write(dev->regmap,0x5F, 0x10); -+ regmap_write(dev->regmap,0x77, 0x40); -+ regmap_write(dev->regmap,0x7A, 0x20); -+ regmap_write(dev->regmap,0x83, 0x10); -+ regmap_write(dev->regmap,0x96, 0x00); -+ regmap_write(dev->regmap,0xAE, 0x00); -+ -+ regmap_write(dev->regmap,0xFC, 0x83); -+ regmap_write(dev->regmap,0xFF, 0x03); -+ -+#if 0 -+ regmap_write(dev->regmap,0x44, 0x48); -+ regmap_write(dev->regmap,0x47, 0x00); -+#endif -+ dev->rtv_1seglpmode= 1; -+ break; -+ case RTV_SERVICE_VHF_ISDBTsb_3seg: -+ printk("[rtvRF_SelectService] 3seg is not implemented\n"); -+ break; -+ -+ case RTV_SERVICE_UHF_ISDBT_13seg: -+ case RTV_SERVICE_VHF_ISDBTmm_13seg: -+ regmap_write(dev->regmap,MAP_SEL_REG,HOST_PAGE); -+ regmap_write(dev->regmap,0x0B, 0x96); -+ -+ regmap_write(dev->regmap,0x12, 0x00); -+ regmap_write(dev->regmap,0x21, 0x00); -+ regmap_write(dev->regmap,0x26, 0xB8); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,OFDM_PAGE); -+ regmap_write(dev->regmap,0x10, 0xD4); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,FEC_PAGE); -+ regmap_write(dev->regmap,0x20, 0x00); -+ regmap_write(dev->regmap,0x21, 0x21); -+ regmap_write(dev->regmap,0x22, 0x21); -+ -+#if 0 -+ regmap_write(dev->regmap,0x23, 0x84); -+ regmap_write(dev->regmap,0x24, 0x31); -+ regmap_write(dev->regmap,0x4F, 0x1F); -+#endif -+ -+ regmap_write(dev->regmap,0x23, 0x90); -+ regmap_write(dev->regmap,0x24, 0x01); -+ regmap_write(dev->regmap,0x4F, 0x00); -+ regmap_write(dev->regmap,0x44, 0x68); -+ regmap_write(dev->regmap,0x47, 0x40); -+ -+ regmap_write(dev->regmap,0x53, 0x1E); -+ regmap_write(dev->regmap,0x5C, 0x11); -+ regmap_write(dev->regmap,0x5F, 0x11); -+ regmap_write(dev->regmap,0x77, 0x00); -+ regmap_write(dev->regmap,0x7A, 0x00); -+ regmap_write(dev->regmap,0x83, 0x00); -+ regmap_write(dev->regmap,0x96, 0x20); -+ regmap_write(dev->regmap,0xAE, 0x02); -+ -+ regmap_write(dev->regmap,0xFC, 0x83); -+ regmap_write(dev->regmap,0xFF, 0x03); -+ -+#if 0 -+ regmap_write(dev->regmap,0x44, 0xE8); -+ regmap_write(dev->regmap,0x47, 0x40); -+#endif -+ dev->rtv_1seglpmode= 0; -+ break; -+ -+ case RTV_SERVICE_DVBT: -+ regmap_write(dev->regmap,MAP_SEL_REG,HOST_PAGE); -+ regmap_write(dev->regmap,0x0B, 0x96); -+ regmap_write(dev->regmap,0x12, 0x00); -+ regmap_write(dev->regmap,0x21, 0x00); -+ regmap_write(dev->regmap,0x26, 0xB8); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,DATA_PAGE); -+ regmap_write(dev->regmap,0xA2, 0x0E); -+ regmap_write(dev->regmap,0xA3, 0x0E); -+ regmap_write(dev->regmap,0xA7, 0x0D); -+ regmap_write(dev->regmap,0xA6, 0x0D); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,OFDM_PAGE); -+ regmap_write(dev->regmap,0x10, 0xD6); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,FEC_PAGE); -+ regmap_write(dev->regmap,0x20, 0x00); -+ regmap_write(dev->regmap,0x21, 0x21); -+ regmap_write(dev->regmap,0x22, 0x21); -+ regmap_write(dev->regmap,0x53, 0x1E); -+ -+ regmap_write(dev->regmap,0x23, 0xF0); /* Layer A */ -+#if !defined(RTV_IF_SPI) && !defined(RTV_IF_EBI2) -+ regmap_write(dev->regmap,0x24, 0x11); -+ regmap_write(dev->regmap,0x4F, 0x07); -+#endif -+ regmap_write(dev->regmap,0x44, 0xE8); -+ regmap_write(dev->regmap,0x47, 0x40); -+ -+ regmap_write(dev->regmap,0x5C, 0x10); -+ regmap_write(dev->regmap,0x5F, 0x10); -+ regmap_write(dev->regmap,0x77, 0x00); -+ regmap_write(dev->regmap,0x7A, 0x00); -+ regmap_write(dev->regmap,0x83, 0x00); -+ regmap_write(dev->regmap,0x96, 0x20); -+ regmap_write(dev->regmap,0xAE, 0x02); -+ -+ regmap_write(dev->regmap,0xFC, 0x83); -+ regmap_write(dev->regmap,0xFF, 0x03); -+ -+#if 0 -+ regmap_write(dev->regmap,0x44, 0xE8); -+ regmap_write(dev->regmap,0x47, 0x40); -+#endif -+ dev->rtv_1seglpmode= 0; -+ break; -+ default: -+ nRet = -9; -+ } -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,RF_PAGE); -+ -+ switch (eServiceType) { -+ case RTV_SERVICE_UHF_ISDBT_1seg: -+ regmap_write(dev->regmap,0x49, 0x21); -+ regmap_write(dev->regmap,0x4A, 0x60); -+ regmap_write(dev->regmap,0x4B, 0x50); -+ regmap_write(dev->regmap,0x5E, 0x70); -+ regmap_write(dev->regmap,0x5F, 0x75); -+ break; -+ case RTV_SERVICE_VHF_ISDBTmm_1seg: -+ regmap_write(dev->regmap,0x49, 0x21); -+ regmap_write(dev->regmap,0x4A, 0x30); -+ regmap_write(dev->regmap,0x4B, 0x20); -+ regmap_write(dev->regmap,0x5E, 0x70); -+ regmap_write(dev->regmap,0x5F, 0x75); -+ break; -+ case RTV_SERVICE_VHF_ISDBTsb_1seg: -+ regmap_write(dev->regmap,0x49, 0x21); -+ regmap_write(dev->regmap,0x4A, 0x60); -+ regmap_write(dev->regmap,0x4B, 0x50); -+ regmap_write(dev->regmap,0x5E, 0x70); -+ regmap_write(dev->regmap,0x5F, 0x75); -+ break; -+ case RTV_SERVICE_VHF_ISDBTsb_3seg: -+ printk("[rtvRF_SelectService] Unsupported 3seg\n"); -+ break; -+ case RTV_SERVICE_UHF_ISDBT_13seg: -+ regmap_write(dev->regmap,0x49, 0x41); -+ regmap_write(dev->regmap,0x4A, 0x70); -+ regmap_write(dev->regmap,0x4B, 0x65); -+ regmap_write(dev->regmap,0x5E, 0x70); -+ regmap_write(dev->regmap,0x5F, 0x75); -+ break; -+ case RTV_SERVICE_VHF_ISDBTmm_13seg: -+ regmap_write(dev->regmap,0x49, 0x41); -+ regmap_write(dev->regmap,0x4A, 0x70); -+ regmap_write(dev->regmap,0x4B, 0x65); -+ regmap_write(dev->regmap,0x5E, 0x70); -+ regmap_write(dev->regmap,0x5F, 0x75); -+ break; -+ case RTV_SERVICE_DVBT: -+ regmap_write(dev->regmap,0x49, 0x41); -+ regmap_write(dev->regmap,0x4A, 0x70); -+ regmap_write(dev->regmap,0x4B, 0x65); -+ regmap_write(dev->regmap,0x5E, 0x70); -+ regmap_write(dev->regmap,0x5F, 0x75); -+ break; -+ -+ default: -+ nRet = -9; -+ } -+ -+ -+ return nRet; -+} -+ -+static int rtvRF_SetFrequency(struct mtv23x_dev*dev,enum E_RTV_SERVICE_TYPE eServiceType, -+ enum E_RTV_BANDWIDTH_TYPE eBwType,u32 dwChFreqKHz) -+{ -+ u8 pllf_mul = 0, r_div = 4; -+ u32 dwPLLN = 0, dwPLLF = 0, dwPLLNF = 0; -+ u32 dwPllFreq = 0, dwLoFreq = 0; -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,RF_PAGE); -+ rtvRF_ConfigureClkCKSYN(dev,eBwType); -+ rtvRF_ConfigureIIRFilter(dev,eBwType); -+ rtvRF_ConfigureBBA(dev,eBwType); -+ rtvRF_ConfigureADC(dev,eBwType); -+ rtvRF_SetOfdmPara(dev,eServiceType, eBwType, dwChFreqKHz); -+ rtvRF_SelectService(dev,eServiceType); -+ -+ if (dev->rtv_1seglpmode) { -+ regmap_write(dev->regmap,MAP_SEL_REG,LPOFDM_PAGE); -+ -+ if (eServiceType == RTV_SERVICE_VHF_ISDBTmm_1seg) { -+ regmap_write(dev->regmap,0x10, 0xFA); -+ dwLoFreq = dwChFreqKHz - 857; -+ } else { -+ regmap_write(dev->regmap,0x10, 0xF8); -+ dwLoFreq = dwChFreqKHz + 857; -+ } -+ } else -+ dwLoFreq = dwChFreqKHz; -+ rtvRF_Lna_Tuning(dev,dwLoFreq); -+ rtvRF_SetUpVCO(dev,dwLoFreq, &dwPllFreq); -+ -+ dwPLLN = dwPllFreq / dev->clk_freq; -+ dwPLLF = dwPllFreq - (dwPLLN * dev->clk_freq); -+ if (dev->clk_freq == 13000 || dev->clk_freq == 27000) { -+ pllf_mul = 1; -+ r_div = 3; -+ } -+ -+ dwPLLNF = (dwPLLN<<20) -+ + (((dwPLLF<<16) / (dev->clk_freq>>r_div)) << pllf_mul); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,RF_PAGE); -+ regmap_write(dev->regmap,0x20, ((dwPLLNF>>22)&0xFF)); -+ regmap_write(dev->regmap,0x21, ((dwPLLNF>>14)&0xFF)); -+ regmap_update_bits(dev->regmap,0x28, 0xFC, ((dwPLLNF&0x3F)<<2)); -+ regmap_write(dev->regmap,0x22, ((dwPLLNF>>6)&0xFF)); -+ -+ msleep(1); -+ -+ if (rtvRF_LockCheck(dev,0) != 0) -+ return -1; -+ -+ if (dwPllFreq >= 2140000 && dwPllFreq < 2950000) { -+ regmap_update_bits(dev->regmap,0x94, 0x02, 0x02); -+ regmap_update_bits(dev->regmap,0x78, 0x70, 0x50); -+ regmap_update_bits(dev->regmap,0xEA, 0x60, 0x40); -+ } else if (dwPllFreq >= 2950000 && dwPllFreq < 3440000) { -+ regmap_update_bits(dev->regmap,0x94, 0x02, 0x02); -+ regmap_update_bits(dev->regmap,0x78, 0x70, 0x40); -+ regmap_update_bits(dev->regmap,0xEA, 0x60, 0x00); -+ } -+ -+ return 0; -+} -+static int mtv23x_set_frontend(struct dvb_frontend *fe) -+{ -+ struct i2c_client*client = fe->demodulator_priv; -+ struct mtv23x_dev*dev = i2c_get_clientdata(client); -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ enum E_RTV_BANDWIDTH_TYPE bandwidth ; -+ enum E_RTV_SERVICE_TYPE svc_type = RTV_SERVICE_VHF_ISDBTmm_13seg; -+ int ret; -+ -+ const u8 g_atSubChNum[] = { -+ 0x00, 0x00, 0x10, 0x10, 0x10, 0x20, /*0 ~ 5 */ -+ 0x20, 0x20, 0x30, 0x30, 0x30, 0x40, /*6 ~ 11 */ -+ 0x40, 0x40, 0x50, 0x50, 0x50, 0x60, /*12 ~ 17 */ -+ 0x60, 0x60, 0x70, 0x70, 0x70, 0x80, /*18 ~ 23 */ -+ 0x80, 0x80, 0x90, 0x90, 0x90, 0xA0, /*24 ~ 29 */ -+ 0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xC0, /*30 ~ 35 */ -+ 0xC0, 0xC0, 0xD0, 0xD0, 0xD0, 0x00 /*31 ~ 41 */ -+ }; -+ if (c->bandwidth_hz == 0) { -+ ret = -EINVAL; -+ goto err; -+ }else if(c->bandwidth_hz<=435000){ -+ bandwidth = RTV_BW_MODE_430KHZ; -+ svc_type = RTV_SERVICE_UHF_ISDBT_1seg|RTV_SERVICE_VHF_ISDBTsb_1seg -+ |RTV_SERVICE_VHF_ISDBTmm_1seg; -+ } -+ else if (c->bandwidth_hz <= 505000){ -+ bandwidth = RTV_BW_MODE_500KHZ; -+ svc_type = RTV_SERVICE_UHF_ISDBT_1seg|RTV_SERVICE_VHF_ISDBTsb_1seg -+ |RTV_SERVICE_VHF_ISDBTmm_1seg; -+ } -+ else if (c->bandwidth_hz <= 575000){ -+ bandwidth = RTV_BW_MODE_571KHZ; -+ svc_type = RTV_SERVICE_UHF_ISDBT_1seg|RTV_SERVICE_VHF_ISDBTsb_1seg| -+ RTV_SERVICE_VHF_ISDBTmm_1seg; -+ } -+ else if (c->bandwidth_hz <= 860000){ -+ bandwidth = RTV_BW_MODE_857KHZ; -+ svc_type = RTV_SERVICE_UHF_ISDBT_1seg|RTV_SERVICE_VHF_ISDBTsb_1seg| -+ RTV_SERVICE_VHF_ISDBTmm_1seg; -+ } -+ else if (c->bandwidth_hz <= 1295000){ -+ bandwidth = RTV_BW_MODE_1290KHZ; -+ svc_type = RTV_SERVICE_VHF_ISDBTsb_3seg; -+ } -+ else if(c->bandwidth_hz <= 5000000) -+ bandwidth = RTV_BW_MODE_5MHZ; -+ else if (c->bandwidth_hz <= 6000000) -+ bandwidth = RTV_BW_MODE_6MHZ; -+ else if (c->bandwidth_hz <= 7000000) -+ bandwidth = RTV_BW_MODE_7MHZ; -+ else if(c->bandwidth_hz <= 8000000) -+ bandwidth = RTV_BW_MODE_8MHZ; -+ else -+ bandwidth = RTV_BW_MODE_6MHZ; -+ -+ -+ rtvRF_SetFrequency(dev,svc_type,bandwidth,c->frequency/1000); -+ -+ if ((svc_type == RTV_SERVICE_VHF_ISDBTmm_1seg) || -+ (svc_type == RTV_SERVICE_VHF_ISDBTsb_1seg) || -+ (svc_type == RTV_SERVICE_VHF_ISDBTsb_3seg)) { -+ regmap_write(dev->regmap,MAP_SEL_REG,LPOFDM_PAGE); -+ regmap_write(dev->regmap,0x31, g_atSubChNum[0]); -+ regmap_write(dev->regmap,0x34, 0xD1); -+ regmap_write(dev->regmap,0x36, 0x00); -+ } else if (svc_type == RTV_SERVICE_UHF_ISDBT_1seg) { -+ regmap_write(dev->regmap,MAP_SEL_REG,LPOFDM_PAGE); -+ regmap_write(dev->regmap,0x31, 0x70); -+ regmap_write(dev->regmap,0x34, 0x9F); -+ regmap_write(dev->regmap,0x36, 0x01); -+ } -+ -+ msleep(20); -+ rtv_softReset(dev); -+ msleep(20); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,FEC_PAGE); -+ regmap_write(dev->regmap,0xA8, 0x87); -+ regmap_write(dev->regmap,0xAB, 0x87); -+ -+ dev->svc_type = svc_type; -+ return 0; -+err: -+ dev_dbg(&client->dev,"Failed =%d\n",ret); -+ return ret; -+ -+} -+static void rtv_UpdateMon(struct mtv23x_dev*dev) -+{ -+ if (dev->rtv_1seglpmode) { -+ regmap_write(dev->regmap,MAP_SEL_REG,LPOFDM_PAGE); -+ regmap_update_bits(dev->regmap,0x13, 0x80, 0x80); -+ regmap_update_bits(dev->regmap,0x13, 0x80, 0x00); -+ } else { -+ regmap_write(dev->regmap,MAP_SEL_REG,OFDM_PAGE); -+ regmap_update_bits(dev->regmap,0x1B, 0x80, 0x80); -+ regmap_update_bits(dev->regmap,0x1B, 0x80, 0x00); -+ } -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,FEC_PAGE); -+ regmap_update_bits(dev->regmap,0x11, 0x04, 0x04); -+ regmap_update_bits(dev->regmap,0x11, 0x04, 0x00); -+} -+ -+static int mtv23x_read_status(struct dvb_frontend *fe, enum fe_status *status) -+{ -+ struct i2c_client*client = fe->demodulator_priv; -+ struct mtv23x_dev*dev = i2c_get_clientdata(client); -+ -+ int OFDMREG = 0, TMCCL = 0, OFDML = 0; -+ int lock_st = 0; -+ -+ if (dev->rtv_1seglpmode) { -+ regmap_write(dev->regmap,MAP_SEL_REG,LPOFDM_PAGE); -+ regmap_read(dev->regmap,0xC0,&OFDMREG); -+ OFDML = OFDMREG & 0x07; -+ } else { -+ regmap_write(dev->regmap,MAP_SEL_REG,SHAD_PAGE); -+ regmap_read(dev->regmap,0x81,&OFDMREG); -+ OFDML = (OFDMREG & 0x04) >> 2; -+ } -+ -+ if (OFDML & 0x01) -+ lock_st = RTV_ISDBT_OFDM_LOCK_MASK; -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,FEC_PAGE); -+ regmap_read(dev->regmap,0x10,&TMCCL); -+ -+ if (TMCCL & 0x01) -+ lock_st |= RTV_ISDBT_TMCC_LOCK_MASK; -+ -+ printk("DVB: lock status is 0%x\n",lock_st); -+ -+ if (RTV_ISDBT_CHANNEL_LOCK_OK == lock_st) { -+ *status = FE_HAS_LOCK|FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC; -+ } else if (lock_st & RTV_ISDBT_TMCC_LOCK_MASK) { -+ printk("TMCC lock \n"); -+ } else if (lock_st & RTV_ISDBT_OFDM_LOCK_MASK) { -+ printk("OFDM lock \n"); -+ } else { -+ *status = FE_TIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+static u32 rtvMTV23x_GetCNR(struct mtv23x_dev*dev) -+{ -+ u32 data = 0, cnr = 0; -+ u8 Mod = 0xFF, Cd = 0xFF; -+ int temp,temp1,temp2; -+ -+ rtv_UpdateMon(dev); -+ -+ regmap_update_bits(dev->regmap,0x76, 0x18, 0x00); -+ -+ if (dev->rtv_1seglpmode) { -+ regmap_read(dev->regmap,0x7B,&temp); -+ Mod = temp & 0x07; -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,LPOFDM_PAGE); -+ regmap_update_bits(dev->regmap,0x25, 0x70, 0x10); -+ regmap_update_bits(dev->regmap,0x13, 0x80, 0x80); -+ regmap_update_bits(dev->regmap,0x13, 0x80, 0x00); -+ -+ regmap_read(dev->regmap,0xCA,&temp); -+ regmap_read(dev->regmap,0xC9,&temp1); -+ regmap_read(dev->regmap,0xC8,&temp2); -+ data = ((temp &0xff)<<16) -+ | ((temp1 &0xff)<<8) -+ | (temp2 &0xff); -+ -+ cnr = GetSNR_LP_Mode(Mod, data); -+ } else { -+ regmap_read(dev->regmap,0x7C,&temp); -+ Cd = (temp >> 3) & 0x0F; -+ -+ if (Cd < 2) -+ regmap_update_bits(dev->regmap,0x76, 0x18, 0x08); -+ -+ -+ if (dev->svc_type == RTV_SERVICE_DVBT){ -+ regmap_read(dev->regmap,0x6F,&temp); -+ Mod = ((temp >> 2) & 0x03) + 1; -+ } -+ else -+ { -+ regmap_read(dev->regmap,0x7B,&temp); -+ Mod = (temp & 0x07); -+ } -+ regmap_write(dev->regmap,MAP_SEL_REG,OFDM_PAGE); -+ regmap_update_bits(dev->regmap,0x1B, 0x80, 0x80); -+ regmap_update_bits(dev->regmap,0x1B, 0x80, 0x00); -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,SHAD_PAGE); -+ -+ regmap_read(dev->regmap,0xde,&temp); -+ regmap_read(dev->regmap,0xdd,&temp1); -+ regmap_read(dev->regmap,0xdc,&temp2); -+ data = ((temp << 16) -+ | (temp1 << 8) -+ | (temp2 << 0)); -+ -+ cnr = GetSNR_FULL_Mode(Mod, data); -+ } -+ -+ return cnr; -+} -+ -+static s32 rtvMTV23x_GetRSSI(struct mtv23x_dev*dev) -+{ -+ u8 RD11 = 0, GVBB = 0, LNAGAIN = 0, RFAGC = 0, CH_FLAG = 0; -+ s32 nRssi = 0; -+ s32 nRssiAppDelta = 4*10; -+ -+ if (dev->rtv_1seglpmode) -+ nRssiAppDelta = 0; -+ -+ regmap_write(dev->regmap,MAP_SEL_REG,RF_PAGE); -+ regmap_read(dev->regmap,0x11,(int)&RD11); -+ regmap_read(dev->regmap,0x14,(int)&GVBB); -+// RD11 = RTV_REG_GET(0x11); -+// GVBB = RTV_REG_GET(0x14); -+ -+ CH_FLAG = ((RD11 & 0xC0) >> 6); -+ LNAGAIN = ((RD11 & 0x18) >> 3); -+ RFAGC = (RD11 & 0x07); -+ -+ switch (LNAGAIN) { -+ case 0: -+ nRssi = -(RSSI_RFAGC_VAL(RFAGC, 2.8) -+ + RSSI_GVBB_VAL(GVBB, 0.44) + 0) -+ + 5*10; -+ break; -+ -+ case 1: -+ nRssi = -(RSSI_RFAGC_VAL(RFAGC, 3) -+ + RSSI_GVBB_VAL(GVBB, 0.3) -+ + (19*10)) -+ + 0*10; -+ break; -+ -+ case 2: -+ nRssi = -(RSSI_RFAGC_VAL(RFAGC, 3) -+ + RSSI_GVBB_VAL(GVBB, 0.3) -+ + (16*2*10)) -+ + 0*10; -+ break; -+ -+ case 3: -+ nRssi = -(RSSI_RFAGC_VAL(RFAGC, 2.6) -+ + RSSI_GVBB_VAL(GVBB, 0.4) -+ + (11*3*10)) -+ + 0*10; -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (dev->rtv_1seglpmode) -+ nRssiAppDelta = 0; -+ else if (CH_FLAG == 0) -+ nRssiAppDelta += (7 * 10); -+ -+ return nRssi + nRssiAppDelta; -+} -+ -+static int mtv23x_read_snr(struct dvb_frontend *fe, u16 *snr) -+{ -+ struct i2c_client*client = fe->demodulator_priv; -+ struct mtv23x_dev*dev = i2c_get_clientdata(client); -+ *snr = (u16)rtvMTV23x_GetCNR(dev); -+ return 0; -+} -+static int mtv23x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -+{ -+ struct i2c_client*client = fe->demodulator_priv; -+ struct mtv23x_dev*dev = i2c_get_clientdata(client); -+ -+ *strength = (u16)rtvMTV23x_GetRSSI(dev); -+ return 0; -+} -+ -+static struct dvb_frontend_ops mtv23x_ops = { -+ .delsys = {SYS_ISDBT}, -+ .info = { -+ .name = "RAONTECH MTV23X", -+ .type = FE_OFDM, -+ .frequency_min = 76000000, -+ .frequency_max = 858000000, -+ .frequency_stepsize = 166667, -+ .frequency_tolerance = 0, -+ .caps = 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_HIERARCHY_AUTO | -+ FE_CAN_RECOVER | -+ FE_CAN_MUTE_TS -+ }, -+ -+ .init = mtv23x_init, -+ .set_frontend = mtv23x_set_frontend, -+ .read_status = mtv23x_read_status, -+ .read_signal_strength = mtv23x_read_signal_strength, -+ .read_snr = mtv23x_read_snr, -+ -+}; -+static int mtv23x_probe(struct i2c_client*client, -+ const struct i2c_device_id *id) -+{ -+ struct mtv23x_config *cfg = client->dev.platform_data; -+ struct mtv23x_dev *dev ; -+ int ret,temp; -+ -+ static const struct regmap_config regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ }; -+ dev = kzalloc(sizeof(*dev),GFP_KERNEL); -+ if(!dev){ -+ ret = -ENOMEM; -+ goto err; -+ } -+ dev->i2c_wr_max = cfg->i2c_wr_max?cfg->i2c_wr_max:~0; -+ dev->client = client; -+ dev->clk_freq = cfg->clk_freq; -+ dev->ts_mode = cfg->ts_mode; -+ dev->rtv_1seglpmode = 0; -+ dev->regmap = regmap_init_i2c(dev->client,®map_config); -+ if(IS_ERR(dev->regmap)){ -+ ret = PTR_ERR(dev->regmap); -+ goto err_kfree; -+ } -+ -+ /*check the i2c */ -+ ret = regmap_read(dev->regmap,0x20,&temp); -+ if(ret) -+ goto err_regmap_exit; -+ ret = regmap_write(dev->regmap,0x20,0xAA); -+ if(ret) -+ goto err_regmap_exit; -+ ret = regmap_read(dev->regmap,0x20,&temp); -+ if(temp!=0xAA) -+ goto err_regmap_exit; -+ -+ /* create a dvb frontend*/ -+ memcpy(&dev->fe.ops,&mtv23x_ops,sizeof(struct dvb_frontend_ops)); -+ dev->fe.demodulator_priv = client; -+ *cfg->fe = &dev->fe; -+ i2c_set_clientdata(client,dev); -+ -+ dev_info(&client->dev, "RAONTECH MTV23X successfully identified\n"); -+ -+ return 0; -+ -+err_regmap_exit: -+ regmap_exit(dev->regmap); -+err_kfree: -+ kfree(dev); -+err: -+ dev_dbg(&client->dev,"failed = %d\n",ret); -+ return ret; -+} -+static int mtv23x_remove(struct i2c_client*client) -+{ -+ struct mtv23x_dev*dev = i2c_get_clientdata(client); -+ -+ regmap_exit(dev->regmap); -+ kfree(dev); -+ -+ return 0; -+} -+ -+static const struct i2c_device_id mtv23x_id_table[] ={ -+ {"mtv23x",0}, -+ {} -+}; -+ -+MODULE_DEVICE_TABLE(i2c,mtv23x_id_table); -+ -+static struct i2c_driver mtv23x_driver = { -+ -+ .driver = { -+ .name = "mtv23x", -+ }, -+ .probe = mtv23x_probe, -+ .remove = mtv23x_remove, -+ .id_table = mtv23x_id_table, -+ -+}; -+ -+module_i2c_driver(mtv23x_driver); -+ -+ -+MODULE_AUTHOR("Davin "); -+MODULE_DESCRIPTION(" ISDB-T Demodulator driver"); -+MODULE_LICENSE("GPL"); -+ -diff --git a/drivers/media/dvb-frontends/mtv23x.h b/drivers/media/dvb-frontends/mtv23x.h -new file mode 100644 -index 0000000..cc52ca4 ---- /dev/null -+++ b/drivers/media/dvb-frontends/mtv23x.h -@@ -0,0 +1,24 @@ -+#ifndef MTV23X_H -+#define MTV23X_H -+#include -+ -+ -+/*TS mode*/ -+//#define RTV_TSIF_FORMAT_0 /* Serial: EN_high, CLK_rising */ -+//#define RTV_TSIF_FORMAT_1 /* Serial: EN_high, CLK_falling */ // -+//#define RTV_TSIF_FORMAT_2 /* Serial: EN_low, CLK_rising */ -+//#define RTV_TSIF_FORMAT_3 /* Serial: EN_low, CLK_falling */ -+//#define RTV_TSIF_FORMAT_4 /* Serial: EN_high, CLK_rising + 1CLK add */ -+//#define RTV_TSIF_FORMAT_5 /* Serial: EN_high, CLK_falling + 1CLK add */ -+//#define RTV_TSIF_FORMAT_6 /* Parallel: EN_high, CLK_rising */ -+//#define RTV_TSIF_FORMAT_7 /* Parallel: EN_high, CLK_falling */ -+ -+struct mtv23x_config{ -+ int ts_mode; // 0:serial 1:parallel -+ int clk_freq; //32000khz , 19200khz -+ u16 i2c_wr_max; -+ -+ struct dvb_frontend **fe; -+}; -+ -+#endif -diff --git a/drivers/media/dvb-frontends/mtv23x_priv.h b/drivers/media/dvb-frontends/mtv23x_priv.h -new file mode 100644 -index 0000000..ae62737 ---- /dev/null -+++ b/drivers/media/dvb-frontends/mtv23x_priv.h -@@ -0,0 +1,95 @@ -+#ifndef MTV23X_PRIV_H -+#define MTV23X_PRIV_H -+ -+#include "dvb_frontend.h" -+#include "mtv23x.h" -+#include -+ -+/* Do not modify the order and value! */ -+enum E_RTV_SERVICE_TYPE { -+ RTV_SERVICE_INVALID = -1, -+ RTV_SERVICE_UHF_ISDBT_1seg = 0, /* ISDB-T 1seg */ -+ RTV_SERVICE_UHF_ISDBT_13seg = 1, /* ISDB-T fullseg */ -+ RTV_SERVICE_VHF_ISDBTmm_1seg = 2, /* ISDB-Tmm 1seg */ -+ RTV_SERVICE_VHF_ISDBTmm_13seg = 3, /* ISDB-Tmm 13seg */ -+ RTV_SERVICE_VHF_ISDBTsb_1seg = 4, /* ISDB-Tsb 1seg */ -+ RTV_SERVICE_VHF_ISDBTsb_3seg = 5, /* ISDB-Tsb 3seg */ -+ RTV_SERVICE_DVBT = 6, /* DVB-T */ -+ MAX_NUM_RTV_SERVICE -+}; -+ -+ -+struct mtv23x_dev { -+ struct i2c_client *client; -+ struct regmap *regmap; -+ struct dvb_frontend fe; -+ u16 i2c_wr_max; -+ -+ int ts_mode; -+ int clk_freq;//u:KHZ -+ -+ bool rtv_1seglpmode; -+ -+ enum E_RTV_SERVICE_TYPE svc_type; -+}; -+ -+#define TOP_PAGE 0x00 -+#define HOST_PAGE 0x00 -+#define OFDM_PAGE 0x01 -+#define SHAD_PAGE 0x02 -+#define FEC_PAGE 0x03 -+#define DATA_PAGE 0x04 -+#define FEC2_PAGE 0x06 -+#define LPOFDM_PAGE 0x07 -+#define SPI_CTRL_PAGE 0x0E -+#define RF_PAGE 0x0F -+ -+#define MAP_SEL_REG 0x03 -+ -+enum E_RTV_BANDWIDTH_TYPE { -+ RTV_BW_MODE_5MHZ = 0, /* DVB_T */ -+ RTV_BW_MODE_6MHZ, /* DVB_T, FULLSEG, ISDB-Tmm */ -+ RTV_BW_MODE_7MHZ, /* DVB_T, FULLSEG */ -+ RTV_BW_MODE_8MHZ, /* DVB_T, FULLSEG */ -+ RTV_BW_MODE_430KHZ, /* 1SEG at 6MHz BW */ -+ RTV_BW_MODE_500KHZ, /* 1SEG at 7MHz BW */ -+ RTV_BW_MODE_571KHZ, /* 1SEG at 8MHz BW */ -+ RTV_BW_MODE_857KHZ, /* DAB */ -+ RTV_BW_MODE_1290KHZ, /* 3SEG */ -+ MAX_NUM_RTV_BW_MODE_TYPE -+}; -+ -+ -+ -+struct RTV_REG_INIT_INFO { -+ u8 bReg; -+ u8 bVal; -+}; -+ -+struct RTV_ADC_CFG_INFO { -+ u8 bData2A; -+ u8 bData6E; -+ u8 bData70; -+ u8 bData71; -+ u8 bData75; -+ u32 dwTNCO; -+ u32 dwPNCO; -+ u32 dwCFREQGAIN; -+ u16 dwGAIN; -+}; -+ -+#define RTV_ISDBT_OFDM_LOCK_MASK 0x1 -+#define RTV_ISDBT_TMCC_LOCK_MASK 0x2 -+#define RTV_ISDBT_CHANNEL_LOCK_OK \ -+ (RTV_ISDBT_OFDM_LOCK_MASK|RTV_ISDBT_TMCC_LOCK_MASK) -+ -+ -+#define RSSI_UINT(val) (s32)((val)*10) -+ -+#define RSSI_RFAGC_VAL(rfagc, coeffi)\ -+ ((rfagc) * RSSI_UINT(coeffi)) -+ -+#define RSSI_GVBB_VAL(gvbb, coeffi)\ -+ ((gvbb) * RSSI_UINT(coeffi)) -+ -+#endif -diff --git a/drivers/media/dvb-frontends/mxl5xx.c b/drivers/media/dvb-frontends/mxl5xx.c -new file mode 100644 -index 0000000..cb6eb22 ---- /dev/null -+++ b/drivers/media/dvb-frontends/mxl5xx.c -@@ -0,0 +1,1594 @@ -+/* -+ * Driver for the Maxlinear MX58x family of tuners/demods -+ * -+ * Copyright (C) 2014-2015 Ralph Metzler -+ * Marcus Metzler -+ * developed for Digital Devices GmbH -+ * -+ * based on code: -+ * Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved -+ * which was released under GPL V2 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2, as published by the Free Software Foundation. -+ * -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dvb_frontend.h" -+#include "mxl5xx.h" -+#include "mxl5xx_regs.h" -+#include "mxl5xx_defs.h" -+ -+ -+#define BYTE0(v) ((v >> 0) & 0xff) -+#define BYTE1(v) ((v >> 8) & 0xff) -+#define BYTE2(v) ((v >> 16) & 0xff) -+#define BYTE3(v) ((v >> 24) & 0xff) -+ -+#define MXL5XX_DEFAULT_FIRMWARE "dvb-fe-mxl5xx.fw" -+ -+static int mode = 0; -+module_param(mode, int, 0444); -+MODULE_PARM_DESC(mode, -+ "Multi-switch mode: 0=quattro/quad 1=normal direct connection"); -+ -+LIST_HEAD(mxllist); -+ -+struct mxl_base { -+ struct list_head mxllist; -+ -+ u8 adr; -+ struct i2c_adapter *i2c; -+ u32 count; -+ u32 type; -+ u32 chipversion; -+ u32 clock; -+ -+ struct mutex i2c_lock; -+ struct mutex status_lock; -+ u8 buf[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; -+ -+ u32 cmd_size; -+ u8 cmd_data[MAX_CMD_DATA]; -+ -+ struct mxl5xx_cfg *cfg; -+}; -+ -+struct mxl { -+ struct mxl_base *base; -+ struct dvb_frontend fe; -+ u32 demod; -+ u32 rf_in; -+ bool diseqcsign; // -+ MXL_HYDRA_DISEQC_TX_MSG_T diseqcMsg; -+}; -+ -+static void convert_endian(u8 flag, u32 size, u8 *d) -+{ -+ u32 i; -+ -+ if (!flag) -+ return; -+ for (i = 0; i < (size & ~3); i += 4) { -+ d[i + 0] ^= d[i + 3]; -+ d[i + 3] ^= d[i + 0]; -+ d[i + 0] ^= d[i + 3]; -+ -+ d[i + 1] ^= d[i + 2]; -+ d[i + 2] ^= d[i + 1]; -+ d[i + 1] ^= d[i + 2]; -+ } -+} -+ -+static int i2c_write(struct i2c_adapter *adap, u8 adr, -+ u8 *data, u32 len) -+{ -+ struct i2c_msg msg = {.addr = adr, .flags = 0, -+ .buf = data, .len = len}; -+ -+ return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; -+} -+ -+static int i2c_read(struct i2c_adapter *adap, u8 adr, -+ u8 *data, u32 len) -+{ -+ struct i2c_msg msg = {.addr = adr, .flags = I2C_M_RD, -+ .buf = data, .len = len}; -+ -+ return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; -+} -+ -+static int i2cread(struct mxl *state, u8 *data, int len) -+{ -+ return i2c_read(state->base->i2c, state->base->adr, data, len); -+} -+ -+static int i2cwrite(struct mxl *state, u8 *data, int len) -+{ -+ return i2c_write(state->base->i2c, state->base->adr, data, len); -+} -+ -+static int send_command(struct mxl *state, u32 size, u8 *buf) -+{ -+ int stat; -+ -+ mutex_lock(&state->base->i2c_lock); -+ stat = i2cwrite(state, buf, size); -+ mutex_unlock(&state->base->i2c_lock); -+ return stat; -+} -+ -+static int write_register(struct mxl *state, u32 reg, u32 val) -+{ -+ int stat; -+ u8 data[MXL_HYDRA_REG_WRITE_LEN] = { -+ MXL_HYDRA_PLID_REG_WRITE, 0x08, -+ BYTE0(reg), BYTE1(reg), BYTE2(reg), BYTE3(reg), -+ BYTE0(val), BYTE1(val), BYTE2(val), BYTE3(val), -+ }; -+ mutex_lock(&state->base->i2c_lock); -+ stat = i2cwrite(state, data, sizeof(data)); -+ mutex_unlock(&state->base->i2c_lock); -+ if (stat) -+ pr_err("i2c write error\n"); -+ return stat; -+} -+ -+static int write_register_block(struct mxl *state, u32 reg, u32 size, u8 *data) -+{ -+ int stat; -+ u8 *buf = state->base->buf; -+ -+ mutex_lock(&state->base->i2c_lock); -+ -+ buf[0] = MXL_HYDRA_PLID_REG_WRITE; -+ buf[1] = size + 4; -+ buf[2] = GET_BYTE(reg, 0); -+ buf[3] = GET_BYTE(reg, 1); -+ buf[4] = GET_BYTE(reg, 2); -+ buf[5] = GET_BYTE(reg, 3); -+ memcpy(&buf[6], data, size); -+ -+ convert_endian(MXL_ENABLE_BIG_ENDIAN, size, &buf[6]); -+ stat = i2cwrite(state, buf, -+ MXL_HYDRA_I2C_HDR_SIZE + -+ MXL_HYDRA_REG_SIZE_IN_BYTES + size); -+ mutex_unlock(&state->base->i2c_lock); -+ return stat; -+} -+ -+static int write_firmware_block(struct mxl *state, -+ u32 reg, u32 size, u8 *regDataPtr) -+{ -+ int stat; -+ u8 *buf = state->base->buf; -+ -+ mutex_lock(&state->base->i2c_lock); -+ buf[0] = MXL_HYDRA_PLID_REG_WRITE; -+ buf[1] = size + 4; -+ buf[2] = GET_BYTE(reg, 0); -+ buf[3] = GET_BYTE(reg, 1); -+ buf[4] = GET_BYTE(reg, 2); -+ buf[5] = GET_BYTE(reg, 3); -+ memcpy(&buf[6], regDataPtr, size); -+ stat = i2cwrite(state, buf, -+ MXL_HYDRA_I2C_HDR_SIZE + -+ MXL_HYDRA_REG_SIZE_IN_BYTES + size); -+ mutex_unlock(&state->base->i2c_lock); -+ if (stat) -+ pr_err("fw block write failed\n"); -+ return stat; -+} -+ -+static int read_register(struct mxl *state, u32 reg, u32 *val) -+{ -+ int stat; -+ u8 data[MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE] = { -+ MXL_HYDRA_PLID_REG_READ, 0x04, -+ GET_BYTE(reg, 0), GET_BYTE(reg, 1), -+ GET_BYTE(reg, 2), GET_BYTE(reg, 3), -+ }; -+ -+ mutex_lock(&state->base->i2c_lock); -+ stat = i2cwrite(state, data, -+ MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE); -+ if (stat) -+ pr_err("i2c read error 1\n"); -+ if (!stat) -+ stat = i2cread(state, (u8 *) val, MXL_HYDRA_REG_SIZE_IN_BYTES); -+ mutex_unlock(&state->base->i2c_lock); -+ le32_to_cpus(val); -+ if (stat) -+ pr_err("i2c read error 2\n"); -+ return stat; -+} -+ -+static int read_register_block(struct mxl *state, u32 reg, u32 size, u8 *data) -+{ -+ int stat; -+ u8 *buf = state->base->buf; -+ -+ mutex_lock(&state->base->i2c_lock); -+ -+ buf[0] = MXL_HYDRA_PLID_REG_READ; -+ buf[1] = size + 4; -+ buf[2] = GET_BYTE(reg, 0); -+ buf[3] = GET_BYTE(reg, 1); -+ buf[4] = GET_BYTE(reg, 2); -+ buf[5] = GET_BYTE(reg, 3); -+ stat = i2cwrite(state, buf, -+ MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES); -+ if (!stat) { -+ stat = i2cread(state, data, size); -+ convert_endian(MXL_ENABLE_BIG_ENDIAN, size, data); -+ } -+ mutex_unlock(&state->base->i2c_lock); -+ return stat; -+} -+ -+static int read_by_mnemonic(struct mxl *state, -+ u32 reg, u8 lsbloc, u8 numofbits, u32 *val) -+{ -+ u32 data = 0, mask = 0; -+ int stat; -+ -+ stat = read_register(state, reg, &data); -+ if (stat) -+ return stat; -+ mask = MXL_GET_REG_MASK_32(lsbloc, numofbits); -+ data &= mask; -+ data >>= lsbloc; -+ *val = data; -+ return 0; -+} -+ -+ -+static int update_by_mnemonic(struct mxl *state, -+ u32 reg, u8 lsbloc, u8 numofbits, u32 val) -+{ -+ u32 data, mask; -+ int stat; -+ -+ stat = read_register(state, reg, &data); -+ if (stat) -+ return stat; -+ mask = MXL_GET_REG_MASK_32(lsbloc, numofbits); -+ data = (data & ~mask) | ((val << lsbloc) & mask); -+ stat = write_register(state, reg, data); -+ return stat; -+} -+ -+static void extract_from_mnemonic(u32 regAddr, u8 lsbPos, u8 width, -+ u32 *toAddr, u8 *toLsbPos, u8 *toWidth) -+{ -+ if (toAddr) -+ *toAddr = regAddr; -+ if (toLsbPos) -+ *toLsbPos = lsbPos; -+ if (toWidth) -+ *toWidth = width; -+} -+ -+static int firmware_is_alive(struct mxl *state) -+{ -+ u32 hb0, hb1; -+ -+ if (read_register(state, HYDRA_HEAR_BEAT, &hb0)) -+ return 0; -+ msleep(20); -+ if (read_register(state, HYDRA_HEAR_BEAT, &hb1)) -+ return 0; -+ if (hb1 == hb0) -+ return 0; -+ return 1; -+} -+ -+static int init(struct dvb_frontend *fe) -+{ -+ return 0; -+} -+ -+static void release(struct dvb_frontend *fe) -+{ -+ struct mxl *state = fe->demodulator_priv; -+ -+ state->base->count--; -+ if (state->base->count == 0) { -+ list_del(&state->base->mxllist); -+ kfree(state->base); -+ } -+ kfree(state); -+} -+ -+static int get_algo(struct dvb_frontend *fe) -+{ -+ return DVBFE_ALGO_HW; -+} -+ -+static int CfgDemodAbortTune(struct mxl *state) -+{ -+ MXL_HYDRA_DEMOD_ABORT_TUNE_T abortTuneCmd; -+ u8 cmdSize = sizeof(abortTuneCmd); -+ u8 cmdBuff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; -+ -+ abortTuneCmd.demodId = state->demod; -+ BUILD_HYDRA_CMD(MXL_HYDRA_ABORT_TUNE_CMD, MXL_CMD_WRITE, cmdSize, &abortTuneCmd, cmdBuff); -+ return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]); -+} -+ -+static int send_master_cmd(struct dvb_frontend *fe, -+ struct dvb_diseqc_master_cmd *cmd) -+{ -+ struct mxl *state = fe->demodulator_priv; -+ MXL_HYDRA_DISEQC_TX_MSG_T diseqcMsgPtr; -+ u8 cmdSize = sizeof(MXL_HYDRA_DISEQC_TX_MSG_T); -+ u8 cmdBuff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; -+ int i = 0,ret = 0; -+ -+ -+ diseqcMsgPtr.diseqcId = state->rf_in; -+ diseqcMsgPtr.nbyte = cmd->msg_len; -+ diseqcMsgPtr.toneBurst = MXL_HYDRA_DISEQC_TONE_NONE; -+ -+ for( i =0;i < cmd->msg_len;i++) -+ diseqcMsgPtr.bufMsg[i] = cmd->msg[i]; -+ -+ if(!mode){ -+ state->diseqcsign= true; -+ memcpy(&state->diseqcMsg,&diseqcMsgPtr,sizeof(MXL_HYDRA_DISEQC_TX_MSG_T)); -+ return 0; -+ -+ } -+ -+ BUILD_HYDRA_CMD(MXL_HYDRA_DISEQC_MSG_CMD, MXL_CMD_WRITE, cmdSize, &diseqcMsgPtr, cmdBuff); -+ mutex_lock(&state->base->status_lock); -+ ret=send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]); -+ mutex_unlock(&state->base->status_lock); -+ -+ return ret; -+} -+ -+static int send_burst(struct dvb_frontend *fe, -+ enum fe_sec_mini_cmd burst) -+{ -+ struct mxl *state = fe->demodulator_priv; -+ MXL_HYDRA_DISEQC_TX_MSG_T diseqcMsgPtr; -+ u8 cmdSize = sizeof(MXL_HYDRA_DISEQC_TX_MSG_T); -+ u8 cmdBuff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; -+ int i = 0,ret = 0; -+ -+ -+ diseqcMsgPtr.diseqcId = state->rf_in; -+ diseqcMsgPtr.nbyte = 0; -+ diseqcMsgPtr.toneBurst = burst == SEC_MINI_B ? MXL_HYDRA_DISEQC_TONE_SB : MXL_HYDRA_DISEQC_TONE_SA; -+ -+ if(!mode){ -+ state->diseqcsign= true; -+ memcpy(&state->diseqcMsg,&diseqcMsgPtr,sizeof(MXL_HYDRA_DISEQC_TX_MSG_T)); -+ return 0; -+ -+ } -+ -+ BUILD_HYDRA_CMD(MXL_HYDRA_DISEQC_MSG_CMD, MXL_CMD_WRITE, cmdSize, &diseqcMsgPtr, cmdBuff); -+ mutex_lock(&state->base->status_lock); -+ ret=send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]); -+ mutex_unlock(&state->base->status_lock); -+ -+ return ret; -+} -+ -+static void senddiseqcAbortTune(struct dvb_frontend *fe) -+{ -+ struct mxl *state = fe->demodulator_priv; -+ u8 cmdSize = sizeof(MXL_HYDRA_DISEQC_TX_MSG_T); -+ u8 cmdBuff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; -+ -+ if(state->diseqcsign){ -+ state->diseqcMsg.diseqcId = state->rf_in; -+ state->diseqcMsg.bufMsg[0] = 0xe0; -+ BUILD_HYDRA_CMD(MXL_HYDRA_DISEQC_MSG_CMD, MXL_CMD_WRITE, cmdSize, &state->diseqcMsg, cmdBuff); -+ mutex_lock(&state->base->status_lock); -+ send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]); -+ mutex_unlock(&state->base->status_lock); -+ -+ state->diseqcsign = false; -+ } -+ msleep(100); -+} -+ -+static int set_parameters(struct dvb_frontend *fe) -+{ -+ struct mxl *state = fe->demodulator_priv; -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ int ret; -+ -+ MXL_HYDRA_DEMOD_PARAM_T demodChanCfg; -+ u8 cmdSize = sizeof(demodChanCfg); -+ u8 cmdBuff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; -+ //MXL_HYDRA_DEMOD_ID_E demodId = state->demod; -+#if 0 -+ MXL_REG_FIELD_T xpt_enable_dss_input[MXL_HYDRA_DEMOD_MAX] = { -+ {XPT_INP_MODE_DSS0}, {XPT_INP_MODE_DSS1}, -+ {XPT_INP_MODE_DSS2}, {XPT_INP_MODE_DSS3}, -+ {XPT_INP_MODE_DSS4}, {XPT_INP_MODE_DSS5}, -+ {XPT_INP_MODE_DSS6}, {XPT_INP_MODE_DSS7} }; -+#endif -+ -+ if (p->frequency < 950000 || p->frequency > 2150000) -+ return -EINVAL; -+ if (p->symbol_rate < 1000000 || p->symbol_rate > 45000000) -+ return -EINVAL; -+ -+ if(!mode) -+ senddiseqcAbortTune(fe); -+ -+ //CfgDemodAbortTune(state); -+ -+ switch (p->delivery_system) { -+ case SYS_DSS: -+ demodChanCfg.standard = MXL_HYDRA_DSS; -+ break; -+ case SYS_DVBS: -+ demodChanCfg.standard = MXL_HYDRA_DVBS; -+ demodChanCfg.rollOff = MXL_HYDRA_ROLLOFF_AUTO; -+ demodChanCfg.modulationScheme = MXL_HYDRA_MOD_QPSK; -+ break; -+ case SYS_DVBS2: -+ demodChanCfg.standard = MXL_HYDRA_DVBS2; -+ demodChanCfg.rollOff = MXL_HYDRA_ROLLOFF_AUTO; -+ demodChanCfg.modulationScheme = MXL_HYDRA_MOD_AUTO; -+ demodChanCfg.pilots = MXL_HYDRA_PILOTS_AUTO; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ demodChanCfg.tunerIndex = state->rf_in; -+ demodChanCfg.demodIndex = state->demod; -+ demodChanCfg.frequencyInHz = p->frequency * 1000; -+ demodChanCfg.symbolRateInHz = p->symbol_rate; -+ demodChanCfg.maxCarrierOffsetInMHz = 10; -+ demodChanCfg.spectrumInversion = MXL_HYDRA_SPECTRUM_AUTO; -+ demodChanCfg.fecCodeRate = MXL_HYDRA_FEC_AUTO; -+ -+ //printk("std %u freq %u\n", demodChanCfg.standard, demodChanCfg.symbolRateInHz); -+ -+#if 0 -+ if (p->delivery_system == SYS_DSS) -+ update_by_mnemonic(state, -+ xpt_enable_dss_input[demodId].regAddr, -+ xpt_enable_dss_input[demodId].lsbPos, -+ xpt_enable_dss_input[demodId].numOfBits, -+ MXL_TRUE); -+ else -+ update_by_mnemonic(state, -+ xpt_enable_dss_input[demodId].regAddr, -+ xpt_enable_dss_input[demodId].lsbPos, -+ xpt_enable_dss_input[demodId].numOfBits, -+ MXL_FALSE); -+#endif -+ -+ BUILD_HYDRA_CMD(MXL_HYDRA_DEMOD_SET_PARAM_CMD, MXL_CMD_WRITE, -+ cmdSize, &demodChanCfg, cmdBuff); -+ -+ mutex_lock(&state->base->status_lock); -+ ret = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]); -+ mutex_unlock(&state->base->status_lock); -+ -+ return ret; -+} -+ -+static int read_status(struct dvb_frontend *fe, enum fe_status *status) -+{ -+ struct mxl *state = fe->demodulator_priv; -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ int stat; -+ u32 reg[8]; -+ -+ -+ *status = FE_HAS_SIGNAL; -+ -+ /* Read RF level */ -+ mutex_lock(&state->base->status_lock); -+ HYDRA_DEMOD_STATUS_LOCK(state, state->demod); -+ stat = read_register(state, (HYDRA_DMD_STATUS_INPUT_POWER_ADDR + -+ HYDRA_DMD_STATUS_OFFSET(state->demod)), -+ reg); -+ HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); -+ mutex_unlock(&state->base->status_lock); -+ -+ p->strength.len = 1; -+ p->strength.stat[0].scale = FE_SCALE_DECIBEL; -+ p->strength.stat[0].svalue = (s16)reg[0] * 10; -+ -+ /* Read demod lock status */ -+ mutex_lock(&state->base->status_lock); -+ HYDRA_DEMOD_STATUS_LOCK(state, state->demod); -+ stat = read_register(state, (HYDRA_DMD_LOCK_STATUS_ADDR_OFFSET + -+ HYDRA_DMD_STATUS_OFFSET(state->demod)), -+ reg); -+ HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); -+ mutex_unlock(&state->base->status_lock); -+ -+ if (reg[0] == 1) -+ *status |= FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; -+ else -+ { -+ p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ return 0; -+ } -+ -+ /* Read SNR */ -+ mutex_lock(&state->base->status_lock); -+ HYDRA_DEMOD_STATUS_LOCK(state, state->demod); -+ stat = read_register(state, (HYDRA_DMD_SNR_ADDR_OFFSET + -+ HYDRA_DMD_STATUS_OFFSET(state->demod)), -+ reg); -+ HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); -+ mutex_unlock(&state->base->status_lock); -+ -+ p->cnr.len = 1; -+ p->cnr.stat[0].scale = FE_SCALE_DECIBEL; -+ p->cnr.stat[0].svalue = (s16)reg[0] * 10; -+ -+ /* Read BER */ -+ mutex_lock(&state->base->status_lock); -+ HYDRA_DEMOD_STATUS_LOCK(state, state->demod); -+ -+ stat = read_register_block(state, -+ (HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET + -+ HYDRA_DMD_STATUS_OFFSET(state->demod)), -+ (4 * sizeof(u32)), -+ (u8 *) reg); -+ HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); -+ -+ switch (p->delivery_system) { -+ case SYS_DSS: -+ case SYS_DVBS: -+ p->pre_bit_error.len = 1; -+ p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; -+ p->pre_bit_error.stat[0].uvalue = reg[2]; -+ p->pre_bit_count.len = 1; -+ p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; -+ p->pre_bit_count.stat[0].uvalue = reg[3]; -+ /* pr_warn("mxl5xx: pre_bit_error=%u pre_bit_count=%u\n", p->pre_bit_error.stat[0].uvalue, p->pre_bit_count.stat[0].uvalue); */ -+ break; -+ default: -+ break; -+ } -+ -+ stat = read_register_block(state, -+ (HYDRA_DMD_DVBS2_CRC_ERRORS_ADDR_OFFSET + -+ HYDRA_DMD_STATUS_OFFSET(state->demod)), -+ (7 * sizeof(u32)), -+ (u8 *) reg); -+ -+ mutex_unlock(&state->base->status_lock); -+ -+ switch (p->delivery_system) { -+ case SYS_DSS: -+ case SYS_DVBS: -+ p->post_bit_error.len = 1; -+ p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; -+ p->post_bit_error.stat[0].uvalue = reg[5]; -+ p->post_bit_count.len = 1; -+ p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; -+ p->post_bit_count.stat[0].uvalue = reg[6]; -+ break; -+ case SYS_DVBS2: -+ p->post_bit_error.len = 1; -+ p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; -+ p->post_bit_error.stat[0].uvalue = reg[1]; -+ p->post_bit_count.len = 1; -+ p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; -+ p->post_bit_count.stat[0].uvalue = reg[2]; -+ break; -+ default: -+ break; -+ } -+ /* pr_warn("mxl5xx: post_bit_error=%u post_bit_count=%u\n", p->post_bit_error.stat[0].uvalue, p->post_bit_count.stat[0].uvalue); */ -+ -+ return 0; -+} -+ -+static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) -+{ -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ -+ *strength = p->strength.stat[0].scale == FE_SCALE_DECIBEL ? ((100000 + (s32)p->strength.stat[0].svalue) / 1000) * 656 : 0; -+ -+ return 0; -+ -+} -+ -+static int read_snr(struct dvb_frontend *fe, u16 *snr) -+{ -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ -+ if (p->cnr.stat[0].scale == FE_SCALE_DECIBEL) { -+ *snr = (s32)p->cnr.stat[0].svalue / 100; -+ if (*snr > 200) -+ *snr = 0xffff; -+ else -+ *snr *= 328; -+ } else *snr = 0; -+ -+ return 0; -+} -+ -+static int read_ber(struct dvb_frontend *fe, u32 *ber) -+{ -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ -+ if ( p->post_bit_error.stat[0].scale == FE_SCALE_COUNTER && -+ p->post_bit_count.stat[0].scale == FE_SCALE_COUNTER ) -+ *ber = (u32)p->post_bit_count.stat[0].uvalue ? (u32)p->post_bit_error.stat[0].uvalue / (u32)p->post_bit_count.stat[0].uvalue : 0; -+ -+ return 0; -+} -+ -+static int read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -+{ -+ *ucblocks = 0; -+ return 0; -+} -+ -+static int tune(struct dvb_frontend *fe, bool re_tune, -+ unsigned int mode_flags, -+ unsigned int *delay, enum fe_status *status) -+{ -+ //struct mxl *state = fe->demodulator_priv; -+ int r = 0; -+ -+ *delay = HZ / 2; -+ if (re_tune) { -+ r = set_parameters(fe); -+ if (r) -+ return r; -+ } -+ -+ r = read_status(fe, status); -+ return r; -+} -+ -+static int sleep(struct dvb_frontend *fe) -+{ -+ return 0; -+} -+ -+static enum fe_code_rate conv_fec(MXL_HYDRA_FEC_E fec) -+{ -+ enum fe_code_rate fec2fec[11] = { -+ FEC_NONE, FEC_1_2, FEC_3_5, FEC_2_3, -+ FEC_3_4, FEC_4_5, FEC_5_6, FEC_6_7, -+ FEC_7_8, FEC_8_9, FEC_9_10 -+ }; -+ -+ if (fec > MXL_HYDRA_FEC_9_10) -+ return FEC_NONE; -+ return fec2fec[fec]; -+} -+ -+static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties *p) -+{ -+ struct mxl *state = fe->demodulator_priv; -+ u32 regData[MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE]; -+ u32 freq; -+ int stat; -+ -+ mutex_lock(&state->base->status_lock); -+ HYDRA_DEMOD_STATUS_LOCK(state, state->demod); -+ stat = read_register_block(state, -+ (HYDRA_DMD_STANDARD_ADDR_OFFSET + -+ HYDRA_DMD_STATUS_OFFSET(state->demod)), -+ (MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE * 4), // 25 * 4 bytes -+ (u8 *) ®Data[0]); -+ // read demod channel parameters -+ stat = read_register_block(state, -+ (HYDRA_DMD_STATUS_CENTER_FREQ_IN_KHZ_ADDR + -+ HYDRA_DMD_STATUS_OFFSET(state->demod)), -+ (4), // 4 bytes -+ (u8 *) &freq); -+ HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); -+ mutex_unlock(&state->base->status_lock); -+ -+#if 0 -+ pr_warn("mxl5xx: freq=%u delsys=%u srate=%u\n", freq * 1000, -+ regData[DMD_STANDARD_ADDR], regData[DMD_SYMBOL_RATE_ADDR]); -+#endif -+ -+ p->symbol_rate = regData[DMD_SYMBOL_RATE_ADDR]; -+ p->frequency = freq; -+ //p->delivery_system = (MXL_HYDRA_BCAST_STD_E )regData[DMD_STANDARD_ADDR]; -+ //p->inversion = (MXL_HYDRA_SPECTRUM_E )regData[DMD_SPECTRUM_INVERSION_ADDR]; -+ //freqSearchRangeKHz = (regData[DMD_FREQ_SEARCH_RANGE_IN_KHZ_ADDR]); -+ -+ p->fec_inner = conv_fec(regData[DMD_FEC_CODE_RATE_ADDR]); -+ switch (p->delivery_system) { -+ case SYS_DSS: -+ break; -+ case SYS_DVBS2: -+ switch ((MXL_HYDRA_PILOTS_E ) regData[DMD_DVBS2_PILOT_ON_OFF_ADDR]) { -+ case MXL_HYDRA_PILOTS_OFF: -+ p->pilot = PILOT_OFF; -+ break; -+ case MXL_HYDRA_PILOTS_ON: -+ p->pilot = PILOT_ON; -+ break; -+ default: -+ break; -+ } -+ case SYS_DVBS: -+ switch ((MXL_HYDRA_MODULATION_E) regData[DMD_MODULATION_SCHEME_ADDR]) { -+ case MXL_HYDRA_MOD_QPSK: -+ p->modulation = QPSK; -+ break; -+ case MXL_HYDRA_MOD_8PSK: -+ p->modulation = PSK_8; -+ break; -+ default: -+ break; -+ } -+ switch ((MXL_HYDRA_ROLLOFF_E) regData[DMD_SPECTRUM_ROLL_OFF_ADDR]) { -+ case MXL_HYDRA_ROLLOFF_0_20: -+ p->rolloff = ROLLOFF_20; -+ break; -+ case MXL_HYDRA_ROLLOFF_0_35: -+ p->rolloff = ROLLOFF_35; -+ break; -+ case MXL_HYDRA_ROLLOFF_0_25: -+ p->rolloff = ROLLOFF_25; -+ break; -+ default: -+ break; -+ } -+ break; -+ default: -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static int set_input_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone, int rf_in) -+{ -+ struct mxl *state = fe->demodulator_priv; -+ u8 buf[14] = { -+ MXL_HYDRA_PLID_CMD_WRITE, -+ 12, 8, -+ MXL_HYDRA_DISEQC_CONT_TONE_CFG, 0, 0, -+ rf_in, 0, 0, 0, -+ (tone == SEC_TONE_ON) ? 1 : 0, 0, 0, 0 -+ }; -+ return send_command(state, sizeof(buf), buf); -+} -+ -+ -+ -+static int set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) -+{ -+ struct mxl *state = fe->demodulator_priv; -+ struct i2c_adapter *i2c = state->base->i2c; -+ struct mxl5xx_cfg *cfg = state->base->cfg; -+ -+ switch (mode) { -+ case 1: -+ cfg->set_voltage(i2c, voltage, state->rf_in); -+ break; -+ case 0: -+ default: -+ if (voltage == SEC_VOLTAGE_18) -+ state->rf_in &= ~2; -+ else -+ state->rf_in |= 2; -+ break; -+ } -+ -+ return 0; //state->base->cfg->set_voltage(fe, voltage, 0); -+} -+ -+ -+static int set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) -+{ -+ struct mxl *state = fe->demodulator_priv; -+ -+ switch (mode) { -+ case 1: -+ set_input_tone(fe, tone, state->rf_in); -+ break; -+ case 0: -+ default: -+ if (tone == SEC_TONE_ON) -+ state->rf_in &= ~1; -+ else -+ state->rf_in |= 1; -+ break; -+ } -+ -+ return 0; -+} -+ -+static struct dvb_frontend_ops mxl_ops = { -+ .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, -+ .info = { -+ .name = "MXL5XX", -+ .frequency_min = 950000, -+ .frequency_max = 2150000, -+ .frequency_stepsize = 0, -+ .frequency_tolerance = 0, -+ .symbol_rate_min = 1000000, -+ .symbol_rate_max = 70000000, -+ .caps = FE_CAN_INVERSION_AUTO | -+ FE_CAN_FEC_AUTO | -+ FE_CAN_QPSK | -+ FE_CAN_2G_MODULATION -+ }, -+ .init = init, -+ .release = release, -+ .get_frontend_algo = get_algo, -+ .tune = tune, -+ .read_status = read_status, -+ .sleep = sleep, -+ .read_snr = read_snr, -+ .read_ber = read_ber, -+ .read_signal_strength = read_signal_strength, -+ .read_ucblocks = read_ucblocks, -+ .get_frontend = get_frontend, -+ .diseqc_send_master_cmd = send_master_cmd, -+ .diseqc_send_burst = send_burst, -+ -+ .set_tone = set_tone, -+ .set_voltage = set_voltage, -+}; -+ -+static struct mxl_base *match_base(struct i2c_adapter *i2c, u8 adr) -+{ -+ struct mxl_base *p; -+ -+ list_for_each_entry(p, &mxllist, mxllist) -+ if (p->i2c == i2c && p->adr == adr) -+ return p; -+ return NULL; -+} -+ -+static void cfg_dev_xtal(struct mxl *state, u32 freq, u32 cap, u32 enable) -+{ -+ SET_REG_FIELD_DATA(AFE_REG_D2A_XTAL_EN_CLKOUT_1P8, enable); -+ if (freq == 24000000) -+ write_register(state, HYDRA_CRYSTAL_SETTING, 0); -+ else -+ write_register(state, HYDRA_CRYSTAL_SETTING, 1); -+ -+ write_register(state, HYDRA_CRYSTAL_CAP, cap); -+} -+ -+static u32 get_big_endian(u8 numOfBits, const u8 buf[]) -+{ -+ u32 retValue = 0; -+ -+ switch (numOfBits) { -+ case 24: -+ retValue = (((u32) buf[0]) << 16) | -+ (((u32) buf[1]) << 8) | buf[2]; -+ break; -+ case 32: -+ retValue = (((u32) buf[0]) << 24) | -+ (((u32) buf[1]) << 16) | -+ (((u32) buf[2]) << 8) | buf[3]; -+ break; -+ default: -+ break; -+ } -+ -+ return retValue; -+} -+ -+static void flip_data_in_dword(u32 size, u8 *d) -+{ -+ u32 i; -+ u8 t; -+ -+ for (i = 0; i < size; i += 4) { -+ t = d[i + 3]; d[i + 3] = d[i]; d[i] = t; -+ t = d[i + 2]; d[i + 2] = d[i + 1]; d[i + 1] = t; -+ } -+} -+ -+static int write_fw_segment(struct mxl *state, -+ u32 MemAddr, u32 totalSize, u8 *dataPtr) -+{ -+ int status; -+ u32 dataCount = 0; -+ u32 size = 0; -+ u32 origSize = 0; -+ u8 *wBufPtr = NULL; -+ u32 blockSize = MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH; -+ u8 wMsgBuffer[MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH]; -+ -+ //pr_info("seg %u\n", totalSize); -+ do { -+ size = origSize = (((u32)(dataCount + blockSize)) > totalSize) ? -+ (totalSize - dataCount) : blockSize; -+ wBufPtr = dataPtr; -+ -+ if (origSize & 3) { -+ size = (origSize + 4) & ~3; -+ wBufPtr = &wMsgBuffer[0]; -+ memset((void *)wBufPtr + origSize, -+ 0x00, size - origSize); -+ memcpy((void *)wBufPtr, (void *)dataPtr, origSize); -+ } -+ flip_data_in_dword(size, wBufPtr); -+ status = write_firmware_block(state, MemAddr, size, wBufPtr); -+ if (status) -+ return status; -+ dataCount += size; -+ MemAddr += size; -+ dataPtr += size; -+ } while (dataCount < totalSize); -+ -+ return status; -+} -+ -+static int do_firmware_download(struct mxl *state, -+ u32 mbinBufferSize, -+ u8 *mbinBufferPtr) -+{ -+ int status; -+ u32 index = 0; -+ u32 segLength = 0; -+ u32 segAddress = 0; -+ MBIN_FILE_T *mbinPtr = (MBIN_FILE_T *)mbinBufferPtr; -+ MBIN_SEGMENT_T *segmentPtr; -+ -+ if (mbinPtr->header.id != MBIN_FILE_HEADER_ID) { -+ pr_err("%s: Invalid file header ID (%c)\n", -+ __func__, mbinPtr->header.id); -+ return -EINVAL; -+ } -+ status = write_register(state, FW_DL_SIGN_ADDR, 0); -+ if (status) -+ return status; -+ segmentPtr = (MBIN_SEGMENT_T *) (&mbinPtr->data[0]); -+ for (index = 0; index < mbinPtr->header.numSegments; index++) { -+ if (segmentPtr->header.id != MBIN_SEGMENT_HEADER_ID) { -+ pr_err("%s: Invalid segment header ID (%c)\n", -+ __func__, segmentPtr->header.id); -+ return -EINVAL; -+ } -+ segLength = get_big_endian(24, &(segmentPtr->header.len24[0])); -+ segAddress = get_big_endian(32, &(segmentPtr->header.address[0])); -+ status = -1; -+ if (((segAddress & 0x90760000) != 0x90760000) && -+ ((segAddress & 0x90740000) != 0x90740000)) -+ status = write_fw_segment(state, segAddress, -+ segLength, (u8 *) segmentPtr->data); -+ if (status) -+ return status; -+ segmentPtr = (MBIN_SEGMENT_T *) -+ &(segmentPtr->data[((segLength + 3) / 4) * 4]); -+ } -+ return status; -+} -+ -+static int firmware_download(struct mxl *state, u32 mbinBufferSize, -+ u8 *mbinBufferPtr) -+{ -+ int status; -+ u32 regData = 0; -+ MXL_HYDRA_SKU_COMMAND_T devSkuCfg; -+ u8 cmdSize = sizeof(MXL_HYDRA_SKU_COMMAND_T); -+ u8 cmdBuff[sizeof(MXL_HYDRA_SKU_COMMAND_T) + 6]; -+ -+ /* put CPU into reset */ -+ status = SET_REG_FIELD_DATA(PRCM_PRCM_CPU_SOFT_RST_N, 0); -+ if (status) -+ return status; -+ usleep_range(1000, 2000); -+ -+ /* Reset TX FIFO's, BBAND, XBAR */ -+ status = write_register(state, HYDRA_RESET_TRANSPORT_FIFO_REG, -+ HYDRA_RESET_TRANSPORT_FIFO_DATA); -+ if (status) -+ return status; -+ status = write_register(state, HYDRA_RESET_BBAND_REG, -+ HYDRA_RESET_BBAND_DATA); -+ if (status) -+ return status; -+ status = write_register(state, HYDRA_RESET_XBAR_REG, -+ HYDRA_RESET_XBAR_DATA); -+ if (status) -+ return status; -+ -+ // lja -+ /* Disable clock to Baseband, Wideband, SerDes, Alias ext & Transport modules */ -+ status = write_register(state, HYDRA_MODULES_CLK_2_REG, HYDRA_DISABLE_CLK_2); -+ if (status) -+ return status; -+ //write_register(state, HYDRA_MODULES_CLK_2_REG, 0x0000000b); -+ -+ -+ /* Clear Software & Host interrupt status - (Clear on read) */ -+ status = read_register(state, HYDRA_PRCM_ROOT_CLK_REG, ®Data); -+ if (status) -+ return status; -+ -+ status = do_firmware_download(state, mbinBufferSize, mbinBufferPtr); -+ if (status) -+ return status; -+ -+ if (state->base->type == MXL_HYDRA_DEVICE_568) { -+ msleep(10); -+ -+ // bring XCPU out of reset -+ status = write_register(state, 0x90720000, 1); -+ if (status) -+ return status; -+ msleep(500); -+ -+ // Enable XCPU UART message processing in MCPU -+ status = write_register(state, 0x9076B510, 1); -+ if (status) -+ return status; -+ } else { -+ /* Bring CPU out of reset */ -+ status = SET_REG_FIELD_DATA(PRCM_PRCM_CPU_SOFT_RST_N, 1); -+ if (status) -+ return status; -+ /* Wait until FW boots */ -+ msleep(150); -+ } -+ -+ // lja -+ // Initilize XPT XBAR -+ status = write_register(state, XPT_DMD0_BASEADDR, 0x76543210); -+ if (status) -+ return status; -+ -+ if (!firmware_is_alive(state)) -+ return -1; -+ -+ pr_info("Hydra FW alive\n"); -+ -+ /* sometimes register values are wrong shortly after first heart beats */ -+ msleep(50); -+ -+ devSkuCfg.skuType = state->base->type; -+ BUILD_HYDRA_CMD(MXL_HYDRA_DEV_CFG_SKU_CMD, MXL_CMD_WRITE, -+ cmdSize, &devSkuCfg, cmdBuff); -+ status = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]); -+ if (status) -+ return status; -+ -+ status = GET_REG_FIELD_DATA(PAD_MUX_BOND_OPTION, ®Data); -+ if (status) -+ return status; -+ pr_info("chipID=%08x\n", regData); -+ -+ status = GET_REG_FIELD_DATA(PRCM_AFE_CHIP_MMSK_VER, ®Data); -+ if (status) -+ return status; -+ pr_info("chipVer=%08x\n", regData); -+ -+ status = read_register(state, HYDRA_FIRMWARE_VERSION, ®Data); -+ if (status) -+ return status; -+ pr_info("FWVer=%08x\n", regData); -+ -+ return status; -+} -+ -+static int cfg_ts_pad_mux(struct mxl *state, MXL_BOOL_E enableSerialTS) -+{ -+ int status = 0; -+ u32 padMuxValue = 0; -+ -+ if (enableSerialTS == MXL_TRUE) -+ padMuxValue = 0; -+ else -+ padMuxValue = 3; -+ -+ switch (state->base->type) { -+ case MXL_HYDRA_DEVICE_561: -+ case MXL_HYDRA_DEVICE_581: -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_14_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_15_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_16_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_17_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_18_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_19_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_20_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_21_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_22_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_23_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_24_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_25_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_26_PINMUX_SEL, padMuxValue); -+ break; -+ -+ case MXL_HYDRA_DEVICE_584: -+ default: -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_09_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_10_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_11_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_12_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_13_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_14_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_15_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_16_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_17_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_18_PINMUX_SEL, padMuxValue); -+ status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_19_PINMUX_SEL, padMuxValue); -+ break; -+ } -+ return status; -+} -+ -+static int config_ts(struct mxl *state, MXL_HYDRA_DEMOD_ID_E demodId, MXL_HYDRA_MPEGOUT_PARAM_T *mpegOutParamPtr) -+{ -+ int status = 0; -+ u32 ncoCountMin = 0; -+ u32 clkType = 0; -+ -+ MXL_REG_FIELD_T xpt_sync_polarity[MXL_HYDRA_DEMOD_MAX] = { -+ {XPT_SYNC_POLARITY0}, {XPT_SYNC_POLARITY1}, -+ {XPT_SYNC_POLARITY2}, {XPT_SYNC_POLARITY3}, -+ {XPT_SYNC_POLARITY4}, {XPT_SYNC_POLARITY5}, -+ {XPT_SYNC_POLARITY6}, {XPT_SYNC_POLARITY7} }; -+ MXL_REG_FIELD_T xpt_clock_polarity[MXL_HYDRA_DEMOD_MAX] = { -+ {XPT_CLOCK_POLARITY0}, {XPT_CLOCK_POLARITY1}, -+ {XPT_CLOCK_POLARITY2}, {XPT_CLOCK_POLARITY3}, -+ {XPT_CLOCK_POLARITY4}, {XPT_CLOCK_POLARITY5}, -+ {XPT_CLOCK_POLARITY6}, {XPT_CLOCK_POLARITY7} }; -+ MXL_REG_FIELD_T xpt_valid_polarity[MXL_HYDRA_DEMOD_MAX] = { -+ {XPT_VALID_POLARITY0}, {XPT_VALID_POLARITY1}, -+ {XPT_VALID_POLARITY2}, {XPT_VALID_POLARITY3}, -+ {XPT_VALID_POLARITY4}, {XPT_VALID_POLARITY5}, -+ {XPT_VALID_POLARITY6}, {XPT_VALID_POLARITY7} }; -+ MXL_REG_FIELD_T xpt_ts_clock_phase[MXL_HYDRA_DEMOD_MAX] = { -+ {XPT_TS_CLK_PHASE0}, {XPT_TS_CLK_PHASE1}, -+ {XPT_TS_CLK_PHASE2}, {XPT_TS_CLK_PHASE3}, -+ {XPT_TS_CLK_PHASE4}, {XPT_TS_CLK_PHASE5}, -+ {XPT_TS_CLK_PHASE6}, {XPT_TS_CLK_PHASE7} }; -+ MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = { -+ {XPT_LSB_FIRST0}, {XPT_LSB_FIRST1}, {XPT_LSB_FIRST2}, {XPT_LSB_FIRST3}, -+ {XPT_LSB_FIRST4}, {XPT_LSB_FIRST5}, {XPT_LSB_FIRST6}, {XPT_LSB_FIRST7} }; -+ MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = { -+ {XPT_SYNC_FULL_BYTE0}, {XPT_SYNC_FULL_BYTE1}, -+ {XPT_SYNC_FULL_BYTE2}, {XPT_SYNC_FULL_BYTE3}, -+ {XPT_SYNC_FULL_BYTE4}, {XPT_SYNC_FULL_BYTE5}, -+ {XPT_SYNC_FULL_BYTE6}, {XPT_SYNC_FULL_BYTE7} }; -+ MXL_REG_FIELD_T xpt_enable_output[MXL_HYDRA_DEMOD_MAX] = { -+ {XPT_ENABLE_OUTPUT0}, {XPT_ENABLE_OUTPUT1}, -+ {XPT_ENABLE_OUTPUT2}, {XPT_ENABLE_OUTPUT3}, -+ {XPT_ENABLE_OUTPUT4}, {XPT_ENABLE_OUTPUT5}, -+ {XPT_ENABLE_OUTPUT6}, {XPT_ENABLE_OUTPUT7} }; -+ MXL_REG_FIELD_T xpt_enable_dvb_input[MXL_HYDRA_DEMOD_MAX] = { -+ {XPT_ENABLE_INPUT0}, {XPT_ENABLE_INPUT1}, -+ {XPT_ENABLE_INPUT2}, {XPT_ENABLE_INPUT3}, -+ {XPT_ENABLE_INPUT4}, {XPT_ENABLE_INPUT5}, -+ {XPT_ENABLE_INPUT6}, {XPT_ENABLE_INPUT7} }; -+ MXL_REG_FIELD_T xpt_err_replace_sync[MXL_HYDRA_DEMOD_MAX] = { -+ {XPT_ERROR_REPLACE_SYNC0}, {XPT_ERROR_REPLACE_SYNC1}, -+ {XPT_ERROR_REPLACE_SYNC2}, {XPT_ERROR_REPLACE_SYNC3}, -+ {XPT_ERROR_REPLACE_SYNC4}, {XPT_ERROR_REPLACE_SYNC5}, -+ {XPT_ERROR_REPLACE_SYNC6}, {XPT_ERROR_REPLACE_SYNC7} }; -+ MXL_REG_FIELD_T xpt_err_replace_valid[MXL_HYDRA_DEMOD_MAX] = { -+ {XPT_ERROR_REPLACE_VALID0}, {XPT_ERROR_REPLACE_VALID1}, -+ {XPT_ERROR_REPLACE_VALID2}, {XPT_ERROR_REPLACE_VALID3}, -+ {XPT_ERROR_REPLACE_VALID4}, {XPT_ERROR_REPLACE_VALID5}, -+ {XPT_ERROR_REPLACE_VALID6}, {XPT_ERROR_REPLACE_VALID7} }; -+ MXL_REG_FIELD_T xpt_continuous_clock[MXL_HYDRA_DEMOD_MAX] = { -+ {XPT_TS_CLK_OUT_EN0}, {XPT_TS_CLK_OUT_EN1}, -+ {XPT_TS_CLK_OUT_EN2}, {XPT_TS_CLK_OUT_EN3}, -+ {XPT_TS_CLK_OUT_EN4}, {XPT_TS_CLK_OUT_EN5}, -+ {XPT_TS_CLK_OUT_EN6}, {XPT_TS_CLK_OUT_EN7} }; -+ MXL_REG_FIELD_T mxl561_xpt_ts_sync[MXL_HYDRA_DEMOD_ID_6] = { -+ {PAD_MUX_DIGIO_25_PINMUX_SEL}, {PAD_MUX_DIGIO_20_PINMUX_SEL}, -+ {PAD_MUX_DIGIO_17_PINMUX_SEL}, {PAD_MUX_DIGIO_11_PINMUX_SEL}, -+ {PAD_MUX_DIGIO_08_PINMUX_SEL}, {PAD_MUX_DIGIO_03_PINMUX_SEL} }; -+ MXL_REG_FIELD_T mxl561_xpt_ts_valid[MXL_HYDRA_DEMOD_ID_6] = { -+ {PAD_MUX_DIGIO_26_PINMUX_SEL}, {PAD_MUX_DIGIO_19_PINMUX_SEL}, -+ {PAD_MUX_DIGIO_18_PINMUX_SEL}, {PAD_MUX_DIGIO_10_PINMUX_SEL}, -+ {PAD_MUX_DIGIO_09_PINMUX_SEL}, {PAD_MUX_DIGIO_02_PINMUX_SEL} }; -+ -+ if (MXL_ENABLE == mpegOutParamPtr->enable) { -+ cfg_ts_pad_mux(state, MXL_TRUE); -+ SET_REG_FIELD_DATA(XPT_ENABLE_PARALLEL_OUTPUT, MXL_FALSE); -+ } -+ ncoCountMin = (u32)(MXL_HYDRA_NCO_CLK/mpegOutParamPtr->maxMpegClkRate); -+ SET_REG_FIELD_DATA(XPT_NCO_COUNT_MIN, ncoCountMin); -+ -+ if (mpegOutParamPtr->mpegClkType == MXL_HYDRA_MPEG_CLK_CONTINUOUS) -+ clkType = 1; -+ -+ if (mpegOutParamPtr->mpegMode < MXL_HYDRA_MPEG_MODE_PARALLEL) { -+ status |= update_by_mnemonic(state, -+ xpt_continuous_clock[demodId].regAddr, -+ xpt_continuous_clock[demodId].lsbPos, -+ xpt_continuous_clock[demodId].numOfBits, -+ clkType); -+ } else -+ SET_REG_FIELD_DATA(XPT_TS_CLK_OUT_EN_PARALLEL, clkType); -+ -+ status |= update_by_mnemonic(state, -+ xpt_sync_polarity[demodId].regAddr, -+ xpt_sync_polarity[demodId].lsbPos, -+ xpt_sync_polarity[demodId].numOfBits, -+ mpegOutParamPtr->mpegSyncPol); -+ -+ status |= update_by_mnemonic(state, -+ xpt_valid_polarity[demodId].regAddr, -+ xpt_valid_polarity[demodId].lsbPos, -+ xpt_valid_polarity[demodId].numOfBits, -+ mpegOutParamPtr->mpegValidPol); -+ -+ status |= update_by_mnemonic(state, -+ xpt_clock_polarity[demodId].regAddr, -+ xpt_clock_polarity[demodId].lsbPos, -+ xpt_clock_polarity[demodId].numOfBits, -+ mpegOutParamPtr->mpegClkPol); -+ -+ status |= update_by_mnemonic(state, -+ xpt_sync_byte[demodId].regAddr, -+ xpt_sync_byte[demodId].lsbPos, -+ xpt_sync_byte[demodId].numOfBits, -+ mpegOutParamPtr->mpegSyncPulseWidth); -+ -+ status |= update_by_mnemonic(state, -+ xpt_ts_clock_phase[demodId].regAddr, -+ xpt_ts_clock_phase[demodId].lsbPos, -+ xpt_ts_clock_phase[demodId].numOfBits, -+ mpegOutParamPtr->mpegClkPhase); -+ -+ status |= update_by_mnemonic(state, -+ xpt_lsb_first[demodId].regAddr, -+ xpt_lsb_first[demodId].lsbPos, -+ xpt_lsb_first[demodId].numOfBits, -+ mpegOutParamPtr->lsbOrMsbFirst); -+ -+ switch (mpegOutParamPtr->mpegErrorIndication) { -+ case MXL_HYDRA_MPEG_ERR_REPLACE_SYNC: -+ status |= update_by_mnemonic(state, -+ xpt_err_replace_sync[demodId].regAddr, -+ xpt_err_replace_sync[demodId].lsbPos, -+ xpt_err_replace_sync[demodId].numOfBits, -+ MXL_TRUE); -+ -+ status |= update_by_mnemonic(state, -+ xpt_err_replace_valid[demodId].regAddr, -+ xpt_err_replace_valid[demodId].lsbPos, -+ xpt_err_replace_valid[demodId].numOfBits, -+ MXL_FALSE); -+ break; -+ -+ case MXL_HYDRA_MPEG_ERR_REPLACE_VALID: -+ status |= update_by_mnemonic(state, -+ xpt_err_replace_sync[demodId].regAddr, -+ xpt_err_replace_sync[demodId].lsbPos, -+ xpt_err_replace_sync[demodId].numOfBits, -+ MXL_FALSE); -+ -+ status |= update_by_mnemonic(state, -+ xpt_err_replace_valid[demodId].regAddr, -+ xpt_err_replace_valid[demodId].lsbPos, -+ xpt_err_replace_valid[demodId].numOfBits, -+ MXL_TRUE); -+ break; -+ -+ case MXL_HYDRA_MPEG_ERR_INDICATION_DISABLED: -+ default: -+ status |= update_by_mnemonic(state, -+ xpt_err_replace_sync[demodId].regAddr, -+ xpt_err_replace_sync[demodId].lsbPos, -+ xpt_err_replace_sync[demodId].numOfBits, -+ MXL_FALSE); -+ -+ status |= update_by_mnemonic(state, -+ xpt_err_replace_valid[demodId].regAddr, -+ xpt_err_replace_valid[demodId].lsbPos, -+ xpt_err_replace_valid[demodId].numOfBits, -+ MXL_FALSE); -+ -+ break; -+ -+ } -+ -+ if (mpegOutParamPtr->mpegMode != MXL_HYDRA_MPEG_MODE_PARALLEL) { -+ status |= update_by_mnemonic(state, -+ xpt_enable_output[demodId].regAddr, -+ xpt_enable_output[demodId].lsbPos, -+ xpt_enable_output[demodId].numOfBits, -+ mpegOutParamPtr->enable); -+ -+ status |= -+ update_by_mnemonic(state, -+ xpt_enable_dvb_input[demodId].regAddr, -+ xpt_enable_dvb_input[demodId].lsbPos, -+ xpt_enable_dvb_input[demodId].numOfBits, -+ mpegOutParamPtr->enable); -+ -+ } -+ return status; -+} -+ -+static int config_mux(struct mxl *state) -+{ -+ SET_REG_FIELD_DATA(XPT_ENABLE_OUTPUT0, 0); -+ SET_REG_FIELD_DATA(XPT_ENABLE_OUTPUT1, 0); -+ SET_REG_FIELD_DATA(XPT_ENABLE_OUTPUT2, 0); -+ SET_REG_FIELD_DATA(XPT_ENABLE_OUTPUT3, 0); -+ SET_REG_FIELD_DATA(XPT_ENABLE_OUTPUT4, 0); -+ SET_REG_FIELD_DATA(XPT_ENABLE_OUTPUT5, 0); -+ SET_REG_FIELD_DATA(XPT_ENABLE_OUTPUT6, 0); -+ SET_REG_FIELD_DATA(XPT_ENABLE_OUTPUT7, 0); -+ SET_REG_FIELD_DATA(XPT_STREAM_MUXMODE0, 1); -+ SET_REG_FIELD_DATA(XPT_STREAM_MUXMODE1, 1); -+ return 0; -+} -+ -+static int config_dis(struct mxl *state, u32 id) -+{ -+ MXL_HYDRA_DISEQC_ID_E diseqcId = id; -+ MXL_HYDRA_DISEQC_OPMODE_E opMode = MXL_HYDRA_DISEQC_TONE_MODE; //lja MXL_HYDRA_DISEQC_ENVELOPE_MODE; -+ MXL_HYDRA_DISEQC_VER_E version = MXL_HYDRA_DISEQC_1_X; -+ MXL_HYDRA_DISEQC_CARRIER_FREQ_E carrierFreqInHz = -+ MXL_HYDRA_DISEQC_CARRIER_FREQ_22KHZ; -+ MXL58x_DSQ_OP_MODE_T diseqcMsg; -+ u8 cmdSize = sizeof(diseqcMsg); -+ u8 cmdBuff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; -+ -+ diseqcMsg.diseqcId = diseqcId; -+ diseqcMsg.opMode = opMode; -+ diseqcMsg.version = version; -+ diseqcMsg.centerFreq = carrierFreqInHz; -+ -+ BUILD_HYDRA_CMD(MXL_HYDRA_DISEQC_CFG_MSG_CMD, -+ MXL_CMD_WRITE, cmdSize, &diseqcMsg, cmdBuff); -+ return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]); -+} -+ -+static int load_fw(struct mxl *state) -+{ -+ struct mxl5xx_cfg *cfg = state->base->cfg; -+ int stat = 0; -+ u8 *buf; -+ -+#if 1 -+ const struct firmware *fw; -+ -+ pr_info("loading firmware, please wait...\n"); -+ -+ stat = request_firmware(&fw, MXL5XX_DEFAULT_FIRMWARE, -+ state->base->i2c->dev.parent); -+ if (stat) -+ return stat; -+ -+ stat = firmware_download(state, fw->size, fw->data); -+ -+ release_firmware(fw); -+ -+ if (stat) -+ pr_info("error loading firmware\n"); -+ -+#else -+ if (cfg->fw) -+ return firmware_download(state, cfg->fw_len, cfg->fw); -+ -+#ifdef FW_INCLUDED -+ return firmware_download(state, sizeof(hydra_fw), hydra_fw); -+#endif -+ -+ if (!cfg->fw_read) -+ return -1; -+ -+ buf = vmalloc(0x40000); -+ if (!buf) -+ return -ENOMEM; -+ -+ cfg->fw_read(cfg->fw_priv, buf, 0x40000); -+ stat = firmware_download(state, 0x40000, buf); -+ vfree(buf); -+#endif -+ return stat; -+} -+ -+static int init_multisw(struct mxl *state) -+{ -+ struct dvb_frontend *fe = &state->fe; -+ struct i2c_adapter *i2c = state->base->i2c; -+ struct mxl5xx_cfg *cfg = state->base->cfg; -+ -+ switch (mode) { -+ case 0: -+ default: -+ cfg->set_voltage(i2c, SEC_VOLTAGE_13, 3); -+ cfg->set_voltage(i2c, SEC_VOLTAGE_13, 2); -+ cfg->set_voltage(i2c, SEC_VOLTAGE_18, 1); -+ cfg->set_voltage(i2c, SEC_VOLTAGE_18, 0); -+ set_input_tone(fe, SEC_TONE_OFF, 3); -+ set_input_tone(fe, SEC_TONE_ON, 2); -+ set_input_tone(fe, SEC_TONE_OFF, 1); -+ set_input_tone(fe, SEC_TONE_ON, 0); -+ break; -+ case 1: -+ break; -+ } -+ -+ return 0; -+} -+ -+static int probe(struct mxl *state) -+{ -+ struct mxl5xx_cfg *cfg = state->base->cfg; -+ u32 chipver; -+ int fw, status, j; -+ MXL_HYDRA_MPEGOUT_PARAM_T mpegInterfaceCfg; -+ -+ fw = firmware_is_alive(state); -+ -+ if (!fw) { -+ // lja -+ SET_REG_FIELD_DATA(PRCM_AFE_REG_CLOCK_ENABLE, 1); -+ //write_register(state, HYDRA_MODULES_CLK_1_REG, 0x0000020b); -+ -+ SET_REG_FIELD_DATA(PRCM_PRCM_AFE_REG_SOFT_RST_N, 1); -+ status = GET_REG_FIELD_DATA(PRCM_CHIP_VERSION, &chipver); -+ if (status) -+ state->base->chipversion = 0; -+ else -+ state->base->chipversion = (chipver == 2) ? 2 : 1; -+ pr_info("Hydra chip version %u\n", state->base->chipversion); -+ -+ -+ -+ cfg_dev_xtal(state, cfg->clk, cfg->cap, 0); -+ -+ status = load_fw(state); -+ if (status) -+ return status; -+ -+ config_dis(state, 0); -+ config_dis(state, 1); -+ config_dis(state, 2); -+ config_dis(state, 3); -+ -+#if 0 -+ config_mux(state); -+ -+ mpegInterfaceCfg.enable = MXL_ENABLE; -+ mpegInterfaceCfg.lsbOrMsbFirst = MXL_HYDRA_MPEG_SERIAL_MSB_1ST; -+ /* supports only (0-104&139)MHz */ -+ mpegInterfaceCfg.maxMpegClkRate = 139; -+ mpegInterfaceCfg.mpegClkPhase = MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_180_DEG; //MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_0_DEG; -+ mpegInterfaceCfg.mpegClkPol = MXL_HYDRA_MPEG_CLK_IN_PHASE; -+ /* MXL_HYDRA_MPEG_CLK_GAPPED; */ -+ mpegInterfaceCfg.mpegClkType = MXL_HYDRA_MPEG_CLK_CONTINUOUS; -+ mpegInterfaceCfg.mpegErrorIndication = -+ MXL_HYDRA_MPEG_ERR_INDICATION_DISABLED; -+ mpegInterfaceCfg.mpegMode = MXL_HYDRA_MPEG_MODE_SERIAL_3_WIRE; -+ mpegInterfaceCfg.mpegSyncPol = MXL_HYDRA_MPEG_ACTIVE_HIGH; -+ mpegInterfaceCfg.mpegSyncPulseWidth = MXL_HYDRA_MPEG_SYNC_WIDTH_BIT; -+ mpegInterfaceCfg.mpegValidPol = MXL_HYDRA_MPEG_ACTIVE_HIGH; -+ -+ for (j = 0; j < 8; j++) { -+ status = config_ts(state, (MXL_HYDRA_DEMOD_ID_E) j, -+ &mpegInterfaceCfg); -+ if (status) -+ return status; -+ } -+#endif -+ -+ // lja -+ write_register(state, 0x90700008, 0x00000005); -+ write_register(state, 0x90000170, 0); -+ write_register(state, 0x90000174, 0); -+ write_register(state, 0x90700044, 0x00030000); -+ write_register(state, 0x90700238, 0x03030303); -+ write_register(state, 0x9070023C, 0x00030303); -+ write_register(state, 0x907001D4, 0x000000ff); -+ write_register(state, 0x90700010, 0x0000ff00); -+ write_register(state, 0x90700014, 0x000000ff); -+ write_register(state, 0x90700018, 0x22222222); -+ write_register(state, 0x9070000C, 0x000000ff); -+ write_register(state, 0x90700000, 0x000000ff); -+ -+ } -+ -+ -+ return 0; -+} -+ -+struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, -+ struct mxl5xx_cfg *cfg, -+ u32 demod) -+{ -+ struct mxl *state; -+ struct mxl_base *base; -+ -+ state = kzalloc(sizeof(struct mxl), GFP_KERNEL); -+ if (!state) -+ return NULL; -+ -+ state->demod = demod; -+ state->rf_in = 0; -+ if(mode) -+ { -+ if((demod ==0)||(demod ==1)) -+ state->rf_in = 3; -+ if((demod ==2)||(demod ==3)) -+ state->rf_in = 2; -+ if((demod ==4)||(demod ==5)) -+ state->rf_in = 1; -+ if((demod ==6)||(demod ==7)) -+ state->rf_in = 0; -+ } -+ state->fe.ops = mxl_ops; -+ state->fe.demodulator_priv = state; -+ -+ base = match_base(i2c, cfg->adr); -+ if (base) { -+ base->count++; -+ state->base = base; -+ } else { -+ base = kzalloc(sizeof(struct mxl_base), GFP_KERNEL); -+ if (!base) -+ goto fail; -+ base->i2c = i2c; -+ base->cfg = cfg; -+ base->adr = cfg->adr; -+ base->type = cfg->type; -+ base->count = 1; -+ mutex_init(&base->i2c_lock); -+ mutex_init(&base->status_lock); -+ state->base = base; -+ if (probe(state) < 0) { -+ kfree(base); -+ goto fail; -+ } -+ -+ init_multisw(state); -+ -+ list_add(&base->mxllist, &mxllist); -+ } -+ -+ -+ return &state->fe; -+ -+fail: -+ kfree(state); -+ return NULL; -+} -+EXPORT_SYMBOL_GPL(mxl5xx_attach); -+ -+MODULE_DESCRIPTION("MXL5XX driver"); -+MODULE_AUTHOR("Ralph Metzler"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/dvb-frontends/mxl5xx.h b/drivers/media/dvb-frontends/mxl5xx.h -new file mode 100644 -index 0000000..e4d54e5 ---- /dev/null -+++ b/drivers/media/dvb-frontends/mxl5xx.h -@@ -0,0 +1,41 @@ -+#ifndef _MXL5XX_H_ -+#define _MXL5XX_H_ -+ -+#include -+#include -+ -+struct mxl5xx_cfg { -+ u8 adr; -+ u8 type; -+ u32 cap; -+ u32 clk; -+ -+ u8 *fw; -+ u32 fw_len; -+ -+ int (*fw_read)(void *priv, u8 *buf, u32 len); -+ void *fw_priv; -+ -+ int (*set_voltage)(struct i2c_adapter *i2c, -+ enum fe_sec_voltage voltage, u8 rf_in); -+}; -+ -+#if defined(CONFIG_DVB_MXL5XX) || \ -+ (defined(CONFIG_DVB_MXL5XX_MODULE) && defined(MODULE)) -+ -+extern struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, -+ struct mxl5xx_cfg *cfg, -+ u32 demod); -+#else -+ -+static inline struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, -+ struct mxl5xx_cfg *cfg, -+ u32 demod) -+{ -+ pr_warn("%s: driver disabled by Kconfig\n", __func__); -+ return NULL; -+} -+ -+#endif -+ -+#endif -diff --git a/drivers/media/dvb-frontends/mxl5xx_defs.h b/drivers/media/dvb-frontends/mxl5xx_defs.h -new file mode 100644 -index 0000000..bd13372 ---- /dev/null -+++ b/drivers/media/dvb-frontends/mxl5xx_defs.h -@@ -0,0 +1,836 @@ -+/* -+ * Defines for the Maxlinear MX58x family of tuners/demods -+ * -+ * Copyright (C) 2014 Digital Devices GmbH -+ * -+ * based on code: -+ * Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved -+ * which was released under GPL V2 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2, as published by the Free Software Foundation. -+ */ -+ -+typedef enum -+{ -+ MXL_DISABLE = 0, -+ MXL_ENABLE = 1, -+ -+ MXL_FALSE = 0, -+ MXL_TRUE = 1, -+ -+ MXL_INVALID = 0, -+ MXL_VALID = 1, -+ -+ MXL_NO = 0, -+ MXL_YES = 1, -+ -+ MXL_OFF = 0, -+ MXL_ON = 1 -+} MXL_BOOL_E; -+ -+// Firmware-Host Command IDs -+typedef enum -+{ -+ //--Device command IDs-- -+ MXL_HYDRA_DEV_NO_OP_CMD = 0, //No OP -+ -+ MXL_HYDRA_DEV_SET_POWER_MODE_CMD = 1, -+ MXL_HYDRA_DEV_SET_OVERWRITE_DEF_CMD = 2, -+ -+ // Host-used CMD, not used by firmware -+ MXL_HYDRA_DEV_FIRMWARE_DOWNLOAD_CMD = 3, -+ -+ // Additional CONTROL types from DTV -+ MXL_HYDRA_DEV_SET_BROADCAST_PID_STB_ID_CMD = 4, -+ MXL_HYDRA_DEV_GET_PMM_SLEEP_CMD = 5, -+ -+ //--Tuner command IDs-- -+ MXL_HYDRA_TUNER_TUNE_CMD = 6, -+ MXL_HYDRA_TUNER_GET_STATUS_CMD = 7, -+ -+ //--Demod command IDs-- -+ MXL_HYDRA_DEMOD_SET_PARAM_CMD = 8, -+ MXL_HYDRA_DEMOD_GET_STATUS_CMD = 9, -+ -+ MXL_HYDRA_DEMOD_RESET_FEC_COUNTER_CMD = 10, -+ -+ MXL_HYDRA_DEMOD_SET_PKT_NUM_CMD = 11, -+ -+ MXL_HYDRA_DEMOD_SET_IQ_SOURCE_CMD = 12, -+ MXL_HYDRA_DEMOD_GET_IQ_DATA_CMD = 13, -+ -+ MXL_HYDRA_DEMOD_GET_M68HC05_VER_CMD = 14, -+ -+ MXL_HYDRA_DEMOD_SET_ERROR_COUNTER_MODE_CMD = 15, -+ -+ //--- ABORT channel tune -+ MXL_HYDRA_ABORT_TUNE_CMD = 16, // Abort current tune command. -+ -+ //--SWM/FSK command IDs-- -+ MXL_HYDRA_FSK_RESET_CMD = 17, -+ MXL_HYDRA_FSK_MSG_CMD = 18, -+ MXL_HYDRA_FSK_SET_OP_MODE_CMD = 19, -+ -+ //--DiSeqC command IDs-- -+ MXL_HYDRA_DISEQC_MSG_CMD = 20, -+ MXL_HYDRA_DISEQC_COPY_MSG_TO_MAILBOX = 21, -+ MXL_HYDRA_DISEQC_CFG_MSG_CMD = 22, -+ -+ //--- FFT Debug Command IDs-- -+ MXL_HYDRA_REQ_FFT_SPECTRUM_CMD = 23, -+ -+ // -- Demod scramblle code -+ MXL_HYDRA_DEMOD_SCRAMBLE_CODE_CMD = 24, -+ -+ //---For host to know how many commands in total--- -+ MXL_HYDRA_LAST_HOST_CMD = 25, -+ -+ MXL_HYDRA_DEMOD_INTR_TYPE_CMD = 47, -+ MXL_HYDRA_DEV_INTR_CLEAR_CMD = 48, -+ MXL_HYDRA_TUNER_SPECTRUM_REQ_CMD = 53, -+ MXL_HYDRA_TUNER_ACTIVATE_CMD = 55, -+ MXL_HYDRA_DEV_CFG_POWER_MODE_CMD = 56, -+ MXL_HYDRA_DEV_XTAL_CAP_CMD = 57, -+ MXL_HYDRA_DEV_CFG_SKU_CMD = 58, -+ MXL_HYDRA_TUNER_SPECTRUM_MIN_GAIN_CMD = 59, -+ MXL_HYDRA_DISEQC_CONT_TONE_CFG = 60, -+ MXL_HYDRA_DEV_RF_WAKE_UP_CMD = 61, -+ MXL_HYDRA_DEMOD_CFG_EQ_CTRL_PARAM_CMD = 62, -+ MXL_HYDRA_DEMOD_FREQ_OFFSET_SEARCH_RANGE_CMD = 63, -+ MXL_HYDRA_DEV_REQ_PWR_FROM_ADCRSSI_CMD = 64, -+ -+ MXL_XCPU_PID_FLT_CFG_CMD = 65, -+ MXL_XCPU_SHMEM_TEST_CMD = 66, -+ MXL_XCPU_ABORT_TUNE_CMD = 67, -+ MXL_XCPU_CHAN_TUNE_CMD = 68, -+ MXL_XCPU_FLT_BOND_HDRS_CMD = 69, -+ -+ MXL_HYDRA_DEV_BROADCAST_WAKE_UP_CMD = 70, -+ MXL_HYDRA_FSK_CFG_FSK_FREQ_CMD = 71, -+ MXL_HYDRA_FSK_POWER_DOWN_CMD = 72, -+ MXL_XCPU_CLEAR_CB_STATS_CMD = 73, -+ MXL_XCPU_CHAN_BOND_RESTART_CMD = 74 -+} MXL_HYDRA_HOST_CMD_ID_E; -+ -+#define MXL_ENABLE_BIG_ENDIAN (0) -+ -+#define MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH 248 -+ -+#define MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN (248) -+ -+#define MXL_HYDRA_CAP_MIN 10 -+#define MXL_HYDRA_CAP_MAX 33 -+ -+#define MXL_HYDRA_PLID_REG_READ 0xFB // Read register PLID -+#define MXL_HYDRA_PLID_REG_WRITE 0xFC // Write register PLID -+ -+#define MXL_HYDRA_PLID_CMD_READ 0xFD // Command Read PLID -+#define MXL_HYDRA_PLID_CMD_WRITE 0xFE // Command Write PLID -+ -+#define MXL_HYDRA_REG_SIZE_IN_BYTES 4 // Hydra register size in bytes -+#define MXL_HYDRA_I2C_HDR_SIZE (2 * sizeof(u8)) // PLID + LEN(0xFF) -+#define MXL_HYDRA_CMD_HEADER_SIZE (MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE) -+ -+#define MXL_HYDRA_SKU_ID_581 0 -+#define MXL_HYDRA_SKU_ID_584 1 -+#define MXL_HYDRA_SKU_ID_585 2 -+#define MXL_HYDRA_SKU_ID_544 3 -+#define MXL_HYDRA_SKU_ID_561 4 -+#define MXL_HYDRA_SKU_ID_582 5 -+#define MXL_HYDRA_SKU_ID_568 6 -+ -+// macro for register write data buffer size (PLID + LEN (0xFF) + RegAddr + RegData) -+#define MXL_HYDRA_REG_WRITE_LEN (MXL_HYDRA_I2C_HDR_SIZE + (2 * MXL_HYDRA_REG_SIZE_IN_BYTES)) -+ -+// maro to extract a single byte from 4-byte(32-bit) data -+#define GET_BYTE(x,n) (((x) >> (8*(n))) & 0xFF) -+ -+#define MAX_CMD_DATA 512 -+ -+#define MXL_GET_REG_MASK_32(lsbLoc,numOfBits) ((0xFFFFFFFF >> (32 - (numOfBits))) << (lsbLoc)) -+ -+#define GET_REG_FIELD_DATA(fieldName, dataPtr) read_by_mnemonic(state, fieldName, dataPtr); -+#define SET_REG_FIELD_DATA(fieldName, data) update_by_mnemonic(state, fieldName, data); -+ -+#define FW_DL_SIGN (0xDEADBEEF) -+ -+#define MBIN_FORMAT_VERSION '1' -+#define MBIN_FILE_HEADER_ID 'M' -+#define MBIN_SEGMENT_HEADER_ID 'S' -+#define MBIN_MAX_FILE_LENGTH (1<<23) -+ -+typedef struct -+{ -+ u8 id; -+ u8 fmtVersion; -+ u8 headerLen; -+ u8 numSegments; -+ u8 entryAddress[4]; -+ u8 imageSize24[3]; -+ u8 imageChecksum; -+ u8 reserved[4]; -+} MBIN_FILE_HEADER_T; -+ -+typedef struct -+{ -+ MBIN_FILE_HEADER_T header; -+ u8 data[1]; -+} MBIN_FILE_T; -+ -+typedef struct -+{ -+ u8 id; -+ u8 len24[3]; -+ u8 address[4]; -+} MBIN_SEGMENT_HEADER_T; -+ -+ -+typedef struct -+{ -+ MBIN_SEGMENT_HEADER_T header; -+ u8 data[1]; -+} MBIN_SEGMENT_T; -+ -+ -+typedef enum { MXL_CMD_WRITE = 0, MXL_CMD_READ} MXL_CMD_TYPE_E; -+ -+#define BUILD_HYDRA_CMD(cmdID, reqType, size, dataPtr, cmdBuff) \ -+ do { \ -+ cmdBuff[0] = ((reqType == MXL_CMD_WRITE) ? MXL_HYDRA_PLID_CMD_WRITE : MXL_HYDRA_PLID_CMD_READ); \ -+ cmdBuff[1] = (size > 251) ? 0xff : (u8) (size + 4); \ -+ cmdBuff[2] = size; \ -+ cmdBuff[3] = cmdID; \ -+ cmdBuff[4] = 0x00; \ -+ cmdBuff[5] = 0x00; \ -+ convert_endian(MXL_ENABLE_BIG_ENDIAN, size, (u8 *)dataPtr); \ -+ memcpy((void *)&cmdBuff[6], dataPtr, size); \ -+ } while(0) //; -+ -+typedef struct { -+ u32 regAddr; -+ u8 lsbPos; -+ u8 numOfBits; -+} MXL_REG_FIELD_T; -+ -+typedef struct { -+ u32 dataSize; -+ u8 data[MAX_CMD_DATA]; -+} MXL_DEV_CMD_DATA_T; -+ -+typedef enum -+{ -+ MXL_HYDRA_SKU_TYPE_MIN = 0x00, -+ MXL_HYDRA_SKU_TYPE_581 = 0x00, -+ MXL_HYDRA_SKU_TYPE_584 = 0x01, -+ MXL_HYDRA_SKU_TYPE_585 = 0x02, -+ MXL_HYDRA_SKU_TYPE_544 = 0x03, -+ MXL_HYDRA_SKU_TYPE_561 = 0x04, -+ MXL_HYDRA_SKU_TYPE_5xx = 0x05, -+ MXL_HYDRA_SKU_TYPE_5yy = 0x06, -+ MXL_HYDRA_SKU_TYPE_511 = 0x07, -+ MXL_HYDRA_SKU_TYPE_561_DE = 0x08, -+ MXL_HYDRA_SKU_TYPE_582 = 0x09, -+ MXL_HYDRA_SKU_TYPE_541 = 0x0A, -+ MXL_HYDRA_SKU_TYPE_568 = 0x0B, -+ MXL_HYDRA_SKU_TYPE_542 = 0x0C, -+ MXL_HYDRA_SKU_TYPE_MAX = 0x0D, -+} MXL_HYDRA_SKU_TYPE_E; -+ -+typedef struct -+{ -+ MXL_HYDRA_SKU_TYPE_E skuType; -+} MXL_HYDRA_SKU_COMMAND_T; -+ -+ -+typedef enum -+{ -+ MXL_HYDRA_DEMOD_ID_0 = 0, -+ MXL_HYDRA_DEMOD_ID_1, -+ MXL_HYDRA_DEMOD_ID_2, -+ MXL_HYDRA_DEMOD_ID_3, -+ MXL_HYDRA_DEMOD_ID_4, -+ MXL_HYDRA_DEMOD_ID_5, -+ MXL_HYDRA_DEMOD_ID_6, -+ MXL_HYDRA_DEMOD_ID_7, -+ MXL_HYDRA_DEMOD_MAX -+} MXL_HYDRA_DEMOD_ID_E; -+ -+#define MXL_DEMOD_SCRAMBLE_SEQ_LEN 12 -+ -+#define MAX_STEP_SIZE_24_XTAL_102_05_KHZ 195 -+#define MAX_STEP_SIZE_24_XTAL_204_10_KHZ 215 -+#define MAX_STEP_SIZE_24_XTAL_306_15_KHZ 203 -+#define MAX_STEP_SIZE_24_XTAL_408_20_KHZ 177 -+ -+#define MAX_STEP_SIZE_27_XTAL_102_05_KHZ 195 -+#define MAX_STEP_SIZE_27_XTAL_204_10_KHZ 215 -+#define MAX_STEP_SIZE_27_XTAL_306_15_KHZ 203 -+#define MAX_STEP_SIZE_27_XTAL_408_20_KHZ 177 -+ -+#define MXL_HYDRA_SPECTRUM_MIN_FREQ_KHZ 300000 -+#define MXL_HYDRA_SPECTRUM_MAX_FREQ_KHZ 2350000 -+ -+typedef enum -+{ -+ DMD_STANDARD_ADDR = 0, -+ DMD_SPECTRUM_INVERSION_ADDR, -+ DMD_SPECTRUM_ROLL_OFF_ADDR, -+ DMD_SYMBOL_RATE_ADDR, -+ DMD_MODULATION_SCHEME_ADDR, -+ DMD_FEC_CODE_RATE_ADDR, -+ DMD_SNR_ADDR, -+ DMD_FREQ_OFFSET_ADDR, -+ DMD_CTL_FREQ_OFFSET_ADDR, -+ DMD_STR_FREQ_OFFSET_ADDR, -+ DMD_FTL_FREQ_OFFSET_ADDR, -+ DMD_STR_NBC_SYNC_LOCK_ADDR, -+ DMD_CYCLE_SLIP_COUNT_ADDR, -+ DMD_DISPLAY_IQ_ADDR, -+ DMD_DVBS2_CRC_ERRORS_ADDR, -+ DMD_DVBS2_PER_COUNT_ADDR, -+ DMD_DVBS2_PER_WINDOW_ADDR, -+ DMD_DVBS_CORR_RS_ERRORS_ADDR, -+ DMD_DVBS_UNCORR_RS_ERRORS_ADDR, -+ DMD_DVBS_BER_COUNT_ADDR, -+ DMD_DVBS_BER_WINDOW_ADDR, -+ DMD_TUNER_ID_ADDR, -+ DMD_DVBS2_PILOT_ON_OFF_ADDR, -+ DMD_FREQ_SEARCH_RANGE_IN_KHZ_ADDR, -+ -+ MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE, -+} MXL_DEMOD_CHAN_PARAMS_OFFSET_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_TUNER_ID_0 = 0, -+ MXL_HYDRA_TUNER_ID_1, -+ MXL_HYDRA_TUNER_ID_2, -+ MXL_HYDRA_TUNER_ID_3, -+ MXL_HYDRA_TUNER_MAX -+} MXL_HYDRA_TUNER_ID_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_DSS = 0, -+ MXL_HYDRA_DVBS, -+ MXL_HYDRA_DVBS2, -+} MXL_HYDRA_BCAST_STD_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_FEC_AUTO = 0, -+ MXL_HYDRA_FEC_1_2, -+ MXL_HYDRA_FEC_3_5, -+ MXL_HYDRA_FEC_2_3, -+ MXL_HYDRA_FEC_3_4, -+ MXL_HYDRA_FEC_4_5, -+ MXL_HYDRA_FEC_5_6, -+ MXL_HYDRA_FEC_6_7, -+ MXL_HYDRA_FEC_7_8, -+ MXL_HYDRA_FEC_8_9, -+ MXL_HYDRA_FEC_9_10, -+} MXL_HYDRA_FEC_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_MOD_AUTO = 0, -+ MXL_HYDRA_MOD_QPSK, -+ MXL_HYDRA_MOD_8PSK -+} MXL_HYDRA_MODULATION_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_SPECTRUM_AUTO = 0, -+ MXL_HYDRA_SPECTRUM_INVERTED, -+ MXL_HYDRA_SPECTRUM_NON_INVERTED, -+} MXL_HYDRA_SPECTRUM_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_ROLLOFF_AUTO = 0, -+ MXL_HYDRA_ROLLOFF_0_20, -+ MXL_HYDRA_ROLLOFF_0_25, -+ MXL_HYDRA_ROLLOFF_0_35 -+} MXL_HYDRA_ROLLOFF_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_PILOTS_OFF = 0, -+ MXL_HYDRA_PILOTS_ON, -+ MXL_HYDRA_PILOTS_AUTO -+} MXL_HYDRA_PILOTS_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_FORMATTER = 0, -+ MXL_HYDRA_LEGACY_FEC, -+ MXL_HYDRA_FREQ_RECOVERY, -+ MXL_HYDRA_NBC, -+ MXL_HYDRA_CTL, -+ MXL_HYDRA_EQ, -+} MXL_HYDRA_CONSTELLATION_SRC_E; -+ -+typedef struct -+{ -+ int agcLock; // AGC lock info -+ int fecLock; // Demod FEC block lock info -+} MXL_HYDRA_DEMOD_LOCK_T; -+ -+typedef struct -+{ -+ u32 rsErrors; // RS decoder err counter -+ u32 berWindow; // Ber Windows -+ u32 berCount; // BER count -+ u32 berWindow_Iter1; // Ber Windows - post viterbi -+ u32 berCount_Iter1; // BER count - post viterbi -+} MXL_HYDRA_DEMOD_STATUS_DVBS_T; -+ -+typedef struct -+{ -+ u32 rsErrors; // RS decoder err counter -+ u32 berWindow; // Ber Windows -+ u32 berCount; // BER count -+} MXL_HYDRA_DEMOD_STATUS_DSS_T; -+ -+typedef struct -+{ -+ u32 crcErrors; // CRC error counter -+ u32 packetErrorCount; // Number of packet errors -+ u32 totalPackets; // Total packets -+} MXL_HYDRA_DEMOD_STATUS_DVBS2_T; -+ -+typedef struct -+{ -+ MXL_HYDRA_BCAST_STD_E standardMask; // Standard DVB-S, DVB-S2 or DSS -+ -+ union -+ { -+ MXL_HYDRA_DEMOD_STATUS_DVBS_T demodStatus_DVBS; // DVB-S demod status -+ MXL_HYDRA_DEMOD_STATUS_DVBS2_T demodStatus_DVBS2; // DVB-S2 demod status -+ MXL_HYDRA_DEMOD_STATUS_DSS_T demodStatus_DSS; // DSS demod status -+ } u; -+ -+} MXL_HYDRA_DEMOD_STATUS_T; -+ -+typedef struct -+{ -+ s32 carrierOffsetInHz; // CRL offset info -+ s32 symbolOffsetInSymbol; // SRL offset info -+} MXL_HYDRA_DEMOD_SIG_OFFSET_INFO_T; -+ -+typedef struct -+{ -+ u8 scrambleSequence[MXL_DEMOD_SCRAMBLE_SEQ_LEN]; // scramble sequence -+ u32 scrambleCode; // scramble gold code -+} MXL_HYDRA_DEMOD_SCRAMBLE_INFO_T; -+ -+typedef enum -+{ -+ MXL_HYDRA_STEP_SIZE_24_XTAL_102_05KHZ, // 102.05 KHz for 24 MHz XTAL -+ MXL_HYDRA_STEP_SIZE_24_XTAL_204_10KHZ, // 204.10 KHz for 24 MHz XTAL -+ MXL_HYDRA_STEP_SIZE_24_XTAL_306_15KHZ, // 306.15 KHz for 24 MHz XTAL -+ MXL_HYDRA_STEP_SIZE_24_XTAL_408_20KHZ, // 408.20 KHz for 24 MHz XTAL -+ -+ MXL_HYDRA_STEP_SIZE_27_XTAL_102_05KHZ, // 102.05 KHz for 27 MHz XTAL -+ MXL_HYDRA_STEP_SIZE_27_XTAL_204_35KHZ, // 204.35 KHz for 27 MHz XTAL -+ MXL_HYDRA_STEP_SIZE_27_XTAL_306_52KHZ, // 306.52 KHz for 27 MHz XTAL -+ MXL_HYDRA_STEP_SIZE_27_XTAL_408_69KHZ, // 408.69 KHz for 27 MHz XTAL -+ -+} MXL_HYDRA_SPECTRUM_STEP_SIZE_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_SPECTRUM_RESOLUTION_00_1_DB, // 0.1 dB -+ MXL_HYDRA_SPECTRUM_RESOLUTION_01_0_DB, // 1.0 dB -+ MXL_HYDRA_SPECTRUM_RESOLUTION_05_0_DB, // 5.0 dB -+ MXL_HYDRA_SPECTRUM_RESOLUTION_10_0_DB, // 10 dB -+} MXL_HYDRA_SPECTRUM_RESOLUTION_E; -+ -+typedef enum -+{ -+ MXL_SPECTRUM_NO_ERROR, -+ MXL_SPECTRUM_INVALID_PARAMETER, -+ MXL_SPECTRUM_INVALID_STEP_SIZE, -+ MXL_SPECTRUM_BW_CANNOT_BE_COVERED, -+ MXL_SPECTRUM_DEMOD_BUSY, -+ MXL_SPECTRUM_TUNER_NOT_ENABLED, -+ -+} MXL_HYDRA_SPECTRUM_ERROR_CODE_E; -+ -+typedef struct -+{ -+ u32 tunerIndex; // TUNER Ctrl: one of MXL58x_TUNER_ID_E -+ u32 demodIndex; // DEMOD Ctrl: one of MXL58x_DEMOD_ID_E -+ MXL_HYDRA_SPECTRUM_STEP_SIZE_E stepSizeInKHz; -+ u32 startingFreqInkHz; -+ u32 totalSteps; -+ MXL_HYDRA_SPECTRUM_RESOLUTION_E spectrumDivision; -+} MXL_HYDRA_SPECTRUM_REQ_T; -+ -+typedef enum -+{ -+ MXL_HYDRA_SEARCH_MAX_OFFSET = 0, // DMD searches for max freq offset (i.e. 5MHz) -+ MXL_HYDRA_SEARCH_BW_PLUS_ROLLOFF, // DMD searches for BW + ROLLOFF/2 -+} MXL_HYDRA_SEARCH_FREQ_OFFSET_TYPE_E; -+ -+typedef struct -+{ -+ u32 demodIndex; -+ MXL_HYDRA_SEARCH_FREQ_OFFSET_TYPE_E searchType; -+} MXL58x_CFG_FREQ_OFF_SEARCH_RANGE_T; -+ -+ -+ -+ -+// there are two slices -+// slice0 - TS0, TS1, TS2 & TS3 -+// slice1 - TS4, TS5, TS6 & TS7 -+#define MXL_HYDRA_TS_SLICE_MAX 2 -+ -+#define MAX_FIXED_PID_NUM 32 -+ -+#define MXL_HYDRA_NCO_CLK 418 // 418 MHz -+ -+#define MXL_HYDRA_MAX_TS_CLOCK 139 // 139 MHz -+ -+#define MXL_HYDRA_TS_FIXED_PID_FILT_SIZE 32 -+ -+#define MXL_HYDRA_SHARED_PID_FILT_SIZE_DEFAULT 33 // Shared PID filter size in 1-1 mux mode -+#define MXL_HYDRA_SHARED_PID_FILT_SIZE_2_TO_1 66 // Shared PID filter size in 2-1 mux mode -+#define MXL_HYDRA_SHARED_PID_FILT_SIZE_4_TO_1 132 // Shared PID filter size in 4-1 mux mode -+ -+typedef enum -+{ -+ MXL_HYDRA_SOFTWARE_PID_BANK = 0, -+ MXL_HYDRA_HARDWARE_PID_BANK, -+} MXL_HYDRA_PID_BANK_TYPE_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_TS_MUX_PID_REMAP = 0, -+ MXL_HYDRA_TS_MUX_PREFIX_EXTRA_HEADER = 1, -+} MXL_HYDRA_TS_MUX_MODE_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_TS_MUX_DISABLE = 0, // No Mux ( 1 TSIF to 1 TSIF) -+ MXL_HYDRA_TS_MUX_2_TO_1, // Mux 2 TSIF to 1 TSIF -+ MXL_HYDRA_TS_MUX_4_TO_1, // Mux 4 TSIF to 1 TSIF -+} MXL_HYDRA_TS_MUX_TYPE_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_TS_GROUP_0_3 = 0, // TS group 0 to 3 (TS0, TS1, TS2 & TS3) -+ MXL_HYDRA_TS_GROUP_4_7, // TS group 0 to 3 (TS4, TS5, TS6 & TS7) -+} MXL_HYDRA_TS_GROUP_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_TS_PIDS_ALLOW_ALL = 0, // Allow all pids -+ MXL_HYDRA_TS_PIDS_DROP_ALL, // Drop all pids -+ MXL_HYDRA_TS_INVALIDATE_PID_FILTER, // Delete current PD filter in the device -+ -+} MXL_HYDRA_TS_PID_FLT_CTRL_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_TS_PID_FIXED = 0, -+ MXL_HYDRA_TS_PID_REGULAR, -+} MXL_HYDRA_TS_PID_TYPE_E; -+ -+typedef struct -+{ -+ u16 originalPid; // pid from TS -+ u16 remappedPid; // remapped pid -+ MXL_BOOL_E enable; // enable or disable pid -+ MXL_BOOL_E allowOrDrop; // allow or drop pid -+ MXL_BOOL_E enablePidRemap; // enable or disable pid remap -+ u8 bondId; // Bond ID in A0 always 0 - Only for 568 Sku -+ u8 destId; // Output port ID for the PID - Only for 568 Sku -+} MXL_HYDRA_TS_PID_T; -+ -+typedef struct -+{ -+ MXL_BOOL_E enable; -+ u8 numByte; -+ u8 header[12]; -+} MXL_HYDRA_TS_MUX_PREFIX_HEADER_T; -+ -+typedef enum -+{ -+ MXL_HYDRA_PID_BANK_A = 0, -+ MXL_HYDRA_PID_BANK_B, -+} MXL_HYDRA_PID_FILTER_BANK_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_MPEG_SERIAL_MSB_1ST = 0, -+ MXL_HYDRA_MPEG_SERIAL_LSB_1ST, -+ -+ MXL_HYDRA_MPEG_SYNC_WIDTH_BIT = 0, -+ MXL_HYDRA_MPEG_SYNC_WIDTH_BYTE -+} MXL_HYDRA_MPEG_DATA_FMT_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_MPEG_MODE_SERIAL_4_WIRE = 0, // MPEG 4 Wire serial mode -+ MXL_HYDRA_MPEG_MODE_SERIAL_3_WIRE, // MPEG 3 Wire serial mode -+ MXL_HYDRA_MPEG_MODE_SERIAL_2_WIRE, // MPEG 2 Wire serial mode -+ MXL_HYDRA_MPEG_MODE_PARALLEL // MPEG parallel mode - valid only for MxL581 -+} MXL_HYDRA_MPEG_MODE_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_MPEG_CLK_CONTINUOUS = 0, // Continuous MPEG clock -+ MXL_HYDRA_MPEG_CLK_GAPPED, // Gapped (gated) MPEG clock -+} MXL_HYDRA_MPEG_CLK_TYPE_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_MPEG_ACTIVE_LOW = 0, -+ MXL_HYDRA_MPEG_ACTIVE_HIGH, -+ -+ MXL_HYDRA_MPEG_CLK_NEGATIVE = 0, -+ MXL_HYDRA_MPEG_CLK_POSITIVE, -+ -+ MXL_HYDRA_MPEG_CLK_IN_PHASE = 0, -+ MXL_HYDRA_MPEG_CLK_INVERTED, -+} MXL_HYDRA_MPEG_CLK_FMT_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_0_DEG = 0, -+ MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_90_DEG, -+ MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_180_DEG, -+ MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_270_DEG -+} MXL_HYDRA_MPEG_CLK_PHASE_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_MPEG_ERR_REPLACE_SYNC = 0, -+ MXL_HYDRA_MPEG_ERR_REPLACE_VALID, -+ MXL_HYDRA_MPEG_ERR_INDICATION_DISABLED -+} MXL_HYDRA_MPEG_ERR_INDICATION_E; -+ -+typedef struct -+{ -+ int enable; // Enable or Disable MPEG OUT -+ MXL_HYDRA_MPEG_CLK_TYPE_E mpegClkType; // Continuous or gapped -+ MXL_HYDRA_MPEG_CLK_FMT_E mpegClkPol; // MPEG Clk polarity -+ u8 maxMpegClkRate; // Max MPEG Clk rate (0 – 104 MHz, 139 MHz) -+ MXL_HYDRA_MPEG_CLK_PHASE_E mpegClkPhase; // MPEG Clk phase -+ MXL_HYDRA_MPEG_DATA_FMT_E lsbOrMsbFirst; // LSB first or MSB first in TS transmission -+ MXL_HYDRA_MPEG_DATA_FMT_E mpegSyncPulseWidth; // MPEG SYNC pulse width (1-bit or 1-byte) -+ MXL_HYDRA_MPEG_CLK_FMT_E mpegValidPol; // MPEG VALID polarity -+ MXL_HYDRA_MPEG_CLK_FMT_E mpegSyncPol; // MPEG SYNC polarity -+ MXL_HYDRA_MPEG_MODE_E mpegMode; // config 4/3/2-wire serial or parallel TS out -+ MXL_HYDRA_MPEG_ERR_INDICATION_E mpegErrorIndication; // Enable or Disable MPEG error indication -+} MXL_HYDRA_MPEGOUT_PARAM_T; -+ -+typedef enum -+{ -+ MXL_HYDRA_EXT_TS_IN_0 = 0, -+ MXL_HYDRA_EXT_TS_IN_1, -+ MXL_HYDRA_EXT_TS_IN_2, -+ MXL_HYDRA_EXT_TS_IN_3, -+ MXL_HYDRA_EXT_TS_IN_MAX -+ -+} MXL_HYDRA_EXT_TS_IN_ID_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_TS_OUT_0 = 0, -+ MXL_HYDRA_TS_OUT_1, -+ MXL_HYDRA_TS_OUT_2, -+ MXL_HYDRA_TS_OUT_3, -+ MXL_HYDRA_TS_OUT_4, -+ MXL_HYDRA_TS_OUT_5, -+ MXL_HYDRA_TS_OUT_6, -+ MXL_HYDRA_TS_OUT_7, -+ MXL_HYDRA_TS_OUT_MAX -+ -+} MXL_HYDRA_TS_OUT_ID_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_TS_DRIVE_STRENGTH_1x = 0, -+ MXL_HYDRA_TS_DRIVE_STRENGTH_2x, -+ MXL_HYDRA_TS_DRIVE_STRENGTH_3x, -+ MXL_HYDRA_TS_DRIVE_STRENGTH_4x, -+ MXL_HYDRA_TS_DRIVE_STRENGTH_5x, -+ MXL_HYDRA_TS_DRIVE_STRENGTH_6x, -+ MXL_HYDRA_TS_DRIVE_STRENGTH_7x, -+ MXL_HYDRA_TS_DRIVE_STRENGTH_8x -+ -+} MXL_HYDRA_TS_DRIVE_STRENGTH_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_DEVICE_581 = 0, -+ MXL_HYDRA_DEVICE_584, -+ MXL_HYDRA_DEVICE_585, -+ MXL_HYDRA_DEVICE_544, -+ MXL_HYDRA_DEVICE_561, -+ MXL_HYDRA_DEVICE_TEST, -+ MXL_HYDRA_DEVICE_582, -+ MXL_HYDRA_DEVICE_541, -+ MXL_HYDRA_DEVICE_568, -+ MXL_HYDRA_DEVICE_542, -+ MXL_HYDRA_DEVICE_541S, -+ MXL_HYDRA_DEVICE_561S, -+ MXL_HYDRA_DEVICE_581S, -+ MXL_HYDRA_DEVICE_MAX -+} MXL_HYDRA_DEVICE_E; -+ -+ -+// Demod IQ data -+typedef struct -+{ -+ u32 demodId; -+ u32 sourceOfIQ; // ==0, it means I/Q comes from Formatter -+ // ==1, Legacy FEC -+ // ==2, Frequency Recovery -+ // ==3, NBC -+ // ==4, CTL -+ // ==5, EQ -+ // ==6, FPGA -+} MXL_HYDRA_DEMOD_IQ_SRC_T; -+ -+typedef struct -+{ -+ u32 demodId; -+} MXL_HYDRA_DEMOD_ABORT_TUNE_T; -+ -+typedef struct -+{ -+ u8 tunerId; -+ u8 enable; -+} MxL_HYDRA_TUNER_CMD; -+ -+// Demod Para for Channel Tune -+typedef struct -+{ -+ u32 tunerIndex; -+ u32 demodIndex; -+ u32 frequencyInHz; // Frequency -+ u32 standard; // one of MXL_HYDRA_BCAST_STD_E -+ u32 spectrumInversion; // Input : Spectrum inversion. -+ u32 rollOff; /* rollOff (alpha) factor */ -+ u32 symbolRateInHz; /* Symbol rate */ -+ u32 pilots; /* TRUE = pilots enabled */ -+ u32 modulationScheme; // Input : Modulation Scheme is one of MXL_HYDRA_MODULATION_E -+ u32 fecCodeRate; // Input : Forward error correction rate. Is one of MXL_HYDRA_FEC_E -+ u32 maxCarrierOffsetInMHz; // Maximum carrier freq offset in MHz. Same as freqSearchRangeKHz, but in unit of MHz. -+} MXL_HYDRA_DEMOD_PARAM_T; -+ -+typedef struct -+{ -+ u32 demodIndex; -+ u8 scrambleSequence[12]; // scramble sequence -+ u32 scrambleCode; // scramble gold code -+} MXL_HYDRA_DEMOD_SCRAMBLE_CODE_T; -+ -+typedef struct -+{ -+ u32 intrType; -+ u32 intrDurationInNanoSecs; -+ u32 intrMask; -+} MXL_INTR_CFG_T; -+ -+typedef struct -+{ -+ u8 powerMode; // enumeration values are defined in MXL_HYDRA_PWR_MODE_E (device API.h) -+} MxL_HYDRA_POWER_MODE_CMD; -+ -+ -+typedef struct -+{ -+ u32 timeIntervalInSeconds; // in seconds -+ u32 tunerIndex; -+ s32 rssiThreshold; -+ -+} MXL_HYDRA_RF_WAKEUP_PARAM_T; -+ -+typedef struct -+{ -+ u32 tunerCount; -+ MXL_HYDRA_RF_WAKEUP_PARAM_T params; -+} MXL_HYDRA_RF_WAKEUP_CFG_T; -+ -+ -+typedef enum -+{ -+ MXL_HYDRA_AUX_CTRL_MODE_FSK = 0, // Select FSK controller -+ MXL_HYDRA_AUX_CTRL_MODE_DISEQC, // Select DiSEqC controller -+} MXL_HYDRA_AUX_CTRL_MODE_E; -+ -+ -+typedef enum -+{ -+ MXL_HYDRA_DISEQC_ENVELOPE_MODE = 0, -+ MXL_HYDRA_DISEQC_TONE_MODE, -+} MXL_HYDRA_DISEQC_OPMODE_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_DISEQC_1_X = 0, // Config DiSEqC 1.x mode -+ MXL_HYDRA_DISEQC_2_X, // Config DiSEqC 2.x mode -+ MXL_HYDRA_DISEQC_DISABLE // Disable DiSEqC -+} MXL_HYDRA_DISEQC_VER_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_DISEQC_CARRIER_FREQ_22KHZ= 0, // DiSEqC signal frequency of 22 KHz -+ MXL_HYDRA_DISEQC_CARRIER_FREQ_33KHZ, // DiSEqC signal frequency of 33 KHz -+ MXL_HYDRA_DISEQC_CARRIER_FREQ_44KHZ // DiSEqC signal frequency of 44 KHz -+} MXL_HYDRA_DISEQC_CARRIER_FREQ_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_DISEQC_ID_0 = 0, -+ MXL_HYDRA_DISEQC_ID_1, -+ MXL_HYDRA_DISEQC_ID_2, -+ MXL_HYDRA_DISEQC_ID_3 -+} MXL_HYDRA_DISEQC_ID_E; -+ -+typedef enum -+{ -+ MXL_HYDRA_FSK_CFG_TYPE_39KPBS = 0, // 39.0kbps -+ MXL_HYDRA_FSK_CFG_TYPE_39_017KPBS, // 39.017kbps -+ MXL_HYDRA_FSK_CFG_TYPE_115_2KPBS // 115.2kbps -+} MXL_HYDRA_FSK_OP_MODE_E; -+ -+ -+typedef struct -+{ -+ u32 diseqcId; // DSQ 0, 1, 2 or 3 -+ u32 opMode; // Envelope mode (0) or internal tone mode (1) -+ u32 version; // 0: 1.0 , 1: 1.1 , 2: Disable -+ u32 centerFreq; // 0: 22KHz, 1: 33KHz and 2: 44 KHz -+}MXL58x_DSQ_OP_MODE_T; -+ -+typedef struct -+{ -+ u32 diseqcId; -+ u32 contToneFlag; // 1: Enable , 0: Disable -+} MXL_HYDRA_DISEQC_CFG_CONT_TONE_T; -+ -+#define MXL_HYDRA_DISEQC_MAX_PKT_SIZE (32) -+ -+typedef enum -+{ -+ MXL_HYDRA_DISEQC_TONE_NONE = 0, -+ MXL_HYDRA_DISEQC_TONE_SA, -+ MXL_HYDRA_DISEQC_TONE_SB -+} MXL_HYDRA_DISEQC_TONE_CTRL_E; -+ -+typedef struct -+{ -+ u32 diseqcId; -+ u32 nbyte; -+ u8 bufMsg[MXL_HYDRA_DISEQC_MAX_PKT_SIZE]; -+ MXL_HYDRA_DISEQC_TONE_CTRL_E toneBurst; -+} MXL_HYDRA_DISEQC_TX_MSG_T; -+ -diff --git a/drivers/media/dvb-frontends/mxl5xx_regs.h b/drivers/media/dvb-frontends/mxl5xx_regs.h -new file mode 100644 -index 0000000..e983d0b ---- /dev/null -+++ b/drivers/media/dvb-frontends/mxl5xx_regs.h -@@ -0,0 +1,941 @@ -+/* -+* Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved -+* -+* License type: GPLv2 -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT -+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -+* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with -+* this program; if not, write to the Free Software Foundation, Inc., -+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -+* -+* This program may alternatively be licensed under a proprietary license from -+* MaxLinear, Inc. -+* -+* See terms and conditions defined in file 'LICENSE.txt', which is part of this -+* source code package. -+*/ -+ -+#ifndef __MXL58X_REGISTERS_H__ -+#define __MXL58X_REGISTERS_H__ -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define HYDRA_INTR_STATUS_REG 0x80030008 -+#define HYDRA_INTR_MASK_REG 0x8003000C -+ -+#define HYDRA_CRYSTAL_SETTING 0x3FFFC5F0 // 0 - 24 MHz & 1 - 27 MHz -+#define HYDRA_CRYSTAL_CAP 0x3FFFEDA4 // 0 - 24 MHz & 1 - 27 MHz -+ -+#define HYDRA_CPU_RESET_REG 0x8003003C -+#define HYDRA_CPU_RESET_DATA 0x00000400 -+ -+#define HYDRA_RESET_TRANSPORT_FIFO_REG 0x80030028 -+#define HYDRA_RESET_TRANSPORT_FIFO_DATA 0x00000000 -+ -+#define HYDRA_RESET_BBAND_REG 0x80030024 -+#define HYDRA_RESET_BBAND_DATA 0x00000000 -+ -+#define HYDRA_RESET_XBAR_REG 0x80030020 -+#define HYDRA_RESET_XBAR_DATA 0x00000000 -+ -+#define HYDRA_MODULES_CLK_1_REG 0x80030014 -+#define HYDRA_DISABLE_CLK_1 0x00000000 -+ -+#define HYDRA_MODULES_CLK_2_REG 0x8003001C -+#define HYDRA_DISABLE_CLK_2 0x0000000B -+ -+#define HYDRA_PRCM_ROOT_CLK_REG 0x80030018 -+#define HYDRA_PRCM_ROOT_CLK_DISABLE 0x00000000 -+ -+#define HYDRA_CPU_RESET_CHECK_REG 0x80030008 -+#define HYDRA_CPU_RESET_CHECK_OFFSET 0x40000000 // -+ -+#define HYDRA_SKU_ID_REG 0x90000190 -+ -+#define FW_DL_SIGN_ADDR 0x3FFFEAE0 -+ -+// Register to check if FW is running or not -+#define HYDRA_HEAR_BEAT 0x3FFFEDDC -+ -+// Firmware version -+#define HYDRA_FIRMWARE_VERSION 0x3FFFEDB8 -+#define HYDRA_FW_RC_VERSION 0x3FFFCFAC -+ -+// Firmware patch version -+#define HYDRA_FIRMWARE_PATCH_VERSION 0x3FFFEDC2 -+ -+// SOC operating temperature in C -+#define HYDRA_TEMPARATURE 0x3FFFEDB4 -+ -+// Demod & Tuner status registers -+// Demod 0 status base address -+#define HYDRA_DEMOD_0_BASE_ADDR 0x3FFFC64C -+ -+// Tuner 0 status base address -+#define HYDRA_TUNER_0_BASE_ADDR 0x3FFFCE4C -+ -+#define POWER_FROM_ADCRSSI_READBACK 0x3FFFEB6C -+ -+// Macros to determine base address of respective demod or tuner -+#define HYDRA_DMD_STATUS_OFFSET(demodID) ((demodID) * 0x100) -+#define HYDRA_TUNER_STATUS_OFFSET(tunerID) ((tunerID) * 0x40) -+ -+// Demod status address offset from respective demod's base address -+#define HYDRA_DMD_AGC_DIG_LEVEL_ADDR_OFFSET 0x3FFFC64C -+#define HYDRA_DMD_LOCK_STATUS_ADDR_OFFSET 0x3FFFC650 -+#define HYDRA_DMD_ACQ_STATUS_ADDR_OFFSET 0x3FFFC654 -+ -+#define HYDRA_DMD_STANDARD_ADDR_OFFSET 0x3FFFC658 -+#define HYDRA_DMD_SPECTRUM_INVERSION_ADDR_OFFSET 0x3FFFC65C -+#define HYDRA_DMD_SPECTRUM_ROLL_OFF_ADDR_OFFSET 0x3FFFC660 -+#define HYDRA_DMD_SYMBOL_RATE_ADDR_OFFSET 0x3FFFC664 -+#define HYDRA_DMD_MODULATION_SCHEME_ADDR_OFFSET 0x3FFFC668 -+#define HYDRA_DMD_FEC_CODE_RATE_ADDR_OFFSET 0x3FFFC66C -+ -+#define HYDRA_DMD_SNR_ADDR_OFFSET 0x3FFFC670 -+#define HYDRA_DMD_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC674 -+#define HYDRA_DMD_CTL_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC678 -+#define HYDRA_DMD_STR_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC67C -+#define HYDRA_DMD_FTL_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC680 -+#define HYDRA_DMD_STR_NBC_SYNC_LOCK_ADDR_OFFSET 0x3FFFC684 -+#define HYDRA_DMD_CYCLE_SLIP_COUNT_ADDR_OFFSET 0x3FFFC688 -+ -+#define HYDRA_DMD_DISPLAY_I_ADDR_OFFSET 0x3FFFC68C -+#define HYDRA_DMD_DISPLAY_Q_ADDR_OFFSET 0x3FFFC68E -+ -+#define HYDRA_DMD_DVBS2_CRC_ERRORS_ADDR_OFFSET 0x3FFFC690 -+#define HYDRA_DMD_DVBS2_PER_COUNT_ADDR_OFFSET 0x3FFFC694 -+#define HYDRA_DMD_DVBS2_PER_WINDOW_ADDR_OFFSET 0x3FFFC698 -+ -+#define HYDRA_DMD_DVBS_CORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC69C -+#define HYDRA_DMD_DVBS_UNCORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC6A0 -+#define HYDRA_DMD_DVBS_BER_COUNT_ADDR_OFFSET 0x3FFFC6A4 -+#define HYDRA_DMD_DVBS_BER_WINDOW_ADDR_OFFSET 0x3FFFC6A8 -+ -+// Debug-purpose DVB-S DMD 0 -+#define HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC6C8 // corrected RS Errors: 1st iteration -+#define HYDRA_DMD_DVBS_1ST_UNCORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC6CC // uncorrected RS Errors: 1st iteration -+#define HYDRA_DMD_DVBS_BER_COUNT_1ST_ADDR_OFFSET 0x3FFFC6D0 -+#define HYDRA_DMD_DVBS_BER_WINDOW_1ST_ADDR_OFFSET 0x3FFFC6D4 -+ -+#define HYDRA_DMD_TUNER_ID_ADDR_OFFSET 0x3FFFC6AC -+#define HYDRA_DMD_DVBS2_PILOT_ON_OFF_ADDR_OFFSET 0x3FFFC6B0 -+#define HYDRA_DMD_FREQ_SEARCH_RANGE_KHZ_ADDR_OFFSET 0x3FFFC6B4 -+#define HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET 0x3FFFC6B8 -+#define HYDRA_DMD_STATUS_CENTER_FREQ_IN_KHZ_ADDR 0x3FFFC704 -+#define HYDRA_DMD_STATUS_INPUT_POWER_ADDR 0x3FFFC708 -+ -+// DVB-S new scaled_BER_count for a new BER API, see HYDRA-1343 "DVB-S post viterbi information" -+#define DMD0_STATUS_DVBS_1ST_SCALED_BER_COUNT_ADDR 0x3FFFC710 // DMD 0: 1st iteration BER count scaled by HYDRA_BER_COUNT_SCALING_FACTOR -+#define DMD0_STATUS_DVBS_SCALED_BER_COUNT_ADDR 0x3FFFC714 // DMD 0: 2nd iteration BER count scaled by HYDRA_BER_COUNT_SCALING_FACTOR -+ -+#define DMD0_SPECTRUM_MIN_GAIN_STATUS 0x3FFFC73C -+#define DMD0_SPECTRUM_MIN_GAIN_WB_SAGC_VALUE 0x3FFFC740 -+#define DMD0_SPECTRUM_ MIN_GAIN_NB_SAGC_VALUE 0x3FFFC744 -+ -+#define HYDRA_DMD_STATUS_END_ADDR_OFFSET 0x3FFFC748 -+ -+// Tuner status address offset from respective tuners's base address -+#define HYDRA_TUNER_DEMOD_ID_ADDR_OFFSET 0x3FFFCE4C -+#define HYDRA_TUNER_AGC_LOCK_OFFSET 0x3FFFCE50 -+#define HYDRA_TUNER_SPECTRUM_STATUS_OFFSET 0x3FFFCE54 -+#define HYDRA_TUNER_SPECTRUM_BIN_SIZE_OFFSET 0x3FFFCE58 -+#define HYDRA_TUNER_SPECTRUM_ADDRESS_OFFSET 0x3FFFCE5C -+#define HYDRA_TUNER_ENABLE_COMPLETE 0x3FFFEB78 -+ -+#define HYDRA_DEMOD_STATUS_LOCK(devId, demodId) write_register(devId, (HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET + HYDRA_DMD_STATUS_OFFSET(demodId)), MXL_YES) -+#define HYDRA_DEMOD_STATUS_UNLOCK(devId, demodId) write_register(devId, (HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET + HYDRA_DMD_STATUS_OFFSET(demodId)), MXL_NO) -+ -+#define HYDRA_TUNER_STATUS_LOCK(devId,tunerId) MxLWare_HYDRA_WriteRegister(devId,(HYDRA_TUNER_STATUS_LOCK_ADDR_OFFSET + HYDRA_TUNER_STATUS_OFFSET(tunerId)), MXL_YES) -+#define HYDRA_TUNER_STATUS_UNLOCK(devId,tunerId) MxLWare_HYDRA_WriteRegister(devId,(HYDRA_TUNER_STATUS_LOCK_ADDR_OFFSET + HYDRA_TUNER_STATUS_OFFSET(tunerId)), MXL_NO) -+ -+#define HYDRA_VERSION 0x3FFFEDB8 -+#define HYDRA_DEMOD0_VERSION 0x3FFFEDBC -+#define HYDRA_DEMOD1_VERSION 0x3FFFEDC0 -+#define HYDRA_DEMOD2_VERSION 0x3FFFEDC4 -+#define HYDRA_DEMOD3_VERSION 0x3FFFEDC8 -+#define HYDRA_DEMOD4_VERSION 0x3FFFEDCC -+#define HYDRA_DEMOD5_VERSION 0x3FFFEDD0 -+#define HYDRA_DEMOD6_VERSION 0x3FFFEDD4 -+#define HYDRA_DEMOD7_VERSION 0x3FFFEDD8 -+#define HYDRA_HEAR_BEAT 0x3FFFEDDC -+#define HYDRA_SKU_MGMT 0x3FFFEBC0 -+ -+#define MXL_HYDRA_FPGA_A_ADDRESS 0x91C00000 -+#define MXL_HYDRA_FPGA_B_ADDRESS 0x91D00000 -+ -+// TS control base address -+#define HYDRA_TS_CTRL_BASE_ADDR 0x90700000 -+ -+#define MPEG_MUX_MODE_SLICE0_REG HYDRA_TS_CTRL_BASE_ADDR + 0x08 -+#define MPEG_MUX_MODE_SLICE0_OFFSET (0),(2) -+ -+#define MPEG_MUX_MODE_SLICE1_REG HYDRA_TS_CTRL_BASE_ADDR + 0x08 -+#define MPEG_MUX_MODE_SLICE1_OFFSET (2),(2) -+ -+#define PID_BANK_SEL_SLICE0_REG HYDRA_TS_CTRL_BASE_ADDR + 0x190 -+#define PID_BANK_SEL_SLICE1_REG HYDRA_TS_CTRL_BASE_ADDR + 0x1B0 -+ -+#define SW_REGULAR_PID_SW_BANK_OFFSET 0,1 -+#define SW_FIXED_PID_SW_BANK_OFFSET 1,1 -+ -+#define HW_REGULAR_PID_BANK_OFFSET 8,4 -+#define HW_FIXED_PID_BANK_OFFSET 4,4 -+ -+#define MPEG_CLK_GATED_REG HYDRA_TS_CTRL_BASE_ADDR + 0x20 -+#define MPEG_CLK_GATED_OFFSET 0,1 -+ -+#define MPEG_CLK_ALWAYS_ON_REG HYDRA_TS_CTRL_BASE_ADDR + 0x1D4 -+#define MPEG_CLK_ALWAYS_ON_OFFSET 0,1 -+ -+#define HYDRA_REGULAR_PID_BANK_A_REG HYDRA_TS_CTRL_BASE_ADDR + 0x190 -+#define HYDRA_REGULAR_PID_BAN K_A_OFFSET 0,1 -+ -+#define HYDRA_FIXED_PID_BANK_A_REG HYDRA_TS_CTRL_BASE_ADDR + 0x190 -+#define HYDRA_FIXED_PID_BANK_A_OFFSET 1,1 -+ -+#define HYDRA_REGULAR_PID_BANK_B_REG HYDRA_TS_CTRL_BASE_ADDR + 0x1B0 -+#define HYDRA_REGULAR_PID_BANK_B_OFFSET 0,1 -+ -+#define HYDRA_FIXED_PID_BANK_B_REG HYDRA_TS_CTRL_BASE_ADDR + 0x1B0 -+#define HYDRA_FIXED_PID_BANK_B_OFFSET 1,1 -+ -+#define FIXED_PID_TBL_REG_ADDRESS_0 HYDRA_TS_CTRL_BASE_ADDR + 0x9000 -+#define FIXED_PID_TBL_REG_ADDRESS_1 HYDRA_TS_CTRL_BASE_ADDR + 0x9100 -+#define FIXED_PID_TBL_REG_ADDRESS_2 HYDRA_TS_CTRL_BASE_ADDR + 0x9200 -+#define FIXED_PID_TBL_REG_ADDRESS_3 HYDRA_TS_CTRL_BASE_ADDR + 0x9300 -+ -+#define FIXED_PID_TBL_REG_ADDRESS_4 HYDRA_TS_CTRL_BASE_ADDR + 0xB000 -+#define FIXED_PID_TBL_REG_ADDRESS_5 HYDRA_TS_CTRL_BASE_ADDR + 0xB100 -+#define FIXED_PID_TBL_REG_ADDRESS_6 HYDRA_TS_CTRL_BASE_ADDR + 0xB200 -+#define FIXED_PID_TBL_REG_ADDRESS_7 HYDRA_TS_CTRL_BASE_ADDR + 0xB300 -+ -+#define REGULAR_PID_TBL_REG_ADDRESS_0 HYDRA_TS_CTRL_BASE_ADDR + 0x8000 -+#define REGULAR_PID_TBL_REG_ADDRESS_1 HYDRA_TS_CTRL_BASE_ADDR + 0x8200 -+#define REGULAR_PID_TBL_REG_ADDRESS_2 HYDRA_TS_CTRL_BASE_ADDR + 0x8400 -+#define REGULAR_PID_TBL_REG_ADDRESS_3 HYDRA_TS_CTRL_BASE_ADDR + 0x8600 -+ -+#define REGULAR_PID_TBL_REG_ADDRESS_4 HYDRA_TS_CTRL_BASE_ADDR + 0xA000 -+#define REGULAR_PID_TBL_REG_ADDRESS_5 HYDRA_TS_CTRL_BASE_ADDR + 0xA200 -+#define REGULAR_PID_TBL_REG_ADDRESS_6 HYDRA_TS_CTRL_BASE_ADDR + 0xA400 -+#define REGULAR_PID_TBL_REG_ADDRESS_7 HYDRA_TS_CTRL_BASE_ADDR + 0xA600 -+ -+#define PID_VALID_OFFSET 0,1 -+#define PID_DROP_OFFSET 1,1 -+#define PID_REMAP_ENABLE_OFFSET 2,1 -+#define PID_VALUE_OFFSET 4,13 -+#define PID_MASK_OFFSET 19,13 -+ -+#define REGULAR_PID_REMAP_VALUE_OFFSET 0,13 -+#define FIXED_PID_REMAP_VALUE_OFFSET 0,16 -+#define PID_DEMODID_OFFSET 16,3 -+ -+ -+/////////////////////////////////////////////// -+ -+#if 0 -+#define AFE_REG_D2A_TA_ADC_CLK_OUT_FLIP 0x90200004,12,1 -+#define AFE_REG_D2A_TA_RFFE_LNACAPLOAD_1P8 0x90200028,24,4 -+#define AFE_REG_D2A_TA_RFFE_RF1_EN_1P8 0x90200028,5,1 -+#define AFE_REG_D2A_TA_RFFE_SPARE_1P8 0x90200028,8,8 -+#define AFE_REG_D2A_TB_ADC_CLK_OUT_FLIP 0x9020000C,23,1 -+#define AFE_REG_D2A_TB_RFFE_LNACAPLOAD_1P8 0x90200030,16,4 -+#define AFE_REG_D2A_TB_RFFE_RF1_EN_1P8 0x9020002C,21,1 -+#define AFE_REG_D2A_TB_RFFE_SPARE_1P8 0x90200030,0,8 -+#define AFE_REG_D2A_TC_ADC_CLK_OUT_FLIP 0x90200018,7,1 -+#define AFE_REG_D2A_TC_RFFE_LNACAPLOAD_1P8 0x90200038,2,4 -+#define AFE_REG_D2A_TC_RFFE_RF1_EN_1P8 0x90200034,14,1 -+#define AFE_REG_D2A_TC_RFFE_SPARE_1P8 0x90200034,17,8 -+#define AFE_REG_D2A_TD_ADC_CLK_OUT_FLIP 0x90200020,18,1 -+#define AFE_REG_D2A_TD_RFFE_LNACAPLOAD_1P8 0x9020003C,17,4 -+#define AFE_REG_D2A_TD_RFFE_RF1_EN_1P8 0x90200038,29,1 -+#define AFE_REG_D2A_TD_RFFE_SPARE_1P8 0x9020003C,1,8 -+#endif -+#define AFE_REG_D2A_XTAL_EN_CLKOUT_1P8 0x90200054,23,1 -+ -+#define PAD_MUX_TS0_IN_CLK_PINMUX_SEL 0x90000018,0,3 -+#define PAD_MUX_TS0_IN_DATA_PINMUX_SEL 0x90000018,4,3 -+#define PAD_MUX_TS1_IN_CLK_PINMUX_SEL 0x90000018,8,3 -+#define PAD_MUX_TS1_IN_DATA_PINMUX_SEL 0x90000018,12,3 -+#define PAD_MUX_TS2_IN_CLK_PINMUX_SEL 0x90000018,16,3 -+#define PAD_MUX_TS2_IN_DATA_PINMUX_SEL 0x90000018,20,3 -+#define PAD_MUX_TS3_IN_CLK_PINMUX_SEL 0x90000018,24,3 -+#define PAD_MUX_TS3_IN_DATA_PINMUX_SEL 0x90000018,28,3 -+ -+#define PAD_MUX_GPIO_00_SYNC_BASEADDR 0x90000188 -+#define PAD_MUX_GPIO_01_SYNC_IN PAD_MUX_GPIO_00_SYNC_BASEADDR,1,1 -+ -+#define PRCM_AFE_SOC_ID 0x80030004,24,8 -+ -+#define PAD_MUX_UART_RX_C_PINMUX_BASEADDR 0x9000001C -+#define PAD_MUX_UART_RX_C_PINMUX_SEL PAD_MUX_UART_RX_C_PINMUX_BASEADDR,0,3 -+#define PAD_MUX_UART_RX_D_PINMUX_SEL PAD_MUX_UART_RX_C_PINMUX_BASEADDR,4,3 -+#define PAD_MUX_BOND_OPTION 0x90000190,0,3 -+#define PAD_MUX_DIGIO_01_PINMUX_SEL 0x9000016C,4,3 -+#define PAD_MUX_DIGIO_02_PINMUX_SEL 0x9000016C,8,3 -+#define PAD_MUX_DIGIO_03_PINMUX_SEL 0x9000016C,12,3 -+#define PAD_MUX_DIGIO_04_PINMUX_SEL 0x9000016C,16,3 -+#define PAD_MUX_DIGIO_05_PINMUX_SEL 0x9000016C,20,3 -+#define PAD_MUX_DIGIO_06_PINMUX_SEL 0x9000016C,24,3 -+#define PAD_MUX_DIGIO_07_PINMUX_SEL 0x9000016C,28,3 -+#define PAD_MUX_DIGIO_08_PINMUX_SEL 0x90000170,0,3 -+#define PAD_MUX_DIGIO_09_PINMUX_SEL 0x90000170,4,3 -+#define PAD_MUX_DIGIO_10_PINMUX_SEL 0x90000170,8,3 -+#define PAD_MUX_DIGIO_11_PINMUX_SEL 0x90000170,12,3 -+#define PAD_MUX_DIGIO_12_PINMUX_SEL 0x90000170,16,3 -+#define PAD_MUX_DIGIO_13_PINMUX_SEL 0x90000170,20,3 -+#define PAD_MUX_DIGIO_14_PINMUX_SEL 0x90000170,24,3 -+#define PAD_MUX_DIGIO_15_PINMUX_SEL 0x90000170,28,3 -+#define PAD_MUX_DIGIO_16_PINMUX_SEL 0x90000174,0,3 -+#define PAD_MUX_DIGIO_17_PINMUX_SEL 0x90000174,4,3 -+#define PAD_MUX_DIGIO_18_PINMUX_SEL 0x90000174,8,3 -+#define PAD_MUX_DIGIO_19_PINMUX_SEL 0x90000174,12,3 -+#define PAD_MUX_DIGIO_20_PINMUX_SEL 0x90000174,16,3 -+#define PAD_MUX_DIGIO_21_PINMUX_SEL 0x90000174,20,3 -+#define PAD_MUX_DIGIO_22_PINMUX_SEL 0x90000174,24,3 -+#define PAD_MUX_DIGIO_23_PINMUX_SEL 0x90000174,28,3 -+#define PAD_MUX_DIGIO_24_PINMUX_SEL 0x90000178,0,3 -+#define PAD_MUX_DIGIO_25_PINMUX_SEL 0x90000178,4,3 -+#define PAD_MUX_DIGIO_26_PINMUX_SEL 0x90000178,8,3 -+#define PAD_MUX_DIGIO_27_PINMUX_SEL 0x90000178,12,3 -+#define PAD_MUX_DIGIO_28_PINMUX_SEL 0x90000178,16,3 -+#define PAD_MUX_DIGIO_29_PINMUX_SEL 0x90000178,20,3 -+#define PAD_MUX_DIGIO_30_PINMUX_SEL 0x90000178,24,3 -+#define PAD_MUX_DIGIO_31_PINMUX_SEL 0x90000178,28,3 -+#define PAD_MUX_DIGIO_32_PINMUX_SEL 0x9000017C,0,3 -+#define PAD_MUX_DIGIO_33_PINMUX_SEL 0x9000017C,4,3 -+#define PAD_MUX_DIGIO_34_PINMUX_SEL 0x9000017C,8,3 -+#define PAD_MUX_EJTAG_TCK_PINMUX_SEL 0x90000020,0,3 -+#define PAD_MUX_EJTAG_TDI_PINMUX_SEL 0x90000020,8,3 -+#define PAD_MUX_EJTAG_TMS_PINMUX_SEL 0x90000020,4,3 -+#define PAD_MUX_EJTAG_TRSTN_PINMUX_SEL 0x90000020,12,3 -+#define PAD_MUX_PAD_DRV_DIGIO_00 0x90000194,0,3 -+#define PAD_MUX_PAD_DRV_DIGIO_05 0x90000194,20,3 -+#define PAD_MUX_PAD_DRV_DIGIO_06 0x90000194,24,3 -+#define PAD_MUX_PAD_DRV_DIGIO_11 0x90000198,12,3 -+#define PAD_MUX_PAD_DRV_DIGIO_12 0x90000198,16,3 -+#define PAD_MUX_PAD_DRV_DIGIO_13 0x90000198,20,3 -+#define PAD_MUX_PAD_DRV_DIGIO_14 0x90000198,24,3 -+#define PAD_MUX_PAD_DRV_DIGIO_16 0x9000019C,0,3 -+#define PAD_MUX_PAD_DRV_DIGIO_17 0x9000019C,4,3 -+#define PAD_MUX_PAD_DRV_DIGIO_18 0x9000019C,8,3 -+#define PAD_MUX_PAD_DRV_DIGIO_22 0x9000019C,24,3 -+#define PAD_MUX_PAD_DRV_DIGIO_23 0x9000019C,28,3 -+#define PAD_MUX_PAD_DRV_DIGIO_24 0x900001A0,0,3 -+#define PAD_MUX_PAD_DRV_DIGIO_25 0x900001A0,4,3 -+#define PAD_MUX_PAD_DRV_DIGIO_29 0x900001A0,20,3 -+#define PAD_MUX_PAD_DRV_DIGIO_30 0x900001A0,24,3 -+#define PAD_MUX_PAD_DRV_DIGIO_31 0x900001A0,28,3 -+#define PRCM_AFE_REG_CLOCK_ENABLE 0x80030014,9,1 -+#define PRCM_CHIP_VERSION 0x80030000,12,4 -+#define PRCM_AFE_CHIP_MMSK_VER 0x80030004,8,8 -+#define PRCM_PRCM_AFE_REG_SOFT_RST_N 0x8003003C,12,1 -+#define PRCM_PRCM_CPU_SOFT_RST_N 0x8003003C,0,1 -+#define PRCM_PRCM_DIGRF_APB_DATA_BB0 0x80030074,0,20 -+#define PRCM_PRCM_DIGRF_APB_DATA_BB1 0x80030078,0,20 -+#define PRCM_PRCM_DIGRF_APB_DATA_BB2 0x8003007C,0,20 -+#define PRCM_PRCM_DIGRF_APB_DATA_BB3 0x80030080,0,20 -+#define PRCM_PRCM_DIGRF_APB_DATA_BB4 0x80030084,0,20 -+#define PRCM_PRCM_DIGRF_APB_DATA_BB5 0x80030088,0,20 -+#define PRCM_PRCM_DIGRF_APB_DATA_BB6 0x8003008C,0,20 -+#define PRCM_PRCM_DIGRF_APB_DATA_BB7 0x80030090,0,20 -+#define PRCM_PRCM_DIGRF_CAPT_DONE 0x80030070,24,8 -+#define PRCM_PRCM_DIGRF_START_CAPT 0x80030064,2,1 -+#define PRCM_PRCM_PAD_MUX_SOFT_RST_N 0x8003003C,11,1 -+#define PRCM_PRCM_XPT_PARALLEL_FIFO_RST_N 0x80030028,20,1 -+#define XPT_APPEND_BYTES0 0x90700008,4,2 -+#define XPT_APPEND_BYTES1 0x90700008,6,2 -+#define XPT_CLOCK_POLARITY0 0x90700010,16,1 -+#define XPT_CLOCK_POLARITY1 0x90700010,17,1 -+#define XPT_CLOCK_POLARITY2 0x90700010,18,1 -+#define XPT_CLOCK_POLARITY3 0x90700010,19,1 -+#define XPT_CLOCK_POLARITY4 0x90700010,20,1 -+#define XPT_CLOCK_POLARITY5 0x90700010,21,1 -+#define XPT_CLOCK_POLARITY6 0x90700010,22,1 -+#define XPT_CLOCK_POLARITY7 0x90700010,23,1 -+#define XPT_DSS_DVB_ENCAP_EN0 0x90700000,16,1 -+#define XPT_DSS_DVB_ENCAP_EN1 0x90700000,17,1 -+#define XPT_DSS_DVB_ENCAP_EN2 0x90700000,18,1 -+#define XPT_DSS_DVB_ENCAP_EN3 0x90700000,19,1 -+#define XPT_DSS_DVB_ENCAP_EN4 0x90700000,20,1 -+#define XPT_DSS_DVB_ENCAP_EN5 0x90700000,21,1 -+#define XPT_DSS_DVB_ENCAP_EN6 0x90700000,22,1 -+#define XPT_DSS_DVB_ENCAP_EN7 0x90700000,23,1 -+#define XPT_DVB_MATCH_BYTE 0x9070017C,16,8 -+#define XPT_DVB_PACKET_SIZE0 0x90700180,0,8 -+#define XPT_DVB_PACKET_SIZE1 0x90700180,8,8 -+#define XPT_DVB_PACKET_SIZE2 0x90700180,16,8 -+#define XPT_DVB_PACKET_SIZE3 0x90700180,24,8 -+#define XPT_ENABLE_DVB_INPUT0 0x90700178,0,1 -+#define XPT_ENABLE_DVB_INPUT1 0x90700178,1,1 -+#define XPT_ENABLE_DVB_INPUT2 0x90700178,2,1 -+#define XPT_ENABLE_DVB_INPUT3 0x90700178,3,1 -+#define XPT_ENABLE_INPUT0 0x90700000,0,1 -+#define XPT_ENABLE_INPUT1 0x90700000,1,1 -+#define XPT_ENABLE_INPUT2 0x90700000,2,1 -+#define XPT_ENABLE_INPUT3 0x90700000,3,1 -+#define XPT_ENABLE_INPUT4 0x90700000,4,1 -+#define XPT_ENABLE_INPUT5 0x90700000,5,1 -+#define XPT_ENABLE_INPUT6 0x90700000,6,1 -+#define XPT_ENABLE_INPUT7 0x90700000,7,1 -+#define XPT_ENABLE_OUTPUT0 0x9070000C,0,1 -+#define XPT_ENABLE_OUTPUT1 0x9070000C,1,1 -+#define XPT_ENABLE_OUTPUT2 0x9070000C,2,1 -+#define XPT_ENABLE_OUTPUT3 0x9070000C,3,1 -+#define XPT_ENABLE_OUTPUT4 0x9070000C,4,1 -+#define XPT_ENABLE_OUTPUT5 0x9070000C,5,1 -+#define XPT_ENABLE_OUTPUT6 0x9070000C,6,1 -+#define XPT_ENABLE_OUTPUT7 0x9070000C,7,1 -+#define XPT_ENABLE_PARALLEL_OUTPUT 0x90700010,27,1 -+#define XPT_ENABLE_PCR_COUNT 0x90700184,1,1 -+#define XPT_ERROR_REPLACE_SYNC0 0x9070000C,24,1 -+#define XPT_ERROR_REPLACE_SYNC1 0x9070000C,25,1 -+#define XPT_ERROR_REPLACE_SYNC2 0x9070000C,26,1 -+#define XPT_ERROR_REPLACE_SYNC3 0x9070000C,27,1 -+#define XPT_ERROR_REPLACE_SYNC4 0x9070000C,28,1 -+#define XPT_ERROR_REPLACE_SYNC5 0x9070000C,29,1 -+#define XPT_ERROR_REPLACE_SYNC6 0x9070000C,30,1 -+#define XPT_ERROR_REPLACE_SYNC7 0x9070000C,31,1 -+#define XPT_ERROR_REPLACE_VALID0 0x90700014,8,1 -+#define XPT_ERROR_REPLACE_VALID1 0x90700014,9,1 -+#define XPT_ERROR_REPLACE_VALID2 0x90700014,10,1 -+#define XPT_ERROR_REPLACE_VALID3 0x90700014,11,1 -+#define XPT_ERROR_REPLACE_VALID4 0x90700014,12,1 -+#define XPT_ERROR_REPLACE_VALID5 0x90700014,13,1 -+#define XPT_ERROR_REPLACE_VALID6 0x90700014,14,1 -+#define XPT_ERROR_REPLACE_VALID7 0x90700014,15,1 -+#define XPT_INP0_MERGE_HDR0 0x90700058,0,32 -+#define XPT_INP0_MERGE_HDR1 0x9070005C,0,32 -+#define XPT_INP0_MERGE_HDR2 0x90700060,0,32 -+#define XPT_INP1_MERGE_HDR0 0x90700064,0,32 -+#define XPT_INP1_MERGE_HDR1 0x90700068,0,32 -+#define XPT_INP1_MERGE_HDR2 0x9070006C,0,32 -+#define XPT_INP2_MERGE_HDR0 0x90700070,0,32 -+#define XPT_INP2_MERGE_HDR1 0x90700074,0,32 -+#define XPT_INP2_MERGE_HDR2 0x90700078,0,32 -+#define XPT_INP3_MERGE_HDR0 0x9070007C,0,32 -+#define XPT_INP3_MERGE_HDR1 0x90700080,0,32 -+#define XPT_INP3_MERGE_HDR2 0x90700084,0,32 -+#define XPT_INP4_MERGE_HDR0 0x90700088,0,32 -+#define XPT_INP4_MERGE_HDR1 0x9070008C,0,32 -+#define XPT_INP4_MERGE_HDR2 0x90700090,0,32 -+#define XPT_INP5_MERGE_HDR0 0x90700094,0,32 -+#define XPT_INP5_MERGE_HDR1 0x90700098,0,32 -+#define XPT_INP5_MERGE_HDR2 0x9070009C,0,32 -+#define XPT_INP6_MERGE_HDR0 0x907000A0,0,32 -+#define XPT_INP6_MERGE_HDR1 0x907000A4,0,32 -+#define XPT_INP6_MERGE_HDR2 0x907000A8,0,32 -+#define XPT_INP7_MERGE_HDR0 0x907000AC,0,32 -+#define XPT_INP7_MERGE_HDR1 0x907000B0,0,32 -+#define XPT_INP7_MERGE_HDR2 0x907000B4,0,32 -+#define XPT_INP_MODE_DSS0 0x90700000,8,1 -+#define XPT_INP_MODE_DSS1 0x90700000,9,1 -+#define XPT_INP_MODE_DSS2 0x90700000,10,1 -+#define XPT_INP_MODE_DSS3 0x90700000,11,1 -+#define XPT_INP_MODE_DSS4 0x90700000,12,1 -+#define XPT_INP_MODE_DSS5 0x90700000,13,1 -+#define XPT_INP_MODE_DSS6 0x90700000,14,1 -+#define XPT_INP_MODE_DSS7 0x90700000,15,1 -+#define XPT_KNOWN_PID_MUX_SELECT0 0x90700190,8,4 -+#define XPT_KNOWN_PID_MUX_SELECT1 0x907001B0,8,4 -+#define XPT_LSB_FIRST0 0x9070000C,16,1 -+#define XPT_LSB_FIRST1 0x9070000C,17,1 -+#define XPT_LSB_FIRST2 0x9070000C,18,1 -+#define XPT_LSB_FIRST3 0x9070000C,19,1 -+#define XPT_LSB_FIRST4 0x9070000C,20,1 -+#define XPT_LSB_FIRST5 0x9070000C,21,1 -+#define XPT_LSB_FIRST6 0x9070000C,22,1 -+#define XPT_LSB_FIRST7 0x9070000C,23,1 -+#define XPT_MODE_27MHZ 0x90700184,0,1 -+#define XPT_NCO_COUNT_MIN 0x90700044,16,8 -+#define XPT_OUTPUT_MODE_DSS0 0x9070000C,8,1 -+#define XPT_OUTPUT_MODE_DSS1 0x9070000C,9,1 -+#define XPT_OUTPUT_MODE_DSS2 0x9070000C,10,1 -+#define XPT_OUTPUT_MODE_DSS3 0x9070000C,11,1 -+#define XPT_OUTPUT_MODE_DSS4 0x9070000C,12,1 -+#define XPT_OUTPUT_MODE_DSS5 0x9070000C,13,1 -+#define XPT_OUTPUT_MODE_DSS6 0x9070000C,14,1 -+#define XPT_OUTPUT_MODE_DSS7 0x9070000C,15,1 -+#define XPT_OUTPUT_MODE_MUXGATING0 0x90700020,0,1 -+#define XPT_OUTPUT_MODE_MUXGATING1 0x90700020,1,1 -+#define XPT_OUTPUT_MODE_MUXGATING2 0x90700020,2,1 -+#define XPT_OUTPUT_MODE_MUXGATING3 0x90700020,3,1 -+#define XPT_OUTPUT_MODE_MUXGATING4 0x90700020,4,1 -+#define XPT_OUTPUT_MODE_MUXGATING5 0x90700020,5,1 -+#define XPT_OUTPUT_MODE_MUXGATING6 0x90700020,6,1 -+#define XPT_OUTPUT_MODE_MUXGATING7 0x90700020,7,1 -+#define XPT_OUTPUT_MUXSELECT0 0x9070001C,0,3 -+#define XPT_OUTPUT_MUXSELECT1 0x9070001C,4,3 -+#define XPT_OUTPUT_MUXSELECT2 0x9070001C,8,3 -+#define XPT_OUTPUT_MUXSELECT3 0x9070001C,12,3 -+#define XPT_OUTPUT_MUXSELECT4 0x9070001C,16,3 -+#define XPT_OUTPUT_MUXSELECT5 0x9070001C,20,3 -+#define XPT_PCR_RTS_CORRECTION_ENABLE 0x90700008,14,1 -+#define XPT_PID_DEFAULT_DROP0 0x90700190,12,1 -+#define XPT_PID_DEFAULT_DROP1 0x90700190,13,1 -+#define XPT_PID_DEFAULT_DROP2 0x90700190,14,1 -+#define XPT_PID_DEFAULT_DROP3 0x90700190,15,1 -+#define XPT_PID_DEFAULT_DROP4 0x907001B0,12,1 -+#define XPT_PID_DEFAULT_DROP5 0x907001B0,13,1 -+#define XPT_PID_DEFAULT_DROP6 0x907001B0,14,1 -+#define XPT_PID_DEFAULT_DROP7 0x907001B0,15,1 -+#define XPT_PID_MUX_SELECT0 0x90700190,4,4 -+#define XPT_PID_MUX_SELECT1 0x907001B0,4,4 -+#define XPT_STREAM_MUXMODE0 0x90700008,0,2 -+#define XPT_STREAM_MUXMODE1 0x90700008,2,2 -+#define XPT_SYNC_FULL_BYTE0 0x90700010,0,1 -+#define XPT_SYNC_FULL_BYTE1 0x90700010,1,1 -+#define XPT_SYNC_FULL_BYTE2 0x90700010,2,1 -+#define XPT_SYNC_FULL_BYTE3 0x90700010,3,1 -+#define XPT_SYNC_FULL_BYTE4 0x90700010,4,1 -+#define XPT_SYNC_FULL_BYTE5 0x90700010,5,1 -+#define XPT_SYNC_FULL_BYTE6 0x90700010,6,1 -+#define XPT_SYNC_FULL_BYTE7 0x90700010,7,1 -+#define XPT_SYNC_LOCK_THRESHOLD 0x9070017C,0,8 -+#define XPT_SYNC_MISS_THRESHOLD 0x9070017C,8,8 -+#define XPT_SYNC_POLARITY0 0x90700010,8,1 -+#define XPT_SYNC_POLARITY1 0x90700010,9,1 -+#define XPT_SYNC_POLARITY2 0x90700010,10,1 -+#define XPT_SYNC_POLARITY3 0x90700010,11,1 -+#define XPT_SYNC_POLARITY4 0x90700010,12,1 -+#define XPT_SYNC_POLARITY5 0x90700010,13,1 -+#define XPT_SYNC_POLARITY6 0x90700010,14,1 -+#define XPT_SYNC_POLARITY7 0x90700010,15,1 -+#define XPT_TS_CLK_OUT_EN0 0x907001D4,0,1 -+#define XPT_TS_CLK_OUT_EN1 0x907001D4,1,1 -+#define XPT_TS_CLK_OUT_EN2 0x907001D4,2,1 -+#define XPT_TS_CLK_OUT_EN3 0x907001D4,3,1 -+#define XPT_TS_CLK_OUT_EN4 0x907001D4,4,1 -+#define XPT_TS_CLK_OUT_EN5 0x907001D4,5,1 -+#define XPT_TS_CLK_OUT_EN6 0x907001D4,6,1 -+#define XPT_TS_CLK_OUT_EN7 0x907001D4,7,1 -+#define XPT_TS_CLK_OUT_EN_PARALLEL 0x907001D4,8,1 -+#define XPT_TS_CLK_PHASE0 0x90700018,0,3 -+#define XPT_TS_CLK_PHASE1 0x90700018,4,3 -+#define XPT_TS_CLK_PHASE2 0x90700018,8,3 -+#define XPT_TS_CLK_PHASE3 0x90700018,12,3 -+#define XPT_TS_CLK_PHASE4 0x90700018,16,3 -+#define XPT_TS_CLK_PHASE5 0x90700018,20,3 -+#define XPT_TS_CLK_PHASE6 0x90700018,24,3 -+#define XPT_TS_CLK_PHASE7 0x90700018,28,3 -+#define XPT_VALID_POLARITY0 0x90700014,0,1 -+#define XPT_VALID_POLARITY1 0x90700014,1,1 -+#define XPT_VALID_POLARITY2 0x90700014,2,1 -+#define XPT_VALID_POLARITY3 0x90700014,3,1 -+#define XPT_VALID_POLARITY4 0x90700014,4,1 -+#define XPT_VALID_POLARITY5 0x90700014,5,1 -+#define XPT_VALID_POLARITY6 0x90700014,6,1 -+#define XPT_VALID_POLARITY7 0x90700014,7,1 -+#define XPT_ZERO_FILL_COUNT 0x90700008,8,6 -+ -+#define XPT_PACKET_GAP_MIN_BASEADDR 0x90700044 -+#define XPT_PACKET_GAP_MIN_TIMER XPT_PACKET_GAP_MIN_BASEADDR,0,16 -+#define XPT_NCO_COUNT_MIN0 XPT_PACKET_GAP_MIN_BASEADDR,16,8 -+#define XPT_NCO_COUNT_BASEADDR 0x90700238 -+#define XPT_NCO_COUNT_MIN1 XPT_NCO_COUNT_BASEADDR,0,8 -+#define XPT_NCO_COUNT_MIN2 XPT_NCO_COUNT_BASEADDR,8,8 -+#define XPT_NCO_COUNT_MIN3 XPT_NCO_COUNT_BASEADDR,16,8 -+#define XPT_NCO_COUNT_MIN4 XPT_NCO_COUNT_BASEADDR,24,8 -+ -+#define XPT_NCO_COUNT_BASEADDR1 0x9070023C -+#define XPT_NCO_COUNT_MIN5 XPT_NCO_COUNT_BASEADDR1,0,8 -+#define XPT_NCO_COUNT_MIN6 XPT_NCO_COUNT_BASEADDR1,8,8 -+#define XPT_NCO_COUNT_MIN7 XPT_NCO_COUNT_BASEADDR1,16,8 -+ -+// V2 DigRF status register -+#define BB0_DIGRF_CAPT_DONE 0x908000CC,0,1 -+#define PRCM_PRCM_CHIP_ID 0x80030000,0,12 -+ -+#define XPT_PID_BASEADDR 0x90708000 -+#define XPT_PID_VALID0 XPT_PID_BASEADDR,0,1 -+#define XPT_PID_DROP0 XPT_PID_BASEADDR,1,1 -+#define XPT_PID_REMAP0 XPT_PID_BASEADDR,2,1 -+#define XPT_PID_VALUE0 XPT_PID_BASEADDR,4,13 -+#define XPT_PID_MASK0 XPT_PID_BASEADDR,19,13 -+ -+#define XPT_PID_REMAP_BASEADDR 0x90708004 -+#define XPT_PID_REMAP_VALUE0 XPT_PID_REMAP_BASEADDR,0,13 -+#define XPT_PID_PORT_ID0 XPT_PID_REMAP_BASEADDR,16,3 -+ -+#define XPT_KNOWN_PID_BASEADDR 0x90709000 -+#define XPT_KNOWN_PID_VALID0 XPT_KNOWN_PID_BASEADDR,0,1 -+#define XPT_KNOWN_PID_DROP0 XPT_KNOWN_PID_BASEADDR,1,1 -+#define XPT_KNOWN_PID_REMAP0 XPT_KNOWN_PID_BASEADDR,2,1 -+#define XPT_KNOWN_PID_REMAP_VALUE0 XPT_KNOWN_PID_BASEADDR,16,13 -+ -+#define XPT_PID_BASEADDR1 0x9070A000 -+#define XPT_PID_VALID1 XPT_PID_BASEADDR1,0,1 -+#define XPT_PID_DROP1 XPT_PID_BASEADDR1,1,1 -+#define XPT_PID_REMAP1 XPT_PID_BASEADDR1,2,1 -+#define XPT_PID_VALUE1 XPT_PID_BASEADDR1,4,13 -+#define XPT_PID_MASK1 XPT_PID_BASEADDR1,19,13 -+ -+#define XPT_PID_REMAP_BASEADDR1 0x9070A004 -+#define XPT_PID_REMAP_VALUE1 XPT_PID_REMAP_BASEADDR1,0,13 -+ -+#define XPT_KNOWN_PID_BASEADDR1 0x9070B000 -+#define XPT_KNOWN_PID_VALID1 XPT_KNOWN_PID_BASEADDR1,0,1 -+#define XPT_KNOWN_PID_DROP1 XPT_KNOWN_PID_BASEADDR1,1,1 -+#define XPT_KNOWN_PID_REMAP1 XPT_KNOWN_PID_BASEADDR1,2,1 -+#define XPT_KNOWN_PID_REMAP_VALUE1 XPT_KNOWN_PID_BASEADDR1,16,13 -+ -+#define XPT_BERT_LOCK_BASEADDR 0x907000B8 -+#define XPT_BERT_LOCK_THRESHOLD XPT_BERT_LOCK_BASEADDR,0,8 -+#define XPT_BERT_LOCK_WINDOW XPT_BERT_LOCK_BASEADDR,8,8 -+ -+#define XPT_BERT_BASEADDR 0x907000BC -+#define XPT_BERT_ENABLE0 XPT_BERT_BASEADDR,0,1 -+#define XPT_BERT_ENABLE1 XPT_BERT_BASEADDR,1,1 -+#define XPT_BERT_ENABLE2 XPT_BERT_BASEADDR,2,1 -+#define XPT_BERT_ENABLE3 XPT_BERT_BASEADDR,3,1 -+#define XPT_BERT_ENABLE4 XPT_BERT_BASEADDR,4,1 -+#define XPT_BERT_ENABLE5 XPT_BERT_BASEADDR,5,1 -+#define XPT_BERT_ENABLE6 XPT_BERT_BASEADDR,6,1 -+#define XPT_BERT_ENABLE7 XPT_BERT_BASEADDR,7,1 -+#define XPT_BERT_SEQUENCE_PN23_0 XPT_BERT_BASEADDR,8,1 -+#define XPT_BERT_SEQUENCE_PN23_1 XPT_BERT_BASEADDR,9,1 -+#define XPT_BERT_SEQUENCE_PN23_2 XPT_BERT_BASEADDR,10,1 -+#define XPT_BERT_SEQUENCE_PN23_3 XPT_BERT_BASEADDR,11,1 -+#define XPT_BERT_SEQUENCE_PN23_4 XPT_BERT_BASEADDR,12,1 -+#define XPT_BERT_SEQUENCE_PN23_5 XPT_BERT_BASEADDR,13,1 -+#define XPT_BERT_SEQUENCE_PN23_6 XPT_BERT_BASEADDR,14,1 -+#define XPT_BERT_SEQUENCE_PN23_7 XPT_BERT_BASEADDR,15,1 -+#define XPT_LOCK_RESYNC0 XPT_BERT_BASEADDR,16,1 -+#define XPT_LOCK_RESYNC1 XPT_BERT_BASEADDR,17,1 -+#define XPT_LOCK_RESYNC2 XPT_BERT_BASEADDR,18,1 -+#define XPT_LOCK_RESYNC3 XPT_BERT_BASEADDR,19,1 -+#define XPT_LOCK_RESYNC4 XPT_BERT_BASEADDR,20,1 -+#define XPT_LOCK_RESYNC5 XPT_BERT_BASEADDR,21,1 -+#define XPT_LOCK_RESYNC6 XPT_BERT_BASEADDR,22,1 -+#define XPT_LOCK_RESYNC7 XPT_BERT_BASEADDR,23,1 -+#define XPT_BERT_DATA_POLARITY0 XPT_BERT_BASEADDR,24,1 -+#define XPT_BERT_DATA_POLARITY1 XPT_BERT_BASEADDR,25,1 -+#define XPT_BERT_DATA_POLARITY2 XPT_BERT_BASEADDR,26,1 -+#define XPT_BERT_DATA_POLARITY3 XPT_BERT_BASEADDR,27,1 -+#define XPT_BERT_DATA_POLARITY4 XPT_BERT_BASEADDR,28,1 -+#define XPT_BERT_DATA_POLARITY5 XPT_BERT_BASEADDR,29,1 -+#define XPT_BERT_DATA_POLARITY6 XPT_BERT_BASEADDR,30,1 -+#define XPT_BERT_DATA_POLARITY7 XPT_BERT_BASEADDR,31,1 -+ -+#define XPT_BERT_INVERT_BASEADDR 0x907000C0 -+#define XPT_BERT_INVERT_DATA0 XPT_BERT_INVERT_BASEADDR,0,1 -+#define XPT_BERT_INVERT_DATA1 XPT_BERT_INVERT_BASEADDR,1,1 -+#define XPT_BERT_INVERT_DATA2 XPT_BERT_INVERT_BASEADDR,2,1 -+#define XPT_BERT_INVERT_DATA3 XPT_BERT_INVERT_BASEADDR,3,1 -+#define XPT_BERT_INVERT_DATA4 XPT_BERT_INVERT_BASEADDR,4,1 -+#define XPT_BERT_INVERT_DATA5 XPT_BERT_INVERT_BASEADDR,5,1 -+#define XPT_BERT_INVERT_DATA6 XPT_BERT_INVERT_BASEADDR,6,1 -+#define XPT_BERT_INVERT_DATA7 XPT_BERT_INVERT_BASEADDR,7,1 -+#define XPT_BERT_INVERT_SEQUENCE0 XPT_BERT_INVERT_BASEADDR,8,1 -+#define XPT_BERT_INVERT_SEQUENCE1 XPT_BERT_INVERT_BASEADDR,9,1 -+#define XPT_BERT_INVERT_SEQUENCE2 XPT_BERT_INVERT_BASEADDR,10,1 -+#define XPT_BERT_INVERT_SEQUENCE3 XPT_BERT_INVERT_BASEADDR,11,1 -+#define XPT_BERT_INVERT_SEQUENCE4 XPT_BERT_INVERT_BASEADDR,12,1 -+#define XPT_BERT_INVERT_SEQUENCE5 XPT_BERT_INVERT_BASEADDR,13,1 -+#define XPT_BERT_INVERT_SEQUENCE6 XPT_BERT_INVERT_BASEADDR,14,1 -+#define XPT_BERT_INVERT_SEQUENCE7 XPT_BERT_INVERT_BASEADDR,15,1 -+#define XPT_BERT_OUTPUT_POLARITY0 XPT_BERT_INVERT_BASEADDR,16,1 -+#define XPT_BERT_OUTPUT_POLARITY1 XPT_BERT_INVERT_BASEADDR,17,1 -+#define XPT_BERT_OUTPUT_POLARITY2 XPT_BERT_INVERT_BASEADDR,18,1 -+#define XPT_BERT_OUTPUT_POLARITY3 XPT_BERT_INVERT_BASEADDR,19,1 -+#define XPT_BERT_OUTPUT_POLARITY4 XPT_BERT_INVERT_BASEADDR,20,1 -+#define XPT_BERT_OUTPUT_POLARITY5 XPT_BERT_INVERT_BASEADDR,21,1 -+#define XPT_BERT_OUTPUT_POLARITY6 XPT_BERT_INVERT_BASEADDR,22,1 -+#define XPT_BERT_OUTPUT_POLARITY7 XPT_BERT_INVERT_BASEADDR,23,1 -+ -+#define XPT_BERT_HEADER_BASEADDR 0x907000C4 -+#define XPT_BERT_HEADER_MODE0 XPT_BERT_HEADER_BASEADDR,0,2 -+#define XPT_BERT_HEADER_MODE1 XPT_BERT_HEADER_BASEADDR,2,2 -+#define XPT_BERT_HEADER_MODE2 XPT_BERT_HEADER_BASEADDR,4,2 -+#define XPT_BERT_HEADER_MODE3 XPT_BERT_HEADER_BASEADDR,6,2 -+#define XPT_BERT_HEADER_MODE4 XPT_BERT_HEADER_BASEADDR,8,2 -+#define XPT_BERT_HEADER_MODE5 XPT_BERT_HEADER_BASEADDR,10,2 -+#define XPT_BERT_HEADER_MODE6 XPT_BERT_HEADER_BASEADDR,12,2 -+#define XPT_BERT_HEADER_MODE7 XPT_BERT_HEADER_BASEADDR,14,2 -+ -+#define XPT_BERT_BASEADDR1 0x907000C8 -+#define XPT_BERT_LOCKED0 XPT_BERT_BASEADDR1,0,1 -+#define XPT_BERT_LOCKED1 XPT_BERT_BASEADDR1,1,1 -+#define XPT_BERT_LOCKED2 XPT_BERT_BASEADDR1,2,1 -+#define XPT_BERT_LOCKED3 XPT_BERT_BASEADDR1,3,1 -+#define XPT_BERT_LOCKED4 XPT_BERT_BASEADDR1,4,1 -+#define XPT_BERT_LOCKED5 XPT_BERT_BASEADDR1,5,1 -+#define XPT_BERT_LOCKED6 XPT_BERT_BASEADDR1,6,1 -+#define XPT_BERT_LOCKED7 XPT_BERT_BASEADDR1,7,1 -+#define XPT_BERT_BIT_COUNT_SAT0 XPT_BERT_BASEADDR1,8,1 -+#define XPT_BERT_BIT_COUNT_SAT1 XPT_BERT_BASEADDR1,9,1 -+#define XPT_BERT_BIT_COUNT_SAT2 XPT_BERT_BASEADDR1,10,1 -+#define XPT_BERT_BIT_COUNT_SAT3 XPT_BERT_BASEADDR1,11,1 -+#define XPT_BERT_BIT_COUNT_SAT4 XPT_BERT_BASEADDR1,12,1 -+#define XPT_BERT_BIT_COUNT_SAT5 XPT_BERT_BASEADDR1,13,1 -+#define XPT_BERT_BIT_COUNT_SAT6 XPT_BERT_BASEADDR1,14,1 -+#define XPT_BERT_BIT_COUNT_SAT7 XPT_BERT_BASEADDR1,15,1 -+ -+#define XPT_BERT_BIT_COUNT0_BASEADDR 0x907000CC -+#define XPT_BERT_BIT_COUNT0_LO XPT_BERT_BIT_COUNT0_BASEADDR,0,32 -+ -+#define XPT_BERT_BIT_COUNT0_BASEADDR1 0x907000D0 -+#define XPT_BERT_BIT_COUNT0_HI XPT_BERT_BIT_COUNT0_BASEADDR1,0,18 -+ -+#define XPT_BERT_BIT_COUNT1_BASEADDR 0x907000D4 -+#define XPT_BERT_BIT_COUNT1_LO XPT_BERT_BIT_COUNT1_BASEADDR,0,32 -+ -+#define XPT_BERT_BIT_COUNT1_BASEADDR1 0x907000D8 -+#define XPT_BERT_BIT_COUNT1_HI XPT_BERT_BIT_COUNT1_BASEADDR1,0,18 -+ -+#define XPT_BERT_BIT_COUNT2_BASEADDR 0x907000DC -+#define XPT_BERT_BIT_COUNT2_LO XPT_BERT_BIT_COUNT2_BASEADDR,0,32 -+ -+#define XPT_BERT_BIT_COUNT2_BASEADDR1 0x907000E0 -+#define XPT_BERT_BIT_COUNT2_HI XPT_BERT_BIT_COUNT2_BASEADDR1,0,18 -+ -+#define XPT_BERT_BIT_COUNT3_BASEADDR 0x907000E4 -+#define XPT_BERT_BIT_COUNT3_LO XPT_BERT_BIT_COUNT3_BASEADDR,0,32 -+ -+#define XPT_BERT_BIT_COUNT3_BASEADDR1 0x907000E8 -+#define XPT_BERT_BIT_COUNT3_HI XPT_BERT_BIT_COUNT3_BASEADDR1,0,18 -+ -+#define XPT_BERT_BIT_COUNT4_BASEADDR 0x907000EC -+#define XPT_BERT_BIT_COUNT4_LO XPT_BERT_BIT_COUNT4_BASEADDR,0,32 -+ -+#define XPT_BERT_BIT_COUNT4_BASEADDR1 0x907000F0 -+#define XPT_BERT_BIT_COUNT4_HI XPT_BERT_BIT_COUNT4_BASEADDR1,0,18 -+ -+#define XPT_BERT_BIT_COUNT5_BASEADDR 0x907000F4 -+#define XPT_BERT_BIT_COUNT5_LO XPT_BERT_BIT_COUNT5_BASEADDR,0,32 -+ -+#define XPT_BERT_BIT_COUNT5_BASEADDR1 0x907000F8 -+#define XPT_BERT_BIT_COUNT5_HI XPT_BERT_BIT_COUNT5_BASEADDR1,0,18 -+ -+#define XPT_BERT_BIT_COUNT6_BASEADDR 0x907000FC -+#define XPT_BERT_BIT_COUNT6_LO XPT_BERT_BIT_COUNT6_BASEADDR,0,32 -+ -+#define XPT_BERT_BIT_COUNT6_BASEADDR1 0x90700100 -+#define XPT_BERT_BIT_COUNT6_HI XPT_BERT_BIT_COUNT6_BASEADDR1,0,18 -+ -+#define XPT_BERT_BIT_COUNT7_BASEADDR 0x90700104 -+#define XPT_BERT_BIT_COUNT7_LO XPT_BERT_BIT_COUNT7_BASEADDR,0,32 -+ -+#define XPT_BERT_BIT_COUNT7_BASEADDR1 0x90700108 -+#define XPT_BERT_BIT_COUNT7_HI XPT_BERT_BIT_COUNT7_BASEADDR1,0,18 -+ -+#define XPT_BERT_ERR_COUNT0_BASEADDR 0x9070010C -+#define XPT_BERT_ERR_COUNT0_LO XPT_BERT_ERR_COUNT0_BASEADDR,0,32 -+ -+#define XPT_BERT_ERR_COUNT0_BASEADDR1 0x90700110 -+#define XPT_BERT_ERR_COUNT0_HI XPT_BERT_ERR_COUNT0_BASEADDR1,0,8 -+ -+#define XPT_BERT_ERR_COUNT1_BASEADDR 0x90700114 -+#define XPT_BERT_ERR_COUNT1_LO XPT_BERT_ERR_COUNT1_BASEADDR,0,32 -+ -+#define XPT_BERT_ERR_COUNT1_BASEADDR1 0x90700118 -+#define XPT_BERT_ERR_COUNT1_HI XPT_BERT_ERR_COUNT1_BASEADDR1,0,8 -+ -+#define XPT_BERT_ERR_COUNT2_BASEADDR 0x9070011C -+#define XPT_BERT_ERR_COUNT2_LO XPT_BERT_ERR_COUNT2_BASEADDR,0,32 -+ -+#define XPT_BERT_ERR_COUNT2_BASEADDR1 0x90700120 -+#define XPT_BERT_ERR_COUNT2_HI XPT_BERT_ERR_COUNT2_BASEADDR1,0,8 -+ -+#define XPT_BERT_ERR_COUNT3_BASEADDR 0x90700124 -+#define XPT_BERT_ERR_COUNT3_LO XPT_BERT_ERR_COUNT3_BASEADDR,0,32 -+ -+#define XPT_BERT_ERR_COUNT3_BASEADDR1 0x90700128 -+#define XPT_BERT_ERR_COUNT3_HI XPT_BERT_ERR_COUNT3_BASEADDR1,0,8 -+ -+#define XPT_BERT_ERR_COUNT4_BASEADDR 0x9070012C -+#define XPT_BERT_ERR_COUNT4_LO XPT_BERT_ERR_COUNT4_BASEADDR,0,32 -+ -+#define XPT_BERT_ERR_COUNT4_BASEADDR1 0x90700130 -+#define XPT_BERT_ERR_COUNT4_HI XPT_BERT_ERR_COUNT4_BASEADDR1,0,8 -+ -+#define XPT_BERT_ERR_COUNT5_BASEADDR 0x90700134 -+#define XPT_BERT_ERR_COUNT5_LO XPT_BERT_ERR_COUNT5_BASEADDR,0,32 -+ -+#define XPT_BERT_ERR_COUNT5_BASEADDR1 0x90700138 -+#define XPT_BERT_ERR_COUNT5_HI XPT_BERT_ERR_COUNT5_BASEADDR1,0,8 -+ -+#define XPT_BERT_ERR_COUNT6_BASEADDR 0x9070013C -+#define XPT_BERT_ERR_COUNT6_LO XPT_BERT_ERR_COUNT6_BASEADDR,0,32 -+ -+#define XPT_BERT_ERR_COUNT6_BASEADDR1 0x90700140 -+#define XPT_BERT_ERR_COUNT6_HI XPT_BERT_ERR_COUNT6_BASEADDR1,0,8 -+ -+#define XPT_BERT_ERR_COUNT7_BASEADDR 0x90700144 -+#define XPT_BERT_ERR_COUNT7_LO XPT_BERT_ERR_COUNT7_BASEADDR,0,32 -+ -+#define XPT_BERT_ERR_COUNT7_BASEADDR1 0x90700148 -+#define XPT_BERT_ERR_COUNT7_HI XPT_BERT_ERR_COUNT7_BASEADDR1,0,8 -+ -+#define XPT_BERT_ERROR_BASEADDR 0x9070014C -+#define XPT_BERT_ERROR_INSERT XPT_BERT_ERROR_BASEADDR,0,24 -+ -+#define XPT_BERT_ANALYZER_BASEADDR 0x90700150 -+#define XPT_BERT_ANALYZER_ENABLE XPT_BERT_ANALYZER_BASEADDR,0,1 -+#define XPT_BERT_ANALYZER_PORT XPT_BERT_ANALYZER_BASEADDR,4,3 -+#define XPT_BERT_ANALYZER_ERR_THRES XPT_BERT_ANALYZER_BASEADDR,15,17 -+ -+#define XPT_BERT_ANALYZER_BASEADDR1 0x90700154 -+#define XPT_BERT_ANALYZER_START XPT_BERT_ANALYZER_BASEADDR1,0,32 -+ -+#define XPT_BERT_ANALYZER_BASEADDR2 0x90700158 -+#define XPT_BERT_ANALYZER_TSTAMP0 XPT_BERT_ANALYZER_BASEADDR2,0,32 -+ -+#define XPT_BERT_ANALYZER_BASEADDR3 0x9070015C -+#define XPT_BERT_ANALYZER_TSTAMP1 XPT_BERT_ANALYZER_BASEADDR3,0,32 -+ -+#define XPT_BERT_ANALYZER_BASEADDR4 0x90700160 -+#define XPT_BERT_ANALYZER_TSTAMP2 XPT_BERT_ANALYZER_BASEADDR4,0,32 -+ -+#define XPT_BERT_ANALYZER_BASEADDR5 0x90700164 -+#define XPT_BERT_ANALYZER_TSTAMP3 XPT_BERT_ANALYZER_BASEADDR5,0,32 -+ -+#define XPT_BERT_ANALYZER_BASEADDR6 0x90700168 -+#define XPT_BERT_ANALYZER_TSTAMP4 XPT_BERT_ANALYZER_BASEADDR6,0,32 -+ -+#define XPT_BERT_ANALYZER_BASEADDR7 0x9070016C -+#define XPT_BERT_ANALYZER_TSTAMP5 XPT_BERT_ANALYZER_BASEADDR7,0,32 -+ -+#define XPT_BERT_ANALYZER_BASEADDR8 0x90700170 -+#define XPT_BERT_ANALYZER_TSTAMP6 XPT_BERT_ANALYZER_BASEADDR8,0,32 -+ -+#define XPT_BERT_ANALYZER_BASEADDR9 0x90700174 -+#define XPT_BERT_ANALYZER_TSTAMP7 XPT_BERT_ANALYZER_BASEADDR9,0,32 -+ -+#define XPT_DMD0_BASEADDR 0x9070024C -+#define XPT_DMD0_SEL XPT_DMD0_BASEADDR,0,3 -+#define XPT_DMD1_SEL XPT_DMD0_BASEADDR,4,3 -+#define XPT_DMD2_SEL XPT_DMD0_BASEADDR,8,3 -+#define XPT_DMD3_SEL XPT_DMD0_BASEADDR,12,3 -+#define XPT_DMD4_SEL XPT_DMD0_BASEADDR,16,3 -+#define XPT_DMD5_SEL XPT_DMD0_BASEADDR,20,3 -+#define XPT_DMD6_SEL XPT_DMD0_BASEADDR,24,3 -+#define XPT_DMD7_SEL XPT_DMD0_BASEADDR,28,3 -+ -+// V2 AGC Gain Freeze & step -+#define DBG_ENABLE_DISABLE_AGC (0x3FFFCF60) // 1: DISABLE, 0:ENABLE -+#define WB_DFE0_DFE_FB_RF1_BASEADDR 0x903004A4 -+#define WB_DFE0_DFE_FB_RF1_BO WB_DFE0_DFE_FB_RF1_BASEADDR,0,3 -+#define WB_DFE0_DFE_FB_RF2_BO WB_DFE0_DFE_FB_RF1_BASEADDR,4,4 -+#define WB_DFE0_DFE_FB_LNA_BO WB_DFE0_DFE_FB_RF1_BASEADDR,8,2 -+ -+#define WB_DFE1_DFE_FB_RF1_BASEADDR 0x904004A4 -+#define WB_DFE1_DFE_FB_RF1_BO WB_DFE1_DFE_FB_RF1_BASEADDR,0,3 -+#define WB_DFE1_DFE_FB_RF2_BO WB_DFE1_DFE_FB_RF1_BASEADDR,4,4 -+#define WB_DFE1_DFE_FB_LNA_BO WB_DFE1_DFE_FB_RF1_BASEADDR,8,2 -+ -+#define WB_DFE2_DFE_FB_RF1_BASEADDR 0x905004A4 -+#define WB_DFE2_DFE_FB_RF1_BO WB_DFE2_DFE_FB_RF1_BASEADDR,0,3 -+#define WB_DFE2_DFE_FB_RF2_BO WB_DFE2_DFE_FB_RF1_BASEADDR,4,4 -+#define WB_DFE2_DFE_FB_LNA_BO WB_DFE2_DFE_FB_RF1_BASEADDR,8,2 -+ -+#define WB_DFE3_DFE_FB_RF1_BASEADDR 0x906004A4 -+#define WB_DFE3_DFE_FB_RF1_BO WB_DFE3_DFE_FB_RF1_BASEADDR,0,3 -+#define WB_DFE3_DFE_FB_RF2_BO WB_DFE3_DFE_FB_RF1_BASEADDR,4,4 -+#define WB_DFE3_DFE_FB_LNA_BO WB_DFE3_DFE_FB_RF1_BASEADDR,8,2 -+ -+#define AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR 0x90200104 -+#define AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_2 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,0,1 -+#define AFE_REG_D2A_TA_RFFE_RF1_BO_1P8_3 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,1,1 -+#define AFE_REG_D2A_TB_RFFE_LNA_BO_1P8_2 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,2,1 -+#define AFE_REG_D2A_TB_RFFE_RF1_BO_1P8_3 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,3,1 -+#define AFE_REG_D2A_TC_RFFE_LNA_BO_1P8_2 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,4,1 -+#define AFE_REG_D2A_TC_RFFE_RF1_BO_1P8_3 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,5,1 -+#define AFE_REG_D2A_TD_RFFE_LNA_BO_1P8_2 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,6,1 -+#define AFE_REG_D2A_TD_RFFE_RF1_BO_1P8_3 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,7,1 -+ -+#define AFE_REG_AFE_REG_SPARE_BASEADDR 0x902000A0 -+#define AFE_REG_D2A_TA_RFFE_RF1_CAP_1P8 AFE_REG_AFE_REG_SPARE_BASEADDR,13,5 -+ -+#define AFE_REG_AFE_REG_SPARE_BASEADDR1 0x902000B4 -+#define AFE_REG_D2A_TB_RFFE_RF1_CAP_1P8 AFE_REG_AFE_REG_SPARE_BASEADDR1,13,5 -+ -+#define AFE_REG_AFE_REG_SPARE_BASEADDR2 0x902000C4 -+#define AFE_REG_D2A_TC_RFFE_RF1_CAP_1P8 AFE_REG_AFE_REG_SPARE_BASEADDR2,13,5 -+ -+#define AFE_REG_AFE_REG_SPARE_BASEADDR3 0x902000D4 -+#define AFE_REG_D2A_TD_RFFE_RF1_CAP_1P8 AFE_REG_AFE_REG_SPARE_BASEADDR3,13,5 -+ -+#define WB_DFE0_DFE_FB_AGC_BASEADDR 0x90300498 -+#define WB_DFE0_DFE_FB_AGC_APPLY WB_DFE0_DFE_FB_AGC_BASEADDR,0,1 -+ -+#define WB_DFE1_DFE_FB_AGC_BASEADDR 0x90400498 -+#define WB_DFE1_DFE_FB_AGC_APPLY WB_DFE1_DFE_FB_AGC_BASEADDR,0,1 -+ -+#define WB_DFE2_DFE_FB_AGC_BASEADDR 0x90500498 -+#define WB_DFE2_DFE_FB_AGC_APPLY WB_DFE2_DFE_FB_AGC_BASEADDR,0,1 -+ -+#define WB_DFE3_DFE_FB_AGC_BASEADDR 0x90600498 -+#define WB_DFE3_DFE_FB_AGC_APPLY WB_DFE3_DFE_FB_AGC_BASEADDR,0,1 -+ -+#define WDT_WD_INT_BASEADDR 0x8002000C -+#define WDT_WD_INT_STATUS WDT_WD_INT_BASEADDR,0,1 -+ -+#define FSK_TX_FTM_BASEADDR 0x80090000 -+#define FSK_TX_FTM_OE FSK_TX_FTM_BASEADDR,12,1 -+#define FSK_TX_FTM_TX_EN FSK_TX_FTM_BASEADDR,10,1 -+#define FSK_TX_FTM_FORCE_CARRIER_ON FSK_TX_FTM_BASEADDR,1,1 -+#define FSK_TX_FTM_FORCE_MARK_SPACE FSK_TX_FTM_BASEADDR,0,1 -+ -+#define FSK_TX_FTM_TX_CNT_BASEADDR 0x80090018 -+#define FSK_TX_FTM_TX_CNT_INT FSK_TX_FTM_TX_CNT_BASEADDR,8,4 -+#define FSK_TX_FTM_TX_INT_EN FSK_TX_FTM_TX_CNT_BASEADDR,4,1 -+#define FSK_TX_FTM_TX_INT_SRC_SEL FSK_TX_FTM_TX_CNT_BASEADDR,0,2 -+ -+#define AFE_REG_D2A_FSK_BIAS_BASEADDR 0x90200040 -+#define AFE_REG_D2A_FSK_BIAS_EN AFE_REG_D2A_FSK_BIAS_BASEADDR,0,1 -+#define AFE_REG_D2A_FSK_TEST_EN AFE_REG_D2A_FSK_BIAS_BASEADDR,10,1 -+#define AFE_REG_D2A_FSK_TEST_MODE AFE_REG_D2A_FSK_BIAS_BASEADDR,11,4 -+#define AFE_REG_D2A_FSK_TERM_INT_EN AFE_REG_D2A_FSK_BIAS_BASEADDR,15,1 -+#define AFE_REG_D2A_FSK_RESETB_1P8 AFE_REG_D2A_FSK_BIAS_BASEADDR,16,1 -+#define AFE_REG_D2A_FSK_REG_EN_1P8 AFE_REG_D2A_FSK_BIAS_BASEADDR,17,1 -+#define AFE_REG_D2A_FSK_REG_EN_LKG_1P8 AFE_REG_D2A_FSK_BIAS_BASEADDR,18,1 -+#define AFE_REG_D2A_FSK_REG_AMP_1P8 AFE_REG_D2A_FSK_BIAS_BASEADDR,19,3 -+#define AFE_REG_D2A_FSK_REG_TEST_CTRL_1P8 AFE_REG_D2A_FSK_BIAS_BASEADDR,22,2 -+#define AFE_REG_D2A_DSQ_RX_MODE AFE_REG_D2A_FSK_BIAS_BASEADDR,24,1 -+#define AFE_REG_D2A_DSQ_RX_EN AFE_REG_D2A_FSK_BIAS_BASEADDR,25,1 -+#define AFE_REG_D2A_DSQ_HYST AFE_REG_D2A_FSK_BIAS_BASEADDR,26,2 -+#define AFE_REG_D2A_DSQ_RESETB_1P8 AFE_REG_D2A_FSK_BIAS_BASEADDR,28,1 -+#define AFE_REG_D2A_FSK_CLKRX_ENA AFE_REG_D2A_FSK_BIAS_BASEADDR,29,1 -+ -+#define DMD_TEI_BASEADDR 0x3FFFEBE0 -+#define DMD_TEI_ENA DMD_TEI_BASEADDR,0,1 -+ -+#define xpt_shm_input_control0 0x90700270,0,8 -+#define xpt_shm_input_control1 0x90700270,8,8 -+#define xpt_shm_input_control2 0x90700270,16,8 -+#define xpt_shm_input_control3 0x90700270,24,8 -+#define xpt_shm_input_control4 0x90700274,0,8 -+#define xpt_shm_input_control5 0x90700274,8,8 -+#define xpt_shm_input_control6 0x90700274,16,8 -+#define xpt_shm_input_control7 0x90700274,24,8 -+ -+ -+#define xpt_shm_output_control0 0x90700278,0,8 -+#define xpt_shm_output_control1 0x90700278,8,8 -+#define xpt_shm_output_control2 0x90700278,16,8 -+#define xpt_shm_output_control3 0x90700278,24,8 -+#define xpt_shm_output_control4 0x9070027C,0,8 -+#define xpt_shm_output_control5 0x9070027C,8,8 -+#define xpt_shm_output_control6 0x9070027C,16,8 -+#define xpt_shm_output_control7 0x9070027C,24,8 -+ -+#define xpt_mode_27mhz 0x90700184,0,1 -+#define xpt_enable_pcr_count 0x90700184,1,1 -+ -+#define xcpu_ctrl_003c_reg 0x9072003C,0,4 -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif //__MXL58X_REGISTERS_H__ -diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c -index 20b4a65..4b6e0bc 100644 ---- a/drivers/media/dvb-frontends/si2168.c -+++ b/drivers/media/dvb-frontends/si2168.c -@@ -95,7 +95,7 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) - goto err; - } - -- switch (c->delivery_system) { -+ switch (dev->delivery_system) { - case SYS_DVBT: - memcpy(cmd.args, "\xa0\x01", 2); - cmd.wlen = 2; -@@ -106,6 +106,11 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) - cmd.wlen = 2; - cmd.rlen = 9; - break; -+ case SYS_DVBC_ANNEX_B: -+ memcpy(cmd.args, "\x98\x01", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 10; -+ break; - case SYS_DVBT2: - memcpy(cmd.args, "\x50\x01", 2); - cmd.wlen = 2; -@@ -135,7 +140,7 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) - if (*status & FE_HAS_LOCK) { - c->cnr.len = 1; - c->cnr.stat[0].scale = FE_SCALE_DECIBEL; -- c->cnr.stat[0].svalue = cmd.args[3] * 1000 / 4; -+ c->cnr.stat[0].svalue = cmd.args[3] * 250; - } else { - c->cnr.len = 1; - c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -@@ -150,6 +155,75 @@ static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) - return ret; - } - -+static int si2168_read_snr(struct dvb_frontend *fe, u16 *snr) -+{ -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ -+ *snr = c->cnr.stat[0].scale == FE_SCALE_DECIBEL ? ((s32)c->cnr.stat[0].svalue / 250) * 328 : 0; -+ -+ return 0; -+} -+ -+static int si2168_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -+{ -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ -+ *strength = c->strength.stat[0].scale == FE_SCALE_DECIBEL ? ((100000 + (s32)c->strength.stat[0].svalue) / 1000) * 656 : 0; -+ -+ return 0; -+} -+ -+static int si2168_read_ber(struct dvb_frontend *fe, u32 *ber) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2168_dev *dev = i2c_get_clientdata(client); -+ struct si2168_cmd cmd; -+ int ret; -+ -+ if (dev->fe_status & FE_HAS_LOCK) { -+ memcpy(cmd.args, "\x82\x00", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 3; -+ ret = si2168_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "read_ber fe%d cmd_exec failed=%d\n", fe->id, ret); -+ goto err; -+ } -+ *ber = (u32)cmd.args[2] * cmd.args[1] & 0xf; -+ } else *ber = 1; -+ -+ return 0; -+err: -+ dev_err(&client->dev, "read_ber failed=%d\n", ret); -+ return ret; -+} -+ -+static int si2168_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2168_dev *dev = i2c_get_clientdata(client); -+ struct si2168_cmd cmd; -+ int ret; -+ -+ if (dev->stat_resp & 0x10) { -+ memcpy(cmd.args, "\x84\x00", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 3; -+ ret = si2168_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "read_ucblocks fe%d cmd_exec failed=%d\n", fe->id, ret); -+ goto err; -+ } -+ -+ *ucblocks = (u16)cmd.args[2] << 8 | cmd.args[1]; -+ } else *ucblocks = 0; -+ -+ return 0; -+err: -+ dev_err(&client->dev, "read_ucblocks failed=%d\n", ret); -+ return ret; -+} -+ - static int si2168_set_frontend(struct dvb_frontend *fe) - { - struct i2c_client *client = fe->demodulator_priv; -@@ -171,11 +245,19 @@ static int si2168_set_frontend(struct dvb_frontend *fe) - } - - switch (c->delivery_system) { -+ case SYS_DVBC_ANNEX_B: -+ delivery_system = 0x10; -+ break; - case SYS_DVBT: - delivery_system = 0x20; - break; - case SYS_DVBC_ANNEX_A: - delivery_system = 0x30; -+ if (c->symbol_rate < 6000000) { -+ delivery_system = 0x10; -+ c->delivery_system = SYS_DVBC_ANNEX_B; -+ c->bandwidth_hz = 6000000; -+ } - break; - case SYS_DVBT2: - delivery_system = 0x70; -@@ -212,26 +294,6 @@ static int si2168_set_frontend(struct dvb_frontend *fe) - goto err; - } - -- memcpy(cmd.args, "\x88\x02\x02\x02\x02", 5); -- cmd.wlen = 5; -- cmd.rlen = 5; -- ret = si2168_cmd_execute(client, &cmd); -- if (ret) -- goto err; -- -- /* that has no big effect */ -- if (c->delivery_system == SYS_DVBT) -- memcpy(cmd.args, "\x89\x21\x06\x11\xff\x98", 6); -- else if (c->delivery_system == SYS_DVBC_ANNEX_A) -- memcpy(cmd.args, "\x89\x21\x06\x11\x89\xf0", 6); -- else if (c->delivery_system == SYS_DVBT2) -- memcpy(cmd.args, "\x89\x21\x06\x11\x89\x20", 6); -- cmd.wlen = 6; -- cmd.rlen = 3; -- ret = si2168_cmd_execute(client, &cmd); -- if (ret) -- goto err; -- - if (c->delivery_system == SYS_DVBT2) { - /* select PLP */ - cmd.args[0] = 0x52; -@@ -298,6 +360,16 @@ static int si2168_set_frontend(struct dvb_frontend *fe) - if (ret) - goto err; - } -+ else if (c->delivery_system == SYS_DVBC_ANNEX_B) { -+ memcpy(cmd.args, "\x14\x00\x02\x16", 4); -+ cmd.args[4] = ((c->symbol_rate / 1000) >> 0) & 0xff; -+ cmd.args[5] = ((c->symbol_rate / 1000) >> 8) & 0xff; -+ cmd.wlen = 6; -+ cmd.rlen = 4; -+ ret = si2168_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ } - - memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6); - cmd.wlen = 6; -@@ -314,13 +386,13 @@ static int si2168_set_frontend(struct dvb_frontend *fe) - if (ret) - goto err; - -- memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x05", 6); -- cmd.args[5] |= dev->ts_clock_inv ? 0x00 : 0x10; -- cmd.wlen = 6; -- cmd.rlen = 4; -- ret = si2168_cmd_execute(client, &cmd); -- if (ret) -- goto err; -+ -+ memcpy(cmd.args, "\x14\x00\x08\x10\xcf\x33", 6); -+ cmd.wlen = 6; -+ cmd.rlen = 4; -+ ret = si2168_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; - - memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6); - cmd.wlen = 6; -@@ -360,6 +432,9 @@ static int si2168_init(struct dvb_frontend *fe) - struct si2168_cmd cmd; - - dev_dbg(&client->dev, "\n"); -+ -+ if (dev->active) -+ return 0; - - /* initialize */ - memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13); -@@ -480,6 +555,56 @@ static int si2168_init(struct dvb_frontend *fe) - dev->version >> 24 & 0xff, dev->version >> 16 & 0xff, - dev->version >> 8 & 0xff, dev->version >> 0 & 0xff); - -+ /* TER FEF */ -+ memcpy(cmd.args, "\x51\x00", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 12; -+ cmd.args[1] = (dev->fef_inv & 1) << 3 | (dev->fef_pin & 7); -+ dev_dbg(&client->dev, "args=%*ph\n", cmd.wlen, cmd.args); -+ -+ ret = si2168_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "err set fef pip\n"); -+ } -+ -+ /* MP DEFAULTS */ -+ memcpy(cmd.args, "\x88\x01\x01\x01\x01", 5); -+ cmd.wlen = 5; -+ cmd.rlen = 2; -+ switch (dev->fef_pin) -+ { -+ case SI2168_MP_A: -+ cmd.args[1] = dev->fef_inv ? 3 : 2; -+ break; -+ case SI2168_MP_B: -+ cmd.args[2] = dev->fef_inv ? 3 : 2; -+ break; -+ case SI2168_MP_C: -+ cmd.args[3] = dev->fef_inv ? 3 : 2; -+ break; -+ case SI2168_MP_D: -+ cmd.args[4] = dev->fef_inv ? 3 : 2; -+ break; -+ } -+ dev_dbg(&client->dev, "args=%*ph\n", cmd.wlen, cmd.args); -+ -+ ret = si2168_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "err set mp defaults\n"); -+ } -+ -+ /* AGC */ -+ memcpy(cmd.args, "\x89\x01\x06\x12\x00\x00", 6); -+ cmd.wlen = 6; -+ cmd.rlen = 3; -+ cmd.args[1] |= (dev->agc_inv & 1) << 7 | (dev->agc_pin & 7) << 4; -+ dev_dbg(&client->dev, "args=%*ph\n", cmd.wlen, cmd.args); -+ -+ ret = si2168_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "err set ter agc\n"); -+ } -+ - /* set ts mode */ - memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6); - cmd.args[4] |= dev->ts_mode; -@@ -581,7 +706,7 @@ static int si2168_deselect(struct i2c_mux_core *muxc, u32 chan) - } - - static const struct dvb_frontend_ops si2168_ops = { -- .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A}, -+ .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_B}, - .info = { - .name = "Silicon Labs Si2168", - .symbol_rate_min = 1000000, -@@ -615,6 +740,10 @@ static const struct dvb_frontend_ops si2168_ops = { - .set_frontend = si2168_set_frontend, - - .read_status = si2168_read_status, -+ .read_signal_strength = si2168_read_signal_strength, -+ .read_snr = si2168_read_snr, -+ .read_ber = si2168_read_ber, -+ .read_ucblocks = si2168_read_ucblocks, - }; - - static int si2168_probe(struct i2c_client *client, -@@ -705,6 +834,13 @@ static int si2168_probe(struct i2c_client *client, - dev->ts_mode = config->ts_mode; - dev->ts_clock_inv = config->ts_clock_inv; - dev->ts_clock_gapped = config->ts_clock_gapped; -+ dev->fef_pin = config->fef_pin; -+ dev->fef_inv = config->fef_inv; -+ dev->agc_pin = config->agc_pin; -+ dev->agc_inv = config->agc_inv; -+ -+ if (!dev->agc_pin) dev->agc_pin = SI2168_MP_A; -+ if (!dev->fef_pin) dev->fef_pin = SI2168_MP_B; - - dev_info(&client->dev, "Silicon Labs Si2168-%c%d%d successfully identified\n", - dev->version >> 24 & 0xff, dev->version >> 16 & 0xff, -diff --git a/drivers/media/dvb-frontends/si2168.h b/drivers/media/dvb-frontends/si2168.h -index 3225d0c..0b411b8 100644 ---- a/drivers/media/dvb-frontends/si2168.h -+++ b/drivers/media/dvb-frontends/si2168.h -@@ -45,6 +45,17 @@ struct si2168_config { - - /* TS clock gapped */ - bool ts_clock_gapped; -+ -+ /* Tuner control pins */ -+#define SI2168_MP_NOT_USED 1 -+#define SI2168_MP_A 2 -+#define SI2168_MP_B 3 -+#define SI2168_MP_C 4 -+#define SI2168_MP_D 5 -+ int agc_pin; -+ bool agc_inv; -+ int fef_pin; -+ bool fef_inv; - }; - - #endif -diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h -index 7843ccb..bc866be 100644 ---- a/drivers/media/dvb-frontends/si2168_priv.h -+++ b/drivers/media/dvb-frontends/si2168_priv.h -@@ -34,6 +34,7 @@ struct si2168_dev { - struct dvb_frontend fe; - enum fe_delivery_system delivery_system; - enum fe_status fe_status; -+ u8 stat_resp; - #define SI2168_CHIP_ID_A20 ('A' << 24 | 68 << 16 | '2' << 8 | '0' << 0) - #define SI2168_CHIP_ID_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0) - #define SI2168_CHIP_ID_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0) -@@ -45,6 +46,10 @@ struct si2168_dev { - u8 ts_mode; - bool ts_clock_inv; - bool ts_clock_gapped; -+ int fef_pin; -+ bool fef_inv; -+ int agc_pin; -+ bool agc_inv; - }; - - /* firmware command struct */ -diff --git a/drivers/media/dvb-frontends/si2183.c b/drivers/media/dvb-frontends/si2183.c -new file mode 100644 -index 0000000..1fd154d ---- /dev/null -+++ b/drivers/media/dvb-frontends/si2183.c -@@ -0,0 +1,1541 @@ -+/* -+ * Silicon Labs Si2183(2) DVB-T/T2/C/C2/S/S2 demodulator driver -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include "si2183.h" -+#include "dvb_frontend.h" -+#include -+#include -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0) -+#define SI2183_USE_I2C_MUX -+#endif -+ -+#define SI2183_B60_FIRMWARE "dvb-demod-si2183-b60-01.fw" -+ -+#define SI2183_PROP_MODE 0x100a -+#define SI2183_PROP_DVBC_CONST 0x1101 -+#define SI2183_PROP_DVBC_SR 0x1102 -+#define SI2183_PROP_DVBT_HIER 0x1201 -+#define SI2183_PROP_DVBT2_MODE 0x1304 -+#define SI2183_PROP_DVBS2_SR 0x1401 -+#define SI2183_PROP_DVBS_SR 0x1501 -+#define SI2183_PROP_MCNS_CONST 0x1601 -+#define SI2183_PROP_MCNS_SR 0x1602 -+ -+#define SI2183_ARGLEN 30 -+struct si2183_cmd { -+ u8 args[SI2183_ARGLEN]; -+ unsigned wlen; -+ unsigned rlen; -+}; -+ -+static const struct dvb_frontend_ops si2183_ops; -+ -+LIST_HEAD(silist); -+ -+struct si_base { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) -+ struct i2c_mux_core *muxc; -+#endif -+ struct list_head silist; -+ -+ u8 adr; -+ struct i2c_adapter *i2c; -+ u32 count; -+ -+ struct i2c_adapter *tuner_adapter; -+ -+#ifndef SI2183_USE_I2C_MUX -+ struct i2c_client *i2c_gate_client; -+#endif -+}; -+ -+/* state struct */ -+struct si2183_dev { -+ struct dvb_frontend fe; -+ enum fe_delivery_system delivery_system; -+ enum fe_status fe_status; -+ u8 stat_resp; -+ u16 snr; -+ bool active; -+ bool fw_loaded; -+ u8 ts_mode; -+ bool ts_clock_inv; -+ bool ts_clock_gapped; -+ u8 agc_mode; -+ struct si_base *base; -+ void (*RF_switch)(struct i2c_adapter * i2c,u8 rf_in,u8 flag); -+ u8 rf_in; -+ u8 active_fe; -+}; -+ -+/* Own I2C adapter locking is needed because of I2C gate logic. */ -+static int si2183_i2c_master_send_unlocked(const struct i2c_client *client, -+ const char *buf, int count) -+{ -+ int ret; -+ struct i2c_msg msg = { -+ .addr = client->addr, -+ .flags = 0, -+ .len = count, -+ .buf = (char *)buf, -+ }; -+ -+ ret = __i2c_transfer(client->adapter, &msg, 1); -+ return (ret == 1) ? count : ret; -+} -+ -+static int si2183_i2c_master_recv_unlocked(const struct i2c_client *client, -+ char *buf, int count) -+{ -+ int ret; -+ struct i2c_msg msg = { -+ .addr = client->addr, -+ .flags = I2C_M_RD, -+ .len = count, -+ .buf = buf, -+ }; -+ -+ ret = __i2c_transfer(client->adapter, &msg, 1); -+ return (ret == 1) ? count : ret; -+} -+ -+/* execute firmware command */ -+static int si2183_cmd_execute_unlocked(struct i2c_client *client, -+ struct si2183_cmd *cmd) -+{ -+ int ret; -+ unsigned long timeout; -+ -+ if (cmd->wlen) { -+ /* write cmd and args for firmware */ -+ ret = si2183_i2c_master_send_unlocked(client, cmd->args, -+ cmd->wlen); -+ if (ret < 0) { -+ goto err; -+ } else if (ret != cmd->wlen) { -+ ret = -EREMOTEIO; -+ goto err; -+ } -+ } -+ -+ if (cmd->rlen) { -+ /* wait cmd execution terminate */ -+ #define TIMEOUT 500 -+ timeout = jiffies + msecs_to_jiffies(TIMEOUT); -+ while (!time_after(jiffies, timeout)) { -+ ret = si2183_i2c_master_recv_unlocked(client, cmd->args, -+ cmd->rlen); -+ if (ret < 0) { -+ goto err; -+ } else if (ret != cmd->rlen) { -+ ret = -EREMOTEIO; -+ goto err; -+ } -+ -+ /* firmware ready? */ -+ if ((cmd->args[0] >> 7) & 0x01) -+ break; -+ } -+ -+ dev_dbg(&client->dev, "cmd execution took %d ms\n", -+ jiffies_to_msecs(jiffies) - -+ (jiffies_to_msecs(timeout) - TIMEOUT)); -+ -+ /* error bit set? */ -+ if ((cmd->args[0] >> 6) & 0x01) { -+ ret = -EREMOTEIO; -+ goto err; -+ } -+ -+ if (!((cmd->args[0] >> 7) & 0x01)) { -+ ret = -ETIMEDOUT; -+ goto err; -+ } -+ } -+ -+ return 0; -+err: -+ dev_dbg(&client->dev, "failed=%d\n", ret); -+ return ret; -+} -+ -+static int si2183_cmd_execute(struct i2c_client *client, struct si2183_cmd *cmd) -+{ -+ int ret; -+ -+ i2c_lock_adapter(client->adapter); -+ ret = si2183_cmd_execute_unlocked(client, cmd); -+ i2c_unlock_adapter(client->adapter); -+ -+ return ret; -+} -+ -+static int si2183_set_prop(struct i2c_client *client, u16 prop, u16 *val) -+{ -+ struct si2183_cmd cmd; -+ int ret; -+ -+ cmd.args[0] = 0x14; -+ cmd.args[1] = 0x00; -+ cmd.args[2] = (u8) prop; -+ cmd.args[3] = (u8) (prop >> 8); -+ cmd.args[4] = (u8) (*val); -+ cmd.args[5] = (u8) (*val >> 8); -+ cmd.wlen = 6; -+ cmd.rlen = 4; -+ ret = si2183_cmd_execute(client, &cmd); -+ *val = (cmd.args[2] | (cmd.args[3] << 8)); -+ return ret; -+} -+#if 0 -+static int si2183_get_prop(struct i2c_client *client, u16 prop, u16 *val) -+{ -+ struct si2183_cmd cmd; -+ int ret; -+ -+ cmd.args[0] = 0x15; -+ cmd.args[1] = 0x00; -+ cmd.args[2] = (u8) prop; -+ cmd.args[3] = (u8) (prop >> 8); -+ cmd.wlen = 4; -+ cmd.rlen = 4; -+ ret = si2183_cmd_execute(client, &cmd); -+ *val = (cmd.args[2] | (cmd.args[3] << 8)); -+ return ret; -+} -+#endif -+ -+static int si2183_read_status(struct dvb_frontend *fe, enum fe_status *status) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int ret; -+ struct si2183_cmd cmd; -+ u16 agc; -+ -+ *status = 0; -+ -+ if (!dev->active) { -+ ret = -EAGAIN; -+ goto err; -+ } -+ -+ if ((dev->delivery_system != c->delivery_system) || (dev->delivery_system == 0)) -+ return 0; -+ -+ switch (c->delivery_system) { -+ case SYS_DVBT: -+ memcpy(cmd.args, "\xa0\x01", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 13; -+ dev->snr = 2; -+ break; -+ case SYS_DVBC_ANNEX_A: -+ memcpy(cmd.args, "\x90\x01", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 9; -+ dev->snr = 2; -+ break; -+ case SYS_DVBC_ANNEX_B: -+ memcpy(cmd.args, "\x98\x01", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 10; -+ dev->snr = 2; -+ break; -+ case SYS_DVBT2: -+ memcpy(cmd.args, "\x50\x01", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 14; -+ dev->snr = 2; -+ break; -+ case SYS_DVBS: -+ memcpy(cmd.args, "\x60\x01", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 10; -+ dev->snr = 5; -+ break; -+ case SYS_DVBS2: -+ memcpy(cmd.args, "\x70\x01", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 13; -+ dev->snr = 5; -+ break; -+ case SYS_ISDBT: -+ memcpy(cmd.args, "\xa4\x01", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 14; -+ dev->snr = 2; -+ break; -+ default: -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "read_status fe%d cmd_exec failed=%d\n", fe->id, ret); -+ goto err; -+ } -+ -+ dev->stat_resp = cmd.args[2]; -+ switch ((dev->stat_resp >> 1) & 0x03) { -+ case 0x01: -+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; -+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ break; -+ case 0x03: -+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | -+ FE_HAS_SYNC | FE_HAS_LOCK; -+ c->cnr.len = 1; -+ c->cnr.stat[0].scale = FE_SCALE_DECIBEL; -+ c->cnr.stat[0].svalue = (s64) cmd.args[3] * 250; -+ dev->snr *= cmd.args[3] * 164; -+ break; -+ default: -+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ break; -+ } -+ -+ dev->fe_status = *status; -+ -+ dev_dbg(&client->dev, "status=%02x args=%*ph\n", -+ *status, cmd.rlen, cmd.args); -+ -+ if (fe->ops.tuner_ops.get_rf_strength) -+ { -+ memcpy(cmd.args, "\x8a\x00\x00\x00\x00\x00", 6); -+ cmd.wlen = 6; -+ cmd.rlen = 3; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "read_status fe%d cmd_exec failed=%d\n", fe->id, ret); -+ goto err; -+ } -+ dev_dbg(&client->dev, "status=%02x args=%*ph\n", -+ *status, cmd.rlen, cmd.args); -+ -+ agc = cmd.args[1]; -+ fe->ops.tuner_ops.get_rf_strength(fe, &agc); -+ } -+ -+ return 0; -+err: -+ dev_err(&client->dev, "read_status failed=%d\n", ret); -+ return ret; -+} -+ -+static int si2183_read_snr(struct dvb_frontend *fe, u16 *snr) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ -+ *snr = (dev->fe_status & FE_HAS_LOCK) ? dev->snr : 0; -+ -+ return 0; -+} -+ -+static int si2183_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -+{ -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ -+ *strength = c->strength.stat[0].scale == FE_SCALE_DECIBEL ? ((100000 + (s32)c->strength.stat[0].svalue) / 1000) * 656 : 0; -+ -+ return 0; -+} -+ -+static int si2183_read_ber(struct dvb_frontend *fe, u32 *ber) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ struct si2183_cmd cmd; -+ int ret; -+ -+ if (dev->fe_status & FE_HAS_LOCK) { -+ memcpy(cmd.args, "\x82\x00", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 3; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "read_ber fe%d cmd_exec failed=%d\n", fe->id, ret); -+ goto err; -+ } -+ *ber = (u32)cmd.args[2] * cmd.args[1] & 0xf; -+ } else *ber = 1; -+ -+ return 0; -+err: -+ dev_err(&client->dev, "read_ber failed=%d\n", ret); -+ return ret; -+} -+ -+static int si2183_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ struct si2183_cmd cmd; -+ int ret; -+ -+ if (dev->stat_resp & 0x10) { -+ memcpy(cmd.args, "\x84\x00", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 3; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "read_ucblocks fe%d cmd_exec failed=%d\n", fe->id, ret); -+ goto err; -+ } -+ -+ *ucblocks = (u16)cmd.args[2] << 8 | cmd.args[1]; -+ } else *ucblocks = 0; -+ -+ return 0; -+err: -+ dev_err(&client->dev, "read_ucblocks failed=%d\n", ret); -+ return ret; -+} -+ -+ -+static int si2183_set_dvbc(struct dvb_frontend *fe) -+{ -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ struct si2183_cmd cmd; -+ int ret; -+ u16 prop; -+ -+ memcpy(cmd.args, "\x89\x41\x06\x12\x0\x0", 6); -+ cmd.args[1]= (dev->agc_mode &0x07)<<4 |0x1; -+ cmd.wlen = 6; -+ cmd.rlen = 3; -+ ret = si2183_cmd_execute(client, &cmd); -+ if(ret){ -+ dev_err(&client->dev, "err set agc mode\n"); -+ } -+ /* dvb-c mode */ -+ prop = 0x38; -+ ret = si2183_set_prop(client, SI2183_PROP_MODE, &prop); -+ if (ret) { -+ dev_err(&client->dev, "err set dvb-c mode\n"); -+ return ret; -+ } -+ -+ switch (c->modulation) { -+ default: -+ case QAM_AUTO: -+ prop = 0; -+ break; -+ case QAM_16: -+ prop = 7; -+ break; -+ case QAM_32: -+ prop = 8; -+ break; -+ case QAM_64: -+ prop = 9; -+ break; -+ case QAM_128: -+ prop = 10; -+ break; -+ case QAM_256: -+ prop = 11; -+ break; -+ } -+ ret = si2183_set_prop(client, SI2183_PROP_DVBC_CONST, &prop); -+ if (ret) { -+ dev_err(&client->dev, "err set dvb-c constelation\n"); -+ return ret; -+ } -+ -+ /* symbol rate */ -+ prop = c->symbol_rate / 1000; -+ ret = si2183_set_prop(client, SI2183_PROP_DVBC_SR, &prop); -+ if (ret) { -+ dev_err(&client->dev, "err set dvb-c symbol rate\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int si2183_set_mcns(struct dvb_frontend *fe) -+{ -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ struct si2183_cmd cmd; -+ int ret; -+ u16 prop,symb; -+ -+ memcpy(cmd.args, "\x89\x41\x06\x12\x0\x0", 6); -+ cmd.args[1]= (dev->agc_mode &0x07)<<4 |0x1; -+ cmd.wlen = 6; -+ cmd.rlen = 3; -+ ret = si2183_cmd_execute(client, &cmd); -+ if(ret){ -+ dev_err(&client->dev, "err set agc mode\n"); -+ } -+ /* mcns mode */ -+ prop = 0x18; -+ ret = si2183_set_prop(client, SI2183_PROP_MODE, &prop); -+ if (ret) { -+ dev_err(&client->dev, "err set mcns mode\n"); -+ return ret; -+ } -+ -+ switch (c->modulation) { -+ default: -+ case QAM_64: -+ prop = 9; -+ symb = 5057; -+ break; -+ case QAM_256: -+ prop = 11; -+ symb = 5361; -+ break; -+ } -+ ret = si2183_set_prop(client, SI2183_PROP_MCNS_CONST, &prop); -+ if (ret) { -+ dev_err(&client->dev, "err set mcns constelation\n"); -+ return ret; -+ } -+ -+ /* symbol rate */ -+ ret = si2183_set_prop(client, SI2183_PROP_MCNS_SR, &symb); -+ if (ret) { -+ dev_err(&client->dev, "err set mcns symbol rate\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int gold_code_index (int gold_sequence_index) -+{ -+ unsigned int i, k , x_init; -+ u8 GOLD_PRBS[19] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -+ for (k=0; kdtv_property_cache; -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ struct si2183_cmd cmd; -+ int ret; -+ u16 prop; -+ u32 pls_mode, pls_code; -+ -+ /*set SAT agc*/ -+ memcpy(cmd.args, "\x8a\x1d\x12\x0\x0\x0", 6); -+ cmd.args[1]= dev->agc_mode|0x18; -+ cmd.wlen = 6; -+ cmd.rlen = 3; -+ ret = si2183_cmd_execute(client, &cmd); -+ if(ret){ -+ dev_err(&client->dev, "err set agc mode\n"); -+ } -+ -+ /* set mode */ -+ prop = 0x8; -+ switch (c->delivery_system) { -+ default: -+ case SYS_DVBS: -+ prop |= 0x80; -+ break; -+ case SYS_DVBS2: -+ prop |= 0x90; -+ break; -+ case SYS_DSS: -+ prop |= 0xa0; -+ break; -+ } -+ if (c->inversion) -+ prop |= 0x100; -+ ret = si2183_set_prop(client, SI2183_PROP_MODE, &prop); -+ if (ret) { -+ dev_err(&client->dev, "err set dvb-s/s2 mode\n"); -+ return ret; -+ } -+ -+ /* symbol rate */ -+ prop = c->symbol_rate / 1000; -+ switch (c->delivery_system) { -+ default: -+ case SYS_DSS: -+ case SYS_DVBS: -+ ret = si2183_set_prop(client, SI2183_PROP_DVBS_SR, &prop); -+ break; -+ case SYS_DVBS2: -+ ret = si2183_set_prop(client, SI2183_PROP_DVBS2_SR, &prop); -+ /* stream_id selection */ -+ cmd.args[0] = 0x71; -+ cmd.args[1] = (u8) c->stream_id; -+ cmd.args[2] = c->stream_id == NO_STREAM_ID_FILTER ? 0 : 1; -+ cmd.wlen = 3; -+ cmd.rlen = 1; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) -+ dev_warn(&client->dev, "dvb-s2: err selecting stream_id\n"); -+ -+ /* pls selection */ -+ pls_mode = c->stream_id == NO_STREAM_ID_FILTER ? 0 : (c->stream_id >> 26) & 3; -+ pls_code = c->stream_id == NO_STREAM_ID_FILTER ? 0 : (c->stream_id >> 8) & 0x3FFFF; -+ if (pls_mode) -+ pls_code = gold_code_index(pls_code); -+ cmd.args[0] = 0x73; -+ cmd.args[1] = pls_code > 0; -+ cmd.args[2] = cmd.args[3] = 0; -+ cmd.args[4] = (u8) pls_code; -+ cmd.args[5] = (u8) (pls_code >> 8); -+ cmd.args[6] = (u8) (pls_code >> 16); -+ cmd.args[7] = (u8) (pls_code >> 24); -+ cmd.wlen = 8; -+ cmd.rlen = 1; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) -+ dev_warn(&client->dev, "dvb-s2: err set pls\n"); -+ } -+ -+ return 0; -+} -+ -+static int si2183_set_dvbt(struct dvb_frontend *fe) -+{ -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ struct si2183_cmd cmd; -+ int ret; -+ u16 prop; -+ -+ memcpy(cmd.args, "\x89\x41\x06\x12\x0\x0", 6); -+ cmd.args[1]= (dev->agc_mode &0x07)<<4 |0x1; -+ cmd.wlen = 6; -+ cmd.rlen = 3; -+ ret = si2183_cmd_execute(client, &cmd); -+ if(ret){ -+ dev_err(&client->dev, "err set agc mode\n"); -+ } -+ -+ if (c->bandwidth_hz == 0) { -+ return -EINVAL; -+ } else if (c->bandwidth_hz <= 2000000) -+ prop = 0x02; -+ else if (c->bandwidth_hz <= 5000000) -+ prop = 0x05; -+ else if (c->bandwidth_hz <= 6000000) -+ prop = 0x06; -+ else if (c->bandwidth_hz <= 7000000) -+ prop = 0x07; -+ else if (c->bandwidth_hz <= 8000000) -+ prop = 0x08; -+ else if (c->bandwidth_hz <= 9000000) -+ prop = 0x09; -+ else if (c->bandwidth_hz <= 10000000) -+ prop = 0x0a; -+ else -+ prop = 0x0f; -+ -+ switch (c->delivery_system) { -+ default: -+ case SYS_DVBT: -+ prop |= 0x20; -+ break; -+ case SYS_DVBT2: -+ prop |= 0x70; -+ break; -+ } -+ ret = si2183_set_prop(client, SI2183_PROP_MODE, &prop); -+ if (ret) { -+ dev_err(&client->dev, "err set dvb-t mode\n"); -+ return ret; -+ } -+ -+ /* hierarchy - HP = 0 / LP = 1 */ -+ prop = c->hierarchy == HIERARCHY_1 ? 1 : 0; -+ ret = si2183_set_prop(client, SI2183_PROP_DVBT_HIER, &prop); -+ if (ret) -+ dev_warn(&client->dev, "dvb-t: err set hierarchy\n"); -+ -+ if (c->delivery_system == SYS_DVBT2) { -+ /* stream_id selection */ -+ cmd.args[0] = 0x52; -+ cmd.args[1] = (u8) c->stream_id; -+ cmd.args[2] = c->stream_id == NO_STREAM_ID_FILTER ? 0 : 1; -+ cmd.wlen = 3; -+ cmd.rlen = 1; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) -+ dev_warn(&client->dev, "dvb-t2: err selecting stream_id\n"); -+ -+ /* dvb-t2 mode - any=0 / base=1 / lite=2 */ -+ prop = 0; -+ ret = si2183_set_prop(client, SI2183_PROP_DVBT2_MODE, &prop); -+ if (ret) -+ dev_warn(&client->dev, "dvb-t2: err set mode\n"); -+ } -+ -+ return 0; -+} -+ -+static int si2183_set_isdbt(struct dvb_frontend *fe) -+{ -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ struct si2183_cmd cmd; -+ int ret; -+ u16 prop; -+ -+ memcpy(cmd.args, "\x89\x41\x06\x12\x0\x0", 6); -+ cmd.args[1]= (dev->agc_mode &0x07)<<4 |0x1; -+ cmd.wlen = 6; -+ cmd.rlen = 3; -+ ret = si2183_cmd_execute(client, &cmd); -+ if(ret){ -+ dev_err(&client->dev, "err set agc mode\n"); -+ } -+ if (c->bandwidth_hz == 0) { -+ return -EINVAL; -+ } else if (c->bandwidth_hz <= 2000000) -+ prop = 0x02; -+ else if (c->bandwidth_hz <= 5000000) -+ prop = 0x05; -+ else if (c->bandwidth_hz <= 6000000) -+ prop = 0x06; -+ else if (c->bandwidth_hz <= 7000000) -+ prop = 0x07; -+ else if (c->bandwidth_hz <= 8000000) -+ prop = 0x08; -+ else if (c->bandwidth_hz <= 9000000) -+ prop = 0x09; -+ else if (c->bandwidth_hz <= 10000000) -+ prop = 0x0a; -+ else -+ prop = 0x0f; -+ -+ /* ISDB-T mode */ -+ prop |= 0x40; -+ ret = si2183_set_prop(client, SI2183_PROP_MODE, &prop); -+ if (ret) { -+ dev_err(&client->dev, "err set dvb-t mode\n"); -+ return ret; -+ } -+ return 0; -+} -+ -+static int si2183_set_frontend(struct dvb_frontend *fe) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int ret; -+ struct si2183_cmd cmd; -+ -+ dev_dbg(&client->dev, -+ "delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u stream_id=%d\n", -+ c->delivery_system, c->modulation, c->frequency, -+ c->bandwidth_hz, c->symbol_rate, c->inversion, -+ c->stream_id); -+ -+ if (!dev->active) { -+ ret = -EAGAIN; -+ goto err; -+ } -+ if(dev->RF_switch) -+ { -+ switch (c->delivery_system) { -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ case SYS_DVBC_ANNEX_A: -+ case SYS_DVBC_ANNEX_B: -+ case SYS_ISDBT: -+ dev->RF_switch(dev->base->i2c,dev->rf_in,1); -+ -+ break; -+ -+ case SYS_DVBS: -+ case SYS_DVBS2: -+ case SYS_DSS: -+ default: -+ dev->RF_switch(dev->base->i2c,dev->rf_in,0); -+ break; -+ -+ } -+ } -+ -+ if (fe->ops.tuner_ops.set_params) { -+#ifndef SI2183_USE_I2C_MUX -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 1); -+#endif -+ ret = fe->ops.tuner_ops.set_params(fe); -+#ifndef SI2183_USE_I2C_MUX -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 0); -+#endif -+ if (ret) { -+ dev_err(&client->dev, "err setting tuner params\n"); -+ goto err; -+ } -+ } -+ -+ switch (c->delivery_system) { -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ ret = si2183_set_dvbt(fe); -+ break; -+ case SYS_DVBC_ANNEX_A: -+ ret = si2183_set_dvbc(fe); -+ break; -+ case SYS_DVBC_ANNEX_B: -+ ret= si2183_set_mcns(fe); -+ break; -+ case SYS_ISDBT: -+ ret = si2183_set_isdbt(fe); -+ break; -+ case SYS_DVBS: -+ case SYS_DVBS2: -+ case SYS_DSS: -+ ret = si2183_set_dvbs(fe); -+ break; -+ default: -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ /* dsp restart */ -+ memcpy(cmd.args, "\x85", 1); -+ cmd.wlen = 1; -+ cmd.rlen = 1; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "err restarting dsp\n"); -+ return ret; -+ } -+ -+ dev->delivery_system = c->delivery_system; -+ return 0; -+err: -+ dev_err(&client->dev, "set_params failed=%d\n", ret); -+ return ret; -+} -+ -+static int si2183_init(struct dvb_frontend *fe) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int ret = 0, len, remaining; -+ const struct firmware *fw; -+ const char *fw_name; -+ struct si2183_cmd cmd; -+ unsigned int chip_id; -+ u16 prop; -+ -+ dev_dbg(&client->dev, "\n"); -+ -+ if (dev->active_fe) { -+ dev->active_fe |= (1 << fe->id); -+ return 0; -+ } -+ -+ c->cnr.len = 1; -+ c->cnr.stat[0].scale = FE_SCALE_DECIBEL; -+ -+ /* initialize */ -+ memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13); -+ cmd.wlen = 13; -+ cmd.rlen = 0; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ if (dev->fw_loaded) { -+ /* resume */ -+ memcpy(cmd.args, "\xc0\x06\x08\x0f\x00\x20\x21\x01", 8); -+ cmd.wlen = 8; -+ cmd.rlen = 1; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ memcpy(cmd.args, "\x85", 1); -+ cmd.wlen = 1; -+ cmd.rlen = 1; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ goto warm; -+ } -+ -+ /* power up */ -+ memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8); -+ cmd.wlen = 8; -+ cmd.rlen = 1; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ /* query chip revision */ -+ memcpy(cmd.args, "\x02", 1); -+ cmd.wlen = 1; -+ cmd.rlen = 13; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 | -+ cmd.args[4] << 0; -+ -+ #define SI2183_B60 ('B' << 24 | 83 << 16 | '6' << 8 | '0' << 0) -+ -+ switch (chip_id) { -+ case SI2183_B60: -+ fw_name = SI2183_B60_FIRMWARE; -+ break; -+ default: -+ dev_err(&client->dev, "unknown chip version Si21%d-%c%c%c\n", -+ cmd.args[2], cmd.args[1], -+ cmd.args[3], cmd.args[4]); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ dev_info(&client->dev, "found a 'Silicon Labs Si21%d-%c%c%c'\n", -+ cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]); -+ -+ ret = request_firmware(&fw, fw_name, &client->dev); -+ if (ret) { -+ dev_err(&client->dev, -+ "firmware file '%s' not found\n", -+ fw_name); -+ goto err; -+ } -+ -+ dev_info(&client->dev, "downloading firmware from file '%s'\n", -+ fw_name); -+ -+ for (remaining = fw->size; remaining > 0; remaining -= 17) { -+ len = fw->data[fw->size - remaining]; -+ if (len > SI2183_ARGLEN) { -+ ret = -EINVAL; -+ break; -+ } -+ memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len); -+ cmd.wlen = len; -+ cmd.rlen = 1; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) -+ break; -+ } -+ release_firmware(fw); -+ -+ if (ret) { -+ dev_err(&client->dev, "firmware download failed %d\n", ret); -+ goto err; -+ } -+ -+ memcpy(cmd.args, "\x01\x01", 2); -+ cmd.wlen = 2; -+ cmd.rlen = 1; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ /* query firmware version */ -+ memcpy(cmd.args, "\x11", 1); -+ cmd.wlen = 1; -+ cmd.rlen = 10; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ dev_info(&client->dev, "firmware version: %c.%c.%d\n", -+ cmd.args[6], cmd.args[7], cmd.args[8]); -+ -+ /* set ts mode */ -+ memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6); -+ cmd.args[4] |= dev->ts_mode; -+ if (dev->ts_clock_gapped) -+ cmd.args[4] |= 0x40; -+ cmd.wlen = 6; -+ cmd.rlen = 4; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ -+ /* FER resol */ -+ memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6); -+ cmd.wlen = 6; -+ cmd.rlen = 4; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "err set FER resol\n"); -+ return ret; -+ } -+ -+ /* DD IEN */ -+ memcpy(cmd.args, "\x14\x00\x06\x10\x24\x00", 6); -+ cmd.wlen = 6; -+ cmd.rlen = 4; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "err set dd ien\n"); -+ return ret; -+ } -+ -+ /* int sense */ -+ memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6); -+ cmd.wlen = 6; -+ cmd.rlen = 4; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "err set int sense\n"); -+ return ret; -+ } -+ -+/* -+ memcpy(cmd.args, "\x88\x02\x02\x02\x02", 5); -+ cmd.wlen = 5; -+ cmd.rlen = 5; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) { -+ dev_err(&client->dev, "err set x88\n"); -+ } -+*/ -+ -+ prop = 0x10; -+ ret = si2183_set_prop(client, 0x100f, &prop); -+ if (ret) { -+ dev_err(&client->dev, "err set 0x100f\n"); -+ return ret; -+ } -+ -+// prop = 0x08e3 | (dev->ts_clock_inv ? 0x0000 : 0x1000); -+ prop = 0x1104; -+ ret = si2183_set_prop(client, 0x1009, &prop); -+ if (ret) { -+ dev_err(&client->dev, "err set par_ts\n"); -+ return ret; -+ } -+ -+ prop = 0x330C ; -+ ret = si2183_set_prop(client, 0x1008, &prop); -+ if (ret) { -+ dev_err(&client->dev, "err set ser_ts\n"); -+ return ret; -+ } -+ -+ dev->fw_loaded = true; -+warm: -+ dev->active = true; -+ dev->active_fe |= (1 << fe->id); -+ return 0; -+ -+err: -+ dev_dbg(&client->dev, "init failed=%d\n", ret); -+ return ret; -+} -+ -+static int si2183_sleep(struct dvb_frontend *fe) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ int ret; -+ struct si2183_cmd cmd; -+ -+ dev_dbg(&client->dev, "\n"); -+ -+ dev->active_fe &= ~(1 << fe->id); -+ if (dev->active_fe) -+ return 0; -+ -+ dev->active = false; -+ -+ memcpy(cmd.args, "\x13", 1); -+ cmd.wlen = 1; -+ cmd.rlen = 0; -+ ret = si2183_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ return 0; -+err: -+ dev_dbg(&client->dev, "failed=%d\n", ret); -+ return ret; -+} -+ -+static int si2183_get_tune_settings(struct dvb_frontend *fe, -+ struct dvb_frontend_tune_settings *s) -+{ -+ s->min_delay_ms = 900; -+ -+ return 0; -+} -+ -+#ifdef SI2183_USE_I2C_MUX -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) -+static int si2183_select(struct i2c_mux_core *muxc, u32 chan) -+{ -+ struct i2c_client *client = i2c_mux_priv(muxc); -+#else -+static int si2183_select(struct i2c_adapter *adap, void *mux_priv, u32 chan) -+{ -+ struct i2c_client *client = mux_priv; -+#endif -+ int ret; -+ struct si2183_cmd cmd; -+ -+ /* open I2C gate */ -+ memcpy(cmd.args, "\xc0\x0d\x01", 3); -+ cmd.wlen = 3; -+ cmd.rlen = 0; -+ ret = si2183_cmd_execute_unlocked(client, &cmd); -+ if (ret) -+ goto err; -+ -+ return 0; -+err: -+ dev_dbg(&client->dev, "failed=%d\n", ret); -+ return ret; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) -+static int si2183_deselect(struct i2c_mux_core *muxc, u32 chan) -+{ -+ struct i2c_client *client = i2c_mux_priv(muxc); -+#else -+static int si2183_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan) -+{ -+ struct i2c_client *client = mux_priv; -+#endif -+ int ret; -+ struct si2183_cmd cmd; -+ -+ /* close I2C gate */ -+ memcpy(cmd.args, "\xc0\x0d\x00", 3); -+ cmd.wlen = 3; -+ cmd.rlen = 0; -+ ret = si2183_cmd_execute_unlocked(client, &cmd); -+ if (ret) -+ goto err; -+ -+ return 0; -+err: -+ dev_dbg(&client->dev, "failed=%d\n", ret); -+ return ret; -+} -+#else -+static int i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ struct si2183_cmd cmd; -+ -+ memcpy(cmd.args, "\xc0\x0d\x00", 3); -+ if (enable) -+ cmd.args[2] = 1; -+ cmd.wlen = 3; -+ cmd.rlen = 0; -+ return si2183_cmd_execute(dev->base->i2c_gate_client, &cmd); -+} -+#endif -+ -+static int si2183_tune(struct dvb_frontend *fe, bool re_tune, -+ unsigned int mode_flags, unsigned int *delay, enum fe_status *status) -+{ -+ *delay = HZ / 5; -+ if (re_tune) { -+ int ret = si2183_set_frontend(fe); -+ if (ret) -+ return ret; -+ } -+ return si2183_read_status(fe, status); -+} -+ -+static int si2183_get_algo(struct dvb_frontend *fe) -+{ -+ return DVBFE_ALGO_HW; -+} -+ -+static int si2183_set_property(struct dvb_frontend *fe, -+ struct dtv_property *p) -+{ -+ int ret = 0; -+ -+ switch (p->cmd) { -+ case DTV_DELIVERY_SYSTEM: -+ switch (p->u.data) { -+ case SYS_DVBS: -+ case SYS_DVBS2: -+ case SYS_DSS: -+ fe->ops.info.frequency_min = 950000; -+ fe->ops.info.frequency_max = 2150000; -+ fe->ops.info.frequency_stepsize = 0; -+ break; -+ case SYS_ISDBT: -+ fe->ops.info.frequency_min = 42000000; -+ fe->ops.info.frequency_max = 1002000000; -+ fe->ops.info.frequency_stepsize = 0; -+ break; -+ case SYS_DVBC_ANNEX_A: -+ case SYS_DVBC_ANNEX_B: -+ fe->ops.info.frequency_min = 47000000; -+ fe->ops.info.frequency_max = 862000000; -+ fe->ops.info.frequency_stepsize = 62500; -+ break; -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ default: -+ fe->ops.info.frequency_min = 174000000; -+ fe->ops.info.frequency_max = 862000000; -+ fe->ops.info.frequency_stepsize = 250000; -+ break; -+ } -+ break; -+ default: -+ break; -+ } -+ -+ return ret; -+} -+ -+ -+static int send_diseqc_cmd(struct dvb_frontend *fe, -+ u8 cont_tone, u8 tone_burst, u8 burst_sel, -+ u8 end_seq, u8 msg_len, u8 *msg) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ struct si2183_cmd cmd; -+ u8 enable = 1; -+ -+ cmd.args[0] = 0x8c; -+ cmd.args[1] = enable | (cont_tone << 1) -+ | (tone_burst << 2) | (burst_sel << 3) -+ | (end_seq << 4) | (msg_len << 5); -+ -+ if (msg_len > 0) -+ memcpy(&cmd.args[2], msg, msg_len); -+ -+ cmd.wlen = 8; -+ cmd.rlen = 1; -+ return si2183_cmd_execute(client, &cmd); -+} -+ -+static int si2183_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ int ret; -+ u8 cont_tone; -+ -+ switch (tone) { -+ case SEC_TONE_ON: -+ cont_tone = 1; -+ break; -+ case SEC_TONE_OFF: -+ cont_tone = 0; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ ret = send_diseqc_cmd(fe, cont_tone, 0, 0, 1, 0, NULL); -+ if (ret) -+ goto err; -+ -+ return 0; -+err: -+ dev_err(&client->dev, "set_tone failed=%d\n", ret); -+ return ret; -+} -+ -+static int si2183_diseqc_send_burst(struct dvb_frontend *fe, -+ enum fe_sec_mini_cmd burst) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ int ret; -+ u8 burst_sel; -+ -+ switch (burst) { -+ case SEC_MINI_A: -+ burst_sel = 0; -+ break; -+ case SEC_MINI_B: -+ burst_sel = 1; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ ret = send_diseqc_cmd(fe, 0, 1, burst_sel, 1, 0, NULL); -+ if (ret) -+ goto err; -+ -+ return 0; -+err: -+ dev_err(&client->dev, "set_tone failed=%d\n", ret); -+ return ret; -+} -+ -+static int si2183_diseqc_send_msg(struct dvb_frontend *fe, -+ struct dvb_diseqc_master_cmd *d) -+{ -+ struct i2c_client *client = fe->demodulator_priv; -+ int ret; -+ u8 remaining = d->msg_len; -+ u8 *p = d->msg; -+ u8 len = 0; -+ -+ while (remaining > 0) { -+ p += len; -+ len = (remaining > 6) ? 6 : remaining; -+ remaining -= len; -+ ret = send_diseqc_cmd(fe, 0, 0, 0, -+ (remaining == 0) ? 1 : 0, len, p); -+ if (ret) -+ goto err; -+ msleep(50); -+ } -+ -+ return 0; -+err: -+ dev_err(&client->dev, "set_tone failed=%d\n", ret); -+ return ret; -+} -+ -+static const struct dvb_frontend_ops si2183_ops = { -+ .delsys = {SYS_DVBT, SYS_DVBT2, -+ SYS_ISDBT, -+ SYS_DVBC_ANNEX_A,SYS_DVBC_ANNEX_B, -+ SYS_DVBS, SYS_DVBS2, SYS_DSS}, -+ .info = { -+ .name = "Silicon Labs Si2183", -+ .symbol_rate_min = 1000000, -+ .symbol_rate_max = 45000000, -+ .caps = 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_32 | -+ FE_CAN_QAM_64 | -+ FE_CAN_QAM_128 | -+ FE_CAN_QAM_256 | -+ FE_CAN_QAM_AUTO | -+ FE_CAN_TRANSMISSION_MODE_AUTO | -+ FE_CAN_GUARD_INTERVAL_AUTO | -+ FE_CAN_HIERARCHY_AUTO | -+ FE_CAN_MUTE_TS | -+ FE_CAN_2G_MODULATION | -+ FE_CAN_MULTISTREAM -+ }, -+ -+ .get_tune_settings = si2183_get_tune_settings, -+ -+ .init = si2183_init, -+ .sleep = si2183_sleep, -+ -+ .set_frontend = si2183_set_frontend, -+ -+ .read_status = si2183_read_status, -+ .read_signal_strength = si2183_read_signal_strength, -+ .read_snr = si2183_read_snr, -+ .read_ber = si2183_read_ber, -+ .read_ucblocks = si2183_read_ucblocks, -+ -+ .get_frontend_algo = si2183_get_algo, -+ .tune = si2183_tune, -+ -+ .set_property = si2183_set_property, -+ -+ .set_tone = si2183_set_tone, -+ .diseqc_send_burst = si2183_diseqc_send_burst, -+ .diseqc_send_master_cmd = si2183_diseqc_send_msg, -+#ifndef SI2183_USE_I2C_MUX -+ .i2c_gate_ctrl = i2c_gate_ctrl, -+#endif -+}; -+ -+ -+static struct si_base *match_base(struct i2c_adapter *i2c, u8 adr) -+{ -+ struct si_base *p; -+ -+ list_for_each_entry(p, &silist, silist) -+ if (p->i2c == i2c)// && p->adr == adr) lja: TO FIX -+ return p; -+ return NULL; -+} -+ -+static int si2183_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct si2183_config *config = client->dev.platform_data; -+ struct si2183_dev *dev; -+ struct si_base *base; -+ int ret; -+ -+ dev_dbg(&client->dev, "\n"); -+ -+ dev = kzalloc(sizeof(*dev), GFP_KERNEL); -+ if (!dev) { -+ ret = -ENOMEM; -+ dev_err(&client->dev, "kzalloc() failed\n"); -+ goto err; -+ } -+ -+ base = match_base(client->adapter, client->addr); -+ if (base) { -+ base->count++; -+ dev->base = base; -+ } else { -+ base = kzalloc(sizeof(struct si_base), GFP_KERNEL); -+ if (!base) -+ goto err_kfree; -+ base->i2c = client->adapter; -+ base->adr = client->addr; -+ base->count = 1; -+ dev->base = base; -+ list_add(&base->silist, &silist); -+ -+#ifdef SI2183_USE_I2C_MUX -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) -+ /* create mux i2c adapter for tuner */ -+ base->muxc = i2c_mux_alloc(client->adapter, &client->adapter->dev, -+ 1, 0, I2C_MUX_LOCKED, -+ si2183_select, si2183_deselect); -+ if (!base->muxc) { -+ ret = -ENOMEM; -+ goto err_base_kfree; -+ } -+ base->muxc->priv = client; -+ ret = i2c_mux_add_adapter(base->muxc, 0, 0, 0); -+ if (ret) -+ goto err_base_kfree; -+ base->tuner_adapter = base->muxc->adapter[0]; -+#else -+ /* create mux i2c adapter for tuners */ -+ base->tuner_adapter = i2c_add_mux_adapter(client->adapter, &client->adapter->dev, -+ client, 0, 0, 0, si2183_select, si2183_deselect); -+ if (base->tuner_adapter == NULL) { -+ ret = -ENODEV; -+ goto err_base_kfree; -+ } -+#endif -+#else -+ base->tuner_adapter = client->adapter; -+ base->i2c_gate_client = client; -+#endif -+ } -+ -+ /* create dvb_frontend */ -+ memcpy(&dev->fe.ops, &si2183_ops, sizeof(struct dvb_frontend_ops)); -+ dev->fe.demodulator_priv = client; -+ *config->i2c_adapter = base->tuner_adapter; -+ *config->fe = &dev->fe; -+ dev->ts_mode = config->ts_mode; -+ dev->ts_clock_inv = config->ts_clock_inv; -+ dev->ts_clock_gapped = config->ts_clock_gapped; -+ dev->agc_mode = config->agc_mode; -+ dev->RF_switch = config->RF_switch; -+ dev->rf_in = config->rf_in; -+ dev->fw_loaded = false; -+ dev->snr = 0; -+ dev->stat_resp = 0; -+ -+ dev->active_fe = 0; -+ -+ i2c_set_clientdata(client, dev); -+ -+#ifndef SI2183_USE_I2C_MUX -+ /* leave gate open for tuner to init */ -+ i2c_gate_ctrl(&dev->fe, 1); -+#endif -+ dev_info(&client->dev, "Silicon Labs Si2183 successfully attached\n"); -+ return 0; -+err_base_kfree: -+ kfree(base); -+err_kfree: -+ kfree(dev); -+err: -+ dev_dbg(&client->dev, "probe failed=%d\n", ret); -+ return ret; -+} -+ -+static int si2183_remove(struct i2c_client *client) -+{ -+ struct si2183_dev *dev = i2c_get_clientdata(client); -+ -+ dev_dbg(&client->dev, "\n"); -+ -+ dev->base->count--; -+ if (dev->base->count == 0) { -+#ifdef SI2183_USE_I2C_MUX -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) -+ i2c_mux_del_adapters(dev->base->muxc); -+#else -+ i2c_del_mux_adapter(dev->base->tuner_adapter); -+#endif -+#endif -+ list_del(&dev->base->silist); -+ kfree(dev->base); -+ } -+ -+ dev->fe.ops.release = NULL; -+ dev->fe.demodulator_priv = NULL; -+ -+ kfree(dev); -+ -+ return 0; -+} -+ -+static const struct i2c_device_id si2183_id_table[] = { -+ {"si2183", 0}, -+ {} -+}; -+MODULE_DEVICE_TABLE(i2c, si2183_id_table); -+ -+static struct i2c_driver si2183_driver = { -+ .driver = { -+ .name = "si2183", -+ }, -+ .probe = si2183_probe, -+ .remove = si2183_remove, -+ .id_table = si2183_id_table, -+}; -+ -+module_i2c_driver(si2183_driver); -+ -+MODULE_AUTHOR("Luis Alves "); -+MODULE_DESCRIPTION("Silicon Labs Si2183 DVB-T/T2/C/C2/S/S2 demodulator driver"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/dvb-frontends/si2183.h b/drivers/media/dvb-frontends/si2183.h -new file mode 100644 -index 0000000..033fe87 ---- /dev/null -+++ b/drivers/media/dvb-frontends/si2183.h -@@ -0,0 +1,55 @@ -+/* -+ * Silicon Labs Si2183(2) DVB-T/T2/C/C2/S/S2 demodulator driver -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef SI2183_H -+#define SI2183_H -+ -+#include -+/* -+ * I2C address -+ * 0x64 -+ */ -+struct si2183_config { -+ /* -+ * frontend -+ * returned by driver -+ */ -+ struct dvb_frontend **fe; -+ -+ /* -+ * tuner I2C adapter -+ * returned by driver -+ */ -+ struct i2c_adapter **i2c_adapter; -+ -+ /* TS mode */ -+#define SI2183_TS_PARALLEL 0x06 -+#define SI2183_TS_SERIAL 0x03 -+ u8 ts_mode; -+ -+ /* TS clock inverted */ -+ bool ts_clock_inv; -+ -+ /* TS clock gapped */ -+ bool ts_clock_gapped; -+ /*agc*/ -+ u8 agc_mode; -+ -+ /*rf switch*/ -+ void (*RF_switch)(struct i2c_adapter * i2c,u8 rf_in,u8 flag); -+ /*rf no.*/ -+ u8 rf_in; -+}; -+ -+#endif -diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c -index 45cbc89..2d0341d 100644 ---- a/drivers/media/dvb-frontends/stv0288.c -+++ b/drivers/media/dvb-frontends/stv0288.c -@@ -382,6 +382,9 @@ static int stv0288_read_status(struct dvb_frontend *fe, enum fe_status *status) - dprintk("stv0288 has locked\n"); - } - -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, *status & FE_HAS_LOCK); -+ - return 0; - } - -@@ -416,6 +419,9 @@ static int stv0288_sleep(struct dvb_frontend *fe) - { - struct stv0288_state *state = fe->demodulator_priv; - -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, 0); -+ - stv0288_writeregI(state, 0x41, 0x84); - state->initialised = 0; - -@@ -532,6 +538,10 @@ static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) - static void stv0288_release(struct dvb_frontend *fe) - { - struct stv0288_state *state = fe->demodulator_priv; -+ -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, 0); -+ - kfree(state); - } - -diff --git a/drivers/media/dvb-frontends/stv0288.h b/drivers/media/dvb-frontends/stv0288.h -index 803acb9..6e8263c 100644 ---- a/drivers/media/dvb-frontends/stv0288.h -+++ b/drivers/media/dvb-frontends/stv0288.h -@@ -40,6 +40,9 @@ struct stv0288_config { - int min_delay_ms; - - int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); -+ -+ /* Hook for Lock LED */ -+ void (*set_lock_led)(struct dvb_frontend *fe, int offon); - }; - - #if IS_REACHABLE(CONFIG_DVB_STV0288) -diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c -index 25bdf6e..ff4c7ef 100644 ---- a/drivers/media/dvb-frontends/stv090x.c -+++ b/drivers/media/dvb-frontends/stv090x.c -@@ -41,6 +41,10 @@ - static unsigned int verbose; - module_param(verbose, int, 0644); - -+static unsigned int ts_nosync=1; -+module_param(ts_nosync, int, 0644); -+MODULE_PARM_DESC(ts_nosync, "TS FIFO Minimum latence mode (default:on)"); -+ - /* internal params node */ - struct stv090x_dev { - /* pointer for internal params, one for each pair of demods */ -@@ -739,14 +743,8 @@ static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 - buf[1] = reg & 0xff; - memcpy(&buf[2], data, count); - -- if (unlikely(*state->verbose >= FE_DEBUGREG)) { -- int i; -- -- printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); -- for (i = 0; i < count; i++) -- printk(" %02x", data[i]); -- printk("\n"); -- } -+ dprintk(FE_DEBUGREG, 1, "%s [0x%04x]: %*ph", -+ __func__, reg, count, data); - - ret = i2c_transfer(state->i2c, &i2c_msg, 1); - if (ret != 1) { -@@ -3435,18 +3433,40 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) - return -1; - } - -+static int stv090x_set_pls(struct stv090x_state *state, u8 pls_mode, u32 pls_code) -+{ -+ if (pls_mode == 0 && pls_code == 0) -+ pls_code = 1; -+ pls_mode &= 0x03; -+ pls_code &= 0x3FFFF; -+ -+ dprintk(FE_DEBUG, 1, "Set PLS code %d (mode %d)", pls_code, pls_mode); -+ if (STV090x_WRITE_DEMOD(state, PLROOT2, (pls_mode<<2) | (pls_code>>16)) < 0) -+ goto err; -+ if (STV090x_WRITE_DEMOD(state, PLROOT1, pls_code>>8) < 0) -+ goto err; -+ if (STV090x_WRITE_DEMOD(state, PLROOT0, pls_code) < 0) -+ goto err; -+ return 0; -+err: -+ dprintk(FE_ERROR, 1, "I/O error"); -+ return -1; -+} -+ - static int stv090x_set_mis(struct stv090x_state *state, int mis) - { - u32 reg; - -- if (mis < 0 || mis > 255) { -+ if (mis == NO_STREAM_ID_FILTER) { - dprintk(FE_DEBUG, 1, "Disable MIS filtering"); -+ stv090x_set_pls(state, 0, 0); - reg = STV090x_READ_DEMOD(state, PDELCTRL1); - STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x00); - if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) - goto err; - } else { - dprintk(FE_DEBUG, 1, "Enable MIS filtering - %d", mis); -+ stv090x_set_pls(state, (mis>>26) & 0x3, (mis>>8) & 0x3FFFF); - reg = STV090x_READ_DEMOD(state, PDELCTRL1); - STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x01); - if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) -@@ -3510,109 +3530,6 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe) - return DVBFE_ALGO_SEARCH_ERROR; - } - --static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) --{ -- struct stv090x_state *state = fe->demodulator_priv; -- u32 reg, dstatus; -- u8 search_state; -- -- *status = 0; -- -- dstatus = STV090x_READ_DEMOD(state, DSTATUS); -- if (STV090x_GETFIELD_Px(dstatus, CAR_LOCK_FIELD)) -- *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; -- -- reg = STV090x_READ_DEMOD(state, DMDSTATE); -- search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD); -- -- switch (search_state) { -- case 0: /* searching */ -- case 1: /* first PLH detected */ -- default: -- dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)"); -- break; -- -- case 2: /* DVB-S2 mode */ -- dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2"); -- if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) { -- reg = STV090x_READ_DEMOD(state, PDELSTATUS1); -- if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) { -- *status |= FE_HAS_VITERBI; -- reg = STV090x_READ_DEMOD(state, TSSTATUS); -- if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) -- *status |= FE_HAS_SYNC | FE_HAS_LOCK; -- } -- } -- break; -- -- case 3: /* DVB-S1/legacy mode */ -- dprintk(FE_DEBUG, 1, "Delivery system: DVB-S"); -- if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) { -- reg = STV090x_READ_DEMOD(state, VSTATUSVIT); -- if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) { -- *status |= FE_HAS_VITERBI; -- reg = STV090x_READ_DEMOD(state, TSSTATUS); -- if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) -- *status |= FE_HAS_SYNC | FE_HAS_LOCK; -- } -- } -- break; -- } -- -- return 0; --} -- --static int stv090x_read_per(struct dvb_frontend *fe, u32 *per) --{ -- struct stv090x_state *state = fe->demodulator_priv; -- -- s32 count_4, count_3, count_2, count_1, count_0, count; -- u32 reg, h, m, l; -- enum fe_status status; -- -- stv090x_read_status(fe, &status); -- if (!(status & FE_HAS_LOCK)) { -- *per = 1 << 23; /* Max PER */ -- } else { -- /* Counter 2 */ -- reg = STV090x_READ_DEMOD(state, ERRCNT22); -- h = STV090x_GETFIELD_Px(reg, ERR_CNT2_FIELD); -- -- reg = STV090x_READ_DEMOD(state, ERRCNT21); -- m = STV090x_GETFIELD_Px(reg, ERR_CNT21_FIELD); -- -- reg = STV090x_READ_DEMOD(state, ERRCNT20); -- l = STV090x_GETFIELD_Px(reg, ERR_CNT20_FIELD); -- -- *per = ((h << 16) | (m << 8) | l); -- -- count_4 = STV090x_READ_DEMOD(state, FBERCPT4); -- count_3 = STV090x_READ_DEMOD(state, FBERCPT3); -- count_2 = STV090x_READ_DEMOD(state, FBERCPT2); -- count_1 = STV090x_READ_DEMOD(state, FBERCPT1); -- count_0 = STV090x_READ_DEMOD(state, FBERCPT0); -- -- if ((!count_4) && (!count_3)) { -- count = (count_2 & 0xff) << 16; -- count |= (count_1 & 0xff) << 8; -- count |= count_0 & 0xff; -- } else { -- count = 1 << 24; -- } -- if (count == 0) -- *per = 1; -- } -- if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0) < 0) -- goto err; -- if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0) -- goto err; -- -- return 0; --err: -- dprintk(FE_ERROR, 1, "I/O error"); -- return -1; --} -- - static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val) - { - int res = 0; -@@ -3649,12 +3566,13 @@ static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val) - return res; - } - --static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -+static int stv090x_read_rflevel(struct dvb_frontend *fe) - { - struct stv090x_state *state = fe->demodulator_priv; -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; - u32 reg; - s32 agc_0, agc_1, agc; -- s32 str; -+ s32 rflevel; - - reg = STV090x_READ_DEMOD(state, AGCIQIN1); - agc_1 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD); -@@ -3662,25 +3580,27 @@ static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) - agc_0 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD); - agc = MAKEWORD16(agc_1, agc_0); - -- str = stv090x_table_lookup(stv090x_rf_tab, -+ rflevel = stv090x_table_lookup(stv090x_rf_tab, - ARRAY_SIZE(stv090x_rf_tab) - 1, agc); - if (agc > stv090x_rf_tab[0].read) -- str = 0; -+ rflevel = 0; - else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read) -- str = -100; -- *strength = (str + 100) * 0xFFFF / 100; -+ rflevel = -100; -+ -+ p->strength.len = 1; -+ p->strength.stat[0].scale = FE_SCALE_DECIBEL; -+ p->strength.stat[0].svalue = rflevel * 1000; - - return 0; - } - --static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) -+static int stv090x_read_cnr(struct dvb_frontend *fe) - { - struct stv090x_state *state = fe->demodulator_priv; -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; - u32 reg_0, reg_1, reg, i; -- s32 val_0, val_1, val = 0; -+ s32 val_0, val_1, val = 0, snr = 0; - u8 lock_f; -- s32 div; -- u32 last; - - switch (state->delsys) { - case STV090x_DVBS2: -@@ -3697,10 +3617,8 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) - msleep(1); - } - val /= 16; -- last = ARRAY_SIZE(stv090x_s2cn_tab) - 1; -- div = stv090x_s2cn_tab[0].read - -- stv090x_s2cn_tab[last].read; -- *cnr = 0xFFFF - ((val * 0xFFFF) / div); -+ snr = stv090x_table_lookup(stv090x_s2cn_tab, -+ ARRAY_SIZE(stv090x_s2cn_tab) - 1, val); - } - break; - -@@ -3719,16 +3637,195 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) - msleep(1); - } - val /= 16; -- last = ARRAY_SIZE(stv090x_s1cn_tab) - 1; -- div = stv090x_s1cn_tab[0].read - -- stv090x_s1cn_tab[last].read; -- *cnr = 0xFFFF - ((val * 0xFFFF) / div); -+ snr = stv090x_table_lookup(stv090x_s1cn_tab, -+ ARRAY_SIZE(stv090x_s1cn_tab) - 1, val); - } - break; - default: - break; - } - -+ p->cnr.len = 1; -+ p->cnr.stat[0].scale = FE_SCALE_DECIBEL; -+ p->cnr.stat[0].svalue = 100 * snr; -+ -+ return 0; -+} -+ -+static int stv090x_read_per(struct dvb_frontend *fe, enum fe_status status) -+{ -+ struct stv090x_state *state = fe->demodulator_priv; -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ -+ s32 count_4, count_3, count_2, count_1, count_0, count; -+ u32 reg, h, m, l, per; -+ -+ if (!(status & FE_HAS_LOCK)) { -+ count = 0; -+ per = 1 << 23; /* Max PER */ -+ } else { -+ /* Counter 2 */ -+ reg = STV090x_READ_DEMOD(state, ERRCNT22); -+ h = STV090x_GETFIELD_Px(reg, ERR_CNT2_FIELD); -+ -+ reg = STV090x_READ_DEMOD(state, ERRCNT21); -+ m = STV090x_GETFIELD_Px(reg, ERR_CNT21_FIELD); -+ -+ reg = STV090x_READ_DEMOD(state, ERRCNT20); -+ l = STV090x_GETFIELD_Px(reg, ERR_CNT20_FIELD); -+ -+ per = ((h << 16) | (m << 8) | l); -+ -+ count_4 = STV090x_READ_DEMOD(state, FBERCPT4); -+ count_3 = STV090x_READ_DEMOD(state, FBERCPT3); -+ count_2 = STV090x_READ_DEMOD(state, FBERCPT2); -+ count_1 = STV090x_READ_DEMOD(state, FBERCPT1); -+ count_0 = STV090x_READ_DEMOD(state, FBERCPT0); -+ -+ if ((!count_4) && (!count_3)) { -+ count = (count_2 & 0xff) << 16; -+ count |= (count_1 & 0xff) << 8; -+ count |= count_0 & 0xff; -+ } else { -+ count = 1 << 24; -+ } -+ if (count == 0) -+ per = 1; -+ } -+ if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0) < 0) -+ goto err; -+ if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0) -+ goto err; -+ -+ p->post_bit_error.len = 1; -+ p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; -+ p->post_bit_error.stat[0].uvalue = per; -+ p->post_bit_count.len = 1; -+ p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; -+ p->post_bit_count.stat[0].uvalue = count; -+ -+ return 0; -+err: -+ dprintk(FE_ERROR, 1, "I/O error"); -+ return -1; -+} -+ -+static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) -+{ -+ struct stv090x_state *state = fe->demodulator_priv; -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ u32 reg, dstatus; -+ u8 search_state; -+ -+ *status = FE_HAS_SIGNAL; -+ stv090x_read_rflevel(fe); -+ -+ dstatus = STV090x_READ_DEMOD(state, DSTATUS); -+ if (STV090x_GETFIELD_Px(dstatus, CAR_LOCK_FIELD)) -+ *status |= FE_HAS_CARRIER; -+ -+ reg = STV090x_READ_DEMOD(state, DMDSTATE); -+ search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD); -+ -+ switch (search_state) { -+ case 0: /* searching */ -+ case 1: /* first PLH detected */ -+ default: -+ dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)"); -+ break; -+ -+ case 2: /* DVB-S2 mode */ -+ dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2"); -+ if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) { -+ reg = STV090x_READ_DEMOD(state, PDELSTATUS1); -+ if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) { -+ *status |= FE_HAS_VITERBI; -+ reg = STV090x_READ_DEMOD(state, TSSTATUS); -+ if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) -+ *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; -+ } -+ } -+ break; -+ -+ case 3: /* DVB-S1/legacy mode */ -+ dprintk(FE_DEBUG, 1, "Delivery system: DVB-S"); -+ if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) { -+ reg = STV090x_READ_DEMOD(state, VSTATUSVIT); -+ if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) { -+ *status |= FE_HAS_VITERBI; -+ reg = STV090x_READ_DEMOD(state, TSSTATUS); -+ if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) -+ *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; -+ } -+ } -+ break; -+ } -+ -+ if (*status & FE_HAS_LOCK) { -+ stv090x_read_cnr(fe); -+ stv090x_read_per(fe, *status); -+ } -+ else { -+ p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ } -+ -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, *status & FE_HAS_LOCK); -+ -+ return 0; -+} -+ -+static int stv090x_read_snr(struct dvb_frontend *fe, u16 *snr) -+{ -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ -+ if (p->cnr.stat[0].scale == FE_SCALE_DECIBEL) { -+ *snr = (s32)p->cnr.stat[0].svalue / 100; -+ if (*snr > 200) -+ *snr = 0xffff; -+ else -+ *snr *= 328; -+ } else *snr = 0; -+ -+ return 0; -+} -+ -+static int stv090x_read_ber(struct dvb_frontend *fe, u32 *ber) -+{ -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ -+ if ( p->post_bit_error.stat[0].scale == FE_SCALE_COUNTER && -+ p->post_bit_count.stat[0].scale == FE_SCALE_COUNTER ) -+ *ber = (u32)p->post_bit_count.stat[0].uvalue ? (u32)p->post_bit_error.stat[0].uvalue / (u32)p->post_bit_count.stat[0].uvalue : 0; -+ -+ return 0; -+} -+ -+static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -+{ -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ -+ *strength = p->strength.stat[0].scale == FE_SCALE_DECIBEL ? ((100000 + (s32)p->strength.stat[0].svalue) / 1000) * 656 : 0; -+ -+ return 0; -+} -+ -+static int stv090x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -+{ -+ struct stv090x_state *state = fe->demodulator_priv; -+ u8 err0, err1; -+ -+ *ucblocks = 0; -+ switch (state->delsys) { -+ case STV090x_DVBS2: -+ err0 = STV090x_READ_DEMOD(state, UPCRCKO0); -+ err1 = STV090x_READ_DEMOD(state, UPCRCKO1); -+ *ucblocks = (err1 << 8) | err0; -+ default: -+ break; -+ } - return 0; - } - -@@ -3907,6 +4004,9 @@ static int stv090x_sleep(struct dvb_frontend *fe) - u32 reg; - u8 full_standby = 0; - -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, 0); -+ - if (stv090x_i2c_gate_ctrl(state, 1) < 0) - goto err; - -@@ -4138,6 +4238,9 @@ static void stv090x_release(struct dvb_frontend *fe) - { - struct stv090x_state *state = fe->demodulator_priv; - -+ if (state->config->set_lock_led) -+ state->config->set_lock_led(fe, 0); -+ - state->internal->num_used--; - if (state->internal->num_used <= 0) { - -@@ -4542,6 +4645,30 @@ static int stv0900_set_tspath(struct stv090x_state *state) - goto err; - } - -+ if (ts_nosync) -+ { -+ dprintk(FE_DEBUG, 1, "TS FIFO Minimum Latence mode\n"); -+ reg = stv090x_read_reg(state, STV090x_P1_TSSTATEM); -+ STV090x_SETFIELD_Px(reg, TSOUT_NOSYNC, 1); -+ if (stv090x_write_reg(state, STV090x_P1_TSSTATEM, reg) < 0) -+ goto err; -+ -+ reg = stv090x_read_reg(state, STV090x_P2_TSSTATEM); -+ STV090x_SETFIELD_Px(reg, TSOUT_NOSYNC, 1); -+ if (stv090x_write_reg(state, STV090x_P2_TSSTATEM, reg) < 0) -+ goto err; -+ -+ reg = stv090x_read_reg(state, STV090x_P1_TSSYNC); -+ STV090x_SETFIELD_Px(reg, TSFIFO_SYNCMODE, 2); -+ if (stv090x_write_reg(state, STV090x_P1_TSSYNC, reg) < 0) -+ goto err; -+ -+ reg = stv090x_read_reg(state, STV090x_P2_TSSYNC); -+ STV090x_SETFIELD_Px(reg, TSFIFO_SYNCMODE, 2); -+ if (stv090x_write_reg(state, STV090x_P2_TSSYNC, reg) < 0) -+ goto err; -+ } -+ - reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); - STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); - if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) -@@ -4665,6 +4792,20 @@ static int stv0903_set_tspath(struct stv090x_state *state) - goto err; - } - -+ if (ts_nosync) -+ { -+ dprintk(FE_DEBUG, 1, "TS FIFO Minimum Latence mode\n"); -+ reg = stv090x_read_reg(state, STV090x_P1_TSSTATEM); -+ STV090x_SETFIELD_Px(reg, TSOUT_NOSYNC, 1); -+ if (stv090x_write_reg(state, STV090x_P1_TSSTATEM, reg) < 0) -+ goto err; -+ -+ reg = stv090x_read_reg(state, STV090x_P1_TSSYNC); -+ STV090x_SETFIELD_Px(reg, TSFIFO_SYNCMODE, 2); -+ if (stv090x_write_reg(state, STV090x_P1_TSSYNC, reg) < 0) -+ goto err; -+ } -+ - reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); - STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); - if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) -@@ -4886,7 +5027,7 @@ static int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, - return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg); - } - --static struct dvb_frontend_ops stv090x_ops = { -+static const struct dvb_frontend_ops stv090x_ops = { - .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, - .info = { - .name = "STV090x Multistandard", -@@ -4915,9 +5056,10 @@ static struct dvb_frontend_ops stv090x_ops = { - - .search = stv090x_search, - .read_status = stv090x_read_status, -- .read_ber = stv090x_read_per, - .read_signal_strength = stv090x_read_signal_strength, -- .read_snr = stv090x_read_cnr, -+ .read_snr = stv090x_read_snr, -+ .read_ber = stv090x_read_ber, -+ .read_ucblocks = stv090x_read_ucblocks, - }; - - -diff --git a/drivers/media/dvb-frontends/stv090x.h b/drivers/media/dvb-frontends/stv090x.h -index 012e55e..59541d1 100644 ---- a/drivers/media/dvb-frontends/stv090x.h -+++ b/drivers/media/dvb-frontends/stv090x.h -@@ -89,21 +89,23 @@ struct stv090x_config { - - bool diseqc_envelope_mode; - -- int (*tuner_init)(struct dvb_frontend *fe); -- int (*tuner_sleep)(struct dvb_frontend *fe); -- int (*tuner_set_mode)(struct dvb_frontend *fe, enum tuner_mode mode); -- int (*tuner_set_frequency)(struct dvb_frontend *fe, u32 frequency); -- int (*tuner_get_frequency)(struct dvb_frontend *fe, u32 *frequency); -- int (*tuner_set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); -- int (*tuner_get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth); -- int (*tuner_set_bbgain)(struct dvb_frontend *fe, u32 gain); -- int (*tuner_get_bbgain)(struct dvb_frontend *fe, u32 *gain); -- int (*tuner_set_refclk)(struct dvb_frontend *fe, u32 refclk); -- int (*tuner_get_status)(struct dvb_frontend *fe, u32 *status); -- void (*tuner_i2c_lock)(struct dvb_frontend *fe, int lock); -+ /* Hook for Lock LED */ -+ void (*set_lock_led) (struct dvb_frontend *fe, int offon); -+ int (*tuner_init) (struct dvb_frontend *fe); -+ int (*tuner_sleep) (struct dvb_frontend *fe); -+ int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); -+ int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); -+ int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency); -+ int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth); -+ int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth); -+ int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain); -+ int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain); -+ int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk); -+ int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status); -+ void (*tuner_i2c_lock) (struct dvb_frontend *fe, int lock); - - /* dir = 0 -> output, dir = 1 -> input/open-drain */ -- int (*set_gpio)(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value, -+ int (*set_gpio) (struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value, - u8 xor_value); - }; - -diff --git a/drivers/media/dvb-frontends/stv090x_priv.h b/drivers/media/dvb-frontends/stv090x_priv.h -index 5b780c8..9f384b77 100644 ---- a/drivers/media/dvb-frontends/stv090x_priv.h -+++ b/drivers/media/dvb-frontends/stv090x_priv.h -@@ -32,16 +32,16 @@ - - #define dprintk(__y, __z, format, arg...) do { \ - if (__z) { \ -- if ((verbose > FE_ERROR) && (verbose > __y)) \ -+ if ((verbose >= FE_ERROR) && (verbose >= __y)) \ - printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ -- else if ((verbose > FE_NOTICE) && (verbose > __y)) \ -+ else if ((verbose >= FE_NOTICE) && (verbose >= __y)) \ - printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ -- else if ((verbose > FE_INFO) && (verbose > __y)) \ -+ else if ((verbose >= FE_INFO) && (verbose >= __y)) \ - printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ -- else if ((verbose > FE_DEBUG) && (verbose > __y)) \ -+ else if ((verbose >= FE_DEBUG) && (verbose >= __y)) \ - printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ - } else { \ -- if (verbose > __y) \ -+ if (verbose >= __y) \ - printk(format, ##arg); \ - } \ - } while (0) -diff --git a/drivers/media/dvb-frontends/stv090x_reg.h b/drivers/media/dvb-frontends/stv090x_reg.h -index 93741ee..c1dac9c 100644 ---- a/drivers/media/dvb-frontends/stv090x_reg.h -+++ b/drivers/media/dvb-frontends/stv090x_reg.h -@@ -2104,6 +2104,14 @@ - #define STV090x_WIDTH_Px_TSDIL_ON_FIELD 1 - #define STV090x_OFFST_Px_TSRS_ON_FIELD 5 - #define STV090x_WIDTH_Px_TSRS_ON_FIELD 1 -+#define STV090x_OFFST_Px_TSDESCRAMB_ON 4 -+#define STV090x_WIDTH_Px_TSDESCRAMB_ON 1 -+#define STV090x_OFFST_Px_TSFRAME_MODE 3 -+#define STV090x_WIDTH_Px_TSFRAME_MODE 1 -+#define STV090x_OFFST_Px_TS_DISABLE 2 -+#define STV090x_WIDTH_Px_TS_DISABLE 1 -+#define STV090x_OFFST_Px_TSOUT_NOSYNC 0 -+#define STV090x_WIDTH_Px_TSOUT_NOSYNC 1 - - #define STV090x_Px_TSCFGH(__x) (0xF572 - (__x - 1) * 0x200) - #define STV090x_P1_TSCFGH STV090x_Px_TSCFGH(1) -@@ -2147,6 +2155,14 @@ - #define STV090x_OFFST_Px_TSFIFO_DPUNACT_FIELD 1 - #define STV090x_WIDTH_Px_TSFIFO_DPUNACT_FIELD 1 - -+#define STV090x_Px_TSSYNC(__x) (0xF575 - (__x - 1) * 0x200) -+#define STV090x_P1_TSSYNC STV090x_Px_TSSYNC(1) -+#define STV090x_P2_TSSYNC STV090x_Px_TSSYNC(2) -+#define STV090x_OFFST_Px_TSFIFO_FISCR3B 5 -+#define STV090x_WIDTH_Px_TSFIFO_FISCR3B 2 -+#define STV090x_OFFST_Px_TSFIFO_SYNCMODE 3 -+#define STV090x_WIDTH_Px_TSFIFO_SYNCMODE 2 -+ - #define STV090x_Px_TSINSDELH(__x) (0xF576 - (__x - 1) * 0x200) - #define STV090x_P1_TSINSDELH STV090x_Px_TSINSDELH(1) - #define STV090x_P2_TSINSDELH STV090x_Px_TSINSDELH(2) -diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c -new file mode 100644 -index 0000000..033cbce ---- /dev/null -+++ b/drivers/media/dvb-frontends/stv0910.c -@@ -0,0 +1,1637 @@ -+/* -+ * Driver for the ST STV0910 DVB-S/S2 demodulator. -+ * -+ * Copyright (C) 2014-2015 Ralph Metzler -+ * Marcus Metzler -+ * developed for Digital Devices GmbH -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 only, as published by the Free Software Foundation. -+ * -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dvb_frontend.h" -+#include "stv0910.h" -+#include "stv0910_regs.h" -+ -+ -+#define TUNING_DELAY 200 -+#define BER_SRC_S 0x20 -+#define BER_SRC_S2 0x20 -+ -+LIST_HEAD(stvlist); -+ -+enum ReceiveMode { Mode_None, Mode_DVBS, Mode_DVBS2, Mode_Auto }; -+ -+enum DVBS2_FECType { DVBS2_64K, DVBS2_16K }; -+ -+enum DVBS2_ModCod { -+ DVBS2_DUMMY_PLF, DVBS2_QPSK_1_4, DVBS2_QPSK_1_3, DVBS2_QPSK_2_5, -+ DVBS2_QPSK_1_2, DVBS2_QPSK_3_5, DVBS2_QPSK_2_3, DVBS2_QPSK_3_4, -+ DVBS2_QPSK_4_5, DVBS2_QPSK_5_6, DVBS2_QPSK_8_9, DVBS2_QPSK_9_10, -+ DVBS2_8PSK_3_5, DVBS2_8PSK_2_3, DVBS2_8PSK_3_4, DVBS2_8PSK_5_6, -+ DVBS2_8PSK_8_9, DVBS2_8PSK_9_10, DVBS2_16APSK_2_3, DVBS2_16APSK_3_4, -+ DVBS2_16APSK_4_5, DVBS2_16APSK_5_6, DVBS2_16APSK_8_9, DVBS2_16APSK_9_10, -+ DVBS2_32APSK_3_4, DVBS2_32APSK_4_5, DVBS2_32APSK_5_6, DVBS2_32APSK_8_9, -+ DVBS2_32APSK_9_10 -+}; -+ -+enum FE_STV0910_ModCod { -+ FE_DUMMY_PLF, FE_QPSK_14, FE_QPSK_13, FE_QPSK_25, -+ FE_QPSK_12, FE_QPSK_35, FE_QPSK_23, FE_QPSK_34, -+ FE_QPSK_45, FE_QPSK_56, FE_QPSK_89, FE_QPSK_910, -+ FE_8PSK_35, FE_8PSK_23, FE_8PSK_34, FE_8PSK_56, -+ FE_8PSK_89, FE_8PSK_910, FE_16APSK_23, FE_16APSK_34, -+ FE_16APSK_45, FE_16APSK_56, FE_16APSK_89, FE_16APSK_910, -+ FE_32APSK_34, FE_32APSK_45, FE_32APSK_56, FE_32APSK_89, -+ FE_32APSK_910 -+}; -+ -+enum FE_STV0910_RollOff { FE_SAT_35, FE_SAT_25, FE_SAT_20, FE_SAT_15 }; -+ -+static inline u32 MulDiv32(u32 a, u32 b, u32 c) -+{ -+ u64 tmp64; -+ -+ tmp64 = (u64)a * (u64)b; -+ do_div(tmp64, c); -+ -+ return (u32) tmp64; -+} -+ -+struct stv_base { -+ struct list_head stvlist; -+ -+ u8 adr; -+ struct i2c_adapter *i2c; -+ struct mutex i2c_lock; -+ struct mutex reg_lock; -+ int count; -+ -+ u32 extclk; -+ u32 mclk; -+ -+ u8 dual_tuner; -+ -+ /* Hook for Lock LED */ -+ void (*set_lock_led) (struct dvb_frontend *fe, int offon); -+}; -+ -+struct stv { -+ struct stv_base *base; -+ struct dvb_frontend fe; -+ int nr; -+ u16 regoff; -+ u8 i2crpt; -+ u8 tscfgh; -+ u8 tsgeneral; -+ u8 tsspeed; -+ unsigned long tune_time; -+ -+ s32 SearchRange; -+ u32 Started; -+ u32 DemodLockTime; -+ enum ReceiveMode ReceiveMode; -+ u32 DemodTimeout; -+ u32 FecTimeout; -+ u32 FirstTimeLock; -+ u8 DEMOD; -+ u32 SymbolRate; -+ -+ u8 LastViterbiRate; -+ enum fe_code_rate PunctureRate; -+ enum FE_STV0910_ModCod ModCod; -+ enum DVBS2_FECType FECType; -+ u32 Pilots; -+ enum FE_STV0910_RollOff FERollOff; -+ -+ u32 LastBERNumerator; -+ u32 LastBERDenominator; -+ u8 BERScale; -+}; -+ -+struct SInitTable { -+ u16 Address; -+ u8 Data; -+}; -+ -+struct SLookup { -+ s16 Value; -+ u32 RegValue; -+}; -+ -+static inline int i2c_write(struct i2c_adapter *adap, u8 adr, -+ u8 *data, int len) -+{ -+ struct i2c_msg msg = {.addr = adr, .flags = 0, -+ .buf = data, .len = len}; -+ -+ return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; -+} -+ -+static int i2c_write_reg16(struct i2c_adapter *adap, u8 adr, u16 reg, u8 val) -+{ -+ u8 msg[3] = {reg >> 8, reg & 0xff, val}; -+ -+ return i2c_write(adap, adr, msg, 3); -+} -+ -+static int write_reg(struct stv *state, u16 reg, u8 val) -+{ -+ return i2c_write_reg16(state->base->i2c, state->base->adr, reg, val); -+} -+ -+static inline int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, -+ u16 reg, u8 *val) -+{ -+ u8 msg[2] = {reg >> 8, reg & 0xff}; -+ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, -+ .buf = msg, .len = 2}, -+ {.addr = adr, .flags = I2C_M_RD, -+ .buf = val, .len = 1 } }; -+ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; -+} -+ -+static int read_reg(struct stv *state, u16 reg, u8 *val) -+{ -+ return i2c_read_reg16(state->base->i2c, state->base->adr, reg, val); -+} -+ -+ -+static inline int i2c_read_regs16(struct i2c_adapter *adapter, u8 adr, -+ u16 reg, u8 *val, int len) -+{ -+ u8 msg[2] = {reg >> 8, reg & 0xff}; -+ struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, -+ .buf = msg, .len = 2}, -+ {.addr = adr, .flags = I2C_M_RD, -+ .buf = val, .len = len } }; -+ return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; -+} -+ -+static int read_regs(struct stv *state, u16 reg, u8 *val, int len) -+{ -+ return i2c_read_regs16(state->base->i2c, state->base->adr, -+ reg, val, len); -+} -+ -+struct SLookup S1_SN_Lookup[] = { -+ { 0, 9242 }, /*C/N= 0dB*/ -+ { 05, 9105 }, /*C/N=0.5dB*/ -+ { 10, 8950 }, /*C/N=1.0dB*/ -+ { 15, 8780 }, /*C/N=1.5dB*/ -+ { 20, 8566 }, /*C/N=2.0dB*/ -+ { 25, 8366 }, /*C/N=2.5dB*/ -+ { 30, 8146 }, /*C/N=3.0dB*/ -+ { 35, 7908 }, /*C/N=3.5dB*/ -+ { 40, 7666 }, /*C/N=4.0dB*/ -+ { 45, 7405 }, /*C/N=4.5dB*/ -+ { 50, 7136 }, /*C/N=5.0dB*/ -+ { 55, 6861 }, /*C/N=5.5dB*/ -+ { 60, 6576 }, /*C/N=6.0dB*/ -+ { 65, 6330 }, /*C/N=6.5dB*/ -+ { 70, 6048 }, /*C/N=7.0dB*/ -+ { 75, 5768 }, /*C/N=7.5dB*/ -+ { 80, 5492 }, /*C/N=8.0dB*/ -+ { 85, 5224 }, /*C/N=8.5dB*/ -+ { 90, 4959 }, /*C/N=9.0dB*/ -+ { 95, 4709 }, /*C/N=9.5dB*/ -+ { 100, 4467 }, /*C/N=10.0dB*/ -+ { 105, 4236 }, /*C/N=10.5dB*/ -+ { 110, 4013 }, /*C/N=11.0dB*/ -+ { 115, 3800 }, /*C/N=11.5dB*/ -+ { 120, 3598 }, /*C/N=12.0dB*/ -+ { 125, 3406 }, /*C/N=12.5dB*/ -+ { 130, 3225 }, /*C/N=13.0dB*/ -+ { 135, 3052 }, /*C/N=13.5dB*/ -+ { 140, 2889 }, /*C/N=14.0dB*/ -+ { 145, 2733 }, /*C/N=14.5dB*/ -+ { 150, 2587 }, /*C/N=15.0dB*/ -+ { 160, 2318 }, /*C/N=16.0dB*/ -+ { 170, 2077 }, /*C/N=17.0dB*/ -+ { 180, 1862 }, /*C/N=18.0dB*/ -+ { 190, 1670 }, /*C/N=19.0dB*/ -+ { 200, 1499 }, /*C/N=20.0dB*/ -+ { 210, 1347 }, /*C/N=21.0dB*/ -+ { 220, 1213 }, /*C/N=22.0dB*/ -+ { 230, 1095 }, /*C/N=23.0dB*/ -+ { 240, 992 }, /*C/N=24.0dB*/ -+ { 250, 900 }, /*C/N=25.0dB*/ -+ { 260, 826 }, /*C/N=26.0dB*/ -+ { 270, 758 }, /*C/N=27.0dB*/ -+ { 280, 702 }, /*C/N=28.0dB*/ -+ { 290, 653 }, /*C/N=29.0dB*/ -+ { 300, 613 }, /*C/N=30.0dB*/ -+ { 310, 579 }, /*C/N=31.0dB*/ -+ { 320, 550 }, /*C/N=32.0dB*/ -+ { 330, 526 }, /*C/N=33.0dB*/ -+ { 350, 490 }, /*C/N=33.0dB*/ -+ { 400, 445 }, /*C/N=40.0dB*/ -+ { 450, 430 }, /*C/N=45.0dB*/ -+ { 500, 426 }, /*C/N=50.0dB*/ -+ { 510, 425 } /*C/N=51.0dB*/ -+}; -+ -+struct SLookup S2_SN_Lookup[] = { -+ { -30, 13950 }, /*C/N=-2.5dB*/ -+ { -25, 13580 }, /*C/N=-2.5dB*/ -+ { -20, 13150 }, /*C/N=-2.0dB*/ -+ { -15, 12760 }, /*C/N=-1.5dB*/ -+ { -10, 12345 }, /*C/N=-1.0dB*/ -+ { -05, 11900 }, /*C/N=-0.5dB*/ -+ { 0, 11520 }, /*C/N= 0dB*/ -+ { 05, 11080 }, /*C/N= 0.5dB*/ -+ { 10, 10630 }, /*C/N= 1.0dB*/ -+ { 15, 10210 }, /*C/N= 1.5dB*/ -+ { 20, 9790 }, /*C/N= 2.0dB*/ -+ { 25, 9390 }, /*C/N= 2.5dB*/ -+ { 30, 8970 }, /*C/N= 3.0dB*/ -+ { 35, 8575 }, /*C/N= 3.5dB*/ -+ { 40, 8180 }, /*C/N= 4.0dB*/ -+ { 45, 7800 }, /*C/N= 4.5dB*/ -+ { 50, 7430 }, /*C/N= 5.0dB*/ -+ { 55, 7080 }, /*C/N= 5.5dB*/ -+ { 60, 6720 }, /*C/N= 6.0dB*/ -+ { 65, 6320 }, /*C/N= 6.5dB*/ -+ { 70, 6060 }, /*C/N= 7.0dB*/ -+ { 75, 5760 }, /*C/N= 7.5dB*/ -+ { 80, 5480 }, /*C/N= 8.0dB*/ -+ { 85, 5200 }, /*C/N= 8.5dB*/ -+ { 90, 4930 }, /*C/N= 9.0dB*/ -+ { 95, 4680 }, /*C/N= 9.5dB*/ -+ { 100, 4425 }, /*C/N=10.0dB*/ -+ { 105, 4210 }, /*C/N=10.5dB*/ -+ { 110, 3980 }, /*C/N=11.0dB*/ -+ { 115, 3765 }, /*C/N=11.5dB*/ -+ { 120, 3570 }, /*C/N=12.0dB*/ -+ { 125, 3315 }, /*C/N=12.5dB*/ -+ { 130, 3140 }, /*C/N=13.0dB*/ -+ { 135, 2980 }, /*C/N=13.5dB*/ -+ { 140, 2820 }, /*C/N=14.0dB*/ -+ { 145, 2670 }, /*C/N=14.5dB*/ -+ { 150, 2535 }, /*C/N=15.0dB*/ -+ { 160, 2270 }, /*C/N=16.0dB*/ -+ { 170, 2035 }, /*C/N=17.0dB*/ -+ { 180, 1825 }, /*C/N=18.0dB*/ -+ { 190, 1650 }, /*C/N=19.0dB*/ -+ { 200, 1485 }, /*C/N=20.0dB*/ -+ { 210, 1340 }, /*C/N=21.0dB*/ -+ { 220, 1212 }, /*C/N=22.0dB*/ -+ { 230, 1100 }, /*C/N=23.0dB*/ -+ { 240, 1000 }, /*C/N=24.0dB*/ -+ { 250, 910 }, /*C/N=25.0dB*/ -+ { 260, 836 }, /*C/N=26.0dB*/ -+ { 270, 772 }, /*C/N=27.0dB*/ -+ { 280, 718 }, /*C/N=28.0dB*/ -+ { 290, 671 }, /*C/N=29.0dB*/ -+ { 300, 635 }, /*C/N=30.0dB*/ -+ { 310, 602 }, /*C/N=31.0dB*/ -+ { 320, 575 }, /*C/N=32.0dB*/ -+ { 330, 550 }, /*C/N=33.0dB*/ -+ { 350, 517 }, /*C/N=35.0dB*/ -+ { 400, 480 }, /*C/N=40.0dB*/ -+ { 450, 466 }, /*C/N=45.0dB*/ -+ { 500, 464 }, /*C/N=50.0dB*/ -+ { 510, 463 }, /*C/N=51.0dB*/ -+}; -+ -+struct SLookup PADC_Lookup[] = { -+ {-2000, 1179 }, /*PADC=-20dBm*/ -+ {-1900, 1485 }, /*PADC=-19dBm*/ -+ {-1700, 2354 }, /*PADC=-17dBm*/ -+ {-1500, 3730 }, /*PADC=-15dBm*/ -+ {-1300, 5910 }, /*PADC=-13dBm*/ -+ {-1100, 9380 }, /*PADC=-11dBm*/ -+ {- 900, 14850}, /*PADC=-9dBm*/ -+ {- 700, 23520}, /*PADC=-7dBm*/ -+ {- 600, 29650}, /*PADC=-6dBm*/ -+ {- 500, 37300}, /*PADC=-5dBm*/ -+ {- 400, 47000}, /*PADC=-4dBm*/ -+ {- 300, 59100}, /*PADC=-3dBm*/ -+ {- 200, 74500}, /*PADC=-2dBm*/ -+ {- 100, 93600}, /*PADC=-1dBm*/ -+ { 0, 118000} /*PADC=+0dBm*/ -+}; -+ -+ -+/********************************************************************* -+Tracking carrier loop carrier QPSK 1/4 to 8PSK 9/10 long Frame -+*********************************************************************/ -+static u8 S2CarLoop[] = { -+ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff -+ 20MPon 20MPoff 30MPon 30MPoff*/ -+ /* FE_QPSK_14 */ -+ 0x0C, 0x3C, 0x0B, 0x3C, 0x2A, 0x2C, 0x2A, 0x1C, 0x3A, 0x3B, -+ /* FE_QPSK_13 */ -+ 0x0C, 0x3C, 0x0B, 0x3C, 0x2A, 0x2C, 0x3A, 0x0C, 0x3A, 0x2B, -+ /* FE_QPSK_25 */ -+ 0x1C, 0x3C, 0x1B, 0x3C, 0x3A, 0x1C, 0x3A, 0x3B, 0x3A, 0x2B, -+ /* FE_QPSK_12 */ -+ 0x0C, 0x1C, 0x2B, 0x1C, 0x0B, 0x2C, 0x0B, 0x0C, 0x2A, 0x2B, -+ /* FE_QPSK_35 */ -+ 0x1C, 0x1C, 0x2B, 0x1C, 0x0B, 0x2C, 0x0B, 0x0C, 0x2A, 0x2B, -+ /* FE_QPSK_23 */ -+ 0x2C, 0x2C, 0x2B, 0x1C, 0x0B, 0x2C, 0x0B, 0x0C, 0x2A, 0x2B, -+ /* FE_QPSK_34 */ -+ 0x3C, 0x2C, 0x3B, 0x2C, 0x1B, 0x1C, 0x1B, 0x3B, 0x3A, 0x1B, -+ /* FE_QPSK_45 */ -+ 0x0D, 0x3C, 0x3B, 0x2C, 0x1B, 0x1C, 0x1B, 0x3B, 0x3A, 0x1B, -+ /* FE_QPSK_56 */ -+ 0x1D, 0x3C, 0x0C, 0x2C, 0x2B, 0x1C, 0x1B, 0x3B, 0x0B, 0x1B, -+ /* FE_QPSK_89 */ -+ 0x3D, 0x0D, 0x0C, 0x2C, 0x2B, 0x0C, 0x2B, 0x2B, 0x0B, 0x0B, -+ /* FE_QPSK_910 */ -+ 0x1E, 0x0D, 0x1C, 0x2C, 0x3B, 0x0C, 0x2B, 0x2B, 0x1B, 0x0B, -+ /* FE_8PSK_35 */ -+ 0x28, 0x09, 0x28, 0x09, 0x28, 0x09, 0x28, 0x08, 0x28, 0x27, -+ /* FE_8PSK_23 */ -+ 0x19, 0x29, 0x19, 0x29, 0x19, 0x29, 0x38, 0x19, 0x28, 0x09, -+ /* FE_8PSK_34 */ -+ 0x1A, 0x0B, 0x1A, 0x3A, 0x0A, 0x2A, 0x39, 0x2A, 0x39, 0x1A, -+ /* FE_8PSK_56 */ -+ 0x2B, 0x2B, 0x1B, 0x1B, 0x0B, 0x1B, 0x1A, 0x0B, 0x1A, 0x1A, -+ /* FE_8PSK_89 */ -+ 0x0C, 0x0C, 0x3B, 0x3B, 0x1B, 0x1B, 0x2A, 0x0B, 0x2A, 0x2A, -+ /* FE_8PSK_910 */ -+ 0x0C, 0x1C, 0x0C, 0x3B, 0x2B, 0x1B, 0x3A, 0x0B, 0x2A, 0x2A, -+ -+ /********************************************************************** -+ Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame -+ **********************************************************************/ -+ /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon -+ 20MPoff 30MPon 30MPoff*/ -+ /* FE_16APSK_23 */ -+ 0x0A, 0x0A, 0x0A, 0x0A, 0x1A, 0x0A, 0x39, 0x0A, 0x29, 0x0A, -+ /* FE_16APSK_34 */ -+ 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0A, 0x2A, 0x0A, 0x1A, 0x0A, -+ /* FE_16APSK_45 */ -+ 0x0A, 0x0A, 0x0A, 0x0A, 0x1B, 0x0A, 0x3A, 0x0A, 0x2A, 0x0A, -+ /* FE_16APSK_56 */ -+ 0x0A, 0x0A, 0x0A, 0x0A, 0x1B, 0x0A, 0x3A, 0x0A, 0x2A, 0x0A, -+ /* FE_16APSK_89 */ -+ 0x0A, 0x0A, 0x0A, 0x0A, 0x2B, 0x0A, 0x0B, 0x0A, 0x3A, 0x0A, -+ /* FE_16APSK_910 */ -+ 0x0A, 0x0A, 0x0A, 0x0A, 0x2B, 0x0A, 0x0B, 0x0A, 0x3A, 0x0A, -+ /* FE_32APSK_34 */ -+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, -+ /* FE_32APSK_45 */ -+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, -+ /* FE_32APSK_56 */ -+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, -+ /* FE_32APSK_89 */ -+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, -+ /* FE_32APSK_910 */ -+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, -+}; -+ -+static u8 get_optim_cloop(struct stv *state, -+ enum FE_STV0910_ModCod ModCod, u32 Pilots) -+{ -+ int i = 0; -+ if (ModCod >= FE_32APSK_910) -+ i = ((int)FE_32APSK_910 - (int)FE_QPSK_14) * 10; -+ else if (ModCod >= FE_QPSK_14) -+ i = ((int)ModCod - (int)FE_QPSK_14) * 10; -+ -+ if (state->SymbolRate <= 3000000) -+ i += 0; -+ else if (state->SymbolRate <= 7000000) -+ i += 2; -+ else if (state->SymbolRate <= 15000000) -+ i += 4; -+ else if (state->SymbolRate <= 25000000) -+ i += 6; -+ else -+ i += 8; -+ -+ if (!Pilots) -+ i += 1; -+ -+ return S2CarLoop[i]; -+} -+ -+static int GetCurSymbolRate(struct stv *state, u32 *pSymbolRate) -+{ -+ int status = 0; -+ u8 SymbFreq0; -+ u8 SymbFreq1; -+ u8 SymbFreq2; -+ u8 SymbFreq3; -+ u8 TimOffs0; -+ u8 TimOffs1; -+ u8 TimOffs2; -+ u32 SymbolRate; -+ s32 TimingOffset; -+ -+ *pSymbolRate = 0; -+ if (!state->Started) -+ return status; -+ -+ read_reg(state, RSTV0910_P2_SFR3 + state->regoff, &SymbFreq3); -+ read_reg(state, RSTV0910_P2_SFR2 + state->regoff, &SymbFreq2); -+ read_reg(state, RSTV0910_P2_SFR1 + state->regoff, &SymbFreq1); -+ read_reg(state, RSTV0910_P2_SFR0 + state->regoff, &SymbFreq0); -+ read_reg(state, RSTV0910_P2_TMGREG2 + state->regoff, &TimOffs2); -+ read_reg(state, RSTV0910_P2_TMGREG1 + state->regoff, &TimOffs1); -+ read_reg(state, RSTV0910_P2_TMGREG0 + state->regoff, &TimOffs0); -+ -+ SymbolRate = ((u32) SymbFreq3 << 24) | ((u32) SymbFreq2 << 16) | -+ ((u32) SymbFreq1 << 8) | (u32) SymbFreq0; -+ TimingOffset = ((u32) TimOffs2 << 16) | ((u32) TimOffs1 << 8) | -+ (u32) TimOffs0; -+ -+ if ((TimingOffset & (1<<23)) != 0) -+ TimingOffset |= 0xFF000000; /* Sign extent */ -+ -+ SymbolRate = (u32) (((u64) SymbolRate * state->base->mclk) >> 32); -+ TimingOffset = (s32) (((s64) SymbolRate * (s64) TimingOffset) >> 29); -+ -+ *pSymbolRate = SymbolRate + TimingOffset; -+ -+ return 0; -+} -+ -+static int GetSignalParameters(struct stv *state) -+{ -+ if (!state->Started) -+ return -1; -+ -+ if (state->ReceiveMode == Mode_DVBS2) { -+ u8 tmp; -+ u8 rolloff; -+ -+ read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp); -+ state->ModCod = (enum FE_STV0910_ModCod) ((tmp & 0x7c) >> 2); -+ state->Pilots = (tmp & 0x01) != 0; -+ state->FECType = (enum DVBS2_FECType) ((tmp & 0x02) >> 1); -+ -+ read_reg(state, RSTV0910_P2_TMGOBS + state->regoff, &rolloff); -+ rolloff = rolloff >> 6; -+ state->FERollOff = (enum FE_STV0910_RollOff) rolloff; -+ -+ } else if (state->ReceiveMode == Mode_DVBS) { -+ /* todo */ -+ } -+ return 0; -+} -+ -+static int TrackingOptimization(struct stv *state) -+{ -+ u32 SymbolRate = 0; -+ u8 tmp; -+ -+ GetCurSymbolRate(state, &SymbolRate); -+ read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, &tmp); -+ tmp &= ~0xC0; -+ -+ switch (state->ReceiveMode) { -+ case Mode_DVBS: -+ tmp |= 0x40; break; -+ case Mode_DVBS2: -+ tmp |= 0x80; break; -+ default: -+ tmp |= 0xC0; break; -+ } -+ write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, tmp); -+ -+ if (state->ReceiveMode == Mode_DVBS2) { -+ /* force to PRE BCH Rate */ -+ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, -+ BER_SRC_S2 | state->BERScale); -+ -+ if (state->FECType == DVBS2_64K) { -+ u8 aclc = get_optim_cloop(state, state->ModCod, -+ state->Pilots); -+ -+ if (state->ModCod <= FE_QPSK_910) { -+ write_reg(state, RSTV0910_P2_ACLC2S2Q + -+ state->regoff, aclc); -+ } else if (state->ModCod <= FE_8PSK_910) { -+ write_reg(state, RSTV0910_P2_ACLC2S2Q + -+ state->regoff, 0x2a); -+ write_reg(state, RSTV0910_P2_ACLC2S28 + -+ state->regoff, aclc); -+ } else if (state->ModCod <= FE_16APSK_910) { -+ write_reg(state, RSTV0910_P2_ACLC2S2Q + -+ state->regoff, 0x2a); -+ write_reg(state, RSTV0910_P2_ACLC2S216A + -+ state->regoff, aclc); -+ } else if (state->ModCod <= FE_32APSK_910) { -+ write_reg(state, RSTV0910_P2_ACLC2S2Q + -+ state->regoff, 0x2a); -+ write_reg(state, RSTV0910_P2_ACLC2S232A + -+ state->regoff, aclc); -+ } -+ } -+ } -+ if (state->ReceiveMode == Mode_DVBS) { -+ u8 tmp; -+ -+ read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp); -+ state->PunctureRate = FEC_NONE; -+ switch (tmp & 0x1F) { -+ case 0x0d: -+ state->PunctureRate = FEC_1_2; -+ break; -+ case 0x12: -+ state->PunctureRate = FEC_2_3; -+ break; -+ case 0x15: -+ state->PunctureRate = FEC_3_4; -+ break; -+ case 0x18: -+ state->PunctureRate = FEC_5_6; -+ break; -+ case 0x1A: -+ state->PunctureRate = FEC_7_8; -+ break; -+ } -+ } -+ return 0; -+} -+ -+static s32 TableLookup(struct SLookup *Table, -+ int TableSize, u16 RegValue) -+{ -+ s32 Value; -+ int imin = 0; -+ int imax = TableSize - 1; -+ int i; -+ s32 RegDiff; -+ -+ // Assumes Table[0].RegValue > Table[imax].RegValue -+ if( RegValue >= Table[0].RegValue ) -+ Value = Table[0].Value; -+ else if( RegValue <= Table[imax].RegValue ) -+ Value = Table[imax].Value; -+ else -+ { -+ while(imax-imin > 1) -+ { -+ i = (imax + imin) / 2; -+ if( (Table[imin].RegValue >= RegValue) && (RegValue >= Table[i].RegValue) ) -+ imax = i; -+ else -+ imin = i; -+ } -+ -+ RegDiff = Table[imax].RegValue - Table[imin].RegValue; -+ Value = Table[imin].Value; -+ if( RegDiff != 0 ) -+ Value += ((s32)(RegValue - Table[imin].RegValue) * -+ (s32)(Table[imax].Value - Table[imin].Value))/(RegDiff); -+ } -+ -+ return Value; -+} -+ -+#ifndef ARRAY_SIZE -+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -+#endif -+ -+static int GetSignalToNoise(struct stv *state, s32 *SignalToNoise) -+{ -+ u8 Data0; -+ u8 Data1; -+ u16 Data; -+ int nLookup; -+ struct SLookup *Lookup; -+ -+ *SignalToNoise = 0; -+ -+ if (!state->Started) -+ return 0; -+ -+ if (state->ReceiveMode == Mode_DVBS2) { -+ read_reg(state, RSTV0910_P2_NNOSPLHT1 + state->regoff, &Data1); -+ read_reg(state, RSTV0910_P2_NNOSPLHT0 + state->regoff, &Data0); -+ nLookup = ARRAY_SIZE(S2_SN_Lookup); -+ Lookup = S2_SN_Lookup; -+ } else { -+ read_reg(state, RSTV0910_P2_NNOSDATAT1 + state->regoff, &Data1); -+ read_reg(state, RSTV0910_P2_NNOSDATAT0 + state->regoff, &Data0); -+ nLookup = ARRAY_SIZE(S1_SN_Lookup); -+ Lookup = S1_SN_Lookup; -+ } -+ Data = (((u16)Data1) << 8) | (u16) Data0; -+ *SignalToNoise = TableLookup(Lookup, nLookup, Data); -+ return 0; -+} -+ -+static int GetBitErrorRateS(struct stv *state, u32 *BERNumerator, -+ u32 *BERDenominator) -+{ -+ u8 Regs[3]; -+ -+ int status = read_regs(state, RSTV0910_P2_ERRCNT12 + state->regoff, -+ Regs, 3); -+ -+ if (status) -+ return -1; -+ -+ if ((Regs[0] & 0x80) == 0) { -+ state->LastBERDenominator = 1 << ((state->BERScale * 2) + -+ 10 + 3); -+ state->LastBERNumerator = ((u32) (Regs[0] & 0x7F) << 16) | -+ ((u32) Regs[1] << 8) | Regs[2]; -+ if (state->LastBERNumerator < 256 && state->BERScale < 6) { -+ state->BERScale += 1; -+ status = write_reg(state, RSTV0910_P2_ERRCTRL1 + -+ state->regoff, -+ 0x20 | state->BERScale); -+ } else if (state->LastBERNumerator > 1024 && -+ state->BERScale > 2) { -+ state->BERScale -= 1; -+ status = write_reg(state, RSTV0910_P2_ERRCTRL1 + -+ state->regoff, 0x20 | -+ state->BERScale); -+ } -+ } -+ *BERNumerator = state->LastBERNumerator; -+ *BERDenominator = state->LastBERDenominator; -+ return 0; -+} -+ -+static u32 DVBS2_nBCH(enum DVBS2_ModCod ModCod, enum DVBS2_FECType FECType) -+{ -+ static u32 nBCH[][2] = { -+ {16200, 3240}, /* QPSK_1_4, */ -+ {21600, 5400}, /* QPSK_1_3, */ -+ {25920, 6480}, /* QPSK_2_5, */ -+ {32400, 7200}, /* QPSK_1_2, */ -+ {38880, 9720}, /* QPSK_3_5, */ -+ {43200, 10800}, /* QPSK_2_3, */ -+ {48600, 11880}, /* QPSK_3_4, */ -+ {51840, 12600}, /* QPSK_4_5, */ -+ {54000, 13320}, /* QPSK_5_6, */ -+ {57600, 14400}, /* QPSK_8_9, */ -+ {58320, 16000}, /* QPSK_9_10, */ -+ {43200, 9720}, /* 8PSK_3_5, */ -+ {48600, 10800}, /* 8PSK_2_3, */ -+ {51840, 11880}, /* 8PSK_3_4, */ -+ {54000, 13320}, /* 8PSK_5_6, */ -+ {57600, 14400}, /* 8PSK_8_9, */ -+ {58320, 16000}, /* 8PSK_9_10, */ -+ {43200, 10800}, /* 16APSK_2_3, */ -+ {48600, 11880}, /* 16APSK_3_4, */ -+ {51840, 12600}, /* 16APSK_4_5, */ -+ {54000, 13320}, /* 16APSK_5_6, */ -+ {57600, 14400}, /* 16APSK_8_9, */ -+ {58320, 16000}, /* 16APSK_9_10 */ -+ {48600, 11880}, /* 32APSK_3_4, */ -+ {51840, 12600}, /* 32APSK_4_5, */ -+ {54000, 13320}, /* 32APSK_5_6, */ -+ {57600, 14400}, /* 32APSK_8_9, */ -+ {58320, 16000}, /* 32APSK_9_10 */ -+ }; -+ -+ if (ModCod >= DVBS2_QPSK_1_4 && -+ ModCod <= DVBS2_32APSK_9_10 && FECType <= DVBS2_16K) -+ return nBCH[FECType][ModCod]; -+ return 64800; -+} -+ -+static int GetBitErrorRateS2(struct stv *state, u32 *BERNumerator, -+ u32 *BERDenominator) -+{ -+ u8 Regs[3]; -+ -+ int status = read_regs(state, RSTV0910_P2_ERRCNT12 + state->regoff, -+ Regs, 3); -+ -+ if (status) -+ return -1; -+ -+ if ((Regs[0] & 0x80) == 0) { -+ state->LastBERDenominator = -+ DVBS2_nBCH((enum DVBS2_ModCod) state->ModCod, -+ state->FECType) << -+ (state->BERScale * 2); -+ state->LastBERNumerator = (((u32) Regs[0] & 0x7F) << 16) | -+ ((u32) Regs[1] << 8) | Regs[2]; -+ if (state->LastBERNumerator < 256 && state->BERScale < 6) { -+ state->BERScale += 1; -+ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, -+ 0x20 | state->BERScale); -+ } else if (state->LastBERNumerator > 1024 && -+ state->BERScale > 2) { -+ state->BERScale -= 1; -+ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, -+ 0x20 | state->BERScale); -+ } -+ } -+ *BERNumerator = state->LastBERNumerator; -+ *BERDenominator = state->LastBERDenominator; -+ return status; -+} -+ -+static int GetBitErrorRate(struct stv *state, u32 *BERNumerator, -+ u32 *BERDenominator) -+{ -+ *BERNumerator = 0; -+ *BERDenominator = 1; -+ -+ switch (state->ReceiveMode) { -+ case Mode_DVBS: -+ return GetBitErrorRateS(state, BERNumerator, BERDenominator); -+ break; -+ case Mode_DVBS2: -+ return GetBitErrorRateS2(state, BERNumerator, BERDenominator); -+ default: -+ break; -+ } -+ return 0; -+} -+ -+static int init(struct dvb_frontend *fe) -+{ -+ return 0; -+} -+ -+static int set_mclock(struct stv *state, u32 MasterClock) -+{ -+ u32 idf = 1; -+ u32 odf = 4; -+ u32 quartz = state->base->extclk / 1000000; -+ u32 Fphi = MasterClock / 1000000; -+ u32 ndiv = (Fphi * odf * idf) / quartz; -+ u32 cp = 7; -+ u32 fvco; -+ -+ if (ndiv >= 7 && ndiv <= 71) -+ cp = 7; -+ else if (ndiv >= 72 && ndiv <= 79) -+ cp = 8; -+ else if (ndiv >= 80 && ndiv <= 87) -+ cp = 9; -+ else if (ndiv >= 88 && ndiv <= 95) -+ cp = 10; -+ else if (ndiv >= 96 && ndiv <= 103) -+ cp = 11; -+ else if (ndiv >= 104 && ndiv <= 111) -+ cp = 12; -+ else if (ndiv >= 112 && ndiv <= 119) -+ cp = 13; -+ else if (ndiv >= 120 && ndiv <= 127) -+ cp = 14; -+ else if (ndiv >= 128 && ndiv <= 135) -+ cp = 15; -+ else if (ndiv >= 136 && ndiv <= 143) -+ cp = 16; -+ else if (ndiv >= 144 && ndiv <= 151) -+ cp = 17; -+ else if (ndiv >= 152 && ndiv <= 159) -+ cp = 18; -+ else if (ndiv >= 160 && ndiv <= 167) -+ cp = 19; -+ else if (ndiv >= 168 && ndiv <= 175) -+ cp = 20; -+ else if (ndiv >= 176 && ndiv <= 183) -+ cp = 21; -+ else if (ndiv >= 184 && ndiv <= 191) -+ cp = 22; -+ else if (ndiv >= 192 && ndiv <= 199) -+ cp = 23; -+ else if (ndiv >= 200 && ndiv <= 207) -+ cp = 24; -+ else if (ndiv >= 208 && ndiv <= 215) -+ cp = 25; -+ else if (ndiv >= 216 && ndiv <= 223) -+ cp = 26; -+ else if (ndiv >= 224 && ndiv <= 225) -+ cp = 27; -+ -+ write_reg(state, RSTV0910_NCOARSE, (cp << 3) | idf); -+ write_reg(state, RSTV0910_NCOARSE2, odf); -+ write_reg(state, RSTV0910_NCOARSE1, ndiv); -+ -+ fvco = (quartz * 2 * ndiv) / idf; -+ state->base->mclk = fvco / (2 * odf) * 1000000; -+ -+ /*pr_info("ndiv = %d, MasterClock = %d\n", ndiv, state->base->mclk);*/ -+ return 0; -+} -+ -+static int Stop(struct stv *state) -+{ -+ if (state->Started) { -+ u8 tmp; -+ -+ write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, -+ state->tscfgh | 0x01); -+ read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp); -+ tmp &= ~0x01; /*release reset DVBS2 packet delin*/ -+ write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp); -+ /* Blind optim*/ -+ write_reg(state, RSTV0910_P2_AGC2O + state->regoff, 0x5B); -+ /* Stop the demod */ -+ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5c); -+ state->Started = 0; -+ } -+ state->ReceiveMode = Mode_None; -+ return 0; -+} -+ -+static int SetPLS(struct stv *state, u8 pls_mode, u32 pls_code) -+{ -+ if (pls_mode == 0 && pls_code == 0) -+ pls_code = 1; -+ pls_mode &= 0x03; -+ pls_code &= 0x3FFFF; -+ -+ //pr_warn("%s: code %d (mode %d)\n", __func__, pls_code, pls_mode); -+ write_reg(state, RSTV0910_P2_PLROOT2 + state->regoff, (pls_mode<<2) | (pls_code>>16)); -+ write_reg(state, RSTV0910_P2_PLROOT1 + state->regoff, pls_code>>8); -+ write_reg(state, RSTV0910_P2_PLROOT0 + state->regoff, pls_code); -+ return 0; -+} -+ -+static int SetMIS(struct stv *state, int mis) -+{ -+ u8 tmp; -+ -+ if (mis == NO_STREAM_ID_FILTER) { -+ //pr_warn("%s: disable MIS filtering\n", __func__); -+ SetPLS(state, 0, 0); -+ read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp); -+ tmp &= ~0x20; -+ write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp); -+ } else { -+ SetPLS(state, (mis>>26) & 0x3, (mis>>8) & 0x3FFFF); -+ read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp); -+ tmp |= 0x20; -+ write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp); -+ //pr_warn("%s: enable MIS filtering - %d\n", __func__, mis & 0xff); -+ write_reg(state, RSTV0910_P2_ISIENTRY + state->regoff, mis & 0xff ); -+ write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0xff ); -+ } -+ return 0; -+} -+ -+static int Start(struct stv *state, struct dtv_frontend_properties *p) -+{ -+ s32 Freq; -+ u8 regDMDCFGMD; -+ u16 symb; -+ -+ if (p->symbol_rate < 100000 || p->symbol_rate > 70000000) -+ return -EINVAL; -+ -+ state->ReceiveMode = Mode_None; -+ state->DemodLockTime = 0; -+ -+ /* Demod Stop*/ -+ if (state->Started) -+ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5C); -+ -+ if (p->symbol_rate <= 1000000) { /*SR <=1Msps*/ -+ state->DemodTimeout = 3000; -+ state->FecTimeout = 2000; -+ } else if (p->symbol_rate <= 2000000) { /*1Msps < SR <=2Msps*/ -+ state->DemodTimeout = 2500; -+ state->FecTimeout = 1300; -+ } else if (p->symbol_rate <= 5000000) { /*2Msps< SR <=5Msps*/ -+ state->DemodTimeout = 1000; -+ state->FecTimeout = 650; -+ } else if (p->symbol_rate <= 10000000) { /*5Msps< SR <=10Msps*/ -+ state->DemodTimeout = 700; -+ state->FecTimeout = 350; -+ } else if (p->symbol_rate < 20000000) { /*10Msps< SR <=20Msps*/ -+ state->DemodTimeout = 400; -+ state->FecTimeout = 200; -+ } else { /*SR >=20Msps*/ -+ state->DemodTimeout = 300; -+ state->FecTimeout = 200; -+ } -+ -+ SetMIS(state, p->stream_id); -+ -+ /* Set the Init Symbol rate*/ -+ symb = MulDiv32(p->symbol_rate, 65536, state->base->mclk); -+ write_reg(state, RSTV0910_P2_SFRINIT1 + state->regoff, -+ ((symb >> 8) & 0x7F)); -+ write_reg(state, RSTV0910_P2_SFRINIT0 + state->regoff, (symb & 0xFF)); -+ -+ /*pr_info("symb = %u\n", symb);*/ -+ -+ state->DEMOD |= 0x80; -+ write_reg(state, RSTV0910_P2_DEMOD + state->regoff, state->DEMOD); -+ -+ /* FE_STV0910_SetSearchStandard */ -+ read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, ®DMDCFGMD); -+ write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, -+ regDMDCFGMD |= 0xC0); -+ -+ /* Disable DSS */ -+ write_reg(state, RSTV0910_P2_FECM + state->regoff, 0x00); -+ write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x2F); -+ -+ /* 8PSK 3/5, 8PSK 2/3 Poff tracking optimization WA*/ -+ write_reg(state, RSTV0910_P2_ACLC2S2Q + state->regoff, 0x0B); -+ write_reg(state, RSTV0910_P2_ACLC2S28 + state->regoff, 0x0A); -+ write_reg(state, RSTV0910_P2_BCLC2S2Q + state->regoff, 0x84); -+ write_reg(state, RSTV0910_P2_BCLC2S28 + state->regoff, 0x84); -+ write_reg(state, RSTV0910_P2_CARHDR + state->regoff, 0x1C); -+ /* Reset demod */ -+ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x1F); -+ -+ write_reg(state, RSTV0910_P2_CARCFG + state->regoff, 0x46); -+ -+ Freq = (state->SearchRange / 2000) + 600; -+ if (p->symbol_rate <= 5000000) -+ Freq -= (600 + 80); -+ Freq = (Freq << 16) / (state->base->mclk / 1000); -+ -+ write_reg(state, RSTV0910_P2_CFRUP1 + state->regoff, -+ (Freq >> 8) & 0xff); -+ write_reg(state, RSTV0910_P2_CFRUP0 + state->regoff, (Freq & 0xff)); -+ /*CFR Low Setting*/ -+ Freq = -Freq; -+ write_reg(state, RSTV0910_P2_CFRLOW1 + state->regoff, -+ (Freq >> 8) & 0xff); -+ write_reg(state, RSTV0910_P2_CFRLOW0 + state->regoff, (Freq & 0xff)); -+ -+ /* init the demod frequency offset to 0 */ -+ write_reg(state, RSTV0910_P2_CFRINIT1 + state->regoff, 0); -+ write_reg(state, RSTV0910_P2_CFRINIT0 + state->regoff, 0); -+ -+ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x1F); -+ /* Trigger acq */ -+ write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x15); -+ -+ state->DemodLockTime += TUNING_DELAY; -+ state->Started = 1; -+ -+ return 0; -+} -+ -+static int init_diseqc(struct stv *state) -+{ -+ u8 Freq = ((state->base->mclk + 11000 * 32) / (22000 * 32)); -+ -+ /* Disable receiver */ -+ write_reg(state, RSTV0910_P1_DISRXCFG, 0x00); -+ write_reg(state, RSTV0910_P2_DISRXCFG, 0x00); -+ write_reg(state, RSTV0910_P1_DISTXCFG, 0x82); /* Reset = 1 */ -+ write_reg(state, RSTV0910_P1_DISTXCFG, 0x02); /* Reset = 0 */ -+ write_reg(state, RSTV0910_P2_DISTXCFG, 0x82); /* Reset = 1 */ -+ write_reg(state, RSTV0910_P2_DISTXCFG, 0x02); /* Reset = 0 */ -+ write_reg(state, RSTV0910_P1_DISTXF22, Freq); -+ write_reg(state, RSTV0910_P2_DISTXF22, Freq); -+ return 0; -+} -+ -+static int probe(struct stv *state) -+{ -+ u8 id; -+ -+ state->ReceiveMode = Mode_None; -+ state->Started = 0; -+ -+ if (read_reg(state, RSTV0910_MID, &id) < 0) -+ return -1; -+ -+ if (id != 0x51) -+ return -EINVAL; -+ /* pr_info("stv0910: found STV0910 id=0x%02x\n", id); */ -+ -+ /* Configure the I2C repeater to off */ -+ write_reg(state, RSTV0910_P1_I2CRPT, 0x24); -+ /* Configure the I2C repeater to off */ -+ write_reg(state, RSTV0910_P2_I2CRPT, 0x24); -+ /* Set the I2C to oversampling ratio */ -+ write_reg(state, RSTV0910_I2CCFG, 0x88); -+ -+ write_reg(state, RSTV0910_OUTCFG, 0x00); /* OUTCFG */ -+ write_reg(state, RSTV0910_PADCFG, 0x05); /* RF AGC Pads Dev = 05 */ -+ write_reg(state, RSTV0910_SYNTCTRL, 0x02); /* SYNTCTRL */ -+ write_reg(state, RSTV0910_TSGENERAL, state->tsgeneral); /* TSGENERAL */ -+ write_reg(state, RSTV0910_CFGEXT, 0x02); /* CFGEXT */ -+ write_reg(state, RSTV0910_GENCFG, 0x15); /* GENCFG */ -+ -+ -+ write_reg(state, RSTV0910_TSTRES0, 0x80); /* LDPC Reset */ -+ write_reg(state, RSTV0910_TSTRES0, 0x00); -+ -+ set_mclock(state, 135000000); -+ -+ /* TS output */ -+ write_reg(state, RSTV0910_P1_TSCFGH , state->tscfgh | 0x01); -+ write_reg(state, RSTV0910_P1_TSCFGH , state->tscfgh); -+ write_reg(state, RSTV0910_P1_TSCFGM , 0xC0); /* Manual speed */ -+ write_reg(state, RSTV0910_P1_TSCFGL , 0x20); -+ -+ /* Speed = 67.5 MHz */ -+ write_reg(state, RSTV0910_P1_TSSPEED , state->tsspeed); -+ -+ write_reg(state, RSTV0910_P2_TSCFGH , state->tscfgh | 0x01); -+ write_reg(state, RSTV0910_P2_TSCFGH , state->tscfgh); -+ write_reg(state, RSTV0910_P2_TSCFGM , 0xC0); /* Manual speed */ -+ write_reg(state, RSTV0910_P2_TSCFGL , 0x20); -+ -+ /* Speed = 67.5 MHz */ -+ write_reg(state, RSTV0910_P2_TSSPEED , state->tsspeed); -+ -+ /* Reset stream merger */ -+ write_reg(state, RSTV0910_P1_TSCFGH , state->tscfgh | 0x01); -+ write_reg(state, RSTV0910_P2_TSCFGH , state->tscfgh | 0x01); -+ write_reg(state, RSTV0910_P1_TSCFGH , state->tscfgh); -+ write_reg(state, RSTV0910_P2_TSCFGH , state->tscfgh); -+ -+ write_reg(state, RSTV0910_P1_I2CRPT, state->i2crpt); -+ write_reg(state, RSTV0910_P2_I2CRPT, state->i2crpt); -+ -+ init_diseqc(state); -+ return 0; -+} -+ -+ -+static int gate_ctrl(struct dvb_frontend *fe, int enable) -+{ -+ struct stv *state = fe->demodulator_priv; -+ u8 i2crpt = state->i2crpt & ~0x86; -+ u16 reg; -+ -+ if (enable) -+ mutex_lock(&state->base->i2c_lock); -+ -+ if (enable) -+ i2crpt |= 0x80; -+ else -+ i2crpt |= 0x02; -+ -+ switch (state->base->dual_tuner) -+ { -+ case 1: -+ reg = RSTV0910_P1_I2CRPT; -+ break; -+ case 2: -+ reg = RSTV0910_P2_I2CRPT; -+ break; -+ default: -+ reg = state->nr ? RSTV0910_P2_I2CRPT : RSTV0910_P1_I2CRPT; -+ } -+ -+ /* pr_info("stv0910: gate_ctrl %d\n", enable); */ -+ -+ if (write_reg(state, reg , i2crpt) < 0) -+ return -EIO; -+ -+ state->i2crpt = i2crpt; -+ -+ if (!enable) -+ mutex_unlock(&state->base->i2c_lock); -+ return 0; -+} -+ -+static void release(struct dvb_frontend *fe) -+{ -+ struct stv *state = fe->demodulator_priv; -+ -+ if (state->base->set_lock_led) -+ state->base->set_lock_led(fe, 0); -+ -+ state->base->count--; -+ if (state->base->count == 0) { -+ list_del(&state->base->stvlist); -+ kfree(state->base); -+ } -+ kfree(state); -+} -+ -+static int set_parameters(struct dvb_frontend *fe) -+{ -+ int stat = 0; -+ struct stv *state = fe->demodulator_priv; -+ u32 IF; -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ -+ Stop(state); -+ if (fe->ops.tuner_ops.set_params) -+ fe->ops.tuner_ops.set_params(fe); -+ if (fe->ops.tuner_ops.get_if_frequency) -+ fe->ops.tuner_ops.get_if_frequency(fe, &IF); -+ state->SymbolRate = p->symbol_rate; -+ stat = Start(state, p); -+ return stat; -+} -+ -+static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties *p) -+{ -+ struct stv *state = fe->demodulator_priv; -+ u8 tmp; -+ -+ if (state->ReceiveMode == Mode_DVBS2) { -+ u32 mc; -+ enum fe_modulation modcod2mod[0x20] = { -+ QPSK, QPSK, QPSK, QPSK, -+ QPSK, QPSK, QPSK, QPSK, -+ QPSK, QPSK, QPSK, QPSK, -+ PSK_8, PSK_8, PSK_8, PSK_8, -+ PSK_8, PSK_8, APSK_16, APSK_16, -+ APSK_16, APSK_16, APSK_16, APSK_16, -+ APSK_32, APSK_32, APSK_32, APSK_32, -+ APSK_32, -+ }; -+ enum fe_code_rate modcod2fec[0x20] = { -+ FEC_NONE, FEC_1_4, FEC_1_3, FEC_2_5, -+ FEC_1_2, FEC_3_5, FEC_2_3, FEC_3_4, -+ FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10, -+ FEC_3_5, FEC_2_3, FEC_3_4, FEC_5_6, -+ FEC_8_9, FEC_9_10, FEC_2_3, FEC_3_4, -+ FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10, -+ FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9, -+ FEC_9_10 -+ }; -+ read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp); -+ mc = ((tmp & 0x7c) >> 2); -+ p->pilot = (tmp & 0x01) ? PILOT_ON : PILOT_OFF; -+ p->modulation = modcod2mod[mc]; -+ p->fec_inner = modcod2fec[mc]; -+ } else if (state->ReceiveMode == Mode_DVBS) { -+ read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp); -+ switch( tmp & 0x1F ) { -+ case 0x0d: -+ p->fec_inner = FEC_1_2; -+ break; -+ case 0x12: -+ p->fec_inner = FEC_2_3; -+ break; -+ case 0x15: -+ p->fec_inner = FEC_3_4; -+ break; -+ case 0x18: -+ p->fec_inner = FEC_5_6; -+ break; -+ case 0x1a: -+ p->fec_inner = FEC_7_8; -+ break; -+ default: -+ p->fec_inner = FEC_NONE; -+ break; -+ } -+ p->rolloff = ROLLOFF_35; -+ } else { -+ -+ } -+ -+ return 0; -+} -+ -+ -+static int read_status(struct dvb_frontend *fe, enum fe_status *status) -+{ -+ struct stv *state = fe->demodulator_priv; -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ u8 DmdState = 0; -+ u8 DStatus = 0; -+ enum ReceiveMode CurReceiveMode = Mode_None; -+ u32 FECLock = 0; -+ s32 snr; -+ u32 n, d; -+ u8 Reg[2]; -+ u16 agc; -+ s32 power = 0, Padc = 0; -+ int i; -+ -+ read_regs(state, RSTV0910_P2_AGCIQIN1 + state->regoff, Reg, 2); -+ -+ agc = (((u32) Reg[0]) << 8) | Reg[1]; -+ -+ if (fe->ops.tuner_ops.get_rf_strength) -+ fe->ops.tuner_ops.get_rf_strength(fe, &agc); -+ else -+ agc = 0; -+ -+ for (i = 0; i < 5; i += 1) { -+ read_regs(state, RSTV0910_P2_POWERI + state->regoff, Reg, 2); -+ power += (u32) Reg[0] * (u32) Reg[0] + (u32) Reg[1] * (u32) Reg[1]; -+ msleep(3); -+ } -+ power /= 5; -+ -+ Padc = TableLookup(PADC_Lookup, ARRAY_SIZE(PADC_Lookup), power) + 352; -+ -+ /*pr_warn("%s: power = %d Padc = %d\n", __func__, power, Padc);*/ -+ -+ p->strength.len = 1; -+ p->strength.stat[0].scale = FE_SCALE_DECIBEL; -+ p->strength.stat[0].svalue = Padc - agc; -+ -+ *status = FE_HAS_SIGNAL; -+ -+ read_reg(state, RSTV0910_P2_DMDSTATE + state->regoff, &DmdState); -+ -+ if (DmdState & 0x40) { -+ read_reg(state, RSTV0910_P2_DSTATUS + state->regoff, &DStatus); -+ if (DStatus & 0x80) -+ *status |= FE_HAS_CARRIER; -+ if (DStatus & 0x08) -+ CurReceiveMode = (DmdState & 0x20) ? -+ Mode_DVBS : Mode_DVBS2; -+ } -+ -+ if (CurReceiveMode == Mode_None) -+ { -+ if (state->base->set_lock_led) -+ state->base->set_lock_led(fe, 0); -+ return 0; -+ } -+ -+ if (state->ReceiveMode == Mode_None) { -+ state->ReceiveMode = CurReceiveMode; -+ state->DemodLockTime = jiffies; -+ state->FirstTimeLock = 1; -+ -+ write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, -+ state->tscfgh); -+ usleep_range(3000, 4000); -+ write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, -+ state->tscfgh | 0x01); -+ write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, -+ state->tscfgh); -+ } -+ if (DmdState & 0x40) { -+ if (state->ReceiveMode == Mode_DVBS2) { -+ u8 PDELStatus; -+ read_reg(state, -+ RSTV0910_P2_PDELSTATUS1 + state->regoff, -+ &PDELStatus); -+ FECLock = (PDELStatus & 0x02) != 0; -+ } else { -+ u8 VStatus; -+ read_reg(state, -+ RSTV0910_P2_VSTATUSVIT + state->regoff, -+ &VStatus); -+ FECLock = (VStatus & 0x08) != 0; -+ } -+ } -+ -+ if (!FECLock) -+ { -+ if (state->base->set_lock_led) -+ state->base->set_lock_led(fe, 0); -+ -+ p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ return 0; -+ } -+ -+ *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; -+ -+ if (state->base->set_lock_led) -+ state->base->set_lock_led(fe, *status & FE_HAS_LOCK); -+ -+ if (state->FirstTimeLock) { -+ u8 tmp; -+ -+ state->FirstTimeLock = 0; -+ GetSignalParameters(state); -+ -+ if (state->ReceiveMode == Mode_DVBS2) { -+ /* FSTV0910_P2_MANUALSX_ROLLOFF, -+ FSTV0910_P2_MANUALS2_ROLLOFF = 0 */ -+ state->DEMOD &= ~0x84; -+ write_reg(state, RSTV0910_P2_DEMOD + state->regoff, -+ state->DEMOD); -+ read_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, -+ &tmp); -+ /*reset DVBS2 packet delinator error counter */ -+ tmp |= 0x40; -+ write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, -+ tmp); -+ /*reset DVBS2 packet delinator error counter */ -+ tmp &= ~0x40; -+ write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, -+ tmp); -+ -+ state->BERScale = 2; -+ state->LastBERNumerator = 0; -+ state->LastBERDenominator = 1; -+ /* force to PRE BCH Rate */ -+ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, -+ BER_SRC_S2 | state->BERScale); -+ } else { -+ state->BERScale = 2; -+ state->LastBERNumerator = 0; -+ state->LastBERDenominator = 1; -+ /* force to PRE RS Rate */ -+ write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, -+ BER_SRC_S | state->BERScale); -+ } -+ /*Reset the Total packet counter */ -+ write_reg(state, RSTV0910_P2_FBERCPT4 + state->regoff, 0x00); -+ /*Reset the packet Error counter2 (and Set it to -+ infinit error count mode )*/ -+ write_reg(state, RSTV0910_P2_ERRCTRL2 + state->regoff, 0xc1); -+ -+ TrackingOptimization(state); -+ } -+ -+ if (GetSignalToNoise(state, &snr)) -+ return -EIO; -+ -+ p->cnr.len = 1; -+ p->cnr.stat[0].scale = FE_SCALE_DECIBEL; -+ p->cnr.stat[0].svalue = snr * 100; -+ -+ if (GetBitErrorRate(state, &n, &d)) -+ return -EIO; -+ -+ p->post_bit_error.len = 1; -+ p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; -+ p->post_bit_error.stat[0].uvalue = n; -+ p->post_bit_count.len = 1; -+ p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; -+ p->post_bit_count.stat[0].uvalue = d; -+ -+ return 0; -+} -+ -+static int tune(struct dvb_frontend *fe, bool re_tune, -+ unsigned int mode_flags, -+ unsigned int *delay, enum fe_status *status) -+{ -+ struct stv *state = fe->demodulator_priv; -+ int r; -+ -+ if (re_tune) { -+ r = set_parameters(fe); -+ if (r) -+ return r; -+ state->tune_time = jiffies; -+ } -+ -+ r = read_status(fe, status); -+ if (r) -+ return r; -+ -+ if (*status & FE_HAS_LOCK) -+ return 0; -+ -+ *delay = HZ; -+ -+ return 0; -+} -+ -+ -+static int get_algo(struct dvb_frontend *fe) -+{ -+ return DVBFE_ALGO_HW; -+} -+ -+static int wait_dis(struct stv *state, u8 flag, u8 val) -+{ -+ int i; -+ u8 stat; -+ u16 offs = state->nr ? 0x40 : 0; -+ -+ for (i = 0; i < 10; i++) { -+ read_reg(state, RSTV0910_P1_DISTXSTATUS + offs, &stat); -+ if ((stat & flag) == val) -+ return 0; -+ msleep(10); -+ } -+ return -1; -+} -+ -+static int set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) -+{ -+ struct stv *state = fe->demodulator_priv; -+ u16 offs = state->nr ? 0x40 : 0; -+ -+ switch (tone) { -+ case SEC_TONE_ON: -+ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x00); -+ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x80); -+ return write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x00); -+ case SEC_TONE_OFF: -+ return write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x80); -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int send_master_cmd(struct dvb_frontend *fe, -+ struct dvb_diseqc_master_cmd *cmd) -+{ -+ struct stv *state = fe->demodulator_priv; -+ u16 offs = state->nr ? 0x40 : 0; -+ int i; -+ -+ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x06); -+ for (i = 0; i < cmd->msg_len; i++) { -+ wait_dis(state, 0x40, 0x00); -+ write_reg(state, RSTV0910_P1_DISTXFIFO + offs, cmd->msg[i]); -+ } -+ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x02); -+ wait_dis(state, 0x20, 0x20); -+ return 0; -+} -+ -+static int recv_slave_reply(struct dvb_frontend *fe, -+ struct dvb_diseqc_slave_reply *reply) -+{ -+ return 0; -+} -+ -+static int send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd burst) -+{ -+ struct stv *state = fe->demodulator_priv; -+ u16 offs = state->nr ? 0x40 : 0; -+ u8 value; -+ -+ if (burst == SEC_MINI_A) { -+ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x07); -+ value = 0x00; -+ } else { -+ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x06); -+ value = 0xFF; -+ } -+ wait_dis(state, 0x40, 0x00); -+ write_reg(state, RSTV0910_P1_DISTXFIFO + offs, value); -+ write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x02); -+ wait_dis(state, 0x20, 0x20); -+ -+ return 0; -+} -+ -+static int sleep(struct dvb_frontend *fe) -+{ -+ struct stv *state = fe->demodulator_priv; -+ -+ Stop(state); -+ return 0; -+} -+ -+static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) -+{ -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ -+ *strength = p->strength.stat[0].scale == FE_SCALE_DECIBEL ? ((100000 + (s32)p->strength.stat[0].svalue) / 1000) * 656 : 0; -+ -+ return 0; -+} -+ -+static int read_snr(struct dvb_frontend *fe, u16 *snr) -+{ -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ -+ if (p->cnr.stat[0].scale == FE_SCALE_DECIBEL) { -+ *snr = (s32)p->cnr.stat[0].svalue / 100; -+ if (*snr > 200) -+ *snr = 0xffff; -+ else -+ *snr *= 328; -+ } else *snr = 0; -+ -+ return 0; -+} -+ -+static int read_ber(struct dvb_frontend *fe, u32 *ber) -+{ -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ -+ if ( p->post_bit_error.stat[0].scale == FE_SCALE_COUNTER && -+ p->post_bit_count.stat[0].scale == FE_SCALE_COUNTER ) -+ *ber = (u32)p->post_bit_count.stat[0].uvalue ? (u32)p->post_bit_error.stat[0].uvalue / (u32)p->post_bit_count.stat[0].uvalue : 0; -+ -+ return 0; -+} -+ -+static int read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -+{ -+ *ucblocks = 0; -+ return 0; -+} -+ -+static struct dvb_frontend_ops stv0910_ops = { -+ .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, -+ .info = { -+ .name = "STV0910 Multistandard", -+ .frequency_min = 950000, -+ .frequency_max = 2150000, -+ .frequency_stepsize = 0, -+ .frequency_tolerance = 0, -+ .symbol_rate_min = 1000000, -+ .symbol_rate_max = 70000000, -+ .caps = FE_CAN_INVERSION_AUTO | -+ FE_CAN_FEC_AUTO | -+ FE_CAN_QPSK | -+ FE_CAN_2G_MODULATION | -+ FE_CAN_MULTISTREAM -+ }, -+ .init = init, -+ .sleep = sleep, -+ .release = release, -+ .i2c_gate_ctrl = gate_ctrl, -+ .get_frontend_algo = get_algo, -+ .get_frontend = get_frontend, -+ .tune = tune, -+ .set_tone = set_tone, -+ -+ .diseqc_send_master_cmd = send_master_cmd, -+ .diseqc_send_burst = send_burst, -+ .diseqc_recv_slave_reply = recv_slave_reply, -+ -+ .read_status = read_status, -+ .read_signal_strength = read_signal_strength, -+ .read_snr = read_snr, -+ .read_ber = read_ber, -+ .read_ucblocks = read_ucblocks, -+}; -+ -+static struct stv_base *match_base(struct i2c_adapter *i2c, u8 adr) -+{ -+ struct stv_base *p; -+ -+ list_for_each_entry(p, &stvlist, stvlist) -+ if (p->i2c == i2c && p->adr == adr) -+ return p; -+ return NULL; -+} -+ -+struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, -+ struct stv0910_cfg *cfg, -+ int nr) -+{ -+ struct stv *state; -+ struct stv_base *base; -+ -+ state = kzalloc(sizeof(struct stv), GFP_KERNEL); -+ if (!state) -+ return NULL; -+ -+ state->tscfgh = 0x20 | (cfg->parallel ? 0 : 0x40); -+ state->tsgeneral = (cfg->parallel == 2) ? 0x02 : 0x00; -+ state->i2crpt = 0x0A | ((cfg->rptlvl & 0x07) << 4); -+ state->tsspeed = 0x28; -+ state->nr = nr; -+ state->regoff = state->nr ? 0 : 0x200; -+ state->SearchRange = 16000000; -+ state->DEMOD = 0x10; /* Inversion : Auto with reset to 0 */ -+ state->ReceiveMode = Mode_None; -+ -+ base = match_base(i2c, cfg->adr); -+ if (base) { -+ base->count++; -+ state->base = base; -+ } else { -+ base = kzalloc(sizeof(struct stv_base), GFP_KERNEL); -+ if (!base) -+ goto fail; -+ base->i2c = i2c; -+ base->adr = cfg->adr; -+ base->count = 1; -+ base->extclk = cfg->clk ? cfg->clk : 30000000; -+ base->dual_tuner = cfg->dual_tuner; -+ base->set_lock_led = cfg->set_lock_led; -+ -+ mutex_init(&base->i2c_lock); -+ mutex_init(&base->reg_lock); -+ state->base = base; -+ if (probe(state) < 0) { -+ kfree(base); -+ goto fail; -+ } -+ list_add(&base->stvlist, &stvlist); -+ } -+ state->fe.ops = stv0910_ops; -+ state->fe.demodulator_priv = state; -+ state->nr = nr; -+ -+ return &state->fe; -+ -+fail: -+ kfree(state); -+ return NULL; -+} -+EXPORT_SYMBOL_GPL(stv0910_attach); -+ -+MODULE_DESCRIPTION("STV0910 driver"); -+MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/dvb-frontends/stv0910.h b/drivers/media/dvb-frontends/stv0910.h -new file mode 100644 -index 0000000..738ac57 ---- /dev/null -+++ b/drivers/media/dvb-frontends/stv0910.h -@@ -0,0 +1,32 @@ -+#ifndef _STV0910_H_ -+#define _STV0910_H_ -+ -+#include -+#include -+ -+struct stv0910_cfg { -+ u32 clk; -+ u8 adr; -+ u8 parallel; -+ u8 rptlvl; -+ u8 dual_tuner; -+ -+ /* Hook for Lock LED */ -+ void (*set_lock_led) (struct dvb_frontend *fe, int offon); -+}; -+ -+#if IS_REACHABLE(CONFIG_DVB_STV0910) -+extern struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, -+ struct stv0910_cfg *cfg, int nr); -+#else -+static inline struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, -+ struct stv0910_cfg *cfg, -+ int nr) -+{ -+ pr_warn("%s: driver disabled by Kconfig\n", __func__); -+ return NULL; -+} -+ -+#endif -+ -+#endif -diff --git a/drivers/media/dvb-frontends/stv0910_regs.h b/drivers/media/dvb-frontends/stv0910_regs.h -new file mode 100644 -index 0000000..26f7645 ---- /dev/null -+++ b/drivers/media/dvb-frontends/stv0910_regs.h -@@ -0,0 +1,4003 @@ -+/* -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 only, as published by the Free Software Foundation. -+ * -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html -+ */ -+ -+/*MID*/ -+#define RSTV0910_MID 0xf100 -+#define FSTV0910_MCHIP_IDENT 0xf10000f0 -+#define FSTV0910_MRELEASE 0xf100000f -+ -+/*DID*/ -+#define RSTV0910_DID 0xf101 -+#define FSTV0910_DEVICE_ID 0xf10100ff -+ -+/*DACR1*/ -+#define RSTV0910_DACR1 0xf113 -+#define FSTV0910_DAC_MODE 0xf11300e0 -+#define FSTV0910_DAC_VALUE1 0xf113000f -+ -+/*DACR2*/ -+#define RSTV0910_DACR2 0xf114 -+#define FSTV0910_DAC_VALUE0 0xf11400ff -+ -+/*PADCFG*/ -+#define RSTV0910_PADCFG 0xf11a -+#define FSTV0910_AGCRF2_OPD 0xf11a0008 -+#define FSTV0910_AGCRF2_XOR 0xf11a0004 -+#define FSTV0910_AGCRF1_OPD 0xf11a0002 -+#define FSTV0910_AGCRF1_XOR 0xf11a0001 -+ -+/*OUTCFG2*/ -+#define RSTV0910_OUTCFG2 0xf11b -+#define FSTV0910_TS2_ERROR_XOR 0xf11b0080 -+#define FSTV0910_TS2_DPN_XOR 0xf11b0040 -+#define FSTV0910_TS2_STROUT_XOR 0xf11b0020 -+#define FSTV0910_TS2_CLOCKOUT_XOR 0xf11b0010 -+#define FSTV0910_TS1_ERROR_XOR 0xf11b0008 -+#define FSTV0910_TS1_DPN_XOR 0xf11b0004 -+#define FSTV0910_TS1_STROUT_XOR 0xf11b0002 -+#define FSTV0910_TS1_CLOCKOUT_XOR 0xf11b0001 -+ -+/*OUTCFG*/ -+#define RSTV0910_OUTCFG 0xf11c -+#define FSTV0910_INV_DATA6 0xf11c0080 -+#define FSTV0910_TS2_OUTSER_HZ 0xf11c0020 -+#define FSTV0910_TS1_OUTSER_HZ 0xf11c0010 -+#define FSTV0910_TS2_OUTPAR_HZ 0xf11c0008 -+#define FSTV0910_TS1_OUTPAR_HZ 0xf11c0004 -+#define FSTV0910_TS_SERDATA0 0xf11c0002 -+ -+/*IRQSTATUS3*/ -+#define RSTV0910_IRQSTATUS3 0xf120 -+#define FSTV0910_SPLL_LOCK 0xf1200020 -+#define FSTV0910_SSTREAM_LCK_1 0xf1200010 -+#define FSTV0910_SSTREAM_LCK_2 0xf1200008 -+#define FSTV0910_SDVBS1_PRF_2 0xf1200002 -+#define FSTV0910_SDVBS1_PRF_1 0xf1200001 -+ -+/*IRQSTATUS2*/ -+#define RSTV0910_IRQSTATUS2 0xf121 -+#define FSTV0910_SSPY_ENDSIM_1 0xf1210080 -+#define FSTV0910_SSPY_ENDSIM_2 0xf1210040 -+#define FSTV0910_SPKTDEL_ERROR_2 0xf1210010 -+#define FSTV0910_SPKTDEL_LOCKB_2 0xf1210008 -+#define FSTV0910_SPKTDEL_LOCK_2 0xf1210004 -+#define FSTV0910_SPKTDEL_ERROR_1 0xf1210002 -+#define FSTV0910_SPKTDEL_LOCKB_1 0xf1210001 -+ -+/*IRQSTATUS1*/ -+#define RSTV0910_IRQSTATUS1 0xf122 -+#define FSTV0910_SPKTDEL_LOCK_1 0xf1220080 -+#define FSTV0910_SFEC_LOCKB_2 0xf1220040 -+#define FSTV0910_SFEC_LOCK_2 0xf1220020 -+#define FSTV0910_SFEC_LOCKB_1 0xf1220010 -+#define FSTV0910_SFEC_LOCK_1 0xf1220008 -+#define FSTV0910_SDEMOD_LOCKB_2 0xf1220004 -+#define FSTV0910_SDEMOD_LOCK_2 0xf1220002 -+#define FSTV0910_SDEMOD_IRQ_2 0xf1220001 -+ -+/*IRQSTATUS0*/ -+#define RSTV0910_IRQSTATUS0 0xf123 -+#define FSTV0910_SDEMOD_LOCKB_1 0xf1230080 -+#define FSTV0910_SDEMOD_LOCK_1 0xf1230040 -+#define FSTV0910_SDEMOD_IRQ_1 0xf1230020 -+#define FSTV0910_SBCH_ERRFLAG 0xf1230010 -+#define FSTV0910_SECW2_IRQ 0xf1230008 -+#define FSTV0910_SDISEQC2_IRQ 0xf1230004 -+#define FSTV0910_SECW1_IRQ 0xf1230002 -+#define FSTV0910_SDISEQC1_IRQ 0xf1230001 -+ -+/*IRQMASK3*/ -+#define RSTV0910_IRQMASK3 0xf124 -+#define FSTV0910_MPLL_LOCK 0xf1240020 -+#define FSTV0910_MSTREAM_LCK_1 0xf1240010 -+#define FSTV0910_MSTREAM_LCK_2 0xf1240008 -+#define FSTV0910_MDVBS1_PRF_2 0xf1240002 -+#define FSTV0910_MDVBS1_PRF_1 0xf1240001 -+ -+/*IRQMASK2*/ -+#define RSTV0910_IRQMASK2 0xf125 -+#define FSTV0910_MSPY_ENDSIM_1 0xf1250080 -+#define FSTV0910_MSPY_ENDSIM_2 0xf1250040 -+#define FSTV0910_MPKTDEL_ERROR_2 0xf1250010 -+#define FSTV0910_MPKTDEL_LOCKB_2 0xf1250008 -+#define FSTV0910_MPKTDEL_LOCK_2 0xf1250004 -+#define FSTV0910_MPKTDEL_ERROR_1 0xf1250002 -+#define FSTV0910_MPKTDEL_LOCKB_1 0xf1250001 -+ -+/*IRQMASK1*/ -+#define RSTV0910_IRQMASK1 0xf126 -+#define FSTV0910_MPKTDEL_LOCK_1 0xf1260080 -+#define FSTV0910_MFEC_LOCKB_2 0xf1260040 -+#define FSTV0910_MFEC_LOCK_2 0xf1260020 -+#define FSTV0910_MFEC_LOCKB_1 0xf1260010 -+#define FSTV0910_MFEC_LOCK_1 0xf1260008 -+#define FSTV0910_MDEMOD_LOCKB_2 0xf1260004 -+#define FSTV0910_MDEMOD_LOCK_2 0xf1260002 -+#define FSTV0910_MDEMOD_IRQ_2 0xf1260001 -+ -+/*IRQMASK0*/ -+#define RSTV0910_IRQMASK0 0xf127 -+#define FSTV0910_MDEMOD_LOCKB_1 0xf1270080 -+#define FSTV0910_MDEMOD_LOCK_1 0xf1270040 -+#define FSTV0910_MDEMOD_IRQ_1 0xf1270020 -+#define FSTV0910_MBCH_ERRFLAG 0xf1270010 -+#define FSTV0910_MECW2_IRQ 0xf1270008 -+#define FSTV0910_MDISEQC2_IRQ 0xf1270004 -+#define FSTV0910_MECW1_IRQ 0xf1270002 -+#define FSTV0910_MDISEQC1_IRQ 0xf1270001 -+ -+/*I2CCFG*/ -+#define RSTV0910_I2CCFG 0xf129 -+#define FSTV0910_I2C2_FASTMODE 0xf1290080 -+#define FSTV0910_STATUS_WR2 0xf1290040 -+#define FSTV0910_I2C2ADDR_INC 0xf1290030 -+#define FSTV0910_I2C_FASTMODE 0xf1290008 -+#define FSTV0910_STATUS_WR 0xf1290004 -+#define FSTV0910_I2CADDR_INC 0xf1290003 -+ -+/*P1_I2CRPT*/ -+#define RSTV0910_P1_I2CRPT 0xf12a -+#define FSTV0910_P1_I2CT_ON 0xf12a0080 -+#define FSTV0910_P1_ENARPT_LEVEL 0xf12a0070 -+#define FSTV0910_P1_SCLT_DELAY 0xf12a0008 -+#define FSTV0910_P1_STOP_ENABLE 0xf12a0004 -+#define FSTV0910_P1_STOP_SDAT2SDA 0xf12a0002 -+ -+/*P2_I2CRPT*/ -+#define RSTV0910_P2_I2CRPT 0xf12b -+#define FSTV0910_P2_I2CT_ON 0xf12b0080 -+#define FSTV0910_P2_ENARPT_LEVEL 0xf12b0070 -+#define FSTV0910_P2_SCLT_DELAY 0xf12b0008 -+#define FSTV0910_P2_STOP_ENABLE 0xf12b0004 -+#define FSTV0910_P2_STOP_SDAT2SDA 0xf12b0002 -+ -+/*GPIO0CFG*/ -+#define RSTV0910_GPIO0CFG 0xf140 -+#define FSTV0910_GPIO0_OPD 0xf1400080 -+#define FSTV0910_GPIO0_CONFIG 0xf140007e -+#define FSTV0910_GPIO0_XOR 0xf1400001 -+ -+/*GPIO1CFG*/ -+#define RSTV0910_GPIO1CFG 0xf141 -+#define FSTV0910_GPIO1_OPD 0xf1410080 -+#define FSTV0910_GPIO1_CONFIG 0xf141007e -+#define FSTV0910_GPIO1_XOR 0xf1410001 -+ -+/*GPIO2CFG*/ -+#define RSTV0910_GPIO2CFG 0xf142 -+#define FSTV0910_GPIO2_OPD 0xf1420080 -+#define FSTV0910_GPIO2_CONFIG 0xf142007e -+#define FSTV0910_GPIO2_XOR 0xf1420001 -+ -+/*GPIO3CFG*/ -+#define RSTV0910_GPIO3CFG 0xf143 -+#define FSTV0910_GPIO3_OPD 0xf1430080 -+#define FSTV0910_GPIO3_CONFIG 0xf143007e -+#define FSTV0910_GPIO3_XOR 0xf1430001 -+ -+/*GPIO4CFG*/ -+#define RSTV0910_GPIO4CFG 0xf144 -+#define FSTV0910_GPIO4_OPD 0xf1440080 -+#define FSTV0910_GPIO4_CONFIG 0xf144007e -+#define FSTV0910_GPIO4_XOR 0xf1440001 -+ -+/*GPIO5CFG*/ -+#define RSTV0910_GPIO5CFG 0xf145 -+#define FSTV0910_GPIO5_OPD 0xf1450080 -+#define FSTV0910_GPIO5_CONFIG 0xf145007e -+#define FSTV0910_GPIO5_XOR 0xf1450001 -+ -+/*GPIO6CFG*/ -+#define RSTV0910_GPIO6CFG 0xf146 -+#define FSTV0910_GPIO6_OPD 0xf1460080 -+#define FSTV0910_GPIO6_CONFIG 0xf146007e -+#define FSTV0910_GPIO6_XOR 0xf1460001 -+ -+/*GPIO7CFG*/ -+#define RSTV0910_GPIO7CFG 0xf147 -+#define FSTV0910_GPIO7_OPD 0xf1470080 -+#define FSTV0910_GPIO7_CONFIG 0xf147007e -+#define FSTV0910_GPIO7_XOR 0xf1470001 -+ -+/*GPIO8CFG*/ -+#define RSTV0910_GPIO8CFG 0xf148 -+#define FSTV0910_GPIO8_OPD 0xf1480080 -+#define FSTV0910_GPIO8_CONFIG 0xf148007e -+#define FSTV0910_GPIO8_XOR 0xf1480001 -+ -+/*GPIO9CFG*/ -+#define RSTV0910_GPIO9CFG 0xf149 -+#define FSTV0910_GPIO9_OPD 0xf1490080 -+#define FSTV0910_GPIO9_CONFIG 0xf149007e -+#define FSTV0910_GPIO9_XOR 0xf1490001 -+ -+/*GPIO10CFG*/ -+#define RSTV0910_GPIO10CFG 0xf14a -+#define FSTV0910_GPIO10_OPD 0xf14a0080 -+#define FSTV0910_GPIO10_CONFIG 0xf14a007e -+#define FSTV0910_GPIO10_XOR 0xf14a0001 -+ -+/*GPIO11CFG*/ -+#define RSTV0910_GPIO11CFG 0xf14b -+#define FSTV0910_GPIO11_OPD 0xf14b0080 -+#define FSTV0910_GPIO11_CONFIG 0xf14b007e -+#define FSTV0910_GPIO11_XOR 0xf14b0001 -+ -+/*GPIO12CFG*/ -+#define RSTV0910_GPIO12CFG 0xf14c -+#define FSTV0910_GPIO12_OPD 0xf14c0080 -+#define FSTV0910_GPIO12_CONFIG 0xf14c007e -+#define FSTV0910_GPIO12_XOR 0xf14c0001 -+ -+/*GPIO13CFG*/ -+#define RSTV0910_GPIO13CFG 0xf14d -+#define FSTV0910_GPIO13_OPD 0xf14d0080 -+#define FSTV0910_GPIO13_CONFIG 0xf14d007e -+#define FSTV0910_GPIO13_XOR 0xf14d0001 -+ -+/*GPIO14CFG*/ -+#define RSTV0910_GPIO14CFG 0xf14e -+#define FSTV0910_GPIO14_OPD 0xf14e0080 -+#define FSTV0910_GPIO14_CONFIG 0xf14e007e -+#define FSTV0910_GPIO14_XOR 0xf14e0001 -+ -+/*GPIO15CFG*/ -+#define RSTV0910_GPIO15CFG 0xf14f -+#define FSTV0910_GPIO15_OPD 0xf14f0080 -+#define FSTV0910_GPIO15_CONFIG 0xf14f007e -+#define FSTV0910_GPIO15_XOR 0xf14f0001 -+ -+/*GPIO16CFG*/ -+#define RSTV0910_GPIO16CFG 0xf150 -+#define FSTV0910_GPIO16_OPD 0xf1500080 -+#define FSTV0910_GPIO16_CONFIG 0xf150007e -+#define FSTV0910_GPIO16_XOR 0xf1500001 -+ -+/*GPIO17CFG*/ -+#define RSTV0910_GPIO17CFG 0xf151 -+#define FSTV0910_GPIO17_OPD 0xf1510080 -+#define FSTV0910_GPIO17_CONFIG 0xf151007e -+#define FSTV0910_GPIO17_XOR 0xf1510001 -+ -+/*GPIO18CFG*/ -+#define RSTV0910_GPIO18CFG 0xf152 -+#define FSTV0910_GPIO18_OPD 0xf1520080 -+#define FSTV0910_GPIO18_CONFIG 0xf152007e -+#define FSTV0910_GPIO18_XOR 0xf1520001 -+ -+/*GPIO19CFG*/ -+#define RSTV0910_GPIO19CFG 0xf153 -+#define FSTV0910_GPIO19_OPD 0xf1530080 -+#define FSTV0910_GPIO19_CONFIG 0xf153007e -+#define FSTV0910_GPIO19_XOR 0xf1530001 -+ -+/*GPIO20CFG*/ -+#define RSTV0910_GPIO20CFG 0xf154 -+#define FSTV0910_GPIO20_OPD 0xf1540080 -+#define FSTV0910_GPIO20_CONFIG 0xf154007e -+#define FSTV0910_GPIO20_XOR 0xf1540001 -+ -+/*GPIO21CFG*/ -+#define RSTV0910_GPIO21CFG 0xf155 -+#define FSTV0910_GPIO21_OPD 0xf1550080 -+#define FSTV0910_GPIO21_CONFIG 0xf155007e -+#define FSTV0910_GPIO21_XOR 0xf1550001 -+ -+/*GPIO22CFG*/ -+#define RSTV0910_GPIO22CFG 0xf156 -+#define FSTV0910_GPIO22_OPD 0xf1560080 -+#define FSTV0910_GPIO22_CONFIG 0xf156007e -+#define FSTV0910_GPIO22_XOR 0xf1560001 -+ -+/*STRSTATUS1*/ -+#define RSTV0910_STRSTATUS1 0xf16a -+#define FSTV0910_STRSTATUS_SEL2 0xf16a00f0 -+#define FSTV0910_STRSTATUS_SEL1 0xf16a000f -+ -+/*STRSTATUS2*/ -+#define RSTV0910_STRSTATUS2 0xf16b -+#define FSTV0910_STRSTATUS_SEL4 0xf16b00f0 -+#define FSTV0910_STRSTATUS_SEL3 0xf16b000f -+ -+/*STRSTATUS3*/ -+#define RSTV0910_STRSTATUS3 0xf16c -+#define FSTV0910_STRSTATUS_SEL6 0xf16c00f0 -+#define FSTV0910_STRSTATUS_SEL5 0xf16c000f -+ -+/*FSKTFC2*/ -+#define RSTV0910_FSKTFC2 0xf170 -+#define FSTV0910_FSKT_KMOD 0xf17000fc -+#define FSTV0910_FSKT_CAR2 0xf1700003 -+ -+/*FSKTFC1*/ -+#define RSTV0910_FSKTFC1 0xf171 -+#define FSTV0910_FSKT_CAR1 0xf17100ff -+ -+/*FSKTFC0*/ -+#define RSTV0910_FSKTFC0 0xf172 -+#define FSTV0910_FSKT_CAR0 0xf17200ff -+ -+/*FSKTDELTAF1*/ -+#define RSTV0910_FSKTDELTAF1 0xf173 -+#define FSTV0910_FSKT_DELTAF1 0xf173000f -+ -+/*FSKTDELTAF0*/ -+#define RSTV0910_FSKTDELTAF0 0xf174 -+#define FSTV0910_FSKT_DELTAF0 0xf17400ff -+ -+/*FSKTCTRL*/ -+#define RSTV0910_FSKTCTRL 0xf175 -+#define FSTV0910_FSKT_PINSEL 0xf1750080 -+#define FSTV0910_FSKT_EN_SGN 0xf1750040 -+#define FSTV0910_FSKT_MOD_SGN 0xf1750020 -+#define FSTV0910_FSKT_MOD_EN 0xf175001c -+#define FSTV0910_FSKT_DACMODE 0xf1750003 -+ -+/*FSKRFC2*/ -+#define RSTV0910_FSKRFC2 0xf176 -+#define FSTV0910_FSKR_DETSGN 0xf1760040 -+#define FSTV0910_FSKR_OUTSGN 0xf1760020 -+#define FSTV0910_FSKR_KAGC 0xf176001c -+#define FSTV0910_FSKR_CAR2 0xf1760003 -+ -+/*FSKRFC1*/ -+#define RSTV0910_FSKRFC1 0xf177 -+#define FSTV0910_FSKR_CAR1 0xf17700ff -+ -+/*FSKRFC0*/ -+#define RSTV0910_FSKRFC0 0xf178 -+#define FSTV0910_FSKR_CAR0 0xf17800ff -+ -+/*FSKRK1*/ -+#define RSTV0910_FSKRK1 0xf179 -+#define FSTV0910_FSKR_K1_EXP 0xf17900e0 -+#define FSTV0910_FSKR_K1_MANT 0xf179001f -+ -+/*FSKRK2*/ -+#define RSTV0910_FSKRK2 0xf17a -+#define FSTV0910_FSKR_K2_EXP 0xf17a00e0 -+#define FSTV0910_FSKR_K2_MANT 0xf17a001f -+ -+/*FSKRAGCR*/ -+#define RSTV0910_FSKRAGCR 0xf17b -+#define FSTV0910_FSKR_OUTCTL 0xf17b00c0 -+#define FSTV0910_FSKR_AGC_REF 0xf17b003f -+ -+/*FSKRAGC*/ -+#define RSTV0910_FSKRAGC 0xf17c -+#define FSTV0910_FSKR_AGC_ACCU 0xf17c00ff -+ -+/*FSKRALPHA*/ -+#define RSTV0910_FSKRALPHA 0xf17d -+#define FSTV0910_FSKR_ALPHA_EXP 0xf17d001c -+#define FSTV0910_FSKR_ALPHA_M 0xf17d0003 -+ -+/*FSKRPLTH1*/ -+#define RSTV0910_FSKRPLTH1 0xf17e -+#define FSTV0910_FSKR_BETA 0xf17e00f0 -+#define FSTV0910_FSKR_PLL_TRESH1 0xf17e000f -+ -+/*FSKRPLTH0*/ -+#define RSTV0910_FSKRPLTH0 0xf17f -+#define FSTV0910_FSKR_PLL_TRESH0 0xf17f00ff -+ -+/*FSKRDF1*/ -+#define RSTV0910_FSKRDF1 0xf180 -+#define FSTV0910_FSKR_OUT 0xf1800080 -+#define FSTV0910_FSKR_STATE 0xf1800060 -+#define FSTV0910_FSKR_DELTAF1 0xf180001f -+ -+/*FSKRDF0*/ -+#define RSTV0910_FSKRDF0 0xf181 -+#define FSTV0910_FSKR_DELTAF0 0xf18100ff -+ -+/*FSKRSTEPP*/ -+#define RSTV0910_FSKRSTEPP 0xf182 -+#define FSTV0910_FSKR_STEP_PLUS 0xf18200ff -+ -+/*FSKRSTEPM*/ -+#define RSTV0910_FSKRSTEPM 0xf183 -+#define FSTV0910_FSKR_STEP_MINUS 0xf18300ff -+ -+/*FSKRDET1*/ -+#define RSTV0910_FSKRDET1 0xf184 -+#define FSTV0910_FSKR_DETECT 0xf1840080 -+#define FSTV0910_FSKR_CARDET_ACCU1 0xf184000f -+ -+/*FSKRDET0*/ -+#define RSTV0910_FSKRDET0 0xf185 -+#define FSTV0910_FSKR_CARDET_ACCU0 0xf18500ff -+ -+/*FSKRDTH1*/ -+#define RSTV0910_FSKRDTH1 0xf186 -+#define FSTV0910_FSKR_CARLOSS_THRESH1 0xf18600f0 -+#define FSTV0910_FSKR_CARDET_THRESH1 0xf186000f -+ -+/*FSKRDTH0*/ -+#define RSTV0910_FSKRDTH0 0xf187 -+#define FSTV0910_FSKR_CARDET_THRESH0 0xf18700ff -+ -+/*FSKRLOSS*/ -+#define RSTV0910_FSKRLOSS 0xf188 -+#define FSTV0910_FSKR_CARLOSS_THRESH0 0xf18800ff -+ -+/*NCOARSE*/ -+#define RSTV0910_NCOARSE 0xf1b3 -+#define FSTV0910_CP 0xf1b300f8 -+#define FSTV0910_IDF 0xf1b30007 -+ -+/*NCOARSE1*/ -+#define RSTV0910_NCOARSE1 0xf1b4 -+#define FSTV0910_N_DIV 0xf1b400ff -+ -+/*NCOARSE2*/ -+#define RSTV0910_NCOARSE2 0xf1b5 -+#define FSTV0910_ODF 0xf1b5003f -+ -+/*SYNTCTRL*/ -+#define RSTV0910_SYNTCTRL 0xf1b6 -+#define FSTV0910_STANDBY 0xf1b60080 -+#define FSTV0910_BYPASSPLLCORE 0xf1b60040 -+#define FSTV0910_STOP_PLL 0xf1b60008 -+#define FSTV0910_OSCI_E 0xf1b60002 -+ -+/*FILTCTRL*/ -+#define RSTV0910_FILTCTRL 0xf1b7 -+#define FSTV0910_INV_CLKFSK 0xf1b70002 -+#define FSTV0910_BYPASS_APPLI 0xf1b70001 -+ -+/*PLLSTAT*/ -+#define RSTV0910_PLLSTAT 0xf1b8 -+#define FSTV0910_PLL_BIST_END 0xf1b80004 -+#define FSTV0910_PLLLOCK 0xf1b80001 -+ -+/*STOPCLK1*/ -+#define RSTV0910_STOPCLK1 0xf1c2 -+#define FSTV0910_INV_CLKADCI2 0xf1c20004 -+#define FSTV0910_INV_CLKADCI1 0xf1c20001 -+ -+/*STOPCLK2*/ -+#define RSTV0910_STOPCLK2 0xf1c3 -+#define FSTV0910_STOP_DVBS2FEC2 0xf1c30020 -+#define FSTV0910_STOP_DVBS2FEC 0xf1c30010 -+#define FSTV0910_STOP_DVBS1FEC2 0xf1c30008 -+#define FSTV0910_STOP_DVBS1FEC 0xf1c30004 -+#define FSTV0910_STOP_DEMOD2 0xf1c30002 -+#define FSTV0910_STOP_DEMOD 0xf1c30001 -+ -+/*PREGCTL*/ -+#define RSTV0910_PREGCTL 0xf1c8 -+#define FSTV0910_REG3V3TO2V5_POFF 0xf1c80080 -+ -+/*TSTTNR0*/ -+#define RSTV0910_TSTTNR0 0xf1df -+#define FSTV0910_FSK_PON 0xf1df0004 -+#define FSTV0910_FSK_OPENLOOP 0xf1df0002 -+ -+/*TSTTNR1*/ -+#define RSTV0910_TSTTNR1 0xf1e0 -+#define FSTV0910_BYPASS_ADC1 0xf1e00080 -+#define FSTV0910_INVADC1_CKOUT 0xf1e00040 -+#define FSTV0910_SELIQSRC1 0xf1e00030 -+#define FSTV0910_DEMOD2_SELADC 0xf1e00008 -+#define FSTV0910_DEMOD1_SELADC 0xf1e00004 -+#define FSTV0910_ADC1_PON 0xf1e00002 -+ -+/*TSTTNR2*/ -+#define RSTV0910_TSTTNR2 0xf1e1 -+#define FSTV0910_I2C_DISEQC_BYPASS 0xf1e10080 -+#define FSTV0910_I2C_DISEQC_ENCH 0xf1e10040 -+#define FSTV0910_I2C_DISEQC_PON 0xf1e10020 -+#define FSTV0910_DISEQC_CLKDIV 0xf1e1000f -+ -+/*TSTTNR3*/ -+#define RSTV0910_TSTTNR3 0xf1e2 -+#define FSTV0910_BYPASS_ADC2 0xf1e20080 -+#define FSTV0910_INVADC2_CKOUT 0xf1e20040 -+#define FSTV0910_SELIQSRC2 0xf1e20030 -+#define FSTV0910_ADC2_PON 0xf1e20002 -+ -+/*P2_IQCONST*/ -+#define RSTV0910_P2_IQCONST 0xf200 -+#define FSTV0910_P2_CONSTEL_SELECT 0xf2000060 -+#define FSTV0910_P2_IQSYMB_SEL 0xf200001f -+ -+/*P2_NOSCFG*/ -+#define RSTV0910_P2_NOSCFG 0xf201 -+#define FSTV0910_P2_DIS_ACMRATIO 0xf2010080 -+#define FSTV0910_P2_NOSIN_EGALSEL 0xf2010040 -+#define FSTV0910_P2_DUMMYPL_NOSDATA 0xf2010020 -+#define FSTV0910_P2_NOSPLH_BETA 0xf2010018 -+#define FSTV0910_P2_NOSDATA_BETA 0xf2010007 -+ -+/*P2_ISYMB*/ -+#define RSTV0910_P2_ISYMB 0xf202 -+#define FSTV0910_P2_I_SYMBOL 0xf20201ff -+ -+/*P2_QSYMB*/ -+#define RSTV0910_P2_QSYMB 0xf203 -+#define FSTV0910_P2_Q_SYMBOL 0xf20301ff -+ -+/*P2_AGC1CFG*/ -+#define RSTV0910_P2_AGC1CFG 0xf204 -+#define FSTV0910_P2_DC_FROZEN 0xf2040080 -+#define FSTV0910_P2_DC_CORRECT 0xf2040040 -+#define FSTV0910_P2_AMM_FROZEN 0xf2040020 -+#define FSTV0910_P2_AMM_CORRECT 0xf2040010 -+#define FSTV0910_P2_QUAD_FROZEN 0xf2040008 -+#define FSTV0910_P2_QUAD_CORRECT 0xf2040004 -+#define FSTV0910_P2_DCCOMP_SLOW 0xf2040002 -+#define FSTV0910_P2_IQMISM_SLOW 0xf2040001 -+ -+/*P2_AGC1CN*/ -+#define RSTV0910_P2_AGC1CN 0xf206 -+#define FSTV0910_P2_AGC1_LOCKED 0xf2060080 -+#define FSTV0910_P2_AGC1_OVERFLOW 0xf2060040 -+#define FSTV0910_P2_AGC1_NOSLOWLK 0xf2060020 -+#define FSTV0910_P2_AGC1_MINPOWER 0xf2060010 -+#define FSTV0910_P2_AGCOUT_FAST 0xf2060008 -+#define FSTV0910_P2_AGCIQ_BETA 0xf2060007 -+ -+/*P2_AGC1REF*/ -+#define RSTV0910_P2_AGC1REF 0xf207 -+#define FSTV0910_P2_AGCIQ_REF 0xf20700ff -+ -+/*P2_IDCCOMP*/ -+#define RSTV0910_P2_IDCCOMP 0xf208 -+#define FSTV0910_P2_IAVERAGE_ADJ 0xf20801ff -+ -+/*P2_QDCCOMP*/ -+#define RSTV0910_P2_QDCCOMP 0xf209 -+#define FSTV0910_P2_QAVERAGE_ADJ 0xf20901ff -+ -+/*P2_POWERI*/ -+#define RSTV0910_P2_POWERI 0xf20a -+#define FSTV0910_P2_POWER_I 0xf20a00ff -+ -+/*P2_POWERQ*/ -+#define RSTV0910_P2_POWERQ 0xf20b -+#define FSTV0910_P2_POWER_Q 0xf20b00ff -+ -+/*P2_AGC1AMM*/ -+#define RSTV0910_P2_AGC1AMM 0xf20c -+#define FSTV0910_P2_AMM_VALUE 0xf20c00ff -+ -+/*P2_AGC1QUAD*/ -+#define RSTV0910_P2_AGC1QUAD 0xf20d -+#define FSTV0910_P2_QUAD_VALUE 0xf20d01ff -+ -+/*P2_AGCIQIN1*/ -+#define RSTV0910_P2_AGCIQIN1 0xf20e -+#define FSTV0910_P2_AGCIQ_VALUE1 0xf20e00ff -+ -+/*P2_AGCIQIN0*/ -+#define RSTV0910_P2_AGCIQIN0 0xf20f -+#define FSTV0910_P2_AGCIQ_VALUE0 0xf20f00ff -+ -+/*P2_DEMOD*/ -+#define RSTV0910_P2_DEMOD 0xf210 -+#define FSTV0910_P2_MANUALS2_ROLLOFF 0xf2100080 -+#define FSTV0910_P2_SPECINV_CONTROL 0xf2100030 -+#define FSTV0910_P2_MANUALSX_ROLLOFF 0xf2100004 -+#define FSTV0910_P2_ROLLOFF_CONTROL 0xf2100003 -+ -+/*P2_DMDMODCOD*/ -+#define RSTV0910_P2_DMDMODCOD 0xf211 -+#define FSTV0910_P2_MANUAL_MODCOD 0xf2110080 -+#define FSTV0910_P2_DEMOD_MODCOD 0xf211007c -+#define FSTV0910_P2_DEMOD_TYPE 0xf2110003 -+ -+/*P2_DSTATUS*/ -+#define RSTV0910_P2_DSTATUS 0xf212 -+#define FSTV0910_P2_CAR_LOCK 0xf2120080 -+#define FSTV0910_P2_TMGLOCK_QUALITY 0xf2120060 -+#define FSTV0910_P2_SDVBS1_ENABLE 0xf2120010 -+#define FSTV0910_P2_LOCK_DEFINITIF 0xf2120008 -+#define FSTV0910_P2_TIMING_IS_LOCKED 0xf2120004 -+#define FSTV0910_P2_DEMOD_SYSCFG 0xf2120002 -+#define FSTV0910_P2_OVADC_DETECT 0xf2120001 -+ -+/*P2_DSTATUS2*/ -+#define RSTV0910_P2_DSTATUS2 0xf213 -+#define FSTV0910_P2_DEMOD_DELOCK 0xf2130080 -+#define FSTV0910_P2_DEMOD_TIMEOUT 0xf2130040 -+#define FSTV0910_P2_MODCODRQ_SYNCTAG 0xf2130020 -+#define FSTV0910_P2_POLYPH_SATEVENT 0xf2130010 -+#define FSTV0910_P2_AGC1_NOSIGNALACK 0xf2130008 -+#define FSTV0910_P2_AGC2_OVERFLOW 0xf2130004 -+#define FSTV0910_P2_CFR_OVERFLOW 0xf2130002 -+#define FSTV0910_P2_GAMMA_OVERUNDER 0xf2130001 -+ -+/*P2_DMDCFGMD*/ -+#define RSTV0910_P2_DMDCFGMD 0xf214 -+#define FSTV0910_P2_DVBS2_ENABLE 0xf2140080 -+#define FSTV0910_P2_DVBS1_ENABLE 0xf2140040 -+#define FSTV0910_P2_SCAN_ENABLE 0xf2140010 -+#define FSTV0910_P2_CFR_AUTOSCAN 0xf2140008 -+#define FSTV0910_P2_NOFORCE_RELOCK 0xf2140004 -+#define FSTV0910_P2_TUN_RNG 0xf2140003 -+ -+/*P2_DMDCFG2*/ -+#define RSTV0910_P2_DMDCFG2 0xf215 -+#define FSTV0910_P2_AGC1_WAITLOCK 0xf2150080 -+#define FSTV0910_P2_S1S2_SEQUENTIAL 0xf2150040 -+#define FSTV0910_P2_BLINDPEA_MODE 0xf2150020 -+#define FSTV0910_P2_INFINITE_RELOCK 0xf2150010 -+#define FSTV0910_P2_BWOFFSET_COLDWARM 0xf2150008 -+#define FSTV0910_P2_TMGLOCK_NSCANSTOP 0xf2150004 -+#define FSTV0910_P2_COARSE_LK3MODE 0xf2150002 -+#define FSTV0910_P2_COARSE_LK2MODE 0xf2150001 -+ -+/*P2_DMDISTATE*/ -+#define RSTV0910_P2_DMDISTATE 0xf216 -+#define FSTV0910_P2_I2C_NORESETDMODE 0xf2160080 -+#define FSTV0910_P2_FORCE_ETAPED 0xf2160040 -+#define FSTV0910_P2_SDMDRST_DIRCLK 0xf2160020 -+#define FSTV0910_P2_I2C_DEMOD_MODE 0xf216001f -+ -+/*P2_DMDT0M*/ -+#define RSTV0910_P2_DMDT0M 0xf217 -+#define FSTV0910_P2_DMDT0_MIN 0xf21700ff -+ -+/*P2_DMDSTATE*/ -+#define RSTV0910_P2_DMDSTATE 0xf21b -+#define FSTV0910_P2_DEMOD_LOCKED 0xf21b0080 -+#define FSTV0910_P2_HEADER_MODE 0xf21b0060 -+#define FSTV0910_P2_DEMOD_MODE 0xf21b001f -+ -+/*P2_DMDFLYW*/ -+#define RSTV0910_P2_DMDFLYW 0xf21c -+#define FSTV0910_P2_I2C_IRQVAL 0xf21c00f0 -+#define FSTV0910_P2_FLYWHEEL_CPT 0xf21c000f -+ -+/*P2_DSTATUS3*/ -+#define RSTV0910_P2_DSTATUS3 0xf21d -+#define FSTV0910_P2_CFR_ZIGZAG 0xf21d0080 -+#define FSTV0910_P2_DEMOD_CFGMODE 0xf21d0060 -+#define FSTV0910_P2_GAMMA_LOWBAUDRATE 0xf21d0010 -+#define FSTV0910_P2_RELOCK_MODE 0xf21d0008 -+#define FSTV0910_P2_DEMOD_FAIL 0xf21d0004 -+#define FSTV0910_P2_ETAPE1A_DVBXMEM 0xf21d0003 -+ -+/*P2_DMDCFG3*/ -+#define RSTV0910_P2_DMDCFG3 0xf21e -+#define FSTV0910_P2_DVBS1_TMGWAIT 0xf21e0080 -+#define FSTV0910_P2_NO_BWCENTERING 0xf21e0040 -+#define FSTV0910_P2_INV_SEQSRCH 0xf21e0020 -+#define FSTV0910_P2_DIS_SFRUPLOW_TRK 0xf21e0010 -+#define FSTV0910_P2_NOSTOP_FIFOFULL 0xf21e0008 -+#define FSTV0910_P2_LOCKTIME_MODE 0xf21e0007 -+ -+/*P2_DMDCFG4*/ -+#define RSTV0910_P2_DMDCFG4 0xf21f -+#define FSTV0910_P2_DIS_VITLOCK 0xf21f0080 -+#define FSTV0910_P2_S1S2TOUT_FAST 0xf21f0040 -+#define FSTV0910_P2_DEMOD_FASTLOCK 0xf21f0020 -+#define FSTV0910_P2_S1HIER_ENABLE 0xf21f0010 -+#define FSTV0910_P2_TUNER_NRELAUNCH 0xf21f0008 -+#define FSTV0910_P2_DIS_CLKENABLE 0xf21f0004 -+#define FSTV0910_P2_DIS_HDRDIVLOCK 0xf21f0002 -+#define FSTV0910_P2_NO_TNRWBINIT 0xf21f0001 -+ -+/*P2_CORRELMANT*/ -+#define RSTV0910_P2_CORRELMANT 0xf220 -+#define FSTV0910_P2_CORREL_MANT 0xf22000ff -+ -+/*P2_CORRELABS*/ -+#define RSTV0910_P2_CORRELABS 0xf221 -+#define FSTV0910_P2_CORREL_ABS 0xf22100ff -+ -+/*P2_CORRELEXP*/ -+#define RSTV0910_P2_CORRELEXP 0xf222 -+#define FSTV0910_P2_CORREL_ABSEXP 0xf22200f0 -+#define FSTV0910_P2_CORREL_EXP 0xf222000f -+ -+/*P2_PLHMODCOD*/ -+#define RSTV0910_P2_PLHMODCOD 0xf224 -+#define FSTV0910_P2_SPECINV_DEMOD 0xf2240080 -+#define FSTV0910_P2_PLH_MODCOD 0xf224007c -+#define FSTV0910_P2_PLH_TYPE 0xf2240003 -+ -+/*P2_DMDREG*/ -+#define RSTV0910_P2_DMDREG 0xf225 -+#define FSTV0910_P2_EXTPSK_MODE 0xf2250080 -+#define FSTV0910_P2_HIER_SHORTFRAME 0xf2250002 -+#define FSTV0910_P2_DECIM_PLFRAMES 0xf2250001 -+ -+/*P2_AGC2O*/ -+#define RSTV0910_P2_AGC2O 0xf22c -+#define FSTV0910_P2_CSTENV_MODE 0xf22c00c0 -+#define FSTV0910_P2_AGC2_LKSQRT 0xf22c0020 -+#define FSTV0910_P2_AGC2_LKMODE 0xf22c0010 -+#define FSTV0910_P2_AGC2_LKEQUA 0xf22c0008 -+#define FSTV0910_P2_AGC2_COEF 0xf22c0007 -+ -+/*P2_AGC2REF*/ -+#define RSTV0910_P2_AGC2REF 0xf22d -+#define FSTV0910_P2_AGC2_REF 0xf22d00ff -+ -+/*P2_AGC1ADJ*/ -+#define RSTV0910_P2_AGC1ADJ 0xf22e -+#define FSTV0910_P2_AGC1ADJ_MANUAL 0xf22e0080 -+#define FSTV0910_P2_AGC1_ADJUSTED 0xf22e007f -+ -+/*P2_AGC2I1*/ -+#define RSTV0910_P2_AGC2I1 0xf236 -+#define FSTV0910_P2_AGC2_INTEGRATOR1 0xf23600ff -+ -+/*P2_AGC2I0*/ -+#define RSTV0910_P2_AGC2I0 0xf237 -+#define FSTV0910_P2_AGC2_INTEGRATOR0 0xf23700ff -+ -+/*P2_CARCFG*/ -+#define RSTV0910_P2_CARCFG 0xf238 -+#define FSTV0910_P2_CFRUPLOW_AUTO 0xf2380080 -+#define FSTV0910_P2_CFRUPLOW_TEST 0xf2380040 -+#define FSTV0910_P2_WIDE_FREQDET 0xf2380020 -+#define FSTV0910_P2_CARHDR_NODIV8 0xf2380010 -+#define FSTV0910_P2_I2C_ROTA 0xf2380008 -+#define FSTV0910_P2_ROTAON 0xf2380004 -+#define FSTV0910_P2_PH_DET_ALGO 0xf2380003 -+ -+/*P2_ACLC*/ -+#define RSTV0910_P2_ACLC 0xf239 -+#define FSTV0910_P2_CARS1_ANOSAUTO 0xf2390040 -+#define FSTV0910_P2_CAR_ALPHA_MANT 0xf2390030 -+#define FSTV0910_P2_CAR_ALPHA_EXP 0xf239000f -+ -+/*P2_BCLC*/ -+#define RSTV0910_P2_BCLC 0xf23a -+#define FSTV0910_P2_CARS1_BNOSAUTO 0xf23a0040 -+#define FSTV0910_P2_CAR_BETA_MANT 0xf23a0030 -+#define FSTV0910_P2_CAR_BETA_EXP 0xf23a000f -+ -+/*P2_CARFREQ*/ -+#define RSTV0910_P2_CARFREQ 0xf23d -+#define FSTV0910_P2_KC_COARSE_EXP 0xf23d00f0 -+#define FSTV0910_P2_BETA_FREQ 0xf23d000f -+ -+/*P2_CARHDR*/ -+#define RSTV0910_P2_CARHDR 0xf23e -+#define FSTV0910_P2_K_FREQ_HDR 0xf23e00ff -+ -+/*P2_LDT*/ -+#define RSTV0910_P2_LDT 0xf23f -+#define FSTV0910_P2_CARLOCK_THRES 0xf23f01ff -+ -+/*P2_LDT2*/ -+#define RSTV0910_P2_LDT2 0xf240 -+#define FSTV0910_P2_CARLOCK_THRES2 0xf24001ff -+ -+/*P2_CFRICFG*/ -+#define RSTV0910_P2_CFRICFG 0xf241 -+#define FSTV0910_P2_CFRINIT_UNVALRNG 0xf2410080 -+#define FSTV0910_P2_CFRINIT_LUNVALCPT 0xf2410040 -+#define FSTV0910_P2_CFRINIT_ABORTDBL 0xf2410020 -+#define FSTV0910_P2_CFRINIT_ABORTPRED 0xf2410010 -+#define FSTV0910_P2_CFRINIT_UNVALSKIP 0xf2410008 -+#define FSTV0910_P2_CFRINIT_CSTINC 0xf2410004 -+#define FSTV0910_P2_CFRIROLL_GARDER 0xf2410002 -+#define FSTV0910_P2_NEG_CFRSTEP 0xf2410001 -+ -+/*P2_CFRUP1*/ -+#define RSTV0910_P2_CFRUP1 0xf242 -+#define FSTV0910_P2_CFR_UP1 0xf24201ff -+ -+/*P2_CFRUP0*/ -+#define RSTV0910_P2_CFRUP0 0xf243 -+#define FSTV0910_P2_CFR_UP0 0xf24300ff -+ -+/*P2_CFRIBASE1*/ -+#define RSTV0910_P2_CFRIBASE1 0xf244 -+#define FSTV0910_P2_CFRINIT_BASE1 0xf24400ff -+ -+/*P2_CFRIBASE0*/ -+#define RSTV0910_P2_CFRIBASE0 0xf245 -+#define FSTV0910_P2_CFRINIT_BASE0 0xf24500ff -+ -+/*P2_CFRLOW1*/ -+#define RSTV0910_P2_CFRLOW1 0xf246 -+#define FSTV0910_P2_CFR_LOW1 0xf24601ff -+ -+/*P2_CFRLOW0*/ -+#define RSTV0910_P2_CFRLOW0 0xf247 -+#define FSTV0910_P2_CFR_LOW0 0xf24700ff -+ -+/*P2_CFRINIT1*/ -+#define RSTV0910_P2_CFRINIT1 0xf248 -+#define FSTV0910_P2_CFR_INIT1 0xf24801ff -+ -+/*P2_CFRINIT0*/ -+#define RSTV0910_P2_CFRINIT0 0xf249 -+#define FSTV0910_P2_CFR_INIT0 0xf24900ff -+ -+/*P2_CFRINC1*/ -+#define RSTV0910_P2_CFRINC1 0xf24a -+#define FSTV0910_P2_MANUAL_CFRINC 0xf24a0080 -+#define FSTV0910_P2_CFR_INC1 0xf24a003f -+ -+/*P2_CFRINC0*/ -+#define RSTV0910_P2_CFRINC0 0xf24b -+#define FSTV0910_P2_CFR_INC0 0xf24b00ff -+ -+/*P2_CFR2*/ -+#define RSTV0910_P2_CFR2 0xf24c -+#define FSTV0910_P2_CAR_FREQ2 0xf24c01ff -+ -+/*P2_CFR1*/ -+#define RSTV0910_P2_CFR1 0xf24d -+#define FSTV0910_P2_CAR_FREQ1 0xf24d00ff -+ -+/*P2_CFR0*/ -+#define RSTV0910_P2_CFR0 0xf24e -+#define FSTV0910_P2_CAR_FREQ0 0xf24e00ff -+ -+/*P2_LDI*/ -+#define RSTV0910_P2_LDI 0xf24f -+#define FSTV0910_P2_LOCK_DET_INTEGR 0xf24f01ff -+ -+/*P2_TMGCFG*/ -+#define RSTV0910_P2_TMGCFG 0xf250 -+#define FSTV0910_P2_TMGLOCK_BETA 0xf25000c0 -+#define FSTV0910_P2_DO_TIMING_CORR 0xf2500010 -+#define FSTV0910_P2_MANUAL_SCAN 0xf250000c -+#define FSTV0910_P2_TMG_MINFREQ 0xf2500003 -+ -+/*P2_RTC*/ -+#define RSTV0910_P2_RTC 0xf251 -+#define FSTV0910_P2_TMGALPHA_EXP 0xf25100f0 -+#define FSTV0910_P2_TMGBETA_EXP 0xf251000f -+ -+/*P2_RTCS2*/ -+#define RSTV0910_P2_RTCS2 0xf252 -+#define FSTV0910_P2_TMGALPHAS2_EXP 0xf25200f0 -+#define FSTV0910_P2_TMGBETAS2_EXP 0xf252000f -+ -+/*P2_TMGTHRISE*/ -+#define RSTV0910_P2_TMGTHRISE 0xf253 -+#define FSTV0910_P2_TMGLOCK_THRISE 0xf25300ff -+ -+/*P2_TMGTHFALL*/ -+#define RSTV0910_P2_TMGTHFALL 0xf254 -+#define FSTV0910_P2_TMGLOCK_THFALL 0xf25400ff -+ -+/*P2_SFRUPRATIO*/ -+#define RSTV0910_P2_SFRUPRATIO 0xf255 -+#define FSTV0910_P2_SFR_UPRATIO 0xf25500ff -+ -+/*P2_SFRLOWRATIO*/ -+#define RSTV0910_P2_SFRLOWRATIO 0xf256 -+#define FSTV0910_P2_SFR_LOWRATIO 0xf25600ff -+ -+/*P2_KTTMG*/ -+#define RSTV0910_P2_KTTMG 0xf257 -+#define FSTV0910_P2_KT_TMG_EXP 0xf25700f0 -+ -+/*P2_KREFTMG*/ -+#define RSTV0910_P2_KREFTMG 0xf258 -+#define FSTV0910_P2_KREF_TMG 0xf25800ff -+ -+/*P2_SFRSTEP*/ -+#define RSTV0910_P2_SFRSTEP 0xf259 -+#define FSTV0910_P2_SFR_SCANSTEP 0xf25900f0 -+#define FSTV0910_P2_SFR_CENTERSTEP 0xf259000f -+ -+/*P2_TMGCFG2*/ -+#define RSTV0910_P2_TMGCFG2 0xf25a -+#define FSTV0910_P2_KREFTMG2_DECMODE 0xf25a00c0 -+#define FSTV0910_P2_DIS_AUTOSAMP 0xf25a0008 -+#define FSTV0910_P2_SCANINIT_QUART 0xf25a0004 -+#define FSTV0910_P2_NOTMG_DVBS1DERAT 0xf25a0002 -+#define FSTV0910_P2_SFRRATIO_FINE 0xf25a0001 -+ -+/*P2_KREFTMG2*/ -+#define RSTV0910_P2_KREFTMG2 0xf25b -+#define FSTV0910_P2_KREF_TMG2 0xf25b00ff -+ -+/*P2_TMGCFG3*/ -+#define RSTV0910_P2_TMGCFG3 0xf25d -+#define FSTV0910_P2_CFRINC_MODE 0xf25d0070 -+#define FSTV0910_P2_CONT_TMGCENTER 0xf25d0008 -+#define FSTV0910_P2_AUTO_GUP 0xf25d0004 -+#define FSTV0910_P2_AUTO_GLOW 0xf25d0002 -+#define FSTV0910_P2_SFRVAL_MINMODE 0xf25d0001 -+ -+/*P2_SFRINIT1*/ -+#define RSTV0910_P2_SFRINIT1 0xf25e -+#define FSTV0910_P2_SFR_INIT1 0xf25e00ff -+ -+/*P2_SFRINIT0*/ -+#define RSTV0910_P2_SFRINIT0 0xf25f -+#define FSTV0910_P2_SFR_INIT0 0xf25f00ff -+ -+/*P2_SFRUP1*/ -+#define RSTV0910_P2_SFRUP1 0xf260 -+#define FSTV0910_P2_SYMB_FREQ_UP1 0xf26000ff -+ -+/*P2_SFRUP0*/ -+#define RSTV0910_P2_SFRUP0 0xf261 -+#define FSTV0910_P2_SYMB_FREQ_UP0 0xf26100ff -+ -+/*P2_SFRLOW1*/ -+#define RSTV0910_P2_SFRLOW1 0xf262 -+#define FSTV0910_P2_SYMB_FREQ_LOW1 0xf26200ff -+ -+/*P2_SFRLOW0*/ -+#define RSTV0910_P2_SFRLOW0 0xf263 -+#define FSTV0910_P2_SYMB_FREQ_LOW0 0xf26300ff -+ -+/*P2_SFR3*/ -+#define RSTV0910_P2_SFR3 0xf264 -+#define FSTV0910_P2_SYMB_FREQ3 0xf26400ff -+ -+/*P2_SFR2*/ -+#define RSTV0910_P2_SFR2 0xf265 -+#define FSTV0910_P2_SYMB_FREQ2 0xf26500ff -+ -+/*P2_SFR1*/ -+#define RSTV0910_P2_SFR1 0xf266 -+#define FSTV0910_P2_SYMB_FREQ1 0xf26600ff -+ -+/*P2_SFR0*/ -+#define RSTV0910_P2_SFR0 0xf267 -+#define FSTV0910_P2_SYMB_FREQ0 0xf26700ff -+ -+/*P2_TMGREG2*/ -+#define RSTV0910_P2_TMGREG2 0xf268 -+#define FSTV0910_P2_TMGREG2 0xf26800ff -+ -+/*P2_TMGREG1*/ -+#define RSTV0910_P2_TMGREG1 0xf269 -+#define FSTV0910_P2_TMGREG1 0xf26900ff -+ -+/*P2_TMGREG0*/ -+#define RSTV0910_P2_TMGREG0 0xf26a -+#define FSTV0910_P2_TMGREG0 0xf26a00ff -+ -+/*P2_TMGLOCK1*/ -+#define RSTV0910_P2_TMGLOCK1 0xf26b -+#define FSTV0910_P2_TMGLOCK_LEVEL1 0xf26b01ff -+ -+/*P2_TMGLOCK0*/ -+#define RSTV0910_P2_TMGLOCK0 0xf26c -+#define FSTV0910_P2_TMGLOCK_LEVEL0 0xf26c00ff -+ -+/*P2_TMGOBS*/ -+#define RSTV0910_P2_TMGOBS 0xf26d -+#define FSTV0910_P2_ROLLOFF_STATUS 0xf26d00c0 -+#define FSTV0910_P2_SCAN_SIGN 0xf26d0030 -+#define FSTV0910_P2_TMG_SCANNING 0xf26d0008 -+#define FSTV0910_P2_CHCENTERING_MODE 0xf26d0004 -+#define FSTV0910_P2_TMG_SCANFAIL 0xf26d0002 -+ -+/*P2_EQUALCFG*/ -+#define RSTV0910_P2_EQUALCFG 0xf26f -+#define FSTV0910_P2_NOTMG_NEGALWAIT 0xf26f0080 -+#define FSTV0910_P2_EQUAL_ON 0xf26f0040 -+#define FSTV0910_P2_SEL_EQUALCOR 0xf26f0038 -+#define FSTV0910_P2_MU_EQUALDFE 0xf26f0007 -+ -+/*P2_EQUAI1*/ -+#define RSTV0910_P2_EQUAI1 0xf270 -+#define FSTV0910_P2_EQUA_ACCI1 0xf27001ff -+ -+/*P2_EQUAQ1*/ -+#define RSTV0910_P2_EQUAQ1 0xf271 -+#define FSTV0910_P2_EQUA_ACCQ1 0xf27101ff -+ -+/*P2_EQUAI2*/ -+#define RSTV0910_P2_EQUAI2 0xf272 -+#define FSTV0910_P2_EQUA_ACCI2 0xf27201ff -+ -+/*P2_EQUAQ2*/ -+#define RSTV0910_P2_EQUAQ2 0xf273 -+#define FSTV0910_P2_EQUA_ACCQ2 0xf27301ff -+ -+/*P2_EQUAI3*/ -+#define RSTV0910_P2_EQUAI3 0xf274 -+#define FSTV0910_P2_EQUA_ACCI3 0xf27401ff -+ -+/*P2_EQUAQ3*/ -+#define RSTV0910_P2_EQUAQ3 0xf275 -+#define FSTV0910_P2_EQUA_ACCQ3 0xf27501ff -+ -+/*P2_EQUAI4*/ -+#define RSTV0910_P2_EQUAI4 0xf276 -+#define FSTV0910_P2_EQUA_ACCI4 0xf27601ff -+ -+/*P2_EQUAQ4*/ -+#define RSTV0910_P2_EQUAQ4 0xf277 -+#define FSTV0910_P2_EQUA_ACCQ4 0xf27701ff -+ -+/*P2_EQUAI5*/ -+#define RSTV0910_P2_EQUAI5 0xf278 -+#define FSTV0910_P2_EQUA_ACCI5 0xf27801ff -+ -+/*P2_EQUAQ5*/ -+#define RSTV0910_P2_EQUAQ5 0xf279 -+#define FSTV0910_P2_EQUA_ACCQ5 0xf27901ff -+ -+/*P2_EQUAI6*/ -+#define RSTV0910_P2_EQUAI6 0xf27a -+#define FSTV0910_P2_EQUA_ACCI6 0xf27a01ff -+ -+/*P2_EQUAQ6*/ -+#define RSTV0910_P2_EQUAQ6 0xf27b -+#define FSTV0910_P2_EQUA_ACCQ6 0xf27b01ff -+ -+/*P2_EQUAI7*/ -+#define RSTV0910_P2_EQUAI7 0xf27c -+#define FSTV0910_P2_EQUA_ACCI7 0xf27c01ff -+ -+/*P2_EQUAQ7*/ -+#define RSTV0910_P2_EQUAQ7 0xf27d -+#define FSTV0910_P2_EQUA_ACCQ7 0xf27d01ff -+ -+/*P2_EQUAI8*/ -+#define RSTV0910_P2_EQUAI8 0xf27e -+#define FSTV0910_P2_EQUA_ACCI8 0xf27e01ff -+ -+/*P2_EQUAQ8*/ -+#define RSTV0910_P2_EQUAQ8 0xf27f -+#define FSTV0910_P2_EQUA_ACCQ8 0xf27f01ff -+ -+/*P2_NNOSDATAT1*/ -+#define RSTV0910_P2_NNOSDATAT1 0xf280 -+#define FSTV0910_P2_NOSDATAT_NORMED1 0xf28000ff -+ -+/*P2_NNOSDATAT0*/ -+#define RSTV0910_P2_NNOSDATAT0 0xf281 -+#define FSTV0910_P2_NOSDATAT_NORMED0 0xf28100ff -+ -+/*P2_NNOSDATA1*/ -+#define RSTV0910_P2_NNOSDATA1 0xf282 -+#define FSTV0910_P2_NOSDATA_NORMED1 0xf28200ff -+ -+/*P2_NNOSDATA0*/ -+#define RSTV0910_P2_NNOSDATA0 0xf283 -+#define FSTV0910_P2_NOSDATA_NORMED0 0xf28300ff -+ -+/*P2_NNOSPLHT1*/ -+#define RSTV0910_P2_NNOSPLHT1 0xf284 -+#define FSTV0910_P2_NOSPLHT_NORMED1 0xf28400ff -+ -+/*P2_NNOSPLHT0*/ -+#define RSTV0910_P2_NNOSPLHT0 0xf285 -+#define FSTV0910_P2_NOSPLHT_NORMED0 0xf28500ff -+ -+/*P2_NNOSPLH1*/ -+#define RSTV0910_P2_NNOSPLH1 0xf286 -+#define FSTV0910_P2_NOSPLH_NORMED1 0xf28600ff -+ -+/*P2_NNOSPLH0*/ -+#define RSTV0910_P2_NNOSPLH0 0xf287 -+#define FSTV0910_P2_NOSPLH_NORMED0 0xf28700ff -+ -+/*P2_NOSDATAT1*/ -+#define RSTV0910_P2_NOSDATAT1 0xf288 -+#define FSTV0910_P2_NOSDATAT_UNNORMED1 0xf28800ff -+ -+/*P2_NOSDATAT0*/ -+#define RSTV0910_P2_NOSDATAT0 0xf289 -+#define FSTV0910_P2_NOSDATAT_UNNORMED0 0xf28900ff -+ -+/*P2_NNOSFRAME1*/ -+#define RSTV0910_P2_NNOSFRAME1 0xf28a -+#define FSTV0910_P2_NOSFRAME_NORMED1 0xf28a00ff -+ -+/*P2_NNOSFRAME0*/ -+#define RSTV0910_P2_NNOSFRAME0 0xf28b -+#define FSTV0910_P2_NOSFRAME_NORMED0 0xf28b00ff -+ -+/*P2_NNOSRAD1*/ -+#define RSTV0910_P2_NNOSRAD1 0xf28c -+#define FSTV0910_P2_NOSRADIAL_NORMED1 0xf28c00ff -+ -+/*P2_NNOSRAD0*/ -+#define RSTV0910_P2_NNOSRAD0 0xf28d -+#define FSTV0910_P2_NOSRADIAL_NORMED0 0xf28d00ff -+ -+/*P2_NOSCFGF1*/ -+#define RSTV0910_P2_NOSCFGF1 0xf28e -+#define FSTV0910_P2_LOWNOISE_MESURE 0xf28e0080 -+#define FSTV0910_P2_NOS_DELFRAME 0xf28e0040 -+#define FSTV0910_P2_NOSDATA_MODE 0xf28e0030 -+#define FSTV0910_P2_FRAMESEL_TYPESEL 0xf28e000c -+#define FSTV0910_P2_FRAMESEL_TYPE 0xf28e0003 -+ -+/*P2_CAR2CFG*/ -+#define RSTV0910_P2_CAR2CFG 0xf290 -+#define FSTV0910_P2_DESCRAMB_OFF 0xf2900080 -+#define FSTV0910_P2_EN_PHNOSRAM 0xf2900020 -+#define FSTV0910_P2_STOP_CFR2UPDATE 0xf2900010 -+#define FSTV0910_P2_STOP_NCO2UPDATE 0xf2900008 -+#define FSTV0910_P2_ROTA2ON 0xf2900004 -+#define FSTV0910_P2_PH_DET_ALGO2 0xf2900003 -+ -+/*P2_CFR2CFR1*/ -+#define RSTV0910_P2_CFR2CFR1 0xf291 -+#define FSTV0910_P2_CFR2_S2CONTROL 0xf29100c0 -+#define FSTV0910_P2_EN_S2CAR2CENTER 0xf2910020 -+#define FSTV0910_P2_BCHERRCFR2_MODE 0xf2910018 -+#define FSTV0910_P2_CFR2TOCFR1_BETA 0xf2910007 -+ -+/*P2_CAR3CFG*/ -+#define RSTV0910_P2_CAR3CFG 0xf292 -+#define FSTV0910_P2_CARRIER23_MODE 0xf29200c0 -+#define FSTV0910_P2_CAR3INTERM_DVBS1 0xf2920020 -+#define FSTV0910_P2_ABAMPLIF_MODE 0xf2920018 -+#define FSTV0910_P2_CARRIER3_ALPHA3DL 0xf2920007 -+ -+/*P2_CFR22*/ -+#define RSTV0910_P2_CFR22 0xf293 -+#define FSTV0910_P2_CAR2_FREQ2 0xf29301ff -+ -+/*P2_CFR21*/ -+#define RSTV0910_P2_CFR21 0xf294 -+#define FSTV0910_P2_CAR2_FREQ1 0xf29400ff -+ -+/*P2_CFR20*/ -+#define RSTV0910_P2_CFR20 0xf295 -+#define FSTV0910_P2_CAR2_FREQ0 0xf29500ff -+ -+/*P2_ACLC2S2Q*/ -+#define RSTV0910_P2_ACLC2S2Q 0xf297 -+#define FSTV0910_P2_ENAB_SPSKSYMB 0xf2970080 -+#define FSTV0910_P2_CAR2S2_QANOSAUTO 0xf2970040 -+#define FSTV0910_P2_CAR2S2_Q_ALPH_M 0xf2970030 -+#define FSTV0910_P2_CAR2S2_Q_ALPH_E 0xf297000f -+ -+/*P2_ACLC2S28*/ -+#define RSTV0910_P2_ACLC2S28 0xf298 -+#define FSTV0910_P2_OLDI3Q_MODE 0xf2980080 -+#define FSTV0910_P2_CAR2S2_8ANOSAUTO 0xf2980040 -+#define FSTV0910_P2_CAR2S2_8_ALPH_M 0xf2980030 -+#define FSTV0910_P2_CAR2S2_8_ALPH_E 0xf298000f -+ -+/*P2_ACLC2S216A*/ -+#define RSTV0910_P2_ACLC2S216A 0xf299 -+#define FSTV0910_P2_CAR2S2_16ANOSAUTO 0xf2990040 -+#define FSTV0910_P2_CAR2S2_16A_ALPH_M 0xf2990030 -+#define FSTV0910_P2_CAR2S2_16A_ALPH_E 0xf299000f -+ -+/*P2_ACLC2S232A*/ -+#define RSTV0910_P2_ACLC2S232A 0xf29a -+#define FSTV0910_P2_CAR2S2_32ANOSUATO 0xf29a0040 -+#define FSTV0910_P2_CAR2S2_32A_ALPH_M 0xf29a0030 -+#define FSTV0910_P2_CAR2S2_32A_ALPH_E 0xf29a000f -+ -+/*P2_BCLC2S2Q*/ -+#define RSTV0910_P2_BCLC2S2Q 0xf29c -+#define FSTV0910_P2_DVBS2S2Q_NIP 0xf29c0080 -+#define FSTV0910_P2_CAR2S2_QBNOSAUTO 0xf29c0040 -+#define FSTV0910_P2_CAR2S2_Q_BETA_M 0xf29c0030 -+#define FSTV0910_P2_CAR2S2_Q_BETA_E 0xf29c000f -+ -+/*P2_BCLC2S28*/ -+#define RSTV0910_P2_BCLC2S28 0xf29d -+#define FSTV0910_P2_DVBS2S28_NIP 0xf29d0080 -+#define FSTV0910_P2_CAR2S2_8BNOSAUTO 0xf29d0040 -+#define FSTV0910_P2_CAR2S2_8_BETA_M 0xf29d0030 -+#define FSTV0910_P2_CAR2S2_8_BETA_E 0xf29d000f -+ -+/*P2_PLROOT2*/ -+#define RSTV0910_P2_PLROOT2 0xf2ac -+#define FSTV0910_P2_PLHAUTO_DISPLH 0xf2ac0040 -+#define FSTV0910_P2_PLHAUTO_FASTMODE 0xf2ac0020 -+#define FSTV0910_P2_PLHAUTO_ENABLE 0xf2ac0010 -+#define FSTV0910_P2_PLSCRAMB_MODE 0xf2ac000c -+#define FSTV0910_P2_PLSCRAMB_ROOT2 0xf2ac0003 -+ -+/*P2_PLROOT1*/ -+#define RSTV0910_P2_PLROOT1 0xf2ad -+#define FSTV0910_P2_PLSCRAMB_ROOT1 0xf2ad00ff -+ -+/*P2_PLROOT0*/ -+#define RSTV0910_P2_PLROOT0 0xf2ae -+#define FSTV0910_P2_PLSCRAMB_ROOT0 0xf2ae00ff -+ -+/*P2_MODCODLST7*/ -+#define RSTV0910_P2_MODCODLST7 0xf2b7 -+#define FSTV0910_P2_MODCOD_NNOSFILTER 0xf2b70080 -+#define FSTV0910_P2_MODCODLST_NOSTYPE 0xf2b70040 -+#define FSTV0910_P2_DIS_8PSK_9_10 0xf2b70030 -+#define FSTV0910_P2_DIS_8P_8_9 0xf2b7000f -+ -+/*P2_MODCODLST8*/ -+#define RSTV0910_P2_MODCODLST8 0xf2b8 -+#define FSTV0910_P2_DIS_8P_5_6 0xf2b800f0 -+#define FSTV0910_P2_DIS_8P_3_4 0xf2b8000f -+ -+/*P2_MODCODLST9*/ -+#define RSTV0910_P2_MODCODLST9 0xf2b9 -+#define FSTV0910_P2_DIS_8P_2_3 0xf2b900f0 -+#define FSTV0910_P2_DIS_8P_3_5 0xf2b9000f -+ -+/*P2_MODCODLSTA*/ -+#define RSTV0910_P2_MODCODLSTA 0xf2ba -+#define FSTV0910_P2_NOSFILTER_LIMITE 0xf2ba0080 -+#define FSTV0910_P2_NOSFILTER_MODE 0xf2ba0040 -+#define FSTV0910_P2_DIS_QPSK_9_10 0xf2ba0030 -+#define FSTV0910_P2_DIS_QP_8_9 0xf2ba000f -+ -+/*P2_MODCODLSTB*/ -+#define RSTV0910_P2_MODCODLSTB 0xf2bb -+#define FSTV0910_P2_DIS_QP_5_6 0xf2bb00f0 -+#define FSTV0910_P2_DIS_QP_4_5 0xf2bb000f -+ -+/*P2_MODCODLSTC*/ -+#define RSTV0910_P2_MODCODLSTC 0xf2bc -+#define FSTV0910_P2_DIS_QP_3_4 0xf2bc00f0 -+#define FSTV0910_P2_DIS_QP_2_3 0xf2bc000f -+ -+/*P2_MODCODLSTD*/ -+#define RSTV0910_P2_MODCODLSTD 0xf2bd -+#define FSTV0910_P2_DIS_QPSK_3_5 0xf2bd00f0 -+#define FSTV0910_P2_DIS_QPSK_1_2 0xf2bd000f -+ -+/*P2_GAUSSR0*/ -+#define RSTV0910_P2_GAUSSR0 0xf2c0 -+#define FSTV0910_P2_EN_CCIMODE 0xf2c00080 -+#define FSTV0910_P2_R0_GAUSSIEN 0xf2c0007f -+ -+/*P2_CCIR0*/ -+#define RSTV0910_P2_CCIR0 0xf2c1 -+#define FSTV0910_P2_CCIDETECT_PLHONLY 0xf2c10080 -+#define FSTV0910_P2_R0_CCI 0xf2c1007f -+ -+/*P2_CCIQUANT*/ -+#define RSTV0910_P2_CCIQUANT 0xf2c2 -+#define FSTV0910_P2_CCI_BETA 0xf2c200e0 -+#define FSTV0910_P2_CCI_QUANT 0xf2c2001f -+ -+/*P2_CCITHRES*/ -+#define RSTV0910_P2_CCITHRES 0xf2c3 -+#define FSTV0910_P2_CCI_THRESHOLD 0xf2c300ff -+ -+/*P2_CCIACC*/ -+#define RSTV0910_P2_CCIACC 0xf2c4 -+#define FSTV0910_P2_CCI_VALUE 0xf2c400ff -+ -+/*P2_DSTATUS4*/ -+#define RSTV0910_P2_DSTATUS4 0xf2c5 -+#define FSTV0910_P2_RAINFADE_DETECT 0xf2c50080 -+#define FSTV0910_P2_NOTHRES2_FAIL 0xf2c50040 -+#define FSTV0910_P2_NOTHRES1_FAIL 0xf2c50020 -+#define FSTV0910_P2_PILOT_FAILDETECT 0xf2c50010 -+#define FSTV0910_P2_HIER_DETECT 0xf2c50008 -+#define FSTV0910_P2_DMDPROG_ERROR 0xf2c50004 -+#define FSTV0910_P2_CSTENV_DETECT 0xf2c50002 -+#define FSTV0910_P2_DETECTION_TRIAX 0xf2c50001 -+ -+/*P2_DMDRESCFG*/ -+#define RSTV0910_P2_DMDRESCFG 0xf2c6 -+#define FSTV0910_P2_DMDRES_RESET 0xf2c60080 -+#define FSTV0910_P2_DMDRES_NOISESQR 0xf2c60010 -+#define FSTV0910_P2_DMDRES_STRALL 0xf2c60008 -+#define FSTV0910_P2_DMDRES_NEWONLY 0xf2c60004 -+#define FSTV0910_P2_DMDRES_NOSTORE 0xf2c60002 -+#define FSTV0910_P2_DMDRES_AGC2MEM 0xf2c60001 -+ -+/*P2_DMDRESADR*/ -+#define RSTV0910_P2_DMDRESADR 0xf2c7 -+#define FSTV0910_P2_SUSP_PREDCANAL 0xf2c70080 -+#define FSTV0910_P2_DMDRES_VALIDCFR 0xf2c70040 -+#define FSTV0910_P2_DMDRES_MEMFULL 0xf2c70030 -+#define FSTV0910_P2_DMDRES_RESNBR 0xf2c7000f -+ -+/*P2_DMDRESDATA7*/ -+#define RSTV0910_P2_DMDRESDATA7 0xf2c8 -+#define FSTV0910_P2_DMDRES_DATA7 0xf2c800ff -+ -+/*P2_DMDRESDATA6*/ -+#define RSTV0910_P2_DMDRESDATA6 0xf2c9 -+#define FSTV0910_P2_DMDRES_DATA6 0xf2c900ff -+ -+/*P2_DMDRESDATA5*/ -+#define RSTV0910_P2_DMDRESDATA5 0xf2ca -+#define FSTV0910_P2_DMDRES_DATA5 0xf2ca00ff -+ -+/*P2_DMDRESDATA4*/ -+#define RSTV0910_P2_DMDRESDATA4 0xf2cb -+#define FSTV0910_P2_DMDRES_DATA4 0xf2cb00ff -+ -+/*P2_DMDRESDATA3*/ -+#define RSTV0910_P2_DMDRESDATA3 0xf2cc -+#define FSTV0910_P2_DMDRES_DATA3 0xf2cc00ff -+ -+/*P2_DMDRESDATA2*/ -+#define RSTV0910_P2_DMDRESDATA2 0xf2cd -+#define FSTV0910_P2_DMDRES_DATA2 0xf2cd00ff -+ -+/*P2_DMDRESDATA1*/ -+#define RSTV0910_P2_DMDRESDATA1 0xf2ce -+#define FSTV0910_P2_DMDRES_DATA1 0xf2ce00ff -+ -+/*P2_DMDRESDATA0*/ -+#define RSTV0910_P2_DMDRESDATA0 0xf2cf -+#define FSTV0910_P2_DMDRES_DATA0 0xf2cf00ff -+ -+/*P2_FFEI1*/ -+#define RSTV0910_P2_FFEI1 0xf2d0 -+#define FSTV0910_P2_FFE_ACCI1 0xf2d001ff -+ -+/*P2_FFEQ1*/ -+#define RSTV0910_P2_FFEQ1 0xf2d1 -+#define FSTV0910_P2_FFE_ACCQ1 0xf2d101ff -+ -+/*P2_FFEI2*/ -+#define RSTV0910_P2_FFEI2 0xf2d2 -+#define FSTV0910_P2_FFE_ACCI2 0xf2d201ff -+ -+/*P2_FFEQ2*/ -+#define RSTV0910_P2_FFEQ2 0xf2d3 -+#define FSTV0910_P2_FFE_ACCQ2 0xf2d301ff -+ -+/*P2_FFEI3*/ -+#define RSTV0910_P2_FFEI3 0xf2d4 -+#define FSTV0910_P2_FFE_ACCI3 0xf2d401ff -+ -+/*P2_FFEQ3*/ -+#define RSTV0910_P2_FFEQ3 0xf2d5 -+#define FSTV0910_P2_FFE_ACCQ3 0xf2d501ff -+ -+/*P2_FFEI4*/ -+#define RSTV0910_P2_FFEI4 0xf2d6 -+#define FSTV0910_P2_FFE_ACCI4 0xf2d601ff -+ -+/*P2_FFEQ4*/ -+#define RSTV0910_P2_FFEQ4 0xf2d7 -+#define FSTV0910_P2_FFE_ACCQ4 0xf2d701ff -+ -+/*P2_FFECFG*/ -+#define RSTV0910_P2_FFECFG 0xf2d8 -+#define FSTV0910_P2_EQUALFFE_ON 0xf2d80040 -+#define FSTV0910_P2_EQUAL_USEDSYMB 0xf2d80030 -+#define FSTV0910_P2_MU_EQUALFFE 0xf2d80007 -+ -+/*P2_TNRCFG2*/ -+#define RSTV0910_P2_TNRCFG2 0xf2e1 -+#define FSTV0910_P2_TUN_IQSWAP 0xf2e10080 -+#define FSTV0910_P2_STB6110_STEP2MHZ 0xf2e10040 -+#define FSTV0910_P2_STB6120_DBLI2C 0xf2e10020 -+#define FSTV0910_P2_TUNER_WIDEBAND 0xf2e10010 -+#define FSTV0910_P2_TUNER_OBSPAGE 0xf2e10008 -+#define FSTV0910_P2_DIS_BWCALC 0xf2e10004 -+#define FSTV0910_P2_SHORT_WAITSTATES 0xf2e10002 -+#define FSTV0910_P2_DIS_2BWAGC1 0xf2e10001 -+ -+/*P2_SMAPCOEF7*/ -+#define RSTV0910_P2_SMAPCOEF7 0xf300 -+#define FSTV0910_P2_DIS_QSCALE 0xf3000080 -+#define FSTV0910_P2_SMAPCOEF_Q_LLR12 0xf300017f -+ -+/*P2_SMAPCOEF6*/ -+#define RSTV0910_P2_SMAPCOEF6 0xf301 -+#define FSTV0910_P2_DIS_AGC2SCALE 0xf3010080 -+#define FSTV0910_P2_DIS_16IQMULT 0xf3010040 -+#define FSTV0910_P2_OLD_16APSK47 0xf3010020 -+#define FSTV0910_P2_OLD_16APSK12 0xf3010010 -+#define FSTV0910_P2_DIS_NEWSCALE 0xf3010008 -+#define FSTV0910_P2_ADJ_8PSKLLR1 0xf3010004 -+#define FSTV0910_P2_OLD_8PSKLLR1 0xf3010002 -+#define FSTV0910_P2_DIS_AB8PSK 0xf3010001 -+ -+/*P2_SMAPCOEF5*/ -+#define RSTV0910_P2_SMAPCOEF5 0xf302 -+#define FSTV0910_P2_DIS_8SCALE 0xf3020080 -+#define FSTV0910_P2_SMAPCOEF_8P_LLR23 0xf302017f -+ -+/*P2_NOSTHRES1*/ -+#define RSTV0910_P2_NOSTHRES1 0xf309 -+#define FSTV0910_P2_NOS_THRESHOLD1 0xf30900ff -+ -+/*P2_NOSTHRES2*/ -+#define RSTV0910_P2_NOSTHRES2 0xf30a -+#define FSTV0910_P2_NOS_THRESHOLD2 0xf30a00ff -+ -+/*P2_NOSDIFF1*/ -+#define RSTV0910_P2_NOSDIFF1 0xf30b -+#define FSTV0910_P2_NOSTHRES1_DIFF 0xf30b00ff -+ -+/*P2_RAINFADE*/ -+#define RSTV0910_P2_RAINFADE 0xf30c -+#define FSTV0910_P2_NOSTHRES_DATAT 0xf30c0080 -+#define FSTV0910_P2_RAINFADE_CNLIMIT 0xf30c0070 -+#define FSTV0910_P2_RAINFADE_TIMEOUT 0xf30c0007 -+ -+/*P2_NOSRAMCFG*/ -+#define RSTV0910_P2_NOSRAMCFG 0xf30d -+#define FSTV0910_P2_NOSRAM_DVBS2DATA 0xf30d0080 -+#define FSTV0910_P2_NOSRAM_QUADRAT 0xf30d0040 -+#define FSTV0910_P2_NOSRAM_ACTIVATION 0xf30d0030 -+#define FSTV0910_P2_NOSRAM_CNRONLY 0xf30d0008 -+#define FSTV0910_P2_NOSRAM_LGNCNR1 0xf30d0007 -+ -+/*P2_NOSRAMPOS*/ -+#define RSTV0910_P2_NOSRAMPOS 0xf30e -+#define FSTV0910_P2_NOSRAM_LGNCNR0 0xf30e00f0 -+#define FSTV0910_P2_NOSRAM_VALIDE 0xf30e0004 -+#define FSTV0910_P2_NOSRAM_CNRVAL1 0xf30e0003 -+ -+/*P2_NOSRAMVAL*/ -+#define RSTV0910_P2_NOSRAMVAL 0xf30f -+#define FSTV0910_P2_NOSRAM_CNRVAL0 0xf30f00ff -+ -+/*P2_DMDPLHSTAT*/ -+#define RSTV0910_P2_DMDPLHSTAT 0xf320 -+#define FSTV0910_P2_PLH_STATISTIC 0xf32000ff -+ -+/*P2_LOCKTIME3*/ -+#define RSTV0910_P2_LOCKTIME3 0xf322 -+#define FSTV0910_P2_DEMOD_LOCKTIME3 0xf32200ff -+ -+/*P2_LOCKTIME2*/ -+#define RSTV0910_P2_LOCKTIME2 0xf323 -+#define FSTV0910_P2_DEMOD_LOCKTIME2 0xf32300ff -+ -+/*P2_LOCKTIME1*/ -+#define RSTV0910_P2_LOCKTIME1 0xf324 -+#define FSTV0910_P2_DEMOD_LOCKTIME1 0xf32400ff -+ -+/*P2_LOCKTIME0*/ -+#define RSTV0910_P2_LOCKTIME0 0xf325 -+#define FSTV0910_P2_DEMOD_LOCKTIME0 0xf32500ff -+ -+/*P2_VITSCALE*/ -+#define RSTV0910_P2_VITSCALE 0xf332 -+#define FSTV0910_P2_NVTH_NOSRANGE 0xf3320080 -+#define FSTV0910_P2_VERROR_MAXMODE 0xf3320040 -+#define FSTV0910_P2_KDIV_MODE 0xf3320030 -+#define FSTV0910_P2_NSLOWSN_LOCKED 0xf3320008 -+#define FSTV0910_P2_DELOCK_PRFLOSS 0xf3320004 -+#define FSTV0910_P2_DIS_RSFLOCK 0xf3320002 -+ -+/*P2_FECM*/ -+#define RSTV0910_P2_FECM 0xf333 -+#define FSTV0910_P2_DSS_DVB 0xf3330080 -+#define FSTV0910_P2_DEMOD_BYPASS 0xf3330040 -+#define FSTV0910_P2_CMP_SLOWMODE 0xf3330020 -+#define FSTV0910_P2_DSS_SRCH 0xf3330010 -+#define FSTV0910_P2_DIFF_MODEVIT 0xf3330004 -+#define FSTV0910_P2_SYNCVIT 0xf3330002 -+#define FSTV0910_P2_IQINV 0xf3330001 -+ -+/*P2_VTH12*/ -+#define RSTV0910_P2_VTH12 0xf334 -+#define FSTV0910_P2_VTH12 0xf33400ff -+ -+/*P2_VTH23*/ -+#define RSTV0910_P2_VTH23 0xf335 -+#define FSTV0910_P2_VTH23 0xf33500ff -+ -+/*P2_VTH34*/ -+#define RSTV0910_P2_VTH34 0xf336 -+#define FSTV0910_P2_VTH34 0xf33600ff -+ -+/*P2_VTH56*/ -+#define RSTV0910_P2_VTH56 0xf337 -+#define FSTV0910_P2_VTH56 0xf33700ff -+ -+/*P2_VTH67*/ -+#define RSTV0910_P2_VTH67 0xf338 -+#define FSTV0910_P2_VTH67 0xf33800ff -+ -+/*P2_VTH78*/ -+#define RSTV0910_P2_VTH78 0xf339 -+#define FSTV0910_P2_VTH78 0xf33900ff -+ -+/*P2_VITCURPUN*/ -+#define RSTV0910_P2_VITCURPUN 0xf33a -+#define FSTV0910_P2_CYCLESLIP_VIT 0xf33a0080 -+#define FSTV0910_P2_VIT_ROTA180 0xf33a0040 -+#define FSTV0910_P2_VIT_ROTA90 0xf33a0020 -+#define FSTV0910_P2_VIT_CURPUN 0xf33a001f -+ -+/*P2_VERROR*/ -+#define RSTV0910_P2_VERROR 0xf33b -+#define FSTV0910_P2_REGERR_VIT 0xf33b00ff -+ -+/*P2_PRVIT*/ -+#define RSTV0910_P2_PRVIT 0xf33c -+#define FSTV0910_P2_DIS_VTHLOCK 0xf33c0040 -+#define FSTV0910_P2_E7_8VIT 0xf33c0020 -+#define FSTV0910_P2_E6_7VIT 0xf33c0010 -+#define FSTV0910_P2_E5_6VIT 0xf33c0008 -+#define FSTV0910_P2_E3_4VIT 0xf33c0004 -+#define FSTV0910_P2_E2_3VIT 0xf33c0002 -+#define FSTV0910_P2_E1_2VIT 0xf33c0001 -+ -+/*P2_VAVSRVIT*/ -+#define RSTV0910_P2_VAVSRVIT 0xf33d -+#define FSTV0910_P2_AMVIT 0xf33d0080 -+#define FSTV0910_P2_FROZENVIT 0xf33d0040 -+#define FSTV0910_P2_SNVIT 0xf33d0030 -+#define FSTV0910_P2_TOVVIT 0xf33d000c -+#define FSTV0910_P2_HYPVIT 0xf33d0003 -+ -+/*P2_VSTATUSVIT*/ -+#define RSTV0910_P2_VSTATUSVIT 0xf33e -+#define FSTV0910_P2_VITERBI_ON 0xf33e0080 -+#define FSTV0910_P2_END_LOOPVIT 0xf33e0040 -+#define FSTV0910_P2_VITERBI_DEPRF 0xf33e0020 -+#define FSTV0910_P2_PRFVIT 0xf33e0010 -+#define FSTV0910_P2_LOCKEDVIT 0xf33e0008 -+#define FSTV0910_P2_VITERBI_DELOCK 0xf33e0004 -+#define FSTV0910_P2_VIT_DEMODSEL 0xf33e0002 -+#define FSTV0910_P2_VITERBI_COMPOUT 0xf33e0001 -+ -+/*P2_VTHINUSE*/ -+#define RSTV0910_P2_VTHINUSE 0xf33f -+#define FSTV0910_P2_VIT_INUSE 0xf33f00ff -+ -+/*P2_KDIV12*/ -+#define RSTV0910_P2_KDIV12 0xf340 -+#define FSTV0910_P2_KDIV12_MANUAL 0xf3400080 -+#define FSTV0910_P2_K_DIVIDER_12 0xf340007f -+ -+/*P2_KDIV23*/ -+#define RSTV0910_P2_KDIV23 0xf341 -+#define FSTV0910_P2_KDIV23_MANUAL 0xf3410080 -+#define FSTV0910_P2_K_DIVIDER_23 0xf341007f -+ -+/*P2_KDIV34*/ -+#define RSTV0910_P2_KDIV34 0xf342 -+#define FSTV0910_P2_KDIV34_MANUAL 0xf3420080 -+#define FSTV0910_P2_K_DIVIDER_34 0xf342007f -+ -+/*P2_KDIV56*/ -+#define RSTV0910_P2_KDIV56 0xf343 -+#define FSTV0910_P2_KDIV56_MANUAL 0xf3430080 -+#define FSTV0910_P2_K_DIVIDER_56 0xf343007f -+ -+/*P2_KDIV67*/ -+#define RSTV0910_P2_KDIV67 0xf344 -+#define FSTV0910_P2_KDIV67_MANUAL 0xf3440080 -+#define FSTV0910_P2_K_DIVIDER_67 0xf344007f -+ -+/*P2_KDIV78*/ -+#define RSTV0910_P2_KDIV78 0xf345 -+#define FSTV0910_P2_KDIV78_MANUAL 0xf3450080 -+#define FSTV0910_P2_K_DIVIDER_78 0xf345007f -+ -+/*P2_PDELCTRL0*/ -+#define RSTV0910_P2_PDELCTRL0 0xf34f -+#define FSTV0910_P2_ISIOBS_MODE 0xf34f0030 -+#define FSTV0910_P2_PDELDIS_BITWISE 0xf34f0004 -+ -+/*P2_PDELCTRL1*/ -+#define RSTV0910_P2_PDELCTRL1 0xf350 -+#define FSTV0910_P2_INV_MISMASK 0xf3500080 -+#define FSTV0910_P2_FORCE_ACCEPTED 0xf3500040 -+#define FSTV0910_P2_FILTER_EN 0xf3500020 -+#define FSTV0910_P2_FORCE_PKTDELINUSE 0xf3500010 -+#define FSTV0910_P2_HYSTEN 0xf3500008 -+#define FSTV0910_P2_HYSTSWRST 0xf3500004 -+#define FSTV0910_P2_EN_MIS00 0xf3500002 -+#define FSTV0910_P2_ALGOSWRST 0xf3500001 -+ -+/*P2_PDELCTRL2*/ -+#define RSTV0910_P2_PDELCTRL2 0xf351 -+#define FSTV0910_P2_FORCE_CONTINUOUS 0xf3510080 -+#define FSTV0910_P2_RESET_UPKO_COUNT 0xf3510040 -+#define FSTV0910_P2_USER_PKTDELIN_NB 0xf3510020 -+#define FSTV0910_P2_DATA_UNBBSCRAMBLED 0xf3510008 -+#define FSTV0910_P2_FORCE_LONGPKT 0xf3510004 -+#define FSTV0910_P2_FRAME_MODE 0xf3510002 -+ -+/*P2_HYSTTHRESH*/ -+#define RSTV0910_P2_HYSTTHRESH 0xf354 -+#define FSTV0910_P2_DELIN_LOCKTHRES 0xf35400f0 -+#define FSTV0910_P2_DELIN_UNLOCKTHRES 0xf354000f -+ -+/*P2_ISIENTRY*/ -+#define RSTV0910_P2_ISIENTRY 0xf35e -+#define FSTV0910_P2_ISI_ENTRY 0xf35e00ff -+ -+/*P2_ISIBITENA*/ -+#define RSTV0910_P2_ISIBITENA 0xf35f -+#define FSTV0910_P2_ISI_BIT_EN 0xf35f00ff -+ -+/*P2_MATSTR1*/ -+#define RSTV0910_P2_MATSTR1 0xf360 -+#define FSTV0910_P2_MATYPE_CURRENT1 0xf36000ff -+ -+/*P2_MATSTR0*/ -+#define RSTV0910_P2_MATSTR0 0xf361 -+#define FSTV0910_P2_MATYPE_CURRENT0 0xf36100ff -+ -+/*P2_UPLSTR1*/ -+#define RSTV0910_P2_UPLSTR1 0xf362 -+#define FSTV0910_P2_UPL_CURRENT1 0xf36200ff -+ -+/*P2_UPLSTR0*/ -+#define RSTV0910_P2_UPLSTR0 0xf363 -+#define FSTV0910_P2_UPL_CURRENT0 0xf36300ff -+ -+/*P2_DFLSTR1*/ -+#define RSTV0910_P2_DFLSTR1 0xf364 -+#define FSTV0910_P2_DFL_CURRENT1 0xf36400ff -+ -+/*P2_DFLSTR0*/ -+#define RSTV0910_P2_DFLSTR0 0xf365 -+#define FSTV0910_P2_DFL_CURRENT0 0xf36500ff -+ -+/*P2_SYNCSTR*/ -+#define RSTV0910_P2_SYNCSTR 0xf366 -+#define FSTV0910_P2_SYNC_CURRENT 0xf36600ff -+ -+/*P2_SYNCDSTR1*/ -+#define RSTV0910_P2_SYNCDSTR1 0xf367 -+#define FSTV0910_P2_SYNCD_CURRENT1 0xf36700ff -+ -+/*P2_SYNCDSTR0*/ -+#define RSTV0910_P2_SYNCDSTR0 0xf368 -+#define FSTV0910_P2_SYNCD_CURRENT0 0xf36800ff -+ -+/*P2_PDELSTATUS1*/ -+#define RSTV0910_P2_PDELSTATUS1 0xf369 -+#define FSTV0910_P2_PKTDELIN_DELOCK 0xf3690080 -+#define FSTV0910_P2_SYNCDUPDFL_BADDFL 0xf3690040 -+#define FSTV0910_P2_CONTINUOUS_STREAM 0xf3690020 -+#define FSTV0910_P2_UNACCEPTED_STREAM 0xf3690010 -+#define FSTV0910_P2_BCH_ERROR_FLAG 0xf3690008 -+#define FSTV0910_P2_BBHCRCKO 0xf3690004 -+#define FSTV0910_P2_PKTDELIN_LOCK 0xf3690002 -+#define FSTV0910_P2_FIRST_LOCK 0xf3690001 -+ -+/*P2_PDELSTATUS2*/ -+#define RSTV0910_P2_PDELSTATUS2 0xf36a -+#define FSTV0910_P2_PKTDEL_DEMODSEL 0xf36a0080 -+#define FSTV0910_P2_FRAME_MODCOD 0xf36a007c -+#define FSTV0910_P2_FRAME_TYPE 0xf36a0003 -+ -+/*P2_BBFCRCKO1*/ -+#define RSTV0910_P2_BBFCRCKO1 0xf36b -+#define FSTV0910_P2_BBHCRC_KOCNT1 0xf36b00ff -+ -+/*P2_BBFCRCKO0*/ -+#define RSTV0910_P2_BBFCRCKO0 0xf36c -+#define FSTV0910_P2_BBHCRC_KOCNT0 0xf36c00ff -+ -+/*P2_UPCRCKO1*/ -+#define RSTV0910_P2_UPCRCKO1 0xf36d -+#define FSTV0910_P2_PKTCRC_KOCNT1 0xf36d00ff -+ -+/*P2_UPCRCKO0*/ -+#define RSTV0910_P2_UPCRCKO0 0xf36e -+#define FSTV0910_P2_PKTCRC_KOCNT0 0xf36e00ff -+ -+/*P2_PDELCTRL3*/ -+#define RSTV0910_P2_PDELCTRL3 0xf36f -+#define FSTV0910_P2_PKTDEL_CONTFAIL 0xf36f0080 -+#define FSTV0910_P2_PKTDEL_ENLONGPKT 0xf36f0040 -+#define FSTV0910_P2_NOFIFO_BCHERR 0xf36f0020 -+#define FSTV0910_P2_PKTDELIN_DELACMERR 0xf36f0010 -+#define FSTV0910_P2_SATURATE_BBPKTKO 0xf36f0004 -+#define FSTV0910_P2_PKTDEL_BCHERRCONT 0xf36f0002 -+#define FSTV0910_P2_ETHERNET_DISFCS 0xf36f0001 -+ -+/*P2_TSSTATEM*/ -+#define RSTV0910_P2_TSSTATEM 0xf370 -+#define FSTV0910_P2_TSDIL_ON 0xf3700080 -+#define FSTV0910_P2_TSSKIPRS_ON 0xf3700040 -+#define FSTV0910_P2_TSRS_ON 0xf3700020 -+#define FSTV0910_P2_TSDESCRAMB_ON 0xf3700010 -+#define FSTV0910_P2_TSFRAME_MODE 0xf3700008 -+#define FSTV0910_P2_TS_DISABLE 0xf3700004 -+#define FSTV0910_P2_TSACM_MODE 0xf3700002 -+#define FSTV0910_P2_TSOUT_NOSYNC 0xf3700001 -+ -+/*P2_TSCFGH*/ -+#define RSTV0910_P2_TSCFGH 0xf372 -+#define FSTV0910_P2_TSFIFO_DVBCI 0xf3720080 -+#define FSTV0910_P2_TSFIFO_SERIAL 0xf3720040 -+#define FSTV0910_P2_TSFIFO_TEIUPDATE 0xf3720020 -+#define FSTV0910_P2_TSFIFO_DUTY50 0xf3720010 -+#define FSTV0910_P2_TSFIFO_HSGNLOUT 0xf3720008 -+#define FSTV0910_P2_TSFIFO_ERRMODE 0xf3720006 -+#define FSTV0910_P2_RST_HWARE 0xf3720001 -+ -+/*P2_TSCFGM*/ -+#define RSTV0910_P2_TSCFGM 0xf373 -+#define FSTV0910_P2_TSFIFO_MANSPEED 0xf37300c0 -+#define FSTV0910_P2_TSFIFO_PERMDATA 0xf3730020 -+#define FSTV0910_P2_TSFIFO_NONEWSGNL 0xf3730010 -+#define FSTV0910_P2_NPD_SPECDVBS2 0xf3730004 -+#define FSTV0910_P2_TSFIFO_DPUNACTIVE 0xf3730002 -+#define FSTV0910_P2_TSFIFO_INVDATA 0xf3730001 -+ -+/*P2_TSCFGL*/ -+#define RSTV0910_P2_TSCFGL 0xf374 -+#define FSTV0910_P2_TSFIFO_BCLKDEL1CK 0xf37400c0 -+#define FSTV0910_P2_BCHERROR_MODE 0xf3740030 -+#define FSTV0910_P2_TSFIFO_NSGNL2DATA 0xf3740008 -+#define FSTV0910_P2_TSFIFO_EMBINDVB 0xf3740004 -+#define FSTV0910_P2_TSFIFO_BITSPEED 0xf3740003 -+ -+/*P2_TSINSDELH*/ -+#define RSTV0910_P2_TSINSDELH 0xf376 -+#define FSTV0910_P2_TSDEL_SYNCBYTE 0xf3760080 -+#define FSTV0910_P2_TSDEL_XXHEADER 0xf3760040 -+#define FSTV0910_P2_TSDEL_BBHEADER 0xf3760020 -+#define FSTV0910_P2_TSDEL_DATAFIELD 0xf3760010 -+#define FSTV0910_P2_TSINSDEL_ISCR 0xf3760008 -+#define FSTV0910_P2_TSINSDEL_NPD 0xf3760004 -+#define FSTV0910_P2_TSINSDEL_RSPARITY 0xf3760002 -+#define FSTV0910_P2_TSINSDEL_CRC8 0xf3760001 -+ -+/*P2_TSDIVN*/ -+#define RSTV0910_P2_TSDIVN 0xf379 -+#define FSTV0910_P2_TSFIFO_SPEEDMODE 0xf37900c0 -+#define FSTV0910_P2_BYTE_OVERSAMPLING 0xf3790038 -+#define FSTV0910_P2_TSFIFO_RISEOK 0xf3790007 -+ -+/*P2_TSCFG4*/ -+#define RSTV0910_P2_TSCFG4 0xf37a -+#define FSTV0910_P2_TSFIFO_TSSPEEDMODE 0xf37a00c0 -+#define FSTV0910_P2_TSFIFO_HIERSEL 0xf37a0020 -+#define FSTV0910_P2_TSFIFO_SPECTOKEN 0xf37a0010 -+#define FSTV0910_P2_TSFIFO_MAXMODE 0xf37a0008 -+#define FSTV0910_P2_TSFIFO_FRFORCEPKT 0xf37a0004 -+#define FSTV0910_P2_EXT_FECSPYIN 0xf37a0002 -+#define FSTV0910_P2_TSFIFO_DELSPEEDUP 0xf37a0001 -+ -+/*P2_TSSPEED*/ -+#define RSTV0910_P2_TSSPEED 0xf380 -+#define FSTV0910_P2_TSFIFO_OUTSPEED 0xf38000ff -+ -+/*P2_TSSTATUS*/ -+#define RSTV0910_P2_TSSTATUS 0xf381 -+#define FSTV0910_P2_TSFIFO_LINEOK 0xf3810080 -+#define FSTV0910_P2_TSFIFO_ERROR 0xf3810040 -+#define FSTV0910_P2_TSFIFO_DATA7 0xf3810020 -+#define FSTV0910_P2_TSFIFO_NOSYNC 0xf3810010 -+#define FSTV0910_P2_ISCR_INITIALIZED 0xf3810008 -+#define FSTV0910_P2_TSREGUL_ERROR 0xf3810004 -+#define FSTV0910_P2_SOFFIFO_UNREGUL 0xf3810002 -+#define FSTV0910_P2_DIL_READY 0xf3810001 -+ -+/*P2_TSSTATUS2*/ -+#define RSTV0910_P2_TSSTATUS2 0xf382 -+#define FSTV0910_P2_TSFIFO_DEMODSEL 0xf3820080 -+#define FSTV0910_P2_TSFIFOSPEED_STORE 0xf3820040 -+#define FSTV0910_P2_DILXX_RESET 0xf3820020 -+#define FSTV0910_P2_TSSPEED_IMPOSSIBLE 0xf3820010 -+#define FSTV0910_P2_TSFIFO_LINENOK 0xf3820008 -+#define FSTV0910_P2_TSFIFO_MUXSTREAM 0xf3820004 -+#define FSTV0910_P2_SCRAMBDETECT 0xf3820002 -+#define FSTV0910_P2_ULDTV67_FALSELOCK 0xf3820001 -+ -+/*P2_TSBITRATE1*/ -+#define RSTV0910_P2_TSBITRATE1 0xf383 -+#define FSTV0910_P2_TSFIFO_BITRATE1 0xf38300ff -+ -+/*P2_TSBITRATE0*/ -+#define RSTV0910_P2_TSBITRATE0 0xf384 -+#define FSTV0910_P2_TSFIFO_BITRATE0 0xf38400ff -+ -+/*P2_ERRCTRL1*/ -+#define RSTV0910_P2_ERRCTRL1 0xf398 -+#define FSTV0910_P2_ERR_SOURCE1 0xf39800f0 -+#define FSTV0910_P2_NUM_EVENT1 0xf3980007 -+ -+/*P2_ERRCNT12*/ -+#define RSTV0910_P2_ERRCNT12 0xf399 -+#define FSTV0910_P2_ERRCNT1_OLDVALUE 0xf3990080 -+#define FSTV0910_P2_ERR_CNT12 0xf399007f -+ -+/*P2_ERRCNT11*/ -+#define RSTV0910_P2_ERRCNT11 0xf39a -+#define FSTV0910_P2_ERR_CNT11 0xf39a00ff -+ -+/*P2_ERRCNT10*/ -+#define RSTV0910_P2_ERRCNT10 0xf39b -+#define FSTV0910_P2_ERR_CNT10 0xf39b00ff -+ -+/*P2_ERRCTRL2*/ -+#define RSTV0910_P2_ERRCTRL2 0xf39c -+#define FSTV0910_P2_ERR_SOURCE2 0xf39c00f0 -+#define FSTV0910_P2_NUM_EVENT2 0xf39c0007 -+ -+/*P2_ERRCNT22*/ -+#define RSTV0910_P2_ERRCNT22 0xf39d -+#define FSTV0910_P2_ERRCNT2_OLDVALUE 0xf39d0080 -+#define FSTV0910_P2_ERR_CNT22 0xf39d007f -+ -+/*P2_ERRCNT21*/ -+#define RSTV0910_P2_ERRCNT21 0xf39e -+#define FSTV0910_P2_ERR_CNT21 0xf39e00ff -+ -+/*P2_ERRCNT20*/ -+#define RSTV0910_P2_ERRCNT20 0xf39f -+#define FSTV0910_P2_ERR_CNT20 0xf39f00ff -+ -+/*P2_FECSPY*/ -+#define RSTV0910_P2_FECSPY 0xf3a0 -+#define FSTV0910_P2_SPY_ENABLE 0xf3a00080 -+#define FSTV0910_P2_NO_SYNCBYTE 0xf3a00040 -+#define FSTV0910_P2_SERIAL_MODE 0xf3a00020 -+#define FSTV0910_P2_UNUSUAL_PACKET 0xf3a00010 -+#define FSTV0910_P2_BERMETER_DATAMODE 0xf3a0000c -+#define FSTV0910_P2_BERMETER_LMODE 0xf3a00002 -+#define FSTV0910_P2_BERMETER_RESET 0xf3a00001 -+ -+/*P2_FSPYCFG*/ -+#define RSTV0910_P2_FSPYCFG 0xf3a1 -+#define FSTV0910_P2_FECSPY_INPUT 0xf3a100c0 -+#define FSTV0910_P2_RST_ON_ERROR 0xf3a10020 -+#define FSTV0910_P2_ONE_SHOT 0xf3a10010 -+#define FSTV0910_P2_I2C_MODE 0xf3a1000c -+#define FSTV0910_P2_SPY_HYSTERESIS 0xf3a10003 -+ -+/*P2_FSPYDATA*/ -+#define RSTV0910_P2_FSPYDATA 0xf3a2 -+#define FSTV0910_P2_SPY_STUFFING 0xf3a20080 -+#define FSTV0910_P2_NOERROR_PKTJITTER 0xf3a20040 -+#define FSTV0910_P2_SPY_CNULLPKT 0xf3a20020 -+#define FSTV0910_P2_SPY_OUTDATA_MODE 0xf3a2001f -+ -+/*P2_FSPYOUT*/ -+#define RSTV0910_P2_FSPYOUT 0xf3a3 -+#define FSTV0910_P2_FSPY_DIRECT 0xf3a30080 -+#define FSTV0910_P2_SPY_OUTDATA_BUS 0xf3a30038 -+#define FSTV0910_P2_STUFF_MODE 0xf3a30007 -+ -+/*P2_FSTATUS*/ -+#define RSTV0910_P2_FSTATUS 0xf3a4 -+#define FSTV0910_P2_SPY_ENDSIM 0xf3a40080 -+#define FSTV0910_P2_VALID_SIM 0xf3a40040 -+#define FSTV0910_P2_FOUND_SIGNAL 0xf3a40020 -+#define FSTV0910_P2_DSS_SYNCBYTE 0xf3a40010 -+#define FSTV0910_P2_RESULT_STATE 0xf3a4000f -+ -+/*P2_FBERCPT4*/ -+#define RSTV0910_P2_FBERCPT4 0xf3a8 -+#define FSTV0910_P2_FBERMETER_CPT4 0xf3a800ff -+ -+/*P2_FBERCPT3*/ -+#define RSTV0910_P2_FBERCPT3 0xf3a9 -+#define FSTV0910_P2_FBERMETER_CPT3 0xf3a900ff -+ -+/*P2_FBERCPT2*/ -+#define RSTV0910_P2_FBERCPT2 0xf3aa -+#define FSTV0910_P2_FBERMETER_CPT2 0xf3aa00ff -+ -+/*P2_FBERCPT1*/ -+#define RSTV0910_P2_FBERCPT1 0xf3ab -+#define FSTV0910_P2_FBERMETER_CPT1 0xf3ab00ff -+ -+/*P2_FBERCPT0*/ -+#define RSTV0910_P2_FBERCPT0 0xf3ac -+#define FSTV0910_P2_FBERMETER_CPT0 0xf3ac00ff -+ -+/*P2_FBERERR2*/ -+#define RSTV0910_P2_FBERERR2 0xf3ad -+#define FSTV0910_P2_FBERMETER_ERR2 0xf3ad00ff -+ -+/*P2_FBERERR1*/ -+#define RSTV0910_P2_FBERERR1 0xf3ae -+#define FSTV0910_P2_FBERMETER_ERR1 0xf3ae00ff -+ -+/*P2_FBERERR0*/ -+#define RSTV0910_P2_FBERERR0 0xf3af -+#define FSTV0910_P2_FBERMETER_ERR0 0xf3af00ff -+ -+/*P2_FSPYBER*/ -+#define RSTV0910_P2_FSPYBER 0xf3b2 -+#define FSTV0910_P2_FSPYOBS_XORREAD 0xf3b20040 -+#define FSTV0910_P2_FSPYBER_OBSMODE 0xf3b20020 -+#define FSTV0910_P2_FSPYBER_SYNCBYTE 0xf3b20010 -+#define FSTV0910_P2_FSPYBER_UNSYNC 0xf3b20008 -+#define FSTV0910_P2_FSPYBER_CTIME 0xf3b20007 -+ -+/*P2_SFERROR*/ -+#define RSTV0910_P2_SFERROR 0xf3c1 -+#define FSTV0910_P2_SFEC_REGERR_VIT 0xf3c100ff -+ -+/*P2_SFECSTATUS*/ -+#define RSTV0910_P2_SFECSTATUS 0xf3c3 -+#define FSTV0910_P2_SFEC_ON 0xf3c30080 -+#define FSTV0910_P2_SFEC_OFF 0xf3c30040 -+#define FSTV0910_P2_LOCKEDSFEC 0xf3c30008 -+#define FSTV0910_P2_SFEC_DELOCK 0xf3c30004 -+#define FSTV0910_P2_SFEC_DEMODSEL 0xf3c30002 -+#define FSTV0910_P2_SFEC_OVFON 0xf3c30001 -+ -+/*P2_SFKDIV12*/ -+#define RSTV0910_P2_SFKDIV12 0xf3c4 -+#define FSTV0910_P2_SFECKDIV12_MAN 0xf3c40080 -+#define FSTV0910_P2_SFEC_K_DIVIDER_12 0xf3c4007f -+ -+/*P2_SFKDIV23*/ -+#define RSTV0910_P2_SFKDIV23 0xf3c5 -+#define FSTV0910_P2_SFECKDIV23_MAN 0xf3c50080 -+#define FSTV0910_P2_SFEC_K_DIVIDER_23 0xf3c5007f -+ -+/*P2_SFKDIV34*/ -+#define RSTV0910_P2_SFKDIV34 0xf3c6 -+#define FSTV0910_P2_SFECKDIV34_MAN 0xf3c60080 -+#define FSTV0910_P2_SFEC_K_DIVIDER_34 0xf3c6007f -+ -+/*P2_SFKDIV56*/ -+#define RSTV0910_P2_SFKDIV56 0xf3c7 -+#define FSTV0910_P2_SFECKDIV56_MAN 0xf3c70080 -+#define FSTV0910_P2_SFEC_K_DIVIDER_56 0xf3c7007f -+ -+/*P2_SFKDIV67*/ -+#define RSTV0910_P2_SFKDIV67 0xf3c8 -+#define FSTV0910_P2_SFECKDIV67_MAN 0xf3c80080 -+#define FSTV0910_P2_SFEC_K_DIVIDER_67 0xf3c8007f -+ -+/*P2_SFKDIV78*/ -+#define RSTV0910_P2_SFKDIV78 0xf3c9 -+#define FSTV0910_P2_SFECKDIV78_MAN 0xf3c90080 -+#define FSTV0910_P2_SFEC_K_DIVIDER_78 0xf3c9007f -+ -+/*P2_SFSTATUS*/ -+#define RSTV0910_P2_SFSTATUS 0xf3cc -+#define FSTV0910_P2_SFEC_LINEOK 0xf3cc0080 -+#define FSTV0910_P2_SFEC_ERROR 0xf3cc0040 -+#define FSTV0910_P2_SFEC_DATA7 0xf3cc0020 -+#define FSTV0910_P2_SFEC_PKTDNBRFAIL 0xf3cc0010 -+#define FSTV0910_P2_TSSFEC_DEMODSEL 0xf3cc0008 -+#define FSTV0910_P2_SFEC_NOSYNC 0xf3cc0004 -+#define FSTV0910_P2_SFEC_UNREGULA 0xf3cc0002 -+#define FSTV0910_P2_SFEC_READY 0xf3cc0001 -+ -+/*P2_SFDLYSET2*/ -+#define RSTV0910_P2_SFDLYSET2 0xf3d0 -+#define FSTV0910_P2_SFEC_OFFSET 0xf3d000c0 -+#define FSTV0910_P2_RST_SFEC 0xf3d00008 -+#define FSTV0910_P2_DILDLINE_ERROR 0xf3d00004 -+#define FSTV0910_P2_SFEC_DISABLE 0xf3d00002 -+#define FSTV0910_P2_SFEC_UNREGUL 0xf3d00001 -+ -+/*P2_SFERRCTRL*/ -+#define RSTV0910_P2_SFERRCTRL 0xf3d8 -+#define FSTV0910_P2_SFEC_ERR_SOURCE 0xf3d800f0 -+#define FSTV0910_P2_SFEC_NUM_EVENT 0xf3d80007 -+ -+/*P2_SFERRCNT2*/ -+#define RSTV0910_P2_SFERRCNT2 0xf3d9 -+#define FSTV0910_P2_SFERRC_OLDVALUE 0xf3d90080 -+#define FSTV0910_P2_SFEC_ERR_CNT2 0xf3d9007f -+ -+/*P2_SFERRCNT1*/ -+#define RSTV0910_P2_SFERRCNT1 0xf3da -+#define FSTV0910_P2_SFEC_ERR_CNT1 0xf3da00ff -+ -+/*P2_SFERRCNT0*/ -+#define RSTV0910_P2_SFERRCNT0 0xf3db -+#define FSTV0910_P2_SFEC_ERR_CNT0 0xf3db00ff -+ -+/*P1_IQCONST*/ -+#define RSTV0910_P1_IQCONST 0xf400 -+#define FSTV0910_P1_CONSTEL_SELECT 0xf4000060 -+#define FSTV0910_P1_IQSYMB_SEL 0xf400001f -+ -+/*P1_NOSCFG*/ -+#define RSTV0910_P1_NOSCFG 0xf401 -+#define FSTV0910_P1_DIS_ACMRATIO 0xf4010080 -+#define FSTV0910_P1_NOSIN_EGALSEL 0xf4010040 -+#define FSTV0910_P1_DUMMYPL_NOSDATA 0xf4010020 -+#define FSTV0910_P1_NOSPLH_BETA 0xf4010018 -+#define FSTV0910_P1_NOSDATA_BETA 0xf4010007 -+ -+/*P1_ISYMB*/ -+#define RSTV0910_P1_ISYMB 0xf402 -+#define FSTV0910_P1_I_SYMBOL 0xf40201ff -+ -+/*P1_QSYMB*/ -+#define RSTV0910_P1_QSYMB 0xf403 -+#define FSTV0910_P1_Q_SYMBOL 0xf40301ff -+ -+/*P1_AGC1CFG*/ -+#define RSTV0910_P1_AGC1CFG 0xf404 -+#define FSTV0910_P1_DC_FROZEN 0xf4040080 -+#define FSTV0910_P1_DC_CORRECT 0xf4040040 -+#define FSTV0910_P1_AMM_FROZEN 0xf4040020 -+#define FSTV0910_P1_AMM_CORRECT 0xf4040010 -+#define FSTV0910_P1_QUAD_FROZEN 0xf4040008 -+#define FSTV0910_P1_QUAD_CORRECT 0xf4040004 -+#define FSTV0910_P1_DCCOMP_SLOW 0xf4040002 -+#define FSTV0910_P1_IQMISM_SLOW 0xf4040001 -+ -+/*P1_AGC1CN*/ -+#define RSTV0910_P1_AGC1CN 0xf406 -+#define FSTV0910_P1_AGC1_LOCKED 0xf4060080 -+#define FSTV0910_P1_AGC1_OVERFLOW 0xf4060040 -+#define FSTV0910_P1_AGC1_NOSLOWLK 0xf4060020 -+#define FSTV0910_P1_AGC1_MINPOWER 0xf4060010 -+#define FSTV0910_P1_AGCOUT_FAST 0xf4060008 -+#define FSTV0910_P1_AGCIQ_BETA 0xf4060007 -+ -+/*P1_AGC1REF*/ -+#define RSTV0910_P1_AGC1REF 0xf407 -+#define FSTV0910_P1_AGCIQ_REF 0xf40700ff -+ -+/*P1_IDCCOMP*/ -+#define RSTV0910_P1_IDCCOMP 0xf408 -+#define FSTV0910_P1_IAVERAGE_ADJ 0xf40801ff -+ -+/*P1_QDCCOMP*/ -+#define RSTV0910_P1_QDCCOMP 0xf409 -+#define FSTV0910_P1_QAVERAGE_ADJ 0xf40901ff -+ -+/*P1_POWERI*/ -+#define RSTV0910_P1_POWERI 0xf40a -+#define FSTV0910_P1_POWER_I 0xf40a00ff -+ -+/*P1_POWERQ*/ -+#define RSTV0910_P1_POWERQ 0xf40b -+#define FSTV0910_P1_POWER_Q 0xf40b00ff -+ -+/*P1_AGC1AMM*/ -+#define RSTV0910_P1_AGC1AMM 0xf40c -+#define FSTV0910_P1_AMM_VALUE 0xf40c00ff -+ -+/*P1_AGC1QUAD*/ -+#define RSTV0910_P1_AGC1QUAD 0xf40d -+#define FSTV0910_P1_QUAD_VALUE 0xf40d01ff -+ -+/*P1_AGCIQIN1*/ -+#define RSTV0910_P1_AGCIQIN1 0xf40e -+#define FSTV0910_P1_AGCIQ_VALUE1 0xf40e00ff -+ -+/*P1_AGCIQIN0*/ -+#define RSTV0910_P1_AGCIQIN0 0xf40f -+#define FSTV0910_P1_AGCIQ_VALUE0 0xf40f00ff -+ -+/*P1_DEMOD*/ -+#define RSTV0910_P1_DEMOD 0xf410 -+#define FSTV0910_P1_MANUALS2_ROLLOFF 0xf4100080 -+#define FSTV0910_P1_SPECINV_CONTROL 0xf4100030 -+#define FSTV0910_P1_MANUALSX_ROLLOFF 0xf4100004 -+#define FSTV0910_P1_ROLLOFF_CONTROL 0xf4100003 -+ -+/*P1_DMDMODCOD*/ -+#define RSTV0910_P1_DMDMODCOD 0xf411 -+#define FSTV0910_P1_MANUAL_MODCOD 0xf4110080 -+#define FSTV0910_P1_DEMOD_MODCOD 0xf411007c -+#define FSTV0910_P1_DEMOD_TYPE 0xf4110003 -+ -+/*P1_DSTATUS*/ -+#define RSTV0910_P1_DSTATUS 0xf412 -+#define FSTV0910_P1_CAR_LOCK 0xf4120080 -+#define FSTV0910_P1_TMGLOCK_QUALITY 0xf4120060 -+#define FSTV0910_P1_SDVBS1_ENABLE 0xf4120010 -+#define FSTV0910_P1_LOCK_DEFINITIF 0xf4120008 -+#define FSTV0910_P1_TIMING_IS_LOCKED 0xf4120004 -+#define FSTV0910_P1_DEMOD_SYSCFG 0xf4120002 -+#define FSTV0910_P1_OVADC_DETECT 0xf4120001 -+ -+/*P1_DSTATUS2*/ -+#define RSTV0910_P1_DSTATUS2 0xf413 -+#define FSTV0910_P1_DEMOD_DELOCK 0xf4130080 -+#define FSTV0910_P1_DEMOD_TIMEOUT 0xf4130040 -+#define FSTV0910_P1_MODCODRQ_SYNCTAG 0xf4130020 -+#define FSTV0910_P1_POLYPH_SATEVENT 0xf4130010 -+#define FSTV0910_P1_AGC1_NOSIGNALACK 0xf4130008 -+#define FSTV0910_P1_AGC2_OVERFLOW 0xf4130004 -+#define FSTV0910_P1_CFR_OVERFLOW 0xf4130002 -+#define FSTV0910_P1_GAMMA_OVERUNDER 0xf4130001 -+ -+/*P1_DMDCFGMD*/ -+#define RSTV0910_P1_DMDCFGMD 0xf414 -+#define FSTV0910_P1_DVBS2_ENABLE 0xf4140080 -+#define FSTV0910_P1_DVBS1_ENABLE 0xf4140040 -+#define FSTV0910_P1_SCAN_ENABLE 0xf4140010 -+#define FSTV0910_P1_CFR_AUTOSCAN 0xf4140008 -+#define FSTV0910_P1_NOFORCE_RELOCK 0xf4140004 -+#define FSTV0910_P1_TUN_RNG 0xf4140003 -+ -+/*P1_DMDCFG2*/ -+#define RSTV0910_P1_DMDCFG2 0xf415 -+#define FSTV0910_P1_AGC1_WAITLOCK 0xf4150080 -+#define FSTV0910_P1_S1S2_SEQUENTIAL 0xf4150040 -+#define FSTV0910_P1_BLINDPEA_MODE 0xf4150020 -+#define FSTV0910_P1_INFINITE_RELOCK 0xf4150010 -+#define FSTV0910_P1_BWOFFSET_COLDWARM 0xf4150008 -+#define FSTV0910_P1_TMGLOCK_NSCANSTOP 0xf4150004 -+#define FSTV0910_P1_COARSE_LK3MODE 0xf4150002 -+#define FSTV0910_P1_COARSE_LK2MODE 0xf4150001 -+ -+/*P1_DMDISTATE*/ -+#define RSTV0910_P1_DMDISTATE 0xf416 -+#define FSTV0910_P1_I2C_NORESETDMODE 0xf4160080 -+#define FSTV0910_P1_FORCE_ETAPED 0xf4160040 -+#define FSTV0910_P1_SDMDRST_DIRCLK 0xf4160020 -+#define FSTV0910_P1_I2C_DEMOD_MODE 0xf416001f -+ -+/*P1_DMDT0M*/ -+#define RSTV0910_P1_DMDT0M 0xf417 -+#define FSTV0910_P1_DMDT0_MIN 0xf41700ff -+ -+/*P1_DMDSTATE*/ -+#define RSTV0910_P1_DMDSTATE 0xf41b -+#define FSTV0910_P1_DEMOD_LOCKED 0xf41b0080 -+#define FSTV0910_P1_HEADER_MODE 0xf41b0060 -+#define FSTV0910_P1_DEMOD_MODE 0xf41b001f -+ -+/*P1_DMDFLYW*/ -+#define RSTV0910_P1_DMDFLYW 0xf41c -+#define FSTV0910_P1_I2C_IRQVAL 0xf41c00f0 -+#define FSTV0910_P1_FLYWHEEL_CPT 0xf41c000f -+ -+/*P1_DSTATUS3*/ -+#define RSTV0910_P1_DSTATUS3 0xf41d -+#define FSTV0910_P1_CFR_ZIGZAG 0xf41d0080 -+#define FSTV0910_P1_DEMOD_CFGMODE 0xf41d0060 -+#define FSTV0910_P1_GAMMA_LOWBAUDRATE 0xf41d0010 -+#define FSTV0910_P1_RELOCK_MODE 0xf41d0008 -+#define FSTV0910_P1_DEMOD_FAIL 0xf41d0004 -+#define FSTV0910_P1_ETAPE1A_DVBXMEM 0xf41d0003 -+ -+/*P1_DMDCFG3*/ -+#define RSTV0910_P1_DMDCFG3 0xf41e -+#define FSTV0910_P1_DVBS1_TMGWAIT 0xf41e0080 -+#define FSTV0910_P1_NO_BWCENTERING 0xf41e0040 -+#define FSTV0910_P1_INV_SEQSRCH 0xf41e0020 -+#define FSTV0910_P1_DIS_SFRUPLOW_TRK 0xf41e0010 -+#define FSTV0910_P1_NOSTOP_FIFOFULL 0xf41e0008 -+#define FSTV0910_P1_LOCKTIME_MODE 0xf41e0007 -+ -+/*P1_DMDCFG4*/ -+#define RSTV0910_P1_DMDCFG4 0xf41f -+#define FSTV0910_P1_DIS_VITLOCK 0xf41f0080 -+#define FSTV0910_P1_S1S2TOUT_FAST 0xf41f0040 -+#define FSTV0910_P1_DEMOD_FASTLOCK 0xf41f0020 -+#define FSTV0910_P1_S1HIER_ENABLE 0xf41f0010 -+#define FSTV0910_P1_TUNER_NRELAUNCH 0xf41f0008 -+#define FSTV0910_P1_DIS_CLKENABLE 0xf41f0004 -+#define FSTV0910_P1_DIS_HDRDIVLOCK 0xf41f0002 -+#define FSTV0910_P1_NO_TNRWBINIT 0xf41f0001 -+ -+/*P1_CORRELMANT*/ -+#define RSTV0910_P1_CORRELMANT 0xf420 -+#define FSTV0910_P1_CORREL_MANT 0xf42000ff -+ -+/*P1_CORRELABS*/ -+#define RSTV0910_P1_CORRELABS 0xf421 -+#define FSTV0910_P1_CORREL_ABS 0xf42100ff -+ -+/*P1_CORRELEXP*/ -+#define RSTV0910_P1_CORRELEXP 0xf422 -+#define FSTV0910_P1_CORREL_ABSEXP 0xf42200f0 -+#define FSTV0910_P1_CORREL_EXP 0xf422000f -+ -+/*P1_PLHMODCOD*/ -+#define RSTV0910_P1_PLHMODCOD 0xf424 -+#define FSTV0910_P1_SPECINV_DEMOD 0xf4240080 -+#define FSTV0910_P1_PLH_MODCOD 0xf424007c -+#define FSTV0910_P1_PLH_TYPE 0xf4240003 -+ -+/*P1_DMDREG*/ -+#define RSTV0910_P1_DMDREG 0xf425 -+#define FSTV0910_P1_EXTPSK_MODE 0xf4250080 -+#define FSTV0910_P1_HIER_SHORTFRAME 0xf4250002 -+#define FSTV0910_P1_DECIM_PLFRAMES 0xf4250001 -+ -+/*P1_AGC2O*/ -+#define RSTV0910_P1_AGC2O 0xf42c -+#define FSTV0910_P1_CSTENV_MODE 0xf42c00c0 -+#define FSTV0910_P1_AGC2_LKSQRT 0xf42c0020 -+#define FSTV0910_P1_AGC2_LKMODE 0xf42c0010 -+#define FSTV0910_P1_AGC2_LKEQUA 0xf42c0008 -+#define FSTV0910_P1_AGC2_COEF 0xf42c0007 -+ -+/*P1_AGC2REF*/ -+#define RSTV0910_P1_AGC2REF 0xf42d -+#define FSTV0910_P1_AGC2_REF 0xf42d00ff -+ -+/*P1_AGC1ADJ*/ -+#define RSTV0910_P1_AGC1ADJ 0xf42e -+#define FSTV0910_P1_AGC1ADJ_MANUAL 0xf42e0080 -+#define FSTV0910_P1_AGC1_ADJUSTED 0xf42e007f -+ -+/*P1_AGC2I1*/ -+#define RSTV0910_P1_AGC2I1 0xf436 -+#define FSTV0910_P1_AGC2_INTEGRATOR1 0xf43600ff -+ -+/*P1_AGC2I0*/ -+#define RSTV0910_P1_AGC2I0 0xf437 -+#define FSTV0910_P1_AGC2_INTEGRATOR0 0xf43700ff -+ -+/*P1_CARCFG*/ -+#define RSTV0910_P1_CARCFG 0xf438 -+#define FSTV0910_P1_CFRUPLOW_AUTO 0xf4380080 -+#define FSTV0910_P1_CFRUPLOW_TEST 0xf4380040 -+#define FSTV0910_P1_WIDE_FREQDET 0xf4380020 -+#define FSTV0910_P1_CARHDR_NODIV8 0xf4380010 -+#define FSTV0910_P1_I2C_ROTA 0xf4380008 -+#define FSTV0910_P1_ROTAON 0xf4380004 -+#define FSTV0910_P1_PH_DET_ALGO 0xf4380003 -+ -+/*P1_ACLC*/ -+#define RSTV0910_P1_ACLC 0xf439 -+#define FSTV0910_P1_CARS1_ANOSAUTO 0xf4390040 -+#define FSTV0910_P1_CAR_ALPHA_MANT 0xf4390030 -+#define FSTV0910_P1_CAR_ALPHA_EXP 0xf439000f -+ -+/*P1_BCLC*/ -+#define RSTV0910_P1_BCLC 0xf43a -+#define FSTV0910_P1_CARS1_BNOSAUTO 0xf43a0040 -+#define FSTV0910_P1_CAR_BETA_MANT 0xf43a0030 -+#define FSTV0910_P1_CAR_BETA_EXP 0xf43a000f -+ -+/*P1_CARFREQ*/ -+#define RSTV0910_P1_CARFREQ 0xf43d -+#define FSTV0910_P1_KC_COARSE_EXP 0xf43d00f0 -+#define FSTV0910_P1_BETA_FREQ 0xf43d000f -+ -+/*P1_CARHDR*/ -+#define RSTV0910_P1_CARHDR 0xf43e -+#define FSTV0910_P1_K_FREQ_HDR 0xf43e00ff -+ -+/*P1_LDT*/ -+#define RSTV0910_P1_LDT 0xf43f -+#define FSTV0910_P1_CARLOCK_THRES 0xf43f01ff -+ -+/*P1_LDT2*/ -+#define RSTV0910_P1_LDT2 0xf440 -+#define FSTV0910_P1_CARLOCK_THRES2 0xf44001ff -+ -+/*P1_CFRICFG*/ -+#define RSTV0910_P1_CFRICFG 0xf441 -+#define FSTV0910_P1_CFRINIT_UNVALRNG 0xf4410080 -+#define FSTV0910_P1_CFRINIT_LUNVALCPT 0xf4410040 -+#define FSTV0910_P1_CFRINIT_ABORTDBL 0xf4410020 -+#define FSTV0910_P1_CFRINIT_ABORTPRED 0xf4410010 -+#define FSTV0910_P1_CFRINIT_UNVALSKIP 0xf4410008 -+#define FSTV0910_P1_CFRINIT_CSTINC 0xf4410004 -+#define FSTV0910_P1_CFRIROLL_GARDER 0xf4410002 -+#define FSTV0910_P1_NEG_CFRSTEP 0xf4410001 -+ -+/*P1_CFRUP1*/ -+#define RSTV0910_P1_CFRUP1 0xf442 -+#define FSTV0910_P1_CFR_UP1 0xf44201ff -+ -+/*P1_CFRUP0*/ -+#define RSTV0910_P1_CFRUP0 0xf443 -+#define FSTV0910_P1_CFR_UP0 0xf44300ff -+ -+/*P1_CFRIBASE1*/ -+#define RSTV0910_P1_CFRIBASE1 0xf444 -+#define FSTV0910_P1_CFRINIT_BASE1 0xf44400ff -+ -+/*P1_CFRIBASE0*/ -+#define RSTV0910_P1_CFRIBASE0 0xf445 -+#define FSTV0910_P1_CFRINIT_BASE0 0xf44500ff -+ -+/*P1_CFRLOW1*/ -+#define RSTV0910_P1_CFRLOW1 0xf446 -+#define FSTV0910_P1_CFR_LOW1 0xf44601ff -+ -+/*P1_CFRLOW0*/ -+#define RSTV0910_P1_CFRLOW0 0xf447 -+#define FSTV0910_P1_CFR_LOW0 0xf44700ff -+ -+/*P1_CFRINIT1*/ -+#define RSTV0910_P1_CFRINIT1 0xf448 -+#define FSTV0910_P1_CFR_INIT1 0xf44801ff -+ -+/*P1_CFRINIT0*/ -+#define RSTV0910_P1_CFRINIT0 0xf449 -+#define FSTV0910_P1_CFR_INIT0 0xf44900ff -+ -+/*P1_CFRINC1*/ -+#define RSTV0910_P1_CFRINC1 0xf44a -+#define FSTV0910_P1_MANUAL_CFRINC 0xf44a0080 -+#define FSTV0910_P1_CFR_INC1 0xf44a003f -+ -+/*P1_CFRINC0*/ -+#define RSTV0910_P1_CFRINC0 0xf44b -+#define FSTV0910_P1_CFR_INC0 0xf44b00ff -+ -+/*P1_CFR2*/ -+#define RSTV0910_P1_CFR2 0xf44c -+#define FSTV0910_P1_CAR_FREQ2 0xf44c01ff -+ -+/*P1_CFR1*/ -+#define RSTV0910_P1_CFR1 0xf44d -+#define FSTV0910_P1_CAR_FREQ1 0xf44d00ff -+ -+/*P1_CFR0*/ -+#define RSTV0910_P1_CFR0 0xf44e -+#define FSTV0910_P1_CAR_FREQ0 0xf44e00ff -+ -+/*P1_LDI*/ -+#define RSTV0910_P1_LDI 0xf44f -+#define FSTV0910_P1_LOCK_DET_INTEGR 0xf44f01ff -+ -+/*P1_TMGCFG*/ -+#define RSTV0910_P1_TMGCFG 0xf450 -+#define FSTV0910_P1_TMGLOCK_BETA 0xf45000c0 -+#define FSTV0910_P1_DO_TIMING_CORR 0xf4500010 -+#define FSTV0910_P1_MANUAL_SCAN 0xf450000c -+#define FSTV0910_P1_TMG_MINFREQ 0xf4500003 -+ -+/*P1_RTC*/ -+#define RSTV0910_P1_RTC 0xf451 -+#define FSTV0910_P1_TMGALPHA_EXP 0xf45100f0 -+#define FSTV0910_P1_TMGBETA_EXP 0xf451000f -+ -+/*P1_RTCS2*/ -+#define RSTV0910_P1_RTCS2 0xf452 -+#define FSTV0910_P1_TMGALPHAS2_EXP 0xf45200f0 -+#define FSTV0910_P1_TMGBETAS2_EXP 0xf452000f -+ -+/*P1_TMGTHRISE*/ -+#define RSTV0910_P1_TMGTHRISE 0xf453 -+#define FSTV0910_P1_TMGLOCK_THRISE 0xf45300ff -+ -+/*P1_TMGTHFALL*/ -+#define RSTV0910_P1_TMGTHFALL 0xf454 -+#define FSTV0910_P1_TMGLOCK_THFALL 0xf45400ff -+ -+/*P1_SFRUPRATIO*/ -+#define RSTV0910_P1_SFRUPRATIO 0xf455 -+#define FSTV0910_P1_SFR_UPRATIO 0xf45500ff -+ -+/*P1_SFRLOWRATIO*/ -+#define RSTV0910_P1_SFRLOWRATIO 0xf456 -+#define FSTV0910_P1_SFR_LOWRATIO 0xf45600ff -+ -+/*P1_KTTMG*/ -+#define RSTV0910_P1_KTTMG 0xf457 -+#define FSTV0910_P1_KT_TMG_EXP 0xf45700f0 -+ -+/*P1_KREFTMG*/ -+#define RSTV0910_P1_KREFTMG 0xf458 -+#define FSTV0910_P1_KREF_TMG 0xf45800ff -+ -+/*P1_SFRSTEP*/ -+#define RSTV0910_P1_SFRSTEP 0xf459 -+#define FSTV0910_P1_SFR_SCANSTEP 0xf45900f0 -+#define FSTV0910_P1_SFR_CENTERSTEP 0xf459000f -+ -+/*P1_TMGCFG2*/ -+#define RSTV0910_P1_TMGCFG2 0xf45a -+#define FSTV0910_P1_KREFTMG2_DECMODE 0xf45a00c0 -+#define FSTV0910_P1_DIS_AUTOSAMP 0xf45a0008 -+#define FSTV0910_P1_SCANINIT_QUART 0xf45a0004 -+#define FSTV0910_P1_NOTMG_DVBS1DERAT 0xf45a0002 -+#define FSTV0910_P1_SFRRATIO_FINE 0xf45a0001 -+ -+/*P1_KREFTMG2*/ -+#define RSTV0910_P1_KREFTMG2 0xf45b -+#define FSTV0910_P1_KREF_TMG2 0xf45b00ff -+ -+/*P1_TMGCFG3*/ -+#define RSTV0910_P1_TMGCFG3 0xf45d -+#define FSTV0910_P1_CFRINC_MODE 0xf45d0070 -+#define FSTV0910_P1_CONT_TMGCENTER 0xf45d0008 -+#define FSTV0910_P1_AUTO_GUP 0xf45d0004 -+#define FSTV0910_P1_AUTO_GLOW 0xf45d0002 -+#define FSTV0910_P1_SFRVAL_MINMODE 0xf45d0001 -+ -+/*P1_SFRINIT1*/ -+#define RSTV0910_P1_SFRINIT1 0xf45e -+#define FSTV0910_P1_SFR_INIT1 0xf45e00ff -+ -+/*P1_SFRINIT0*/ -+#define RSTV0910_P1_SFRINIT0 0xf45f -+#define FSTV0910_P1_SFR_INIT0 0xf45f00ff -+ -+/*P1_SFRUP1*/ -+#define RSTV0910_P1_SFRUP1 0xf460 -+#define FSTV0910_P1_SYMB_FREQ_UP1 0xf46000ff -+ -+/*P1_SFRUP0*/ -+#define RSTV0910_P1_SFRUP0 0xf461 -+#define FSTV0910_P1_SYMB_FREQ_UP0 0xf46100ff -+ -+/*P1_SFRLOW1*/ -+#define RSTV0910_P1_SFRLOW1 0xf462 -+#define FSTV0910_P1_SYMB_FREQ_LOW1 0xf46200ff -+ -+/*P1_SFRLOW0*/ -+#define RSTV0910_P1_SFRLOW0 0xf463 -+#define FSTV0910_P1_SYMB_FREQ_LOW0 0xf46300ff -+ -+/*P1_SFR3*/ -+#define RSTV0910_P1_SFR3 0xf464 -+#define FSTV0910_P1_SYMB_FREQ3 0xf46400ff -+ -+/*P1_SFR2*/ -+#define RSTV0910_P1_SFR2 0xf465 -+#define FSTV0910_P1_SYMB_FREQ2 0xf46500ff -+ -+/*P1_SFR1*/ -+#define RSTV0910_P1_SFR1 0xf466 -+#define FSTV0910_P1_SYMB_FREQ1 0xf46600ff -+ -+/*P1_SFR0*/ -+#define RSTV0910_P1_SFR0 0xf467 -+#define FSTV0910_P1_SYMB_FREQ0 0xf46700ff -+ -+/*P1_TMGREG2*/ -+#define RSTV0910_P1_TMGREG2 0xf468 -+#define FSTV0910_P1_TMGREG2 0xf46800ff -+ -+/*P1_TMGREG1*/ -+#define RSTV0910_P1_TMGREG1 0xf469 -+#define FSTV0910_P1_TMGREG1 0xf46900ff -+ -+/*P1_TMGREG0*/ -+#define RSTV0910_P1_TMGREG0 0xf46a -+#define FSTV0910_P1_TMGREG0 0xf46a00ff -+ -+/*P1_TMGLOCK1*/ -+#define RSTV0910_P1_TMGLOCK1 0xf46b -+#define FSTV0910_P1_TMGLOCK_LEVEL1 0xf46b01ff -+ -+/*P1_TMGLOCK0*/ -+#define RSTV0910_P1_TMGLOCK0 0xf46c -+#define FSTV0910_P1_TMGLOCK_LEVEL0 0xf46c00ff -+ -+/*P1_TMGOBS*/ -+#define RSTV0910_P1_TMGOBS 0xf46d -+#define FSTV0910_P1_ROLLOFF_STATUS 0xf46d00c0 -+#define FSTV0910_P1_SCAN_SIGN 0xf46d0030 -+#define FSTV0910_P1_TMG_SCANNING 0xf46d0008 -+#define FSTV0910_P1_CHCENTERING_MODE 0xf46d0004 -+#define FSTV0910_P1_TMG_SCANFAIL 0xf46d0002 -+ -+/*P1_EQUALCFG*/ -+#define RSTV0910_P1_EQUALCFG 0xf46f -+#define FSTV0910_P1_NOTMG_NEGALWAIT 0xf46f0080 -+#define FSTV0910_P1_EQUAL_ON 0xf46f0040 -+#define FSTV0910_P1_SEL_EQUALCOR 0xf46f0038 -+#define FSTV0910_P1_MU_EQUALDFE 0xf46f0007 -+ -+/*P1_EQUAI1*/ -+#define RSTV0910_P1_EQUAI1 0xf470 -+#define FSTV0910_P1_EQUA_ACCI1 0xf47001ff -+ -+/*P1_EQUAQ1*/ -+#define RSTV0910_P1_EQUAQ1 0xf471 -+#define FSTV0910_P1_EQUA_ACCQ1 0xf47101ff -+ -+/*P1_EQUAI2*/ -+#define RSTV0910_P1_EQUAI2 0xf472 -+#define FSTV0910_P1_EQUA_ACCI2 0xf47201ff -+ -+/*P1_EQUAQ2*/ -+#define RSTV0910_P1_EQUAQ2 0xf473 -+#define FSTV0910_P1_EQUA_ACCQ2 0xf47301ff -+ -+/*P1_EQUAI3*/ -+#define RSTV0910_P1_EQUAI3 0xf474 -+#define FSTV0910_P1_EQUA_ACCI3 0xf47401ff -+ -+/*P1_EQUAQ3*/ -+#define RSTV0910_P1_EQUAQ3 0xf475 -+#define FSTV0910_P1_EQUA_ACCQ3 0xf47501ff -+ -+/*P1_EQUAI4*/ -+#define RSTV0910_P1_EQUAI4 0xf476 -+#define FSTV0910_P1_EQUA_ACCI4 0xf47601ff -+ -+/*P1_EQUAQ4*/ -+#define RSTV0910_P1_EQUAQ4 0xf477 -+#define FSTV0910_P1_EQUA_ACCQ4 0xf47701ff -+ -+/*P1_EQUAI5*/ -+#define RSTV0910_P1_EQUAI5 0xf478 -+#define FSTV0910_P1_EQUA_ACCI5 0xf47801ff -+ -+/*P1_EQUAQ5*/ -+#define RSTV0910_P1_EQUAQ5 0xf479 -+#define FSTV0910_P1_EQUA_ACCQ5 0xf47901ff -+ -+/*P1_EQUAI6*/ -+#define RSTV0910_P1_EQUAI6 0xf47a -+#define FSTV0910_P1_EQUA_ACCI6 0xf47a01ff -+ -+/*P1_EQUAQ6*/ -+#define RSTV0910_P1_EQUAQ6 0xf47b -+#define FSTV0910_P1_EQUA_ACCQ6 0xf47b01ff -+ -+/*P1_EQUAI7*/ -+#define RSTV0910_P1_EQUAI7 0xf47c -+#define FSTV0910_P1_EQUA_ACCI7 0xf47c01ff -+ -+/*P1_EQUAQ7*/ -+#define RSTV0910_P1_EQUAQ7 0xf47d -+#define FSTV0910_P1_EQUA_ACCQ7 0xf47d01ff -+ -+/*P1_EQUAI8*/ -+#define RSTV0910_P1_EQUAI8 0xf47e -+#define FSTV0910_P1_EQUA_ACCI8 0xf47e01ff -+ -+/*P1_EQUAQ8*/ -+#define RSTV0910_P1_EQUAQ8 0xf47f -+#define FSTV0910_P1_EQUA_ACCQ8 0xf47f01ff -+ -+/*P1_NNOSDATAT1*/ -+#define RSTV0910_P1_NNOSDATAT1 0xf480 -+#define FSTV0910_P1_NOSDATAT_NORMED1 0xf48000ff -+ -+/*P1_NNOSDATAT0*/ -+#define RSTV0910_P1_NNOSDATAT0 0xf481 -+#define FSTV0910_P1_NOSDATAT_NORMED0 0xf48100ff -+ -+/*P1_NNOSDATA1*/ -+#define RSTV0910_P1_NNOSDATA1 0xf482 -+#define FSTV0910_P1_NOSDATA_NORMED1 0xf48200ff -+ -+/*P1_NNOSDATA0*/ -+#define RSTV0910_P1_NNOSDATA0 0xf483 -+#define FSTV0910_P1_NOSDATA_NORMED0 0xf48300ff -+ -+/*P1_NNOSPLHT1*/ -+#define RSTV0910_P1_NNOSPLHT1 0xf484 -+#define FSTV0910_P1_NOSPLHT_NORMED1 0xf48400ff -+ -+/*P1_NNOSPLHT0*/ -+#define RSTV0910_P1_NNOSPLHT0 0xf485 -+#define FSTV0910_P1_NOSPLHT_NORMED0 0xf48500ff -+ -+/*P1_NNOSPLH1*/ -+#define RSTV0910_P1_NNOSPLH1 0xf486 -+#define FSTV0910_P1_NOSPLH_NORMED1 0xf48600ff -+ -+/*P1_NNOSPLH0*/ -+#define RSTV0910_P1_NNOSPLH0 0xf487 -+#define FSTV0910_P1_NOSPLH_NORMED0 0xf48700ff -+ -+/*P1_NOSDATAT1*/ -+#define RSTV0910_P1_NOSDATAT1 0xf488 -+#define FSTV0910_P1_NOSDATAT_UNNORMED1 0xf48800ff -+ -+/*P1_NOSDATAT0*/ -+#define RSTV0910_P1_NOSDATAT0 0xf489 -+#define FSTV0910_P1_NOSDATAT_UNNORMED0 0xf48900ff -+ -+/*P1_NNOSFRAME1*/ -+#define RSTV0910_P1_NNOSFRAME1 0xf48a -+#define FSTV0910_P1_NOSFRAME_NORMED1 0xf48a00ff -+ -+/*P1_NNOSFRAME0*/ -+#define RSTV0910_P1_NNOSFRAME0 0xf48b -+#define FSTV0910_P1_NOSFRAME_NORMED0 0xf48b00ff -+ -+/*P1_NNOSRAD1*/ -+#define RSTV0910_P1_NNOSRAD1 0xf48c -+#define FSTV0910_P1_NOSRADIAL_NORMED1 0xf48c00ff -+ -+/*P1_NNOSRAD0*/ -+#define RSTV0910_P1_NNOSRAD0 0xf48d -+#define FSTV0910_P1_NOSRADIAL_NORMED0 0xf48d00ff -+ -+/*P1_NOSCFGF1*/ -+#define RSTV0910_P1_NOSCFGF1 0xf48e -+#define FSTV0910_P1_LOWNOISE_MESURE 0xf48e0080 -+#define FSTV0910_P1_NOS_DELFRAME 0xf48e0040 -+#define FSTV0910_P1_NOSDATA_MODE 0xf48e0030 -+#define FSTV0910_P1_FRAMESEL_TYPESEL 0xf48e000c -+#define FSTV0910_P1_FRAMESEL_TYPE 0xf48e0003 -+ -+/*P1_CAR2CFG*/ -+#define RSTV0910_P1_CAR2CFG 0xf490 -+#define FSTV0910_P1_DESCRAMB_OFF 0xf4900080 -+#define FSTV0910_P1_EN_PHNOSRAM 0xf4900020 -+#define FSTV0910_P1_STOP_CFR2UPDATE 0xf4900010 -+#define FSTV0910_P1_STOP_NCO2UPDATE 0xf4900008 -+#define FSTV0910_P1_ROTA2ON 0xf4900004 -+#define FSTV0910_P1_PH_DET_ALGO2 0xf4900003 -+ -+/*P1_CFR2CFR1*/ -+#define RSTV0910_P1_CFR2CFR1 0xf491 -+#define FSTV0910_P1_CFR2_S2CONTROL 0xf49100c0 -+#define FSTV0910_P1_EN_S2CAR2CENTER 0xf4910020 -+#define FSTV0910_P1_BCHERRCFR2_MODE 0xf4910018 -+#define FSTV0910_P1_CFR2TOCFR1_BETA 0xf4910007 -+ -+/*P1_CAR3CFG*/ -+#define RSTV0910_P1_CAR3CFG 0xf492 -+#define FSTV0910_P1_CARRIER23_MODE 0xf49200c0 -+#define FSTV0910_P1_CAR3INTERM_DVBS1 0xf4920020 -+#define FSTV0910_P1_ABAMPLIF_MODE 0xf4920018 -+#define FSTV0910_P1_CARRIER3_ALPHA3DL 0xf4920007 -+ -+/*P1_CFR22*/ -+#define RSTV0910_P1_CFR22 0xf493 -+#define FSTV0910_P1_CAR2_FREQ2 0xf49301ff -+ -+/*P1_CFR21*/ -+#define RSTV0910_P1_CFR21 0xf494 -+#define FSTV0910_P1_CAR2_FREQ1 0xf49400ff -+ -+/*P1_CFR20*/ -+#define RSTV0910_P1_CFR20 0xf495 -+#define FSTV0910_P1_CAR2_FREQ0 0xf49500ff -+ -+/*P1_ACLC2S2Q*/ -+#define RSTV0910_P1_ACLC2S2Q 0xf497 -+#define FSTV0910_P1_ENAB_SPSKSYMB 0xf4970080 -+#define FSTV0910_P1_CAR2S2_QANOSAUTO 0xf4970040 -+#define FSTV0910_P1_CAR2S2_Q_ALPH_M 0xf4970030 -+#define FSTV0910_P1_CAR2S2_Q_ALPH_E 0xf497000f -+ -+/*P1_ACLC2S28*/ -+#define RSTV0910_P1_ACLC2S28 0xf498 -+#define FSTV0910_P1_OLDI3Q_MODE 0xf4980080 -+#define FSTV0910_P1_CAR2S2_8ANOSAUTO 0xf4980040 -+#define FSTV0910_P1_CAR2S2_8_ALPH_M 0xf4980030 -+#define FSTV0910_P1_CAR2S2_8_ALPH_E 0xf498000f -+ -+/*P1_ACLC2S216A*/ -+#define RSTV0910_P1_ACLC2S216A 0xf499 -+#define FSTV0910_P1_CAR2S2_16ANOSAUTO 0xf4990040 -+#define FSTV0910_P1_CAR2S2_16A_ALPH_M 0xf4990030 -+#define FSTV0910_P1_CAR2S2_16A_ALPH_E 0xf499000f -+ -+/*P1_ACLC2S232A*/ -+#define RSTV0910_P1_ACLC2S232A 0xf49a -+#define FSTV0910_P1_CAR2S2_32ANOSUATO 0xf49a0040 -+#define FSTV0910_P1_CAR2S2_32A_ALPH_M 0xf49a0030 -+#define FSTV0910_P1_CAR2S2_32A_ALPH_E 0xf49a000f -+ -+/*P1_BCLC2S2Q*/ -+#define RSTV0910_P1_BCLC2S2Q 0xf49c -+#define FSTV0910_P1_DVBS2S2Q_NIP 0xf49c0080 -+#define FSTV0910_P1_CAR2S2_QBNOSAUTO 0xf49c0040 -+#define FSTV0910_P1_CAR2S2_Q_BETA_M 0xf49c0030 -+#define FSTV0910_P1_CAR2S2_Q_BETA_E 0xf49c000f -+ -+/*P1_BCLC2S28*/ -+#define RSTV0910_P1_BCLC2S28 0xf49d -+#define FSTV0910_P1_DVBS2S28_NIP 0xf49d0080 -+#define FSTV0910_P1_CAR2S2_8BNOSAUTO 0xf49d0040 -+#define FSTV0910_P1_CAR2S2_8_BETA_M 0xf49d0030 -+#define FSTV0910_P1_CAR2S2_8_BETA_E 0xf49d000f -+ -+/*P1_PLROOT2*/ -+#define RSTV0910_P1_PLROOT2 0xf4ac -+#define FSTV0910_P1_PLHAUTO_DISPLH 0xf4ac0040 -+#define FSTV0910_P1_PLHAUTO_FASTMODE 0xf4ac0020 -+#define FSTV0910_P1_PLHAUTO_ENABLE 0xf4ac0010 -+#define FSTV0910_P1_PLSCRAMB_MODE 0xf4ac000c -+#define FSTV0910_P1_PLSCRAMB_ROOT2 0xf4ac0003 -+ -+/*P1_PLROOT1*/ -+#define RSTV0910_P1_PLROOT1 0xf4ad -+#define FSTV0910_P1_PLSCRAMB_ROOT1 0xf4ad00ff -+ -+/*P1_PLROOT0*/ -+#define RSTV0910_P1_PLROOT0 0xf4ae -+#define FSTV0910_P1_PLSCRAMB_ROOT0 0xf4ae00ff -+ -+/*P1_MODCODLST7*/ -+#define RSTV0910_P1_MODCODLST7 0xf4b7 -+#define FSTV0910_P1_MODCOD_NNOSFILTER 0xf4b70080 -+#define FSTV0910_P1_MODCODLST_NOSTYPE 0xf4b70040 -+#define FSTV0910_P1_DIS_8PSK_9_10 0xf4b70030 -+#define FSTV0910_P1_DIS_8P_8_9 0xf4b7000f -+ -+/*P1_MODCODLST8*/ -+#define RSTV0910_P1_MODCODLST8 0xf4b8 -+#define FSTV0910_P1_DIS_8P_5_6 0xf4b800f0 -+#define FSTV0910_P1_DIS_8P_3_4 0xf4b8000f -+ -+/*P1_MODCODLST9*/ -+#define RSTV0910_P1_MODCODLST9 0xf4b9 -+#define FSTV0910_P1_DIS_8P_2_3 0xf4b900f0 -+#define FSTV0910_P1_DIS_8P_3_5 0xf4b9000f -+ -+/*P1_MODCODLSTA*/ -+#define RSTV0910_P1_MODCODLSTA 0xf4ba -+#define FSTV0910_P1_NOSFILTER_LIMITE 0xf4ba0080 -+#define FSTV0910_P1_NOSFILTER_MODE 0xf4ba0040 -+#define FSTV0910_P1_DIS_QPSK_9_10 0xf4ba0030 -+#define FSTV0910_P1_DIS_QP_8_9 0xf4ba000f -+ -+/*P1_MODCODLSTB*/ -+#define RSTV0910_P1_MODCODLSTB 0xf4bb -+#define FSTV0910_P1_DIS_QP_5_6 0xf4bb00f0 -+#define FSTV0910_P1_DIS_QP_4_5 0xf4bb000f -+ -+/*P1_MODCODLSTC*/ -+#define RSTV0910_P1_MODCODLSTC 0xf4bc -+#define FSTV0910_P1_DIS_QP_3_4 0xf4bc00f0 -+#define FSTV0910_P1_DIS_QP_2_3 0xf4bc000f -+ -+/*P1_MODCODLSTD*/ -+#define RSTV0910_P1_MODCODLSTD 0xf4bd -+#define FSTV0910_P1_DIS_QPSK_3_5 0xf4bd00f0 -+#define FSTV0910_P1_DIS_QPSK_1_2 0xf4bd000f -+ -+/*P1_GAUSSR0*/ -+#define RSTV0910_P1_GAUSSR0 0xf4c0 -+#define FSTV0910_P1_EN_CCIMODE 0xf4c00080 -+#define FSTV0910_P1_R0_GAUSSIEN 0xf4c0007f -+ -+/*P1_CCIR0*/ -+#define RSTV0910_P1_CCIR0 0xf4c1 -+#define FSTV0910_P1_CCIDETECT_PLHONLY 0xf4c10080 -+#define FSTV0910_P1_R0_CCI 0xf4c1007f -+ -+/*P1_CCIQUANT*/ -+#define RSTV0910_P1_CCIQUANT 0xf4c2 -+#define FSTV0910_P1_CCI_BETA 0xf4c200e0 -+#define FSTV0910_P1_CCI_QUANT 0xf4c2001f -+ -+/*P1_CCITHRES*/ -+#define RSTV0910_P1_CCITHRES 0xf4c3 -+#define FSTV0910_P1_CCI_THRESHOLD 0xf4c300ff -+ -+/*P1_CCIACC*/ -+#define RSTV0910_P1_CCIACC 0xf4c4 -+#define FSTV0910_P1_CCI_VALUE 0xf4c400ff -+ -+/*P1_DSTATUS4*/ -+#define RSTV0910_P1_DSTATUS4 0xf4c5 -+#define FSTV0910_P1_RAINFADE_DETECT 0xf4c50080 -+#define FSTV0910_P1_NOTHRES2_FAIL 0xf4c50040 -+#define FSTV0910_P1_NOTHRES1_FAIL 0xf4c50020 -+#define FSTV0910_P1_PILOT_FAILDETECT 0xf4c50010 -+#define FSTV0910_P1_HIER_DETECT 0xf4c50008 -+#define FSTV0910_P1_DMDPROG_ERROR 0xf4c50004 -+#define FSTV0910_P1_CSTENV_DETECT 0xf4c50002 -+#define FSTV0910_P1_DETECTION_TRIAX 0xf4c50001 -+ -+/*P1_DMDRESCFG*/ -+#define RSTV0910_P1_DMDRESCFG 0xf4c6 -+#define FSTV0910_P1_DMDRES_RESET 0xf4c60080 -+#define FSTV0910_P1_DMDRES_NOISESQR 0xf4c60010 -+#define FSTV0910_P1_DMDRES_STRALL 0xf4c60008 -+#define FSTV0910_P1_DMDRES_NEWONLY 0xf4c60004 -+#define FSTV0910_P1_DMDRES_NOSTORE 0xf4c60002 -+#define FSTV0910_P1_DMDRES_AGC2MEM 0xf4c60001 -+ -+/*P1_DMDRESADR*/ -+#define RSTV0910_P1_DMDRESADR 0xf4c7 -+#define FSTV0910_P1_SUSP_PREDCANAL 0xf4c70080 -+#define FSTV0910_P1_DMDRES_VALIDCFR 0xf4c70040 -+#define FSTV0910_P1_DMDRES_MEMFULL 0xf4c70030 -+#define FSTV0910_P1_DMDRES_RESNBR 0xf4c7000f -+ -+/*P1_DMDRESDATA7*/ -+#define RSTV0910_P1_DMDRESDATA7 0xf4c8 -+#define FSTV0910_P1_DMDRES_DATA7 0xf4c800ff -+ -+/*P1_DMDRESDATA6*/ -+#define RSTV0910_P1_DMDRESDATA6 0xf4c9 -+#define FSTV0910_P1_DMDRES_DATA6 0xf4c900ff -+ -+/*P1_DMDRESDATA5*/ -+#define RSTV0910_P1_DMDRESDATA5 0xf4ca -+#define FSTV0910_P1_DMDRES_DATA5 0xf4ca00ff -+ -+/*P1_DMDRESDATA4*/ -+#define RSTV0910_P1_DMDRESDATA4 0xf4cb -+#define FSTV0910_P1_DMDRES_DATA4 0xf4cb00ff -+ -+/*P1_DMDRESDATA3*/ -+#define RSTV0910_P1_DMDRESDATA3 0xf4cc -+#define FSTV0910_P1_DMDRES_DATA3 0xf4cc00ff -+ -+/*P1_DMDRESDATA2*/ -+#define RSTV0910_P1_DMDRESDATA2 0xf4cd -+#define FSTV0910_P1_DMDRES_DATA2 0xf4cd00ff -+ -+/*P1_DMDRESDATA1*/ -+#define RSTV0910_P1_DMDRESDATA1 0xf4ce -+#define FSTV0910_P1_DMDRES_DATA1 0xf4ce00ff -+ -+/*P1_DMDRESDATA0*/ -+#define RSTV0910_P1_DMDRESDATA0 0xf4cf -+#define FSTV0910_P1_DMDRES_DATA0 0xf4cf00ff -+ -+/*P1_FFEI1*/ -+#define RSTV0910_P1_FFEI1 0xf4d0 -+#define FSTV0910_P1_FFE_ACCI1 0xf4d001ff -+ -+/*P1_FFEQ1*/ -+#define RSTV0910_P1_FFEQ1 0xf4d1 -+#define FSTV0910_P1_FFE_ACCQ1 0xf4d101ff -+ -+/*P1_FFEI2*/ -+#define RSTV0910_P1_FFEI2 0xf4d2 -+#define FSTV0910_P1_FFE_ACCI2 0xf4d201ff -+ -+/*P1_FFEQ2*/ -+#define RSTV0910_P1_FFEQ2 0xf4d3 -+#define FSTV0910_P1_FFE_ACCQ2 0xf4d301ff -+ -+/*P1_FFEI3*/ -+#define RSTV0910_P1_FFEI3 0xf4d4 -+#define FSTV0910_P1_FFE_ACCI3 0xf4d401ff -+ -+/*P1_FFEQ3*/ -+#define RSTV0910_P1_FFEQ3 0xf4d5 -+#define FSTV0910_P1_FFE_ACCQ3 0xf4d501ff -+ -+/*P1_FFEI4*/ -+#define RSTV0910_P1_FFEI4 0xf4d6 -+#define FSTV0910_P1_FFE_ACCI4 0xf4d601ff -+ -+/*P1_FFEQ4*/ -+#define RSTV0910_P1_FFEQ4 0xf4d7 -+#define FSTV0910_P1_FFE_ACCQ4 0xf4d701ff -+ -+/*P1_FFECFG*/ -+#define RSTV0910_P1_FFECFG 0xf4d8 -+#define FSTV0910_P1_EQUALFFE_ON 0xf4d80040 -+#define FSTV0910_P1_EQUAL_USEDSYMB 0xf4d80030 -+#define FSTV0910_P1_MU_EQUALFFE 0xf4d80007 -+ -+/*P1_TNRCFG2*/ -+#define RSTV0910_P1_TNRCFG2 0xf4e1 -+#define FSTV0910_P1_TUN_IQSWAP 0xf4e10080 -+#define FSTV0910_P1_STB6110_STEP2MHZ 0xf4e10040 -+#define FSTV0910_P1_STB6120_DBLI2C 0xf4e10020 -+#define FSTV0910_P1_TUNER_WIDEBAND 0xf4e10010 -+#define FSTV0910_P1_TUNER_OBSPAGE 0xf4e10008 -+#define FSTV0910_P1_DIS_BWCALC 0xf4e10004 -+#define FSTV0910_P1_SHORT_WAITSTATES 0xf4e10002 -+#define FSTV0910_P1_DIS_2BWAGC1 0xf4e10001 -+ -+/*P1_SMAPCOEF7*/ -+#define RSTV0910_P1_SMAPCOEF7 0xf500 -+#define FSTV0910_P1_DIS_QSCALE 0xf5000080 -+#define FSTV0910_P1_SMAPCOEF_Q_LLR12 0xf500017f -+ -+/*P1_SMAPCOEF6*/ -+#define RSTV0910_P1_SMAPCOEF6 0xf501 -+#define FSTV0910_P1_DIS_AGC2SCALE 0xf5010080 -+#define FSTV0910_P1_DIS_16IQMULT 0xf5010040 -+#define FSTV0910_P1_OLD_16APSK47 0xf5010020 -+#define FSTV0910_P1_OLD_16APSK12 0xf5010010 -+#define FSTV0910_P1_DIS_NEWSCALE 0xf5010008 -+#define FSTV0910_P1_ADJ_8PSKLLR1 0xf5010004 -+#define FSTV0910_P1_OLD_8PSKLLR1 0xf5010002 -+#define FSTV0910_P1_DIS_AB8PSK 0xf5010001 -+ -+/*P1_SMAPCOEF5*/ -+#define RSTV0910_P1_SMAPCOEF5 0xf502 -+#define FSTV0910_P1_DIS_8SCALE 0xf5020080 -+#define FSTV0910_P1_SMAPCOEF_8P_LLR23 0xf502017f -+ -+/*P1_NOSTHRES1*/ -+#define RSTV0910_P1_NOSTHRES1 0xf509 -+#define FSTV0910_P1_NOS_THRESHOLD1 0xf50900ff -+ -+/*P1_NOSTHRES2*/ -+#define RSTV0910_P1_NOSTHRES2 0xf50a -+#define FSTV0910_P1_NOS_THRESHOLD2 0xf50a00ff -+ -+/*P1_NOSDIFF1*/ -+#define RSTV0910_P1_NOSDIFF1 0xf50b -+#define FSTV0910_P1_NOSTHRES1_DIFF 0xf50b00ff -+ -+/*P1_RAINFADE*/ -+#define RSTV0910_P1_RAINFADE 0xf50c -+#define FSTV0910_P1_NOSTHRES_DATAT 0xf50c0080 -+#define FSTV0910_P1_RAINFADE_CNLIMIT 0xf50c0070 -+#define FSTV0910_P1_RAINFADE_TIMEOUT 0xf50c0007 -+ -+/*P1_NOSRAMCFG*/ -+#define RSTV0910_P1_NOSRAMCFG 0xf50d -+#define FSTV0910_P1_NOSRAM_DVBS2DATA 0xf50d0080 -+#define FSTV0910_P1_NOSRAM_QUADRAT 0xf50d0040 -+#define FSTV0910_P1_NOSRAM_ACTIVATION 0xf50d0030 -+#define FSTV0910_P1_NOSRAM_CNRONLY 0xf50d0008 -+#define FSTV0910_P1_NOSRAM_LGNCNR1 0xf50d0007 -+ -+/*P1_NOSRAMPOS*/ -+#define RSTV0910_P1_NOSRAMPOS 0xf50e -+#define FSTV0910_P1_NOSRAM_LGNCNR0 0xf50e00f0 -+#define FSTV0910_P1_NOSRAM_VALIDE 0xf50e0004 -+#define FSTV0910_P1_NOSRAM_CNRVAL1 0xf50e0003 -+ -+/*P1_NOSRAMVAL*/ -+#define RSTV0910_P1_NOSRAMVAL 0xf50f -+#define FSTV0910_P1_NOSRAM_CNRVAL0 0xf50f00ff -+ -+/*P1_DMDPLHSTAT*/ -+#define RSTV0910_P1_DMDPLHSTAT 0xf520 -+#define FSTV0910_P1_PLH_STATISTIC 0xf52000ff -+ -+/*P1_LOCKTIME3*/ -+#define RSTV0910_P1_LOCKTIME3 0xf522 -+#define FSTV0910_P1_DEMOD_LOCKTIME3 0xf52200ff -+ -+/*P1_LOCKTIME2*/ -+#define RSTV0910_P1_LOCKTIME2 0xf523 -+#define FSTV0910_P1_DEMOD_LOCKTIME2 0xf52300ff -+ -+/*P1_LOCKTIME1*/ -+#define RSTV0910_P1_LOCKTIME1 0xf524 -+#define FSTV0910_P1_DEMOD_LOCKTIME1 0xf52400ff -+ -+/*P1_LOCKTIME0*/ -+#define RSTV0910_P1_LOCKTIME0 0xf525 -+#define FSTV0910_P1_DEMOD_LOCKTIME0 0xf52500ff -+ -+/*P1_VITSCALE*/ -+#define RSTV0910_P1_VITSCALE 0xf532 -+#define FSTV0910_P1_NVTH_NOSRANGE 0xf5320080 -+#define FSTV0910_P1_VERROR_MAXMODE 0xf5320040 -+#define FSTV0910_P1_KDIV_MODE 0xf5320030 -+#define FSTV0910_P1_NSLOWSN_LOCKED 0xf5320008 -+#define FSTV0910_P1_DELOCK_PRFLOSS 0xf5320004 -+#define FSTV0910_P1_DIS_RSFLOCK 0xf5320002 -+ -+/*P1_FECM*/ -+#define RSTV0910_P1_FECM 0xf533 -+#define FSTV0910_P1_DSS_DVB 0xf5330080 -+#define FSTV0910_P1_DEMOD_BYPASS 0xf5330040 -+#define FSTV0910_P1_CMP_SLOWMODE 0xf5330020 -+#define FSTV0910_P1_DSS_SRCH 0xf5330010 -+#define FSTV0910_P1_DIFF_MODEVIT 0xf5330004 -+#define FSTV0910_P1_SYNCVIT 0xf5330002 -+#define FSTV0910_P1_IQINV 0xf5330001 -+ -+/*P1_VTH12*/ -+#define RSTV0910_P1_VTH12 0xf534 -+#define FSTV0910_P1_VTH12 0xf53400ff -+ -+/*P1_VTH23*/ -+#define RSTV0910_P1_VTH23 0xf535 -+#define FSTV0910_P1_VTH23 0xf53500ff -+ -+/*P1_VTH34*/ -+#define RSTV0910_P1_VTH34 0xf536 -+#define FSTV0910_P1_VTH34 0xf53600ff -+ -+/*P1_VTH56*/ -+#define RSTV0910_P1_VTH56 0xf537 -+#define FSTV0910_P1_VTH56 0xf53700ff -+ -+/*P1_VTH67*/ -+#define RSTV0910_P1_VTH67 0xf538 -+#define FSTV0910_P1_VTH67 0xf53800ff -+ -+/*P1_VTH78*/ -+#define RSTV0910_P1_VTH78 0xf539 -+#define FSTV0910_P1_VTH78 0xf53900ff -+ -+/*P1_VITCURPUN*/ -+#define RSTV0910_P1_VITCURPUN 0xf53a -+#define FSTV0910_P1_CYCLESLIP_VIT 0xf53a0080 -+#define FSTV0910_P1_VIT_ROTA180 0xf53a0040 -+#define FSTV0910_P1_VIT_ROTA90 0xf53a0020 -+#define FSTV0910_P1_VIT_CURPUN 0xf53a001f -+ -+/*P1_VERROR*/ -+#define RSTV0910_P1_VERROR 0xf53b -+#define FSTV0910_P1_REGERR_VIT 0xf53b00ff -+ -+/*P1_PRVIT*/ -+#define RSTV0910_P1_PRVIT 0xf53c -+#define FSTV0910_P1_DIS_VTHLOCK 0xf53c0040 -+#define FSTV0910_P1_E7_8VIT 0xf53c0020 -+#define FSTV0910_P1_E6_7VIT 0xf53c0010 -+#define FSTV0910_P1_E5_6VIT 0xf53c0008 -+#define FSTV0910_P1_E3_4VIT 0xf53c0004 -+#define FSTV0910_P1_E2_3VIT 0xf53c0002 -+#define FSTV0910_P1_E1_2VIT 0xf53c0001 -+ -+/*P1_VAVSRVIT*/ -+#define RSTV0910_P1_VAVSRVIT 0xf53d -+#define FSTV0910_P1_AMVIT 0xf53d0080 -+#define FSTV0910_P1_FROZENVIT 0xf53d0040 -+#define FSTV0910_P1_SNVIT 0xf53d0030 -+#define FSTV0910_P1_TOVVIT 0xf53d000c -+#define FSTV0910_P1_HYPVIT 0xf53d0003 -+ -+/*P1_VSTATUSVIT*/ -+#define RSTV0910_P1_VSTATUSVIT 0xf53e -+#define FSTV0910_P1_VITERBI_ON 0xf53e0080 -+#define FSTV0910_P1_END_LOOPVIT 0xf53e0040 -+#define FSTV0910_P1_VITERBI_DEPRF 0xf53e0020 -+#define FSTV0910_P1_PRFVIT 0xf53e0010 -+#define FSTV0910_P1_LOCKEDVIT 0xf53e0008 -+#define FSTV0910_P1_VITERBI_DELOCK 0xf53e0004 -+#define FSTV0910_P1_VIT_DEMODSEL 0xf53e0002 -+#define FSTV0910_P1_VITERBI_COMPOUT 0xf53e0001 -+ -+/*P1_VTHINUSE*/ -+#define RSTV0910_P1_VTHINUSE 0xf53f -+#define FSTV0910_P1_VIT_INUSE 0xf53f00ff -+ -+/*P1_KDIV12*/ -+#define RSTV0910_P1_KDIV12 0xf540 -+#define FSTV0910_P1_KDIV12_MANUAL 0xf5400080 -+#define FSTV0910_P1_K_DIVIDER_12 0xf540007f -+ -+/*P1_KDIV23*/ -+#define RSTV0910_P1_KDIV23 0xf541 -+#define FSTV0910_P1_KDIV23_MANUAL 0xf5410080 -+#define FSTV0910_P1_K_DIVIDER_23 0xf541007f -+ -+/*P1_KDIV34*/ -+#define RSTV0910_P1_KDIV34 0xf542 -+#define FSTV0910_P1_KDIV34_MANUAL 0xf5420080 -+#define FSTV0910_P1_K_DIVIDER_34 0xf542007f -+ -+/*P1_KDIV56*/ -+#define RSTV0910_P1_KDIV56 0xf543 -+#define FSTV0910_P1_KDIV56_MANUAL 0xf5430080 -+#define FSTV0910_P1_K_DIVIDER_56 0xf543007f -+ -+/*P1_KDIV67*/ -+#define RSTV0910_P1_KDIV67 0xf544 -+#define FSTV0910_P1_KDIV67_MANUAL 0xf5440080 -+#define FSTV0910_P1_K_DIVIDER_67 0xf544007f -+ -+/*P1_KDIV78*/ -+#define RSTV0910_P1_KDIV78 0xf545 -+#define FSTV0910_P1_KDIV78_MANUAL 0xf5450080 -+#define FSTV0910_P1_K_DIVIDER_78 0xf545007f -+ -+/*P1_PDELCTRL0*/ -+#define RSTV0910_P1_PDELCTRL0 0xf54f -+#define FSTV0910_P1_ISIOBS_MODE 0xf54f0030 -+#define FSTV0910_P1_PDELDIS_BITWISE 0xf54f0004 -+ -+/*P1_PDELCTRL1*/ -+#define RSTV0910_P1_PDELCTRL1 0xf550 -+#define FSTV0910_P1_INV_MISMASK 0xf5500080 -+#define FSTV0910_P1_FORCE_ACCEPTED 0xf5500040 -+#define FSTV0910_P1_FILTER_EN 0xf5500020 -+#define FSTV0910_P1_FORCE_PKTDELINUSE 0xf5500010 -+#define FSTV0910_P1_HYSTEN 0xf5500008 -+#define FSTV0910_P1_HYSTSWRST 0xf5500004 -+#define FSTV0910_P1_EN_MIS00 0xf5500002 -+#define FSTV0910_P1_ALGOSWRST 0xf5500001 -+ -+/*P1_PDELCTRL2*/ -+#define RSTV0910_P1_PDELCTRL2 0xf551 -+#define FSTV0910_P1_FORCE_CONTINUOUS 0xf5510080 -+#define FSTV0910_P1_RESET_UPKO_COUNT 0xf5510040 -+#define FSTV0910_P1_USER_PKTDELIN_NB 0xf5510020 -+#define FSTV0910_P1_DATA_UNBBSCRAMBLED 0xf5510008 -+#define FSTV0910_P1_FORCE_LONGPKT 0xf5510004 -+#define FSTV0910_P1_FRAME_MODE 0xf5510002 -+ -+/*P1_HYSTTHRESH*/ -+#define RSTV0910_P1_HYSTTHRESH 0xf554 -+#define FSTV0910_P1_DELIN_LOCKTHRES 0xf55400f0 -+#define FSTV0910_P1_DELIN_UNLOCKTHRES 0xf554000f -+ -+/*P1_ISIENTRY*/ -+#define RSTV0910_P1_ISIENTRY 0xf55e -+#define FSTV0910_P1_ISI_ENTRY 0xf55e00ff -+ -+/*P1_ISIBITENA*/ -+#define RSTV0910_P1_ISIBITENA 0xf55f -+#define FSTV0910_P1_ISI_BIT_EN 0xf55f00ff -+ -+/*P1_MATSTR1*/ -+#define RSTV0910_P1_MATSTR1 0xf560 -+#define FSTV0910_P1_MATYPE_CURRENT1 0xf56000ff -+ -+/*P1_MATSTR0*/ -+#define RSTV0910_P1_MATSTR0 0xf561 -+#define FSTV0910_P1_MATYPE_CURRENT0 0xf56100ff -+ -+/*P1_UPLSTR1*/ -+#define RSTV0910_P1_UPLSTR1 0xf562 -+#define FSTV0910_P1_UPL_CURRENT1 0xf56200ff -+ -+/*P1_UPLSTR0*/ -+#define RSTV0910_P1_UPLSTR0 0xf563 -+#define FSTV0910_P1_UPL_CURRENT0 0xf56300ff -+ -+/*P1_DFLSTR1*/ -+#define RSTV0910_P1_DFLSTR1 0xf564 -+#define FSTV0910_P1_DFL_CURRENT1 0xf56400ff -+ -+/*P1_DFLSTR0*/ -+#define RSTV0910_P1_DFLSTR0 0xf565 -+#define FSTV0910_P1_DFL_CURRENT0 0xf56500ff -+ -+/*P1_SYNCSTR*/ -+#define RSTV0910_P1_SYNCSTR 0xf566 -+#define FSTV0910_P1_SYNC_CURRENT 0xf56600ff -+ -+/*P1_SYNCDSTR1*/ -+#define RSTV0910_P1_SYNCDSTR1 0xf567 -+#define FSTV0910_P1_SYNCD_CURRENT1 0xf56700ff -+ -+/*P1_SYNCDSTR0*/ -+#define RSTV0910_P1_SYNCDSTR0 0xf568 -+#define FSTV0910_P1_SYNCD_CURRENT0 0xf56800ff -+ -+/*P1_PDELSTATUS1*/ -+#define RSTV0910_P1_PDELSTATUS1 0xf569 -+#define FSTV0910_P1_PKTDELIN_DELOCK 0xf5690080 -+#define FSTV0910_P1_SYNCDUPDFL_BADDFL 0xf5690040 -+#define FSTV0910_P1_CONTINUOUS_STREAM 0xf5690020 -+#define FSTV0910_P1_UNACCEPTED_STREAM 0xf5690010 -+#define FSTV0910_P1_BCH_ERROR_FLAG 0xf5690008 -+#define FSTV0910_P1_BBHCRCKO 0xf5690004 -+#define FSTV0910_P1_PKTDELIN_LOCK 0xf5690002 -+#define FSTV0910_P1_FIRST_LOCK 0xf5690001 -+ -+/*P1_PDELSTATUS2*/ -+#define RSTV0910_P1_PDELSTATUS2 0xf56a -+#define FSTV0910_P1_PKTDEL_DEMODSEL 0xf56a0080 -+#define FSTV0910_P1_FRAME_MODCOD 0xf56a007c -+#define FSTV0910_P1_FRAME_TYPE 0xf56a0003 -+ -+/*P1_BBFCRCKO1*/ -+#define RSTV0910_P1_BBFCRCKO1 0xf56b -+#define FSTV0910_P1_BBHCRC_KOCNT1 0xf56b00ff -+ -+/*P1_BBFCRCKO0*/ -+#define RSTV0910_P1_BBFCRCKO0 0xf56c -+#define FSTV0910_P1_BBHCRC_KOCNT0 0xf56c00ff -+ -+/*P1_UPCRCKO1*/ -+#define RSTV0910_P1_UPCRCKO1 0xf56d -+#define FSTV0910_P1_PKTCRC_KOCNT1 0xf56d00ff -+ -+/*P1_UPCRCKO0*/ -+#define RSTV0910_P1_UPCRCKO0 0xf56e -+#define FSTV0910_P1_PKTCRC_KOCNT0 0xf56e00ff -+ -+/*P1_PDELCTRL3*/ -+#define RSTV0910_P1_PDELCTRL3 0xf56f -+#define FSTV0910_P1_PKTDEL_CONTFAIL 0xf56f0080 -+#define FSTV0910_P1_PKTDEL_ENLONGPKT 0xf56f0040 -+#define FSTV0910_P1_NOFIFO_BCHERR 0xf56f0020 -+#define FSTV0910_P1_PKTDELIN_DELACMERR 0xf56f0010 -+#define FSTV0910_P1_SATURATE_BBPKTKO 0xf56f0004 -+#define FSTV0910_P1_PKTDEL_BCHERRCONT 0xf56f0002 -+#define FSTV0910_P1_ETHERNET_DISFCS 0xf56f0001 -+ -+/*P1_TSSTATEM*/ -+#define RSTV0910_P1_TSSTATEM 0xf570 -+#define FSTV0910_P1_TSDIL_ON 0xf5700080 -+#define FSTV0910_P1_TSSKIPRS_ON 0xf5700040 -+#define FSTV0910_P1_TSRS_ON 0xf5700020 -+#define FSTV0910_P1_TSDESCRAMB_ON 0xf5700010 -+#define FSTV0910_P1_TSFRAME_MODE 0xf5700008 -+#define FSTV0910_P1_TS_DISABLE 0xf5700004 -+#define FSTV0910_P1_TSACM_MODE 0xf5700002 -+#define FSTV0910_P1_TSOUT_NOSYNC 0xf5700001 -+ -+/*P1_TSCFGH*/ -+#define RSTV0910_P1_TSCFGH 0xf572 -+#define FSTV0910_P1_TSFIFO_DVBCI 0xf5720080 -+#define FSTV0910_P1_TSFIFO_SERIAL 0xf5720040 -+#define FSTV0910_P1_TSFIFO_TEIUPDATE 0xf5720020 -+#define FSTV0910_P1_TSFIFO_DUTY50 0xf5720010 -+#define FSTV0910_P1_TSFIFO_HSGNLOUT 0xf5720008 -+#define FSTV0910_P1_TSFIFO_ERRMODE 0xf5720006 -+#define FSTV0910_P1_RST_HWARE 0xf5720001 -+ -+/*P1_TSCFGM*/ -+#define RSTV0910_P1_TSCFGM 0xf573 -+#define FSTV0910_P1_TSFIFO_MANSPEED 0xf57300c0 -+#define FSTV0910_P1_TSFIFO_PERMDATA 0xf5730020 -+#define FSTV0910_P1_TSFIFO_NONEWSGNL 0xf5730010 -+#define FSTV0910_P1_NPD_SPECDVBS2 0xf5730004 -+#define FSTV0910_P1_TSFIFO_DPUNACTIVE 0xf5730002 -+#define FSTV0910_P1_TSFIFO_INVDATA 0xf5730001 -+ -+/*P1_TSCFGL*/ -+#define RSTV0910_P1_TSCFGL 0xf574 -+#define FSTV0910_P1_TSFIFO_BCLKDEL1CK 0xf57400c0 -+#define FSTV0910_P1_BCHERROR_MODE 0xf5740030 -+#define FSTV0910_P1_TSFIFO_NSGNL2DATA 0xf5740008 -+#define FSTV0910_P1_TSFIFO_EMBINDVB 0xf5740004 -+#define FSTV0910_P1_TSFIFO_BITSPEED 0xf5740003 -+ -+/*P1_TSINSDELH*/ -+#define RSTV0910_P1_TSINSDELH 0xf576 -+#define FSTV0910_P1_TSDEL_SYNCBYTE 0xf5760080 -+#define FSTV0910_P1_TSDEL_XXHEADER 0xf5760040 -+#define FSTV0910_P1_TSDEL_BBHEADER 0xf5760020 -+#define FSTV0910_P1_TSDEL_DATAFIELD 0xf5760010 -+#define FSTV0910_P1_TSINSDEL_ISCR 0xf5760008 -+#define FSTV0910_P1_TSINSDEL_NPD 0xf5760004 -+#define FSTV0910_P1_TSINSDEL_RSPARITY 0xf5760002 -+#define FSTV0910_P1_TSINSDEL_CRC8 0xf5760001 -+ -+/*P1_TSDIVN*/ -+#define RSTV0910_P1_TSDIVN 0xf579 -+#define FSTV0910_P1_TSFIFO_SPEEDMODE 0xf57900c0 -+#define FSTV0910_P1_BYTE_OVERSAMPLING 0xf5790038 -+#define FSTV0910_P1_TSFIFO_RISEOK 0xf5790007 -+ -+/*P1_TSCFG4*/ -+#define RSTV0910_P1_TSCFG4 0xf57a -+#define FSTV0910_P1_TSFIFO_TSSPEEDMODE 0xf57a00c0 -+#define FSTV0910_P1_TSFIFO_HIERSEL 0xf57a0020 -+#define FSTV0910_P1_TSFIFO_SPECTOKEN 0xf57a0010 -+#define FSTV0910_P1_TSFIFO_MAXMODE 0xf57a0008 -+#define FSTV0910_P1_TSFIFO_FRFORCEPKT 0xf57a0004 -+#define FSTV0910_P1_EXT_FECSPYIN 0xf57a0002 -+#define FSTV0910_P1_TSFIFO_DELSPEEDUP 0xf57a0001 -+ -+/*P1_TSSPEED*/ -+#define RSTV0910_P1_TSSPEED 0xf580 -+#define FSTV0910_P1_TSFIFO_OUTSPEED 0xf58000ff -+ -+/*P1_TSSTATUS*/ -+#define RSTV0910_P1_TSSTATUS 0xf581 -+#define FSTV0910_P1_TSFIFO_LINEOK 0xf5810080 -+#define FSTV0910_P1_TSFIFO_ERROR 0xf5810040 -+#define FSTV0910_P1_TSFIFO_DATA7 0xf5810020 -+#define FSTV0910_P1_TSFIFO_NOSYNC 0xf5810010 -+#define FSTV0910_P1_ISCR_INITIALIZED 0xf5810008 -+#define FSTV0910_P1_TSREGUL_ERROR 0xf5810004 -+#define FSTV0910_P1_SOFFIFO_UNREGUL 0xf5810002 -+#define FSTV0910_P1_DIL_READY 0xf5810001 -+ -+/*P1_TSSTATUS2*/ -+#define RSTV0910_P1_TSSTATUS2 0xf582 -+#define FSTV0910_P1_TSFIFO_DEMODSEL 0xf5820080 -+#define FSTV0910_P1_TSFIFOSPEED_STORE 0xf5820040 -+#define FSTV0910_P1_DILXX_RESET 0xf5820020 -+#define FSTV0910_P1_TSSPEED_IMPOSSIBLE 0xf5820010 -+#define FSTV0910_P1_TSFIFO_LINENOK 0xf5820008 -+#define FSTV0910_P1_TSFIFO_MUXSTREAM 0xf5820004 -+#define FSTV0910_P1_SCRAMBDETECT 0xf5820002 -+#define FSTV0910_P1_ULDTV67_FALSELOCK 0xf5820001 -+ -+/*P1_TSBITRATE1*/ -+#define RSTV0910_P1_TSBITRATE1 0xf583 -+#define FSTV0910_P1_TSFIFO_BITRATE1 0xf58300ff -+ -+/*P1_TSBITRATE0*/ -+#define RSTV0910_P1_TSBITRATE0 0xf584 -+#define FSTV0910_P1_TSFIFO_BITRATE0 0xf58400ff -+ -+/*P1_ERRCTRL1*/ -+#define RSTV0910_P1_ERRCTRL1 0xf598 -+#define FSTV0910_P1_ERR_SOURCE1 0xf59800f0 -+#define FSTV0910_P1_NUM_EVENT1 0xf5980007 -+ -+/*P1_ERRCNT12*/ -+#define RSTV0910_P1_ERRCNT12 0xf599 -+#define FSTV0910_P1_ERRCNT1_OLDVALUE 0xf5990080 -+#define FSTV0910_P1_ERR_CNT12 0xf599007f -+ -+/*P1_ERRCNT11*/ -+#define RSTV0910_P1_ERRCNT11 0xf59a -+#define FSTV0910_P1_ERR_CNT11 0xf59a00ff -+ -+/*P1_ERRCNT10*/ -+#define RSTV0910_P1_ERRCNT10 0xf59b -+#define FSTV0910_P1_ERR_CNT10 0xf59b00ff -+ -+/*P1_ERRCTRL2*/ -+#define RSTV0910_P1_ERRCTRL2 0xf59c -+#define FSTV0910_P1_ERR_SOURCE2 0xf59c00f0 -+#define FSTV0910_P1_NUM_EVENT2 0xf59c0007 -+ -+/*P1_ERRCNT22*/ -+#define RSTV0910_P1_ERRCNT22 0xf59d -+#define FSTV0910_P1_ERRCNT2_OLDVALUE 0xf59d0080 -+#define FSTV0910_P1_ERR_CNT22 0xf59d007f -+ -+/*P1_ERRCNT21*/ -+#define RSTV0910_P1_ERRCNT21 0xf59e -+#define FSTV0910_P1_ERR_CNT21 0xf59e00ff -+ -+/*P1_ERRCNT20*/ -+#define RSTV0910_P1_ERRCNT20 0xf59f -+#define FSTV0910_P1_ERR_CNT20 0xf59f00ff -+ -+/*P1_FECSPY*/ -+#define RSTV0910_P1_FECSPY 0xf5a0 -+#define FSTV0910_P1_SPY_ENABLE 0xf5a00080 -+#define FSTV0910_P1_NO_SYNCBYTE 0xf5a00040 -+#define FSTV0910_P1_SERIAL_MODE 0xf5a00020 -+#define FSTV0910_P1_UNUSUAL_PACKET 0xf5a00010 -+#define FSTV0910_P1_BERMETER_DATAMODE 0xf5a0000c -+#define FSTV0910_P1_BERMETER_LMODE 0xf5a00002 -+#define FSTV0910_P1_BERMETER_RESET 0xf5a00001 -+ -+/*P1_FSPYCFG*/ -+#define RSTV0910_P1_FSPYCFG 0xf5a1 -+#define FSTV0910_P1_FECSPY_INPUT 0xf5a100c0 -+#define FSTV0910_P1_RST_ON_ERROR 0xf5a10020 -+#define FSTV0910_P1_ONE_SHOT 0xf5a10010 -+#define FSTV0910_P1_I2C_MODE 0xf5a1000c -+#define FSTV0910_P1_SPY_HYSTERESIS 0xf5a10003 -+ -+/*P1_FSPYDATA*/ -+#define RSTV0910_P1_FSPYDATA 0xf5a2 -+#define FSTV0910_P1_SPY_STUFFING 0xf5a20080 -+#define FSTV0910_P1_NOERROR_PKTJITTER 0xf5a20040 -+#define FSTV0910_P1_SPY_CNULLPKT 0xf5a20020 -+#define FSTV0910_P1_SPY_OUTDATA_MODE 0xf5a2001f -+ -+/*P1_FSPYOUT*/ -+#define RSTV0910_P1_FSPYOUT 0xf5a3 -+#define FSTV0910_P1_FSPY_DIRECT 0xf5a30080 -+#define FSTV0910_P1_SPY_OUTDATA_BUS 0xf5a30038 -+#define FSTV0910_P1_STUFF_MODE 0xf5a30007 -+ -+/*P1_FSTATUS*/ -+#define RSTV0910_P1_FSTATUS 0xf5a4 -+#define FSTV0910_P1_SPY_ENDSIM 0xf5a40080 -+#define FSTV0910_P1_VALID_SIM 0xf5a40040 -+#define FSTV0910_P1_FOUND_SIGNAL 0xf5a40020 -+#define FSTV0910_P1_DSS_SYNCBYTE 0xf5a40010 -+#define FSTV0910_P1_RESULT_STATE 0xf5a4000f -+ -+/*P1_FBERCPT4*/ -+#define RSTV0910_P1_FBERCPT4 0xf5a8 -+#define FSTV0910_P1_FBERMETER_CPT4 0xf5a800ff -+ -+/*P1_FBERCPT3*/ -+#define RSTV0910_P1_FBERCPT3 0xf5a9 -+#define FSTV0910_P1_FBERMETER_CPT3 0xf5a900ff -+ -+/*P1_FBERCPT2*/ -+#define RSTV0910_P1_FBERCPT2 0xf5aa -+#define FSTV0910_P1_FBERMETER_CPT2 0xf5aa00ff -+ -+/*P1_FBERCPT1*/ -+#define RSTV0910_P1_FBERCPT1 0xf5ab -+#define FSTV0910_P1_FBERMETER_CPT1 0xf5ab00ff -+ -+/*P1_FBERCPT0*/ -+#define RSTV0910_P1_FBERCPT0 0xf5ac -+#define FSTV0910_P1_FBERMETER_CPT0 0xf5ac00ff -+ -+/*P1_FBERERR2*/ -+#define RSTV0910_P1_FBERERR2 0xf5ad -+#define FSTV0910_P1_FBERMETER_ERR2 0xf5ad00ff -+ -+/*P1_FBERERR1*/ -+#define RSTV0910_P1_FBERERR1 0xf5ae -+#define FSTV0910_P1_FBERMETER_ERR1 0xf5ae00ff -+ -+/*P1_FBERERR0*/ -+#define RSTV0910_P1_FBERERR0 0xf5af -+#define FSTV0910_P1_FBERMETER_ERR0 0xf5af00ff -+ -+/*P1_FSPYBER*/ -+#define RSTV0910_P1_FSPYBER 0xf5b2 -+#define FSTV0910_P1_FSPYOBS_XORREAD 0xf5b20040 -+#define FSTV0910_P1_FSPYBER_OBSMODE 0xf5b20020 -+#define FSTV0910_P1_FSPYBER_SYNCBYTE 0xf5b20010 -+#define FSTV0910_P1_FSPYBER_UNSYNC 0xf5b20008 -+#define FSTV0910_P1_FSPYBER_CTIME 0xf5b20007 -+ -+/*P1_SFERROR*/ -+#define RSTV0910_P1_SFERROR 0xf5c1 -+#define FSTV0910_P1_SFEC_REGERR_VIT 0xf5c100ff -+ -+/*P1_SFECSTATUS*/ -+#define RSTV0910_P1_SFECSTATUS 0xf5c3 -+#define FSTV0910_P1_SFEC_ON 0xf5c30080 -+#define FSTV0910_P1_SFEC_OFF 0xf5c30040 -+#define FSTV0910_P1_LOCKEDSFEC 0xf5c30008 -+#define FSTV0910_P1_SFEC_DELOCK 0xf5c30004 -+#define FSTV0910_P1_SFEC_DEMODSEL 0xf5c30002 -+#define FSTV0910_P1_SFEC_OVFON 0xf5c30001 -+ -+/*P1_SFKDIV12*/ -+#define RSTV0910_P1_SFKDIV12 0xf5c4 -+#define FSTV0910_P1_SFECKDIV12_MAN 0xf5c40080 -+#define FSTV0910_P1_SFEC_K_DIVIDER_12 0xf5c4007f -+ -+/*P1_SFKDIV23*/ -+#define RSTV0910_P1_SFKDIV23 0xf5c5 -+#define FSTV0910_P1_SFECKDIV23_MAN 0xf5c50080 -+#define FSTV0910_P1_SFEC_K_DIVIDER_23 0xf5c5007f -+ -+/*P1_SFKDIV34*/ -+#define RSTV0910_P1_SFKDIV34 0xf5c6 -+#define FSTV0910_P1_SFECKDIV34_MAN 0xf5c60080 -+#define FSTV0910_P1_SFEC_K_DIVIDER_34 0xf5c6007f -+ -+/*P1_SFKDIV56*/ -+#define RSTV0910_P1_SFKDIV56 0xf5c7 -+#define FSTV0910_P1_SFECKDIV56_MAN 0xf5c70080 -+#define FSTV0910_P1_SFEC_K_DIVIDER_56 0xf5c7007f -+ -+/*P1_SFKDIV67*/ -+#define RSTV0910_P1_SFKDIV67 0xf5c8 -+#define FSTV0910_P1_SFECKDIV67_MAN 0xf5c80080 -+#define FSTV0910_P1_SFEC_K_DIVIDER_67 0xf5c8007f -+ -+/*P1_SFKDIV78*/ -+#define RSTV0910_P1_SFKDIV78 0xf5c9 -+#define FSTV0910_P1_SFECKDIV78_MAN 0xf5c90080 -+#define FSTV0910_P1_SFEC_K_DIVIDER_78 0xf5c9007f -+ -+/*P1_SFSTATUS*/ -+#define RSTV0910_P1_SFSTATUS 0xf5cc -+#define FSTV0910_P1_SFEC_LINEOK 0xf5cc0080 -+#define FSTV0910_P1_SFEC_ERROR 0xf5cc0040 -+#define FSTV0910_P1_SFEC_DATA7 0xf5cc0020 -+#define FSTV0910_P1_SFEC_PKTDNBRFAIL 0xf5cc0010 -+#define FSTV0910_P1_TSSFEC_DEMODSEL 0xf5cc0008 -+#define FSTV0910_P1_SFEC_NOSYNC 0xf5cc0004 -+#define FSTV0910_P1_SFEC_UNREGULA 0xf5cc0002 -+#define FSTV0910_P1_SFEC_READY 0xf5cc0001 -+ -+/*P1_SFDLYSET2*/ -+#define RSTV0910_P1_SFDLYSET2 0xf5d0 -+#define FSTV0910_P1_SFEC_OFFSET 0xf5d000c0 -+#define FSTV0910_P1_RST_SFEC 0xf5d00008 -+#define FSTV0910_P1_DILDLINE_ERROR 0xf5d00004 -+#define FSTV0910_P1_SFEC_DISABLE 0xf5d00002 -+#define FSTV0910_P1_SFEC_UNREGUL 0xf5d00001 -+ -+/*P1_SFERRCTRL*/ -+#define RSTV0910_P1_SFERRCTRL 0xf5d8 -+#define FSTV0910_P1_SFEC_ERR_SOURCE 0xf5d800f0 -+#define FSTV0910_P1_SFEC_NUM_EVENT 0xf5d80007 -+ -+/*P1_SFERRCNT2*/ -+#define RSTV0910_P1_SFERRCNT2 0xf5d9 -+#define FSTV0910_P1_SFERRC_OLDVALUE 0xf5d90080 -+#define FSTV0910_P1_SFEC_ERR_CNT2 0xf5d9007f -+ -+/*P1_SFERRCNT1*/ -+#define RSTV0910_P1_SFERRCNT1 0xf5da -+#define FSTV0910_P1_SFEC_ERR_CNT1 0xf5da00ff -+ -+/*P1_SFERRCNT0*/ -+#define RSTV0910_P1_SFERRCNT0 0xf5db -+#define FSTV0910_P1_SFEC_ERR_CNT0 0xf5db00ff -+ -+/*TSGENERAL*/ -+#define RSTV0910_TSGENERAL 0xf630 -+#define FSTV0910_EN_LGNERROR 0xf6300080 -+#define FSTV0910_TSFIFO_DISTS2PAR 0xf6300040 -+#define FSTV0910_MUXSTREAM_COMPMOSE 0xf6300030 -+#define FSTV0910_MUXSTREAM_OUTMODE 0xf6300008 -+#define FSTV0910_TSFIFO_PERMPARAL 0xf6300006 -+#define FSTV0910_RST_REEDSOLO 0xf6300001 -+ -+/*P1_DISIRQCFG*/ -+#define RSTV0910_P1_DISIRQCFG 0xf700 -+#define FSTV0910_P1_ENRXEND 0xf7000040 -+#define FSTV0910_P1_ENRXFIFO8B 0xf7000020 -+#define FSTV0910_P1_ENTRFINISH 0xf7000010 -+#define FSTV0910_P1_ENTIMEOUT 0xf7000008 -+#define FSTV0910_P1_ENTXEND 0xf7000004 -+#define FSTV0910_P1_ENTXFIFO64B 0xf7000002 -+#define FSTV0910_P1_ENGAPBURST 0xf7000001 -+ -+/*P1_DISIRQSTAT*/ -+#define RSTV0910_P1_DISIRQSTAT 0xf701 -+#define FSTV0910_P1_IRQRXEND 0xf7010040 -+#define FSTV0910_P1_IRQRXFIFO8B 0xf7010020 -+#define FSTV0910_P1_IRQTRFINISH 0xf7010010 -+#define FSTV0910_P1_IRQTIMEOUT 0xf7010008 -+#define FSTV0910_P1_IRQTXEND 0xf7010004 -+#define FSTV0910_P1_IRQTXFIFO64B 0xf7010002 -+#define FSTV0910_P1_IRQGAPBURST 0xf7010001 -+ -+/*P1_DISTXCFG*/ -+#define RSTV0910_P1_DISTXCFG 0xf702 -+#define FSTV0910_P1_DISTX_RESET 0xf7020080 -+#define FSTV0910_P1_TIM_OFF 0xf7020040 -+#define FSTV0910_P1_TIM_CMD 0xf7020030 -+#define FSTV0910_P1_ENVELOP 0xf7020008 -+#define FSTV0910_P1_DIS_PRECHARGE 0xf7020004 -+#define FSTV0910_P1_DISEQC_MODE 0xf7020003 -+ -+/*P1_DISTXSTATUS*/ -+#define RSTV0910_P1_DISTXSTATUS 0xf703 -+#define FSTV0910_P1_TX_FIFO_FULL 0xf7030040 -+#define FSTV0910_P1_TX_IDLE 0xf7030020 -+#define FSTV0910_P1_GAP_BURST 0xf7030010 -+#define FSTV0910_P1_TX_FIFO64B 0xf7030008 -+#define FSTV0910_P1_TX_END 0xf7030004 -+#define FSTV0910_P1_TR_TIMEOUT 0xf7030002 -+#define FSTV0910_P1_TR_FINISH 0xf7030001 -+ -+/*P1_DISTXBYTES*/ -+#define RSTV0910_P1_DISTXBYTES 0xf704 -+#define FSTV0910_P1_TXFIFO_BYTES 0xf70400ff -+ -+/*P1_DISTXFIFO*/ -+#define RSTV0910_P1_DISTXFIFO 0xf705 -+#define FSTV0910_P1_DISEQC_TX_FIFO 0xf70500ff -+ -+/*P1_DISTXF22*/ -+#define RSTV0910_P1_DISTXF22 0xf706 -+#define FSTV0910_P1_F22TX 0xf70600ff -+ -+/*P1_DISTIMEOCFG*/ -+#define RSTV0910_P1_DISTIMEOCFG 0xf708 -+#define FSTV0910_P1_RXCHOICE 0xf7080006 -+#define FSTV0910_P1_TIMEOUT_OFF 0xf7080001 -+ -+/*P1_DISTIMEOUT*/ -+#define RSTV0910_P1_DISTIMEOUT 0xf709 -+#define FSTV0910_P1_TIMEOUT_COUNT 0xf70900ff -+ -+/*P1_DISRXCFG*/ -+#define RSTV0910_P1_DISRXCFG 0xf70a -+#define FSTV0910_P1_DISRX_RESET 0xf70a0080 -+#define FSTV0910_P1_EXTENVELOP 0xf70a0040 -+#define FSTV0910_P1_PINSELECT 0xf70a0038 -+#define FSTV0910_P1_IGNORE_SHORT22K 0xf70a0004 -+#define FSTV0910_P1_SIGNED_RXIN 0xf70a0002 -+#define FSTV0910_P1_DISRX_ON 0xf70a0001 -+ -+/*P1_DISRXSTAT1*/ -+#define RSTV0910_P1_DISRXSTAT1 0xf70b -+#define FSTV0910_P1_RXEND 0xf70b0080 -+#define FSTV0910_P1_RXACTIVE 0xf70b0040 -+#define FSTV0910_P1_RXDETECT 0xf70b0020 -+#define FSTV0910_P1_CONTTONE 0xf70b0010 -+#define FSTV0910_P1_8BFIFOREADY 0xf70b0008 -+#define FSTV0910_P1_FIFOEMPTY 0xf70b0004 -+ -+/*P1_DISRXSTAT0*/ -+#define RSTV0910_P1_DISRXSTAT0 0xf70c -+#define FSTV0910_P1_RXFAIL 0xf70c0080 -+#define FSTV0910_P1_FIFOPFAIL 0xf70c0040 -+#define FSTV0910_P1_RXNONBYTE 0xf70c0020 -+#define FSTV0910_P1_FIFOOVF 0xf70c0010 -+#define FSTV0910_P1_SHORT22K 0xf70c0008 -+#define FSTV0910_P1_RXMSGLOST 0xf70c0004 -+ -+/*P1_DISRXBYTES*/ -+#define RSTV0910_P1_DISRXBYTES 0xf70d -+#define FSTV0910_P1_RXFIFO_BYTES 0xf70d001f -+ -+/*P1_DISRXPARITY1*/ -+#define RSTV0910_P1_DISRXPARITY1 0xf70e -+#define FSTV0910_P1_DISRX_PARITY1 0xf70e00ff -+ -+/*P1_DISRXPARITY0*/ -+#define RSTV0910_P1_DISRXPARITY0 0xf70f -+#define FSTV0910_P1_DISRX_PARITY0 0xf70f00ff -+ -+/*P1_DISRXFIFO*/ -+#define RSTV0910_P1_DISRXFIFO 0xf710 -+#define FSTV0910_P1_DISEQC_RX_FIFO 0xf71000ff -+ -+/*P1_DISRXDC1*/ -+#define RSTV0910_P1_DISRXDC1 0xf711 -+#define FSTV0910_P1_DC_VALUE1 0xf7110103 -+ -+/*P1_DISRXDC0*/ -+#define RSTV0910_P1_DISRXDC0 0xf712 -+#define FSTV0910_P1_DC_VALUE0 0xf71200ff -+ -+/*P1_DISRXF221*/ -+#define RSTV0910_P1_DISRXF221 0xf714 -+#define FSTV0910_P1_F22RX1 0xf714000f -+ -+/*P1_DISRXF220*/ -+#define RSTV0910_P1_DISRXF220 0xf715 -+#define FSTV0910_P1_F22RX0 0xf71500ff -+ -+/*P1_DISRXF100*/ -+#define RSTV0910_P1_DISRXF100 0xf716 -+#define FSTV0910_P1_F100RX 0xf71600ff -+ -+/*P1_DISRXSHORT22K*/ -+#define RSTV0910_P1_DISRXSHORT22K 0xf71c -+#define FSTV0910_P1_SHORT22K_LENGTH 0xf71c001f -+ -+/*P1_ACRPRESC*/ -+#define RSTV0910_P1_ACRPRESC 0xf71e -+#define FSTV0910_P1_ACR_CODFRDY 0xf71e0008 -+#define FSTV0910_P1_ACR_PRESC 0xf71e0007 -+ -+/*P1_ACRDIV*/ -+#define RSTV0910_P1_ACRDIV 0xf71f -+#define FSTV0910_P1_ACR_DIV 0xf71f00ff -+ -+/*P2_DISIRQCFG*/ -+#define RSTV0910_P2_DISIRQCFG 0xf740 -+#define FSTV0910_P2_ENRXEND 0xf7400040 -+#define FSTV0910_P2_ENRXFIFO8B 0xf7400020 -+#define FSTV0910_P2_ENTRFINISH 0xf7400010 -+#define FSTV0910_P2_ENTIMEOUT 0xf7400008 -+#define FSTV0910_P2_ENTXEND 0xf7400004 -+#define FSTV0910_P2_ENTXFIFO64B 0xf7400002 -+#define FSTV0910_P2_ENGAPBURST 0xf7400001 -+ -+/*P2_DISIRQSTAT*/ -+#define RSTV0910_P2_DISIRQSTAT 0xf741 -+#define FSTV0910_P2_IRQRXEND 0xf7410040 -+#define FSTV0910_P2_IRQRXFIFO8B 0xf7410020 -+#define FSTV0910_P2_IRQTRFINISH 0xf7410010 -+#define FSTV0910_P2_IRQTIMEOUT 0xf7410008 -+#define FSTV0910_P2_IRQTXEND 0xf7410004 -+#define FSTV0910_P2_IRQTXFIFO64B 0xf7410002 -+#define FSTV0910_P2_IRQGAPBURST 0xf7410001 -+ -+/*P2_DISTXCFG*/ -+#define RSTV0910_P2_DISTXCFG 0xf742 -+#define FSTV0910_P2_DISTX_RESET 0xf7420080 -+#define FSTV0910_P2_TIM_OFF 0xf7420040 -+#define FSTV0910_P2_TIM_CMD 0xf7420030 -+#define FSTV0910_P2_ENVELOP 0xf7420008 -+#define FSTV0910_P2_DIS_PRECHARGE 0xf7420004 -+#define FSTV0910_P2_DISEQC_MODE 0xf7420003 -+ -+/*P2_DISTXSTATUS*/ -+#define RSTV0910_P2_DISTXSTATUS 0xf743 -+#define FSTV0910_P2_TX_FIFO_FULL 0xf7430040 -+#define FSTV0910_P2_TX_IDLE 0xf7430020 -+#define FSTV0910_P2_GAP_BURST 0xf7430010 -+#define FSTV0910_P2_TX_FIFO64B 0xf7430008 -+#define FSTV0910_P2_TX_END 0xf7430004 -+#define FSTV0910_P2_TR_TIMEOUT 0xf7430002 -+#define FSTV0910_P2_TR_FINISH 0xf7430001 -+ -+/*P2_DISTXBYTES*/ -+#define RSTV0910_P2_DISTXBYTES 0xf744 -+#define FSTV0910_P2_TXFIFO_BYTES 0xf74400ff -+ -+/*P2_DISTXFIFO*/ -+#define RSTV0910_P2_DISTXFIFO 0xf745 -+#define FSTV0910_P2_DISEQC_TX_FIFO 0xf74500ff -+ -+/*P2_DISTXF22*/ -+#define RSTV0910_P2_DISTXF22 0xf746 -+#define FSTV0910_P2_F22TX 0xf74600ff -+ -+/*P2_DISTIMEOCFG*/ -+#define RSTV0910_P2_DISTIMEOCFG 0xf748 -+#define FSTV0910_P2_RXCHOICE 0xf7480006 -+#define FSTV0910_P2_TIMEOUT_OFF 0xf7480001 -+ -+/*P2_DISTIMEOUT*/ -+#define RSTV0910_P2_DISTIMEOUT 0xf749 -+#define FSTV0910_P2_TIMEOUT_COUNT 0xf74900ff -+ -+/*P2_DISRXCFG*/ -+#define RSTV0910_P2_DISRXCFG 0xf74a -+#define FSTV0910_P2_DISRX_RESET 0xf74a0080 -+#define FSTV0910_P2_EXTENVELOP 0xf74a0040 -+#define FSTV0910_P2_PINSELECT 0xf74a0038 -+#define FSTV0910_P2_IGNORE_SHORT22K 0xf74a0004 -+#define FSTV0910_P2_SIGNED_RXIN 0xf74a0002 -+#define FSTV0910_P2_DISRX_ON 0xf74a0001 -+ -+/*P2_DISRXSTAT1*/ -+#define RSTV0910_P2_DISRXSTAT1 0xf74b -+#define FSTV0910_P2_RXEND 0xf74b0080 -+#define FSTV0910_P2_RXACTIVE 0xf74b0040 -+#define FSTV0910_P2_RXDETECT 0xf74b0020 -+#define FSTV0910_P2_CONTTONE 0xf74b0010 -+#define FSTV0910_P2_8BFIFOREADY 0xf74b0008 -+#define FSTV0910_P2_FIFOEMPTY 0xf74b0004 -+ -+/*P2_DISRXSTAT0*/ -+#define RSTV0910_P2_DISRXSTAT0 0xf74c -+#define FSTV0910_P2_RXFAIL 0xf74c0080 -+#define FSTV0910_P2_FIFOPFAIL 0xf74c0040 -+#define FSTV0910_P2_RXNONBYTE 0xf74c0020 -+#define FSTV0910_P2_FIFOOVF 0xf74c0010 -+#define FSTV0910_P2_SHORT22K 0xf74c0008 -+#define FSTV0910_P2_RXMSGLOST 0xf74c0004 -+ -+/*P2_DISRXBYTES*/ -+#define RSTV0910_P2_DISRXBYTES 0xf74d -+#define FSTV0910_P2_RXFIFO_BYTES 0xf74d001f -+ -+/*P2_DISRXPARITY1*/ -+#define RSTV0910_P2_DISRXPARITY1 0xf74e -+#define FSTV0910_P2_DISRX_PARITY1 0xf74e00ff -+ -+/*P2_DISRXPARITY0*/ -+#define RSTV0910_P2_DISRXPARITY0 0xf74f -+#define FSTV0910_P2_DISRX_PARITY0 0xf74f00ff -+ -+/*P2_DISRXFIFO*/ -+#define RSTV0910_P2_DISRXFIFO 0xf750 -+#define FSTV0910_P2_DISEQC_RX_FIFO 0xf75000ff -+ -+/*P2_DISRXDC1*/ -+#define RSTV0910_P2_DISRXDC1 0xf751 -+#define FSTV0910_P2_DC_VALUE1 0xf7510103 -+ -+/*P2_DISRXDC0*/ -+#define RSTV0910_P2_DISRXDC0 0xf752 -+#define FSTV0910_P2_DC_VALUE0 0xf75200ff -+ -+/*P2_DISRXF221*/ -+#define RSTV0910_P2_DISRXF221 0xf754 -+#define FSTV0910_P2_F22RX1 0xf754000f -+ -+/*P2_DISRXF220*/ -+#define RSTV0910_P2_DISRXF220 0xf755 -+#define FSTV0910_P2_F22RX0 0xf75500ff -+ -+/*P2_DISRXF100*/ -+#define RSTV0910_P2_DISRXF100 0xf756 -+#define FSTV0910_P2_F100RX 0xf75600ff -+ -+/*P2_DISRXSHORT22K*/ -+#define RSTV0910_P2_DISRXSHORT22K 0xf75c -+#define FSTV0910_P2_SHORT22K_LENGTH 0xf75c001f -+ -+/*P2_ACRPRESC*/ -+#define RSTV0910_P2_ACRPRESC 0xf75e -+#define FSTV0910_P2_ACR_CODFRDY 0xf75e0008 -+#define FSTV0910_P2_ACR_PRESC 0xf75e0007 -+ -+/*P2_ACRDIV*/ -+#define RSTV0910_P2_ACRDIV 0xf75f -+#define FSTV0910_P2_ACR_DIV 0xf75f00ff -+ -+/*P1_NBITER_NF4*/ -+#define RSTV0910_P1_NBITER_NF4 0xfa03 -+#define FSTV0910_P1_NBITER_NF_QPSK_1_2 0xfa0300ff -+ -+/*P1_NBITER_NF5*/ -+#define RSTV0910_P1_NBITER_NF5 0xfa04 -+#define FSTV0910_P1_NBITER_NF_QPSK_3_5 0xfa0400ff -+ -+/*P1_NBITER_NF6*/ -+#define RSTV0910_P1_NBITER_NF6 0xfa05 -+#define FSTV0910_P1_NBITER_NF_QPSK_2_3 0xfa0500ff -+ -+/*P1_NBITER_NF7*/ -+#define RSTV0910_P1_NBITER_NF7 0xfa06 -+#define FSTV0910_P1_NBITER_NF_QPSK_3_4 0xfa0600ff -+ -+/*P1_NBITER_NF8*/ -+#define RSTV0910_P1_NBITER_NF8 0xfa07 -+#define FSTV0910_P1_NBITER_NF_QPSK_4_5 0xfa0700ff -+ -+/*P1_NBITER_NF9*/ -+#define RSTV0910_P1_NBITER_NF9 0xfa08 -+#define FSTV0910_P1_NBITER_NF_QPSK_5_6 0xfa0800ff -+ -+/*P1_NBITER_NF10*/ -+#define RSTV0910_P1_NBITER_NF10 0xfa09 -+#define FSTV0910_P1_NBITER_NF_QPSK_8_9 0xfa0900ff -+ -+/*P1_NBITER_NF11*/ -+#define RSTV0910_P1_NBITER_NF11 0xfa0a -+#define FSTV0910_P1_NBITER_NF_QPSK_9_10 0xfa0a00ff -+ -+/*P1_NBITER_NF12*/ -+#define RSTV0910_P1_NBITER_NF12 0xfa0b -+#define FSTV0910_P1_NBITER_NF_8PSK_3_5 0xfa0b00ff -+ -+/*P1_NBITER_NF13*/ -+#define RSTV0910_P1_NBITER_NF13 0xfa0c -+#define FSTV0910_P1_NBITER_NF_8PSK_2_3 0xfa0c00ff -+ -+/*P1_NBITER_NF14*/ -+#define RSTV0910_P1_NBITER_NF14 0xfa0d -+#define FSTV0910_P1_NBITER_NF_8PSK_3_4 0xfa0d00ff -+ -+/*P1_NBITER_NF15*/ -+#define RSTV0910_P1_NBITER_NF15 0xfa0e -+#define FSTV0910_P1_NBITER_NF_8PSK_5_6 0xfa0e00ff -+ -+/*P1_NBITER_NF16*/ -+#define RSTV0910_P1_NBITER_NF16 0xfa0f -+#define FSTV0910_P1_NBITER_NF_8PSK_8_9 0xfa0f00ff -+ -+/*P1_NBITER_NF17*/ -+#define RSTV0910_P1_NBITER_NF17 0xfa10 -+#define FSTV0910_P1_NBITER_NF_8PSK_9_10 0xfa1000ff -+ -+/*GAINLLR_NF4*/ -+#define RSTV0910_GAINLLR_NF4 0xfa43 -+#define FSTV0910_GAINLLR_NF_QPSK_1_2 0xfa43007f -+ -+/*GAINLLR_NF5*/ -+#define RSTV0910_GAINLLR_NF5 0xfa44 -+#define FSTV0910_GAINLLR_NF_QPSK_3_5 0xfa44007f -+ -+/*GAINLLR_NF6*/ -+#define RSTV0910_GAINLLR_NF6 0xfa45 -+#define FSTV0910_GAINLLR_NF_QPSK_2_3 0xfa45007f -+ -+/*GAINLLR_NF7*/ -+#define RSTV0910_GAINLLR_NF7 0xfa46 -+#define FSTV0910_GAINLLR_NF_QPSK_3_4 0xfa46007f -+ -+/*GAINLLR_NF8*/ -+#define RSTV0910_GAINLLR_NF8 0xfa47 -+#define FSTV0910_GAINLLR_NF_QPSK_4_5 0xfa47007f -+ -+/*GAINLLR_NF9*/ -+#define RSTV0910_GAINLLR_NF9 0xfa48 -+#define FSTV0910_GAINLLR_NF_QPSK_5_6 0xfa48007f -+ -+/*GAINLLR_NF10*/ -+#define RSTV0910_GAINLLR_NF10 0xfa49 -+#define FSTV0910_GAINLLR_NF_QPSK_8_9 0xfa49007f -+ -+/*GAINLLR_NF11*/ -+#define RSTV0910_GAINLLR_NF11 0xfa4a -+#define FSTV0910_GAINLLR_NF_QPSK_9_10 0xfa4a007f -+ -+/*GAINLLR_NF12*/ -+#define RSTV0910_GAINLLR_NF12 0xfa4b -+#define FSTV0910_GAINLLR_NF_8PSK_3_5 0xfa4b007f -+ -+/*GAINLLR_NF13*/ -+#define RSTV0910_GAINLLR_NF13 0xfa4c -+#define FSTV0910_GAINLLR_NF_8PSK_2_3 0xfa4c007f -+ -+/*GAINLLR_NF14*/ -+#define RSTV0910_GAINLLR_NF14 0xfa4d -+#define FSTV0910_GAINLLR_NF_8PSK_3_4 0xfa4d007f -+ -+/*GAINLLR_NF15*/ -+#define RSTV0910_GAINLLR_NF15 0xfa4e -+#define FSTV0910_GAINLLR_NF_8PSK_5_6 0xfa4e007f -+ -+/*GAINLLR_NF16*/ -+#define RSTV0910_GAINLLR_NF16 0xfa4f -+#define FSTV0910_GAINLLR_NF_8PSK_8_9 0xfa4f007f -+ -+/*GAINLLR_NF17*/ -+#define RSTV0910_GAINLLR_NF17 0xfa50 -+#define FSTV0910_GAINLLR_NF_8PSK_9_10 0xfa50007f -+ -+/*CFGEXT*/ -+#define RSTV0910_CFGEXT 0xfa80 -+#define FSTV0910_BYPFIFOBCH 0xfa800080 -+#define FSTV0910_BYPBCH 0xfa800040 -+#define FSTV0910_BYPLDPC 0xfa800020 -+#define FSTV0910_BYPFIFOBCHF 0xfa800010 -+#define FSTV0910_INVLLRSIGN 0xfa800008 -+#define FSTV0910_SHORTMULT 0xfa800004 -+#define FSTV0910_ENSTOPDEC 0xfa800002 -+ -+/*GENCFG*/ -+#define RSTV0910_GENCFG 0xfa86 -+#define FSTV0910_LEG_ITER 0xfa860040 -+#define FSTV0910_NOSHFRD1 0xfa860020 -+#define FSTV0910_BROADCAST 0xfa860010 -+#define FSTV0910_NOSHFRD2 0xfa860008 -+#define FSTV0910_BCHERRFLAG 0xfa860004 -+#define FSTV0910_CROSSINPUT 0xfa860002 -+#define FSTV0910_DDEMOD 0xfa860001 -+ -+/*LDPCERR1*/ -+#define RSTV0910_LDPCERR1 0xfa96 -+#define FSTV0910_LDPC_ERRORS1 0xfa9600ff -+ -+/*LDPCERR0*/ -+#define RSTV0910_LDPCERR0 0xfa97 -+#define FSTV0910_LDPC_ERRORS0 0xfa9700ff -+ -+/*BCHERR*/ -+#define RSTV0910_BCHERR 0xfa98 -+#define FSTV0910_ERRORFLAG 0xfa980010 -+#define FSTV0910_BCH_ERRORS_COUNTER 0xfa98000f -+ -+/*P1_MAXEXTRAITER*/ -+#define RSTV0910_P1_MAXEXTRAITER 0xfab1 -+#define FSTV0910_P1_MAX_EXTRA_ITER 0xfab100ff -+ -+/*P2_MAXEXTRAITER*/ -+#define RSTV0910_P2_MAXEXTRAITER 0xfab6 -+#define FSTV0910_P2_MAX_EXTRA_ITER 0xfab600ff -+ -+/*P1_STATUSITER*/ -+#define RSTV0910_P1_STATUSITER 0xfabc -+#define FSTV0910_P1_STATUS_ITER 0xfabc00ff -+ -+/*P1_STATUSMAXITER*/ -+#define RSTV0910_P1_STATUSMAXITER 0xfabd -+#define FSTV0910_P1_STATUS_MAX_ITER 0xfabd00ff -+ -+/*P2_STATUSITER*/ -+#define RSTV0910_P2_STATUSITER 0xfabe -+#define FSTV0910_P2_STATUS_ITER 0xfabe00ff -+ -+/*P2_STATUSMAXITER*/ -+#define RSTV0910_P2_STATUSMAXITER 0xfabf -+#define FSTV0910_P2_STATUS_MAX_ITER 0xfabf00ff -+ -+/*P2_NBITER_NF4*/ -+#define RSTV0910_P2_NBITER_NF4 0xfac3 -+#define FSTV0910_P2_NBITER_NF_QPSK_1_2 0xfac300ff -+ -+/*P2_NBITER_NF5*/ -+#define RSTV0910_P2_NBITER_NF5 0xfac4 -+#define FSTV0910_P2_NBITER_NF_QPSK_3_5 0xfac400ff -+ -+/*P2_NBITER_NF6*/ -+#define RSTV0910_P2_NBITER_NF6 0xfac5 -+#define FSTV0910_P2_NBITER_NF_QPSK_2_3 0xfac500ff -+ -+/*P2_NBITER_NF7*/ -+#define RSTV0910_P2_NBITER_NF7 0xfac6 -+#define FSTV0910_P2_NBITER_NF_QPSK_3_4 0xfac600ff -+ -+/*P2_NBITER_NF8*/ -+#define RSTV0910_P2_NBITER_NF8 0xfac7 -+#define FSTV0910_P2_NBITER_NF_QPSK_4_5 0xfac700ff -+ -+/*P2_NBITER_NF9*/ -+#define RSTV0910_P2_NBITER_NF9 0xfac8 -+#define FSTV0910_P2_NBITER_NF_QPSK_5_6 0xfac800ff -+ -+/*P2_NBITER_NF10*/ -+#define RSTV0910_P2_NBITER_NF10 0xfac9 -+#define FSTV0910_P2_NBITER_NF_QPSK_8_9 0xfac900ff -+ -+/*P2_NBITER_NF11*/ -+#define RSTV0910_P2_NBITER_NF11 0xfaca -+#define FSTV0910_P2_NBITER_NF_QPSK_9_10 0xfaca00ff -+ -+/*P2_NBITER_NF12*/ -+#define RSTV0910_P2_NBITER_NF12 0xfacb -+#define FSTV0910_P2_NBITER_NF_8PSK_3_5 0xfacb00ff -+ -+/*P2_NBITER_NF13*/ -+#define RSTV0910_P2_NBITER_NF13 0xfacc -+#define FSTV0910_P2_NBITER_NF_8PSK_2_3 0xfacc00ff -+ -+/*P2_NBITER_NF14*/ -+#define RSTV0910_P2_NBITER_NF14 0xfacd -+#define FSTV0910_P2_NBITER_NF_8PSK_3_4 0xfacd00ff -+ -+/*P2_NBITER_NF15*/ -+#define RSTV0910_P2_NBITER_NF15 0xface -+#define FSTV0910_P2_NBITER_NF_8PSK_5_6 0xface00ff -+ -+/*P2_NBITER_NF16*/ -+#define RSTV0910_P2_NBITER_NF16 0xfacf -+#define FSTV0910_P2_NBITER_NF_8PSK_8_9 0xfacf00ff -+ -+/*P2_NBITER_NF17*/ -+#define RSTV0910_P2_NBITER_NF17 0xfad0 -+#define FSTV0910_P2_NBITER_NF_8PSK_9_10 0xfad000ff -+ -+/*TSTRES0*/ -+#define RSTV0910_TSTRES0 0xff11 -+#define FSTV0910_FRESFEC 0xff110080 -+#define FSTV0910_FRESTS 0xff110040 -+#define FSTV0910_FRESVIT1 0xff110020 -+#define FSTV0910_FRESVIT2 0xff110010 -+#define FSTV0910_FRESSYM1 0xff110008 -+#define FSTV0910_FRESSYM2 0xff110004 -+#define FSTV0910_FRESMAS 0xff110002 -+#define FSTV0910_FRESINT 0xff110001 -+ -+/*P2_TCTL4*/ -+#define RSTV0910_P2_TCTL4 0xff28 -+#define FSTV0910_P2_CFR2TOCFR1_DVBS1 0xff2800c0 -+#define FSTV0910_P2_TSTINV_PHERR 0xff280020 -+#define FSTV0910_P2_EN_PLHCALC 0xff280010 -+#define FSTV0910_P2_TETA3L_RSTTETA3D 0xff280008 -+#define FSTV0910_P2_DIS_FORCEBETA2 0xff280004 -+#define FSTV0910_P2_CAR3_NOTRACEBACK 0xff280002 -+#define FSTV0910_P2_CAR3_NOFORWARD 0xff280001 -+ -+/*P1_TCTL4*/ -+#define RSTV0910_P1_TCTL4 0xff48 -+#define FSTV0910_P1_CFR2TOCFR1_DVBS1 0xff4800c0 -+#define FSTV0910_P1_TSTINV_PHERR 0xff480020 -+#define FSTV0910_P1_EN_PLHCALC 0xff480010 -+#define FSTV0910_P1_TETA3L_RSTTETA3D 0xff480008 -+#define FSTV0910_P1_DIS_FORCEBETA2 0xff480004 -+#define FSTV0910_P1_CAR3_NOTRACEBACK 0xff480002 -+#define FSTV0910_P1_CAR3_NOFORWARD 0xff480001 -+ -+#define STV0910_NBREGS 735 -+#define STV0910_NBFIELDS 1776 -+ -diff --git a/drivers/media/dvb-frontends/tas2101.c b/drivers/media/dvb-frontends/tas2101.c -new file mode 100644 -index 0000000..6e6d0b8 ---- /dev/null -+++ b/drivers/media/dvb-frontends/tas2101.c -@@ -0,0 +1,897 @@ -+/* -+ Tmax TAS2101 - DVBS/S2 Satellite demodulator driver -+ -+ Copyright (C) 2014 Luis Alves -+ -+ 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. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dvb_frontend.h" -+ -+#include "tas2101.h" -+#include "tas2101_priv.h" -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0) -+#if IS_ENABLED(CONFIG_I2C_MUX) -+#define TAS2101_USE_I2C_MUX -+#endif -+#endif -+ -+/* return i2c adapter */ -+/* bus = 0 master */ -+/* bus = 1 demod */ -+/* bus = 2 tuner */ -+struct i2c_adapter *tas2101_get_i2c_adapter(struct dvb_frontend *fe, int bus) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ switch (bus) { -+ case 0: -+ default: -+ return priv->i2c; -+ case 1: -+ return priv->i2c_demod; -+ case 2: -+ return priv->i2c_tuner; -+ } -+} -+EXPORT_SYMBOL_GPL(tas2101_get_i2c_adapter); -+ -+/* write multiple (continuous) registers */ -+/* the first value is the starting address */ -+static int tas2101_wrm(struct tas2101_priv *priv, u8 *buf, int len) -+{ -+ int ret; -+ struct i2c_msg msg = { -+ .addr = priv->cfg->i2c_address, -+ .flags = 0, .buf = buf, .len = len }; -+ -+ dev_dbg(&priv->i2c->dev, "%s() i2c wrm @0x%02x (len=%d)\n", -+ __func__, buf[0], len); -+ -+ ret = i2c_transfer(priv->i2c_demod, &msg, 1); -+ if (ret < 0) { -+ dev_warn(&priv->i2c->dev, -+ "%s: i2c wrm err(%i) @0x%02x (len=%d)\n", -+ KBUILD_MODNAME, ret, buf[0], len); -+ return ret; -+ } -+ return 0; -+} -+ -+/* write one register */ -+static int tas2101_wr(struct tas2101_priv *priv, u8 addr, u8 data) -+{ -+ u8 buf[] = { addr, data }; -+ return tas2101_wrm(priv, buf, 2); -+} -+ -+/* read multiple (continuous) registers starting at addr */ -+static int tas2101_rdm(struct tas2101_priv *priv, u8 addr, u8 *buf, int len) -+{ -+ int ret; -+ struct i2c_msg msg[] = { -+ { .addr = priv->cfg->i2c_address, .flags = 0, -+ .buf = &addr, .len = 1 }, -+ { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, -+ .buf = buf, .len = len } -+ }; -+ -+ dev_dbg(&priv->i2c->dev, "%s() i2c rdm @0x%02x (len=%d)\n", -+ __func__, addr, len); -+ -+ ret = i2c_transfer(priv->i2c_demod, msg, 2); -+ if (ret < 0) { -+ dev_warn(&priv->i2c->dev, -+ "%s: i2c rdm err(%i) @0x%02x (len=%d)\n", -+ KBUILD_MODNAME, ret, addr, len); -+ return ret; -+ } -+ return 0; -+} -+ -+/* read one register */ -+static int tas2101_rd(struct tas2101_priv *priv, u8 addr, u8 *data) -+{ -+ return tas2101_rdm(priv, addr, data, 1); -+} -+ -+static int tas2101_regmask(struct tas2101_priv *priv, -+ u8 reg, u8 setmask, u8 clrmask) -+{ -+ int ret; -+ u8 b = 0; -+ if (clrmask != 0xff) { -+ ret = tas2101_rd(priv, reg, &b); -+ if (ret) -+ return ret; -+ b &= ~clrmask; -+ } -+ return tas2101_wr(priv, reg, b | setmask); -+} -+ -+static int tas2101_wrtable(struct tas2101_priv *priv, -+ struct tas2101_regtable *regtable, int len) -+{ -+ int ret, i; -+ -+ for (i = 0; i < len; i++) { -+ ret = tas2101_regmask(priv, regtable[i].addr, -+ regtable[i].setmask, regtable[i].clrmask); -+ if (ret) -+ return ret; -+ if (regtable[i].sleep) -+ msleep(regtable[i].sleep); -+ } -+ return 0; -+} -+ -+static int tas2101_read_ber(struct dvb_frontend *fe, u32 *ber) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int ret; -+ u8 buf[4]; -+ -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ -+ switch (c->delivery_system) { -+ case SYS_DVBS: -+ ret = tas2101_rdm(priv, S1_BER_0, buf, 4); -+ if (ret) -+ return ret; -+ -+ *ber = ((((u32) buf[3] & 3) << 24) | (((u32) buf[2]) << 16) -+ | (((u32) buf[1]) << 8) | ((u32) buf[0])); -+ break; -+ -+ case SYS_DVBS2: -+ ret = tas2101_rdm(priv, S2_BER_0, buf, 2); -+ if (ret) -+ return ret; -+ -+ *ber = ((((u32) buf[1]) << 8) | ((u32) buf[0])); -+ break; -+ -+ default: -+ *ber = 0; -+ break; -+ } -+ -+ dev_dbg(&priv->i2c->dev, "%s() ber = %d\n", __func__, *ber); -+ return 0; -+} -+ -+static int tas2101_read_signal_strength(struct dvb_frontend *fe, -+ u16 *signal_strength) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ int ret, i; -+ long val, dbm_raw; -+ u8 buf[2]; -+ -+ ret = tas2101_rdm(priv, SIGSTR_0, buf, 2); -+ if (ret) -+ return ret; -+ -+ dbm_raw = (((u16)buf[1] & 0x0f) << 8) | buf[0]; -+ -+ for (i = 0; i < ARRAY_SIZE(tas2101_dbmtable) - 1; i++) -+ if (tas2101_dbmtable[i].raw < dbm_raw) -+ break; -+ -+ if( i == 0 ) -+ *signal_strength = tas2101_dbmtable[i].dbm; -+ else -+ { -+ /* linear interpolation between two calibrated values */ -+ val = (dbm_raw - tas2101_dbmtable[i].raw) * tas2101_dbmtable[i-1].dbm; -+ val += (tas2101_dbmtable[i-1].raw - dbm_raw) * tas2101_dbmtable[i].dbm; -+ val /= (tas2101_dbmtable[i-1].raw - tas2101_dbmtable[i].raw); -+ -+ *signal_strength = (u16)val; -+ } -+ -+ dev_dbg(&priv->i2c->dev, "%s() strength = 0x%04x\n", -+ __func__, *signal_strength); -+ return 0; -+} -+ -+static int tas2101_read_snr(struct dvb_frontend *fe, u16 *snr) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int ret, i; -+ long val; -+ u16 snr_raw; -+ u8 buf[2]; -+ -+ ret = tas2101_rdm(priv, SNR_0, buf, 2); -+ if (ret) -+ return ret; -+ -+ snr_raw = (((u16)buf[1] & 0x0f) << 8) | buf[0]; -+ -+ for (i = 0; i < ARRAY_SIZE(tas2101_snrtable) - 1; i++) -+ if (tas2101_snrtable[i].raw < snr_raw) -+ break; -+ -+ if( i == 0 ) -+ val = tas2101_snrtable[i].snr; -+ else -+ { -+ /* linear interpolation between two calibrated values */ -+ val = (snr_raw - tas2101_snrtable[i].raw) * tas2101_snrtable[i-1].snr; -+ val += (tas2101_snrtable[i-1].raw - snr_raw) * tas2101_snrtable[i].snr; -+ val /= (tas2101_snrtable[i-1].raw - tas2101_snrtable[i].raw); -+ } -+ -+ c->cnr.len = 1; -+ c->cnr.stat[0].scale = FE_SCALE_DECIBEL; -+ c->cnr.stat[0].uvalue = 100 * (s64) val; -+ -+ *snr = (u16) val * 328; /* 20dB = 100% */ -+ -+ dev_dbg(&priv->i2c->dev, "%s() snr = 0x%04x\n", -+ __func__, *snr); -+ -+ return 0; -+} -+ -+/* unimplemented */ -+static int tas2101_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ *ucblocks = 0; -+ return 0; -+} -+ -+static int tas2101_read_status(struct dvb_frontend *fe, enum fe_status *status) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ int ret; -+ u8 reg; -+ u16 snr; -+ -+ *status = 0; -+ -+ ret = tas2101_rd(priv, DEMOD_STATUS, ®); -+ if (ret) -+ return ret; -+ -+ reg &= DEMOD_STATUS_MASK; -+ if (reg == DEMOD_LOCKED) { -+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | -+ FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; -+ -+ ret = tas2101_rd(priv, REG_04, ®); -+ if (ret) -+ return ret; -+ if (reg & 0x08) -+ ret = tas2101_wr(priv, REG_04, reg & ~0x08); -+ -+ tas2101_read_snr(fe, &snr); -+ } -+ -+ dev_dbg(&priv->i2c->dev, "%s() status = 0x%02x\n", __func__, *status); -+ return ret; -+} -+ -+static int tas2101_set_voltage(struct dvb_frontend *fe, -+ enum fe_sec_voltage voltage) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ int ret = 0; -+ -+ dev_dbg(&priv->i2c->dev, "%s() %s\n", __func__, -+ voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : -+ voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : -+ "SEC_VOLTAGE_OFF"); -+ -+ switch (voltage) { -+ case SEC_VOLTAGE_13: -+ if (priv->cfg->lnb_power) -+ priv->cfg->lnb_power(fe, LNB_ON); -+ ret = tas2101_regmask(priv, LNB_CTRL, -+ 0, VSEL13_18); -+ break; -+ case SEC_VOLTAGE_18: -+ if (priv->cfg->lnb_power) -+ priv->cfg->lnb_power(fe, LNB_ON); -+ ret = tas2101_regmask(priv, LNB_CTRL, -+ VSEL13_18, 0); -+ break; -+ default: /* OFF */ -+ if (priv->cfg->lnb_power) -+ priv->cfg->lnb_power(fe, LNB_OFF); -+ break; -+ } -+ return ret; -+} -+ -+static int tas2101_set_tone(struct dvb_frontend *fe, -+ enum fe_sec_tone_mode tone) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ int ret = -EINVAL; -+ -+ dev_dbg(&priv->i2c->dev, "%s() %s\n", __func__, -+ tone == SEC_TONE_ON ? "SEC_TONE_ON" : "SEC_TONE_OFF"); -+ -+ switch (tone) { -+ case SEC_TONE_ON: -+ ret = tas2101_regmask(priv, LNB_CTRL, -+ TONE_ON, DISEQC_CMD_MASK); -+ break; -+ case SEC_TONE_OFF: -+ ret = tas2101_regmask(priv, LNB_CTRL, -+ TONE_OFF, DISEQC_CMD_MASK); -+ break; -+ default: -+ dev_warn(&priv->i2c->dev, "%s() invalid tone (%d)\n", -+ __func__, tone); -+ break; -+ } -+ return ret; -+} -+ -+static int tas2101_send_diseqc_msg(struct dvb_frontend *fe, -+ struct dvb_diseqc_master_cmd *d) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ int ret, i; -+ u8 bck, buf[9]; -+ -+ /* dump DiSEqC message */ -+ dev_dbg(&priv->i2c->dev, "%s() ( ", __func__); -+ for (i = 0; i < d->msg_len; i++) -+ dev_dbg(&priv->i2c->dev, "0x%02x ", d->msg[i]); -+ dev_dbg(&priv->i2c->dev, ")\n"); -+ -+ /* backup LNB tone state */ -+ ret = tas2101_rd(priv, LNB_CTRL, &bck); -+ if (ret) -+ return ret; -+ -+ ret = tas2101_regmask(priv, REG_34, 0, 0x40); -+ if (ret) -+ goto exit; -+ -+ /* setup DISEqC message to demod */ -+ buf[0] = DISEQC_BUFFER; -+ memcpy(&buf[1], d->msg, 8); -+ ret = tas2101_wrm(priv, buf, d->msg_len + 1); -+ if (ret) -+ goto exit; -+ -+ /* send DISEqC send command */ -+ buf[0] = (bck & ~(DISEQC_CMD_LEN_MASK | DISEQC_CMD_MASK)) | -+ DISEQC_SEND_MSG | ((d->msg_len - 1) << 3); -+ ret = tas2101_wr(priv, LNB_CTRL, buf[0]); -+ if (ret) -+ goto exit; -+ -+ /* wait at least diseqc typical tx time */ -+ msleep(54); -+ -+ /* Wait for busy flag to clear */ -+ for (i = 0; i < 10; i++) { -+ ret = tas2101_rd(priv, LNB_STATUS, &buf[0]); -+ if (ret) -+ break; -+ if (buf[0] & DISEQC_BUSY) -+ goto exit; -+ msleep(20); -+ } -+ -+ /* try to restore the tone setting but return a timeout error */ -+ ret = tas2101_wr(priv, LNB_CTRL, bck); -+ dev_warn(&priv->i2c->dev, "%s() timeout sending burst\n", __func__); -+ return -ETIMEDOUT; -+exit: -+ /* restore tone setting */ -+ return tas2101_wr(priv, LNB_CTRL, bck); -+} -+ -+static int tas2101_diseqc_send_burst(struct dvb_frontend *fe, -+ enum fe_sec_mini_cmd burst) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ int ret, i; -+ u8 bck, r; -+ -+ if ((burst != SEC_MINI_A) && (burst != SEC_MINI_B)) { -+ dev_err(&priv->i2c->dev, "%s() invalid burst(%d)\n", -+ __func__, burst); -+ return -EINVAL; -+ } -+ -+ dev_dbg(&priv->i2c->dev, "%s() %s\n", __func__, -+ burst == SEC_MINI_A ? "SEC_MINI_A" : "SEC_MINI_B"); -+ -+ /* backup LNB tone state */ -+ ret = tas2101_rd(priv, LNB_CTRL, &bck); -+ if (ret) -+ return ret; -+ -+ ret = tas2101_regmask(priv, REG_34, 0, 0x40); -+ if (ret) -+ goto exit; -+ -+ /* set tone burst cmd */ -+ r = (bck & ~DISEQC_CMD_MASK) | -+ (burst == SEC_MINI_A) ? DISEQC_BURST_A : DISEQC_BURST_B; -+ -+ ret = tas2101_wr(priv, LNB_CTRL, r); -+ if (ret) -+ goto exit; -+ -+ /* spec = around 12.5 ms for the burst */ -+ for (i = 0; i < 10; i++) { -+ ret = tas2101_rd(priv, LNB_STATUS, &r); -+ if (ret) -+ break; -+ if (r & DISEQC_BUSY) -+ goto exit; -+ msleep(20); -+ } -+ -+ /* try to restore the tone setting but return a timeout error */ -+ ret = tas2101_wr(priv, LNB_CTRL, bck); -+ dev_warn(&priv->i2c->dev, "%s() timeout sending burst\n", __func__); -+ return -ETIMEDOUT; -+exit: -+ /* restore tone setting */ -+ return tas2101_wr(priv, LNB_CTRL, bck); -+} -+ -+static void tas2101_release(struct dvb_frontend *fe) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ -+ dev_dbg(&priv->i2c->dev, "%s\n", __func__); -+#ifdef TAS2101_USE_I2C_MUX -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) -+ i2c_mux_del_adapters(priv->muxc); -+#else -+ i2c_del_mux_adapter(priv->i2c_demod); -+ i2c_del_mux_adapter(priv->i2c_tuner); -+#endif -+#endif -+ kfree(priv); -+} -+ -+#ifdef TAS2101_USE_I2C_MUX -+/* channel 0: demod */ -+/* channel 1: tuner */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) -+static int tas2101_i2c_select(struct i2c_mux_core *muxc, u32 chan_id) -+{ -+ struct tas2101_priv *priv = i2c_mux_priv(muxc); -+ struct i2c_adapter *adap = priv->i2c; -+#else -+static int tas2101_i2c_select(struct i2c_adapter *adap, -+ void *mux_priv, u32 chan_id) -+{ -+ struct tas2101_priv *priv = mux_priv; -+#endif -+ int ret; -+ u8 buf[2]; -+ struct i2c_msg msg_wr[] = { -+ { .addr = priv->cfg->i2c_address, .flags = 0, -+ .buf = buf, .len = 2 } -+ }; -+ struct i2c_msg msg_rd[] = { -+ { .addr = priv->cfg->i2c_address, .flags = 0, -+ .buf = &buf[0], .len = 1 }, -+ { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, -+ .buf = &buf[1], .len = 1 } -+ }; -+ -+ dev_dbg(&priv->i2c->dev, "%s() ch=%d\n", __func__, chan_id); -+ -+ if (priv->i2c_ch == chan_id) -+ return 0; -+ -+ buf[0] = REG_06; -+ ret = __i2c_transfer(adap, msg_rd, 2); -+ if (ret != 2) -+ goto err; -+ -+ if (chan_id == 0) -+ buf[1] &= ~I2C_GATE; -+ else -+ buf[1] |= I2C_GATE; -+ -+ ret = __i2c_transfer(adap, msg_wr, 1); -+ if (ret != 1) -+ goto err; -+ -+ priv->i2c_ch = chan_id; -+ -+ return 0; -+err: -+ dev_dbg(&priv->i2c->dev, "%s() failed=%d\n", __func__, ret); -+ return -EREMOTEIO; -+} -+#endif -+ -+static struct dvb_frontend_ops tas2101_ops; -+ -+struct dvb_frontend *tas2101_attach(const struct tas2101_config *cfg, -+ struct i2c_adapter *i2c) -+{ -+ struct tas2101_priv *priv = NULL; -+ int ret; -+ u8 id[2]; -+ -+ dev_dbg(&i2c->dev, "%s: Attaching frontend\n", KBUILD_MODNAME); -+ -+ /* allocate memory for the priv data */ -+ priv = kzalloc(sizeof(struct tas2101_priv), GFP_KERNEL); -+ if (priv == NULL) -+ goto err; -+ -+ priv->cfg = cfg; -+ priv->i2c = i2c; -+ priv->i2c_ch = 0; -+ -+#ifdef TAS2101_USE_I2C_MUX -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) -+ /* create mux i2c adapter for tuner */ -+ priv->muxc = i2c_mux_alloc(i2c, &i2c->dev, -+ 2, 0, I2C_MUX_LOCKED, -+ tas2101_i2c_select, NULL); -+ if (!priv->muxc) { -+ ret = -ENOMEM; -+ goto err1; -+ } -+ priv->muxc->priv = priv; -+ ret = i2c_mux_add_adapter(priv->muxc, 0, 0, 0); -+ if (ret) -+ goto err1; -+ ret = i2c_mux_add_adapter(priv->muxc, 0, 1, 0); -+ if (ret) -+ goto err1; -+ priv->i2c_demod = priv->muxc->adapter[0]; -+ priv->i2c_tuner = priv->muxc->adapter[1]; -+#else -+ /* create muxed i2c adapter for the demod */ -+ priv->i2c_demod = i2c_add_mux_adapter(i2c, &i2c->dev, priv, 0, 0, 0, -+ tas2101_i2c_select, NULL); -+ if (priv->i2c_demod == NULL) -+ goto err1; -+ -+ /* create muxed i2c adapter for the tuner */ -+ priv->i2c_tuner = i2c_add_mux_adapter(i2c, &i2c->dev, priv, 0, 1, 0, -+ tas2101_i2c_select, NULL); -+ if (priv->i2c_tuner == NULL) -+ goto err2; -+#endif -+#else -+ priv->i2c_demod = i2c; -+ priv->i2c_tuner = i2c; -+#endif -+ -+ /* create dvb_frontend */ -+ memcpy(&priv->fe.ops, &tas2101_ops, -+ sizeof(struct dvb_frontend_ops)); -+ priv->fe.demodulator_priv = priv; -+ -+ /* reset demod */ -+ if (cfg->reset_demod) -+ cfg->reset_demod(&priv->fe); -+ -+ msleep(100); -+ -+ /* check if demod is alive */ -+ ret = tas2101_rdm(priv, ID_0, id, 2); -+ if ((id[0] != 0x44) || (id[1] != 0x4c)) -+ ret |= -EIO; -+ if (ret) -+ goto err3; -+ -+ return &priv->fe; -+ -+err3: -+#ifdef TAS2101_USE_I2C_MUX -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) -+ i2c_mux_del_adapters(priv->muxc); -+#else -+ i2c_del_mux_adapter(priv->i2c_tuner); -+err2: -+ i2c_del_mux_adapter(priv->i2c_demod); -+#endif -+#endif -+err1: -+ kfree(priv); -+err: -+ dev_err(&i2c->dev, "%s: Error attaching frontend\n", KBUILD_MODNAME); -+ return NULL; -+} -+EXPORT_SYMBOL_GPL(tas2101_attach); -+ -+static int tas2101_initfe(struct dvb_frontend *fe) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ struct tas2101_regtable *t; -+ u8 buf[7], size; -+ int ret; -+ -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ -+ if (priv->cfg->id == ID_TAS2101) { -+ t = tas2101_initfe0; -+ size = ARRAY_SIZE(tas2101_initfe0); -+ } else { -+ t = tas2100_initfe0; -+ size = ARRAY_SIZE(tas2100_initfe0); -+ } -+ ret = tas2101_wrtable(priv, t, size); -+ if (ret) -+ return ret; -+ -+ buf[0] = 0xe6; -+ memcpy(&buf[1], priv->cfg->init, 6); -+ ret = tas2101_wrm(priv, buf, 7); -+ if (ret) -+ return ret; -+ -+ ret = tas2101_regmask(priv, 0xe0, priv->cfg->init[6], 0xff); -+ if (ret) -+ return ret; -+ -+ if (priv->cfg->id == ID_TAS2101) { -+ t = tas2101_initfe1; -+ size = ARRAY_SIZE(tas2101_initfe1); -+ } else { -+ t = tas2100_initfe1; -+ size = ARRAY_SIZE(tas2100_initfe1); -+ } -+ ret = tas2101_wrtable(priv, t, size); -+ if (ret) -+ return ret; -+ -+ if (priv->cfg->init2) { -+ t = tas2101_initfe2; -+ size = ARRAY_SIZE(tas2101_initfe2); -+ ret = tas2101_wrtable(priv, t, size); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int tas2101_sleep(struct dvb_frontend *fe) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ return 0; -+} -+ -+static int tas2101_set_frontend(struct dvb_frontend *fe) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ enum fe_status tunerstat; -+ int ret, i; -+ u32 s; -+ u8 buf[3]; -+ -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ -+ /* do some basic parameter validation */ -+ switch (c->delivery_system) { -+ case SYS_DVBS: -+ dev_dbg(&priv->i2c->dev, "%s() DVB-S\n", __func__); -+ /* Only QPSK is supported for DVB-S */ -+ if (c->modulation != QPSK) { -+ dev_dbg(&priv->i2c->dev, -+ "%s() unsupported modulation (%d)\n", -+ __func__, c->modulation); -+ return -EINVAL; -+ } -+ break; -+ case SYS_DVBS2: -+ dev_dbg(&priv->i2c->dev, "%s() DVB-S2\n", __func__); -+ break; -+ default: -+ dev_warn(&priv->i2c->dev, -+ "%s() unsupported delivery system (%d)\n", -+ __func__, c->delivery_system); -+ return -EINVAL; -+ } -+ -+ ret = tas2101_wrtable(priv, tas2101_setfe, ARRAY_SIZE(tas2101_setfe)); -+ if (ret) -+ return ret; -+ -+ /* set symbol rate */ -+ s = c->symbol_rate / 1000; -+ buf[0] = SET_SRATE0; -+ buf[1] = (u8) s; -+ buf[2] = (u8) (s >> 8); -+ ret = tas2101_wrm(priv, buf, 3); -+ if (ret) -+ return ret; -+ -+ /* clear freq offset */ -+ buf[0] = FREQ_OS0; -+ buf[1] = 0; -+ buf[2] = 0; -+ ret = tas2101_wrm(priv, buf, 3); -+ if (ret) -+ return ret; -+ -+ if (fe->ops.tuner_ops.set_params) { -+#ifndef TAS2101_USE_I2C_MUX -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 1); -+#endif -+ fe->ops.tuner_ops.set_params(fe); -+#ifndef TAS2101_USE_I2C_MUX -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 0); -+#endif -+ } -+ -+ ret = tas2101_regmask(priv, REG_30, 0x01, 0); -+ if (ret) -+ return ret; -+ -+ for (i = 0; i<15; i++) { -+ ret = tas2101_read_status(fe, &tunerstat); -+ if (tunerstat & FE_HAS_LOCK) -+ return 0; -+ msleep(20); -+ } -+ return -EINVAL; -+} -+ -+static int tas2101_get_frontend(struct dvb_frontend *fe, -+ struct dtv_frontend_properties *c) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ int ret; -+ u8 reg, buf[2]; -+ -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ -+ ret = tas2101_rd(priv, MODFEC_0, ®); -+ if (ret) -+ return ret; -+ -+ if ((reg >> 6) == 0) { -+ /* DVB-S */ -+ reg &= 0x07; -+ } else { -+ /* DVB-S2 */ -+ ret = tas2101_rd(priv, MODFEC_1, ®); -+ if (ret) -+ return ret; -+ reg += 5; -+ } -+ -+ if (reg > 33) { -+ dev_dbg(&priv->i2c->dev, "%s() Unable to get current delivery" -+ " system and mode.\n", __func__); -+ reg = 0; -+ } -+ -+ c->fec_inner = tas2101_modfec_modes[reg].fec; -+ c->modulation = tas2101_modfec_modes[reg].modulation; -+ c->delivery_system = tas2101_modfec_modes[reg].delivery_system; -+ c->inversion = INVERSION_AUTO; -+ -+ /* symbol rate */ -+ ret = tas2101_rdm(priv, GET_SRATE0, buf, 2); -+ if (ret) -+ return ret; -+ c->symbol_rate = ((buf[1] << 8) | buf[0]) * 1000; -+ -+ return 0; -+} -+ -+static int tas2101_tune(struct dvb_frontend *fe, bool re_tune, -+ unsigned int mode_flags, unsigned int *delay, enum fe_status *status) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ -+ *delay = HZ / 5; -+ if (re_tune) { -+ int ret = tas2101_set_frontend(fe); -+ if (ret) -+ return ret; -+ } -+ return tas2101_read_status(fe, status); -+} -+ -+static int tas2101_get_algo(struct dvb_frontend *fe) -+{ -+ return DVBFE_ALGO_HW; -+} -+ -+#ifndef TAS2101_USE_I2C_MUX -+static int tas2101_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -+{ -+ struct tas2101_priv *priv = fe->demodulator_priv; -+ int ret; -+ -+ if (enable) -+ ret = tas2101_regmask(priv, REG_06, I2C_GATE, 0); -+ else -+ ret = tas2101_regmask(priv, REG_06, 0, I2C_GATE); -+ -+ return ret; -+} -+#endif -+ -+static struct dvb_frontend_ops tas2101_ops = { -+ .delsys = { SYS_DVBS, SYS_DVBS2 }, -+ .info = { -+ .name = "Tmax TAS2101", -+ .frequency_min = 950000, -+ .frequency_max = 2150000, -+ .frequency_stepsize = 1011, /* kHz for QPSK frontends */ -+ .frequency_tolerance = 5000, -+ .symbol_rate_min = 1000000, -+ .symbol_rate_max = 45000000, -+ .caps = FE_CAN_INVERSION_AUTO | -+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | -+ FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | -+ FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | -+ FE_CAN_2G_MODULATION | -+ FE_CAN_QPSK | FE_CAN_RECOVER -+ }, -+ .release = tas2101_release, -+ -+ .init = tas2101_initfe, -+ .sleep = tas2101_sleep, -+#ifndef TAS2101_USE_I2C_MUX -+ .i2c_gate_ctrl = tas2101_i2c_gate_ctrl, -+#endif -+ .read_status = tas2101_read_status, -+ .read_ber = tas2101_read_ber, -+ .read_signal_strength = tas2101_read_signal_strength, -+ .read_snr = tas2101_read_snr, -+ .read_ucblocks = tas2101_read_ucblocks, -+ -+ .set_tone = tas2101_set_tone, -+ .set_voltage = tas2101_set_voltage, -+ .diseqc_send_master_cmd = tas2101_send_diseqc_msg, -+ .diseqc_send_burst = tas2101_diseqc_send_burst, -+ .get_frontend_algo = tas2101_get_algo, -+ .tune = tas2101_tune, -+ -+ .set_frontend = tas2101_set_frontend, -+ .get_frontend = tas2101_get_frontend, -+ -+}; -+ -+MODULE_DESCRIPTION("DVB Frontend module for Tmax TAS2101"); -+MODULE_AUTHOR("Luis Alves (ljalvs@gmail.com)"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION("1.0"); -+ -diff --git a/drivers/media/dvb-frontends/tas2101.h b/drivers/media/dvb-frontends/tas2101.h -new file mode 100644 -index 0000000..c2fcf65 ---- /dev/null -+++ b/drivers/media/dvb-frontends/tas2101.h -@@ -0,0 +1,70 @@ -+/* -+ Tmax TAS2101 - DVBS/S2 Satellite demod/tuner driver -+ -+ Copyright (C) 2014 Luis Alves -+ -+ 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. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+*/ -+ -+#ifndef TAS2101_H -+#define TAS2101_H -+ -+#include -+#include -+ -+typedef enum tas210x_id { -+ ID_TAS2100, -+ ID_TAS2101, -+} tas210x_id_t; -+ -+struct tas2101_config { -+ /* demodulator i2c address */ -+ u8 i2c_address; -+ -+ /* chip id */ -+ tas210x_id_t id; -+ -+ /* demod hard reset */ -+ void (*reset_demod)(struct dvb_frontend *fe); -+ /* lnb power */ -+ void (*lnb_power)(struct dvb_frontend *fe, int onoff); -+ -+ /* frontend gpio/tuner init */ -+ u8 init[7]; -+ u8 init2; -+}; -+ -+ -+ -+#if IS_ENABLED(CONFIG_DVB_TAS2101) -+extern struct dvb_frontend *tas2101_attach( -+ const struct tas2101_config *cfg, -+ struct i2c_adapter *i2c); -+struct i2c_adapter *tas2101_get_i2c_adapter(struct dvb_frontend *fe, int bus); -+#else -+static inline struct dvb_frontend *tas2101_attach( -+ const struct tas2101_config *cfg, -+ struct i2c_adapter *i2c) -+{ -+ dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__); -+ return NULL; -+} -+struct i2c_adapter *tas2101_get_i2c_adapter(struct dvb_frontend *fe, int bus) -+{ -+ return NULL; -+} -+#endif -+ -+#endif /* TAS2101_H */ -diff --git a/drivers/media/dvb-frontends/tas2101_priv.h b/drivers/media/dvb-frontends/tas2101_priv.h -new file mode 100644 -index 0000000..79ed06b ---- /dev/null -+++ b/drivers/media/dvb-frontends/tas2101_priv.h -@@ -0,0 +1,325 @@ -+/* -+ Tmas TAS2101 - DVBS/S2 Satellite demod/tuner driver -+ -+ Copyright (C) 2014 Luis Alves -+ -+ 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. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+*/ -+ -+#ifndef TAS2101_PRIV_H -+#define TAS2101_PRIV_H -+ -+struct tas2101_priv { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) -+ struct i2c_mux_core *muxc; -+#endif -+ /* master i2c adapter */ -+ struct i2c_adapter *i2c; -+ /* muxed i2c adapter for the demod */ -+ struct i2c_adapter *i2c_demod; -+ /* muxed i2c adapter for the tuner */ -+ struct i2c_adapter *i2c_tuner; -+ -+ int i2c_ch; -+ -+ struct dvb_frontend fe; -+ const struct tas2101_config *cfg; -+}; -+ -+/* demod registers */ -+enum tas2101_reg_addr { -+ ID_0 = 0x00, -+ ID_1 = 0x01, -+ REG_04 = 0x04, -+ REG_06 = 0x06, -+ LNB_CTRL = 0x10, -+ LNB_STATUS = 0x16, -+ DISEQC_BUFFER = 0x20, -+ REG_30 = 0x30, -+ DEMOD_STATUS = 0x31, -+ REG_34 = 0x34, -+ SIGSTR_0 = 0x42, -+ SIGSTR_1 = 0x43, -+ GET_SRATE0 = 0x5c, -+ GET_SRATE1 = 0x5d, -+ SET_SRATE0 = 0x73, -+ SET_SRATE1 = 0x74, -+ FREQ_OS0 = 0x75, -+ FREQ_OS1 = 0x76, -+ SNR_0 = 0x92, -+ SNR_1 = 0x93, -+ S1_BER_0 = 0xd1, -+ S1_BER_1 = 0xd2, -+ S1_BER_2 = 0xd3, -+ S1_BER_3 = 0xd4, -+ S2_BER_0 = 0xec, -+ S2_BER_1 = 0xed, -+ MODFEC_0 = 0xee, -+ MODFEC_1 = 0xef, -+}; -+ -+#define I2C_GATE 0x80 -+ -+#define VSEL13_18 0x40 -+#define DISEQC_CMD_LEN_MASK 0x38 -+#define DISEQC_CMD_MASK 0x07 -+ -+ -+ -+enum tas2101_diseqc_cmd { -+ TONE_OFF = 0x00, -+ TONE_ON = 0x01, -+ DISEQC_BURST_A = 0x02, -+ DISEQC_BURST_B = 0x03, -+ DISEQC_SEND_MSG = 0x04, -+}; -+ -+#define DISEQC_BUSY 0x10 -+ -+#define DEMOD_STATUS_MASK 0x75 -+#define DEMOD_LOCKED 0x75 -+ -+ -+enum tas2101_lnb_power { -+ LNB_OFF = 0, -+ LNB_ON = 1, -+}; -+ -+struct tas2101_regtable { -+ u8 addr; -+ u8 setmask; -+ u8 clrmask; -+ int sleep; -+}; -+ -+static struct tas2101_regtable tas2101_initfe0[] = { -+ {REG_30, 0x02, 0x00, 0}, -+ {0x56, 0x00, 0x02, 0}, -+ {0x05, 0x04, 0x00, 0}, -+ {0x05, 0x00, 0x04, 60}, -+ {0x08, 0x80, 0x00, 0}, -+ {0x09, 0x3b, 0xff, 0}, -+ {0x08, 0x00, 0x80, 60}, -+ {0x0a, 0x80, 0x00, 0}, -+ {0x0b, 0x47, 0xff, 0}, -+ {0x0a, 0x00, 0x80, 40}, -+ {0x03, 0xa9, 0xff, 40}, -+ {0x0e, 0x05, 0xff, 0}, -+ {0x0f, 0x06, 0xff, 40}, -+ {0x70, 0x82, 0xff, 0}, -+ {0x71, 0x8b, 0xff, 0}, -+ {0x72, 0x01, 0xff, 0}, -+ {0x0d, 0x00, 0xc0, 40}, -+ {0x0d, 0xc0, 0x00, 0}, -+}; -+ -+static struct tas2101_regtable tas2100_initfe0[] = { -+ {REG_30, 0x02, 0x00, 0}, -+ {0x08, 0x00, 0x80, 60}, -+ {0x0b, 0x55, 0xff, 0}, -+ {0x0a, 0x00, 0x80, 40}, -+ {0x0e, 0x04, 0xff, 0}, -+ {0x0f, 0x05, 0xff, 40}, -+ {0x70, 0x98, 0xff, 0}, -+ {0x71, 0x66, 0xff, 0}, -+ {0x72, 0x01, 0xff, 0}, -+ {0x0d, 0x00, 0xc0, 40}, -+ {0x0d, 0xc0, 0x00, 0}, -+}; -+ -+static struct tas2101_regtable tas2101_initfe1[] = { -+/* {0xe0, 0x33, 0xff, 0}, depends on tsmode ( 0xb1 tsmode=1 ) */ -+ {0x56, 0x81, 0x00, 0}, -+ {0x05, 0x00, 0x08, 0}, -+ {0x36, 0x00, 0x40, 0}, -+ {0x91, 0x00, 0xf0, 0}, -+ {0x35, 0x75, 0xff, 0}, -+ {REG_04, 0x00, 0x80, 0}, -+ {0x0d, 0x80, 0x00, 0}, -+ {0x30, 0x01, 0x00, 0}, -+ {0x05, 0x00, 0x80, 0}, -+ {REG_06, 0, I2C_GATE, 0}, -+ {0x41, 0x1c, 0x3f, 0}, -+ {0x46, 0xdc, 0xff, 0}, -+ {0x11, 0x7f, 0xff, 0}, -+ {0x12, 0x04, 0x07, 0}, -+ {0x1f, 0x00, 0x01, 0}, -+ {REG_34, 0x00, 0x40, 0}, -+ {0xd0, 0x05, 0x7f, 0}, -+ {0xe3, 0x02, 0x03, 0}, -+ {0x58, 0x60, 0xe0, 0}, -+ {0x50, 0x64, 0xff, 0}, -+ {0x9e, 0x08, 0x3f, 0}, -+ {0x9d, 0x07, 0x00, 0}, -+ {0x49, 0xa0, 0xf0, 0}, -+ {0x87, 0x70, 0xf0, 0}, -+ {0x90, 0x04, 0xff, 0}, -+ {0x9d, 0x07, 0x00, 0}, -+ {0x9e, 0x20, 0x3f, 0}, -+ {REG_06, 0x00, 0x1f, 0}, -+ {0x46, 0x18, 0x1f, 0}, -+ {0x40, 0x04, 0x07, 0}, -+}; -+ -+ -+static struct tas2101_regtable tas2101_initfe2[] = { -+ {0xfa, 0x01, 0x03, 0}, -+ {0xfb, 0x02, 0xff, 0}, -+}; -+ -+static struct tas2101_regtable tas2100_initfe1[] = { -+ {0x56, 0x81, 0x00, 0}, -+ {0x05, 0x00, 0x08, 0}, -+ {0x36, 0x00, 0x40, 0}, -+ {0x91, 0x22, 0xff, 0}, -+ {0x35, 0x75, 0xff, 0}, -+ {REG_04, 0x30, 0xff, 0}, -+ {0x30, 0x01, 0x00, 0}, -+ {0x05, 0x00, 0x80, 0}, -+ {REG_06, 0, I2C_GATE, 0}, -+ {0x41, 0x1c, 0x3f, 0}, -+ {0x46, 0xdc, 0xff, 0}, -+ {0x11, 0x13, 0xff, 0}, -+ {0x12, 0x04, 0x07, 0}, -+ {REG_34, 0x00, 0x40, 0}, -+ {0xd0, 0x05, 0x7f, 0}, -+ {0xe3, 0x02, 0x03, 0}, -+ {0x58, 0x60, 0xe0, 0}, -+ {0x50, 0x64, 0xff, 0}, -+ {0x9e, 0x20, 0x3f, 0}, -+ {0x9d, 0x07, 0x00, 0}, -+ {0x49, 0x90, 0xf0, 0}, -+ {0x87, 0xd0, 0xf0, 0}, -+ {0x90, 0x10, 0xff, 0}, -+ {0x9d, 0x07, 0x00, 0}, -+ {0x9e, 0x20, 0x3f, 0}, -+ {REG_06, 0x00, 0x1f, 0}, -+}; -+ -+static struct tas2101_regtable tas2101_setfe[] = { -+ {REG_04, 0x08, 0x00, 0}, -+ {0x36, 0x01, 0x00, 0}, -+ {0x56, 0x01, 0x81, 0}, -+ {0x05, 0x08, 0x00, 0}, -+ {0x36, 0x40, 0x00, 0}, -+ {0x58, 0x60, 0xe0, 0}, -+}; -+ -+struct tas2101_snrtable_pair { -+ u16 snr; -+ u16 raw; -+}; -+ -+static struct tas2101_snrtable_pair tas2101_snrtable[] = { -+ {10, 0x65a}, /* 1.0 dB */ -+ {20, 0x50c}, -+ {30, 0x402}, -+ {40, 0x32f}, -+ {50, 0x287}, -+ {60, 0x202}, -+ {70, 0x198}, -+ {80, 0x144}, -+ {90, 0x100}, -+ {100, 0xcc}, -+ {110, 0xa2}, -+ {120, 0x81}, -+ {130, 0x66}, -+ {140, 0x51}, -+ {150, 0x40}, -+ {160, 0x33}, -+ {170, 0x28}, -+ {180, 0x20}, -+ {190, 0x19}, -+ {200, 0x14}, -+ {210, 0x10}, -+ {220, 0xc}, -+ {230, 0xa}, -+ {240, 0x8}, -+ {250, 0x6}, -+ {260, 0x5}, -+ {270, 0x4}, -+ {280, 0x3}, -+ {300, 0x2}, -+ {330, 0x1}, /* 33.0 dB */ -+ {0, 0} -+}; -+ -+struct tas2101_dbmtable_pair { -+ u16 dbm; -+ u16 raw; -+}; -+ -+static struct tas2101_dbmtable_pair tas2101_dbmtable[] = { -+ { 0x3333, 0xfff}, /* 20% */ -+ { 0x4CCC, 0x778}, -+ { 0x6666, 0x621}, -+ { 0x7FFF, 0x55c}, -+ { 0x9999, 0x40e}, -+ { 0xB332, 0x343}, -+ { 0xCCCC, 0x2b7}, -+ { 0xE665, 0x231}, -+ { 0xFFFF, 0x1a1}, /* 100% */ -+ {0, 0} -+}; -+ -+/* modfec (modulation and FEC) lookup table */ -+struct tas2101_modfec { -+ enum fe_delivery_system delivery_system; -+ enum fe_modulation modulation; -+ enum fe_code_rate fec; -+}; -+ -+static struct tas2101_modfec tas2101_modfec_modes[] = { -+ { SYS_DVBS, QPSK, FEC_AUTO }, -+ { SYS_DVBS, QPSK, FEC_1_2 }, -+ { SYS_DVBS, QPSK, FEC_2_3 }, -+ { SYS_DVBS, QPSK, FEC_3_4 }, -+ { SYS_DVBS, QPSK, FEC_4_5 }, -+ { SYS_DVBS, QPSK, FEC_5_6 }, -+ { SYS_DVBS, QPSK, FEC_6_7 }, -+ { SYS_DVBS, QPSK, FEC_7_8 }, -+ { SYS_DVBS, QPSK, FEC_8_9 }, -+ -+ { SYS_DVBS2, QPSK, FEC_1_2 }, -+ { SYS_DVBS2, QPSK, FEC_3_5 }, -+ { SYS_DVBS2, QPSK, FEC_2_3 }, -+ { SYS_DVBS2, QPSK, FEC_3_4 }, -+ { SYS_DVBS2, QPSK, FEC_4_5 }, -+ { SYS_DVBS2, QPSK, FEC_5_6 }, -+ { SYS_DVBS2, QPSK, FEC_8_9 }, -+ { SYS_DVBS2, QPSK, FEC_9_10 }, -+ -+ { SYS_DVBS2, PSK_8, FEC_3_5 }, -+ { SYS_DVBS2, PSK_8, FEC_2_3 }, -+ { SYS_DVBS2, PSK_8, FEC_3_4 }, -+ { SYS_DVBS2, PSK_8, FEC_5_6 }, -+ { SYS_DVBS2, PSK_8, FEC_8_9 }, -+ { SYS_DVBS2, PSK_8, FEC_9_10 }, -+ -+ { SYS_DVBS2, APSK_16, FEC_2_3 }, -+ { SYS_DVBS2, APSK_16, FEC_3_4 }, -+ { SYS_DVBS2, APSK_16, FEC_4_5 }, -+ { SYS_DVBS2, APSK_16, FEC_5_6 }, -+ { SYS_DVBS2, APSK_16, FEC_8_9 }, -+ { SYS_DVBS2, APSK_16, FEC_9_10 }, -+ -+ { SYS_DVBS2, APSK_32, FEC_3_4 }, -+ { SYS_DVBS2, APSK_32, FEC_4_5 }, -+ { SYS_DVBS2, APSK_32, FEC_5_6 }, -+ { SYS_DVBS2, APSK_32, FEC_8_9 }, -+ { SYS_DVBS2, APSK_32, FEC_9_10 }, -+}; -+ -+#endif /* TAS2101_PRIV_H */ -diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig -index da28e68..f6bbdb2 100644 ---- a/drivers/media/pci/Kconfig -+++ b/drivers/media/pci/Kconfig -@@ -36,6 +36,7 @@ source "drivers/media/pci/bt8xx/Kconfig" - source "drivers/media/pci/saa7134/Kconfig" - source "drivers/media/pci/saa7164/Kconfig" - source "drivers/media/pci/cobalt/Kconfig" -+source "drivers/media/pci/saa716x/Kconfig" - - endif - -@@ -52,6 +53,7 @@ source "drivers/media/pci/ngene/Kconfig" - source "drivers/media/pci/ddbridge/Kconfig" - source "drivers/media/pci/smipcie/Kconfig" - source "drivers/media/pci/netup_unidvb/Kconfig" -+source "drivers/media/pci/tbsecp3/Kconfig" - endif - - endif #MEDIA_PCI_SUPPORT -diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile -index a7e8af0..43d5896 100644 ---- a/drivers/media/pci/Makefile -+++ b/drivers/media/pci/Makefile -@@ -13,7 +13,8 @@ obj-y += ttpci/ \ - ddbridge/ \ - saa7146/ \ - smipcie/ \ -- netup_unidvb/ -+ netup_unidvb/ \ -+ tbsecp3/ - - obj-$(CONFIG_VIDEO_IVTV) += ivtv/ - obj-$(CONFIG_VIDEO_ZORAN) += zoran/ -@@ -24,6 +25,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/ - obj-$(CONFIG_VIDEO_BT848) += bt8xx/ - obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ - obj-$(CONFIG_VIDEO_SAA7164) += saa7164/ -+obj-$(CONFIG_SAA716X_CORE) += saa716x/ - obj-$(CONFIG_VIDEO_TW68) += tw68/ - obj-$(CONFIG_VIDEO_TW686X) += tw686x/ - obj-$(CONFIG_VIDEO_DT3155) += dt3155/ -diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c -index 589a168..ae27b3d 100644 ---- a/drivers/media/pci/cx23885/cx23885-dvb.c -+++ b/drivers/media/pci/cx23885/cx23885-dvb.c -@@ -511,6 +511,7 @@ static struct cx24116_config tbs_cx24116_config = { - - static struct cx24117_config tbs_cx24117_config = { - .demod_address = 0x55, -+ .lnb_power = NULL, - }; - - static struct ds3000_config tevii_ds3000_config = { -diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c -index cdfbde2..6303938 100644 ---- a/drivers/media/pci/cx88/cx88-cards.c -+++ b/drivers/media/pci/cx88/cx88-cards.c -@@ -2079,6 +2079,19 @@ static const struct cx88_board cx88_boards[] = { - } }, - .mpeg = CX88_MPEG_DVB, - }, -+ [CX88_BOARD_TBS_8922] = { -+ .name = "TBS 8922 DVB-S/S2", -+ .tuner_type = UNSET, -+ .radio_type = UNSET, -+ .tuner_addr = ADDR_UNSET, -+ .radio_addr = ADDR_UNSET, -+ .input = { { -+ .type = CX88_VMUX_DVB, -+ .vmux = 0, -+ .gpio0 = 0x4343, -+ } }, -+ .mpeg = CX88_MPEG_DVB, -+ }, - [CX88_BOARD_PROF_6200] = { - .name = "Prof 6200 DVB-S", - .tuner_type = UNSET, -@@ -2727,6 +2740,11 @@ static const struct cx88_subid cx88_subids[] = { - .subdevice = 0x8888, - .card = CX88_BOARD_TBS_8920, - }, { -+ }, { -+ .subvendor = 0x8922, -+ .subdevice = 0x8888, -+ .card = CX88_BOARD_TBS_8922, -+ }, { - .subvendor = 0xb022, - .subdevice = 0x3022, - .card = CX88_BOARD_PROF_6200, -@@ -3547,6 +3565,14 @@ static void cx88_card_setup(struct cx88_core *core) - cx_write(MO_SRST_IO, 1); - msleep(100); - break; -+ case CX88_BOARD_TBS_8922: -+ cx_write(MO_GP0_IO, 0x4340); -+ msleep(10); -+ cx_write(MO_GP0_IO, 0x4342); -+ msleep(200); -+ cx_write(MO_GP0_IO, 0x4343); -+ msleep(100); -+ break; - } /*end switch() */ - - /* Setup tuners */ -diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c -index ddf9067..89d3b62 100644 ---- a/drivers/media/pci/cx88/cx88-dvb.c -+++ b/drivers/media/pci/cx88/cx88-dvb.c -@@ -56,6 +56,8 @@ - #include "mb86a16.h" - #include "ts2020.h" - #include "ds3000.h" -+#include "tas2101.h" -+#include "av201x.h" - - MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); - MODULE_AUTHOR("Chris Pascoe "); -@@ -996,6 +998,21 @@ static const struct stv0299_config samsung_stv0299_config = { - .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate, - }; - -+static struct tas2101_config tbs8922_demod_cfg = { -+ -+ .i2c_address = 0x68, -+ .id = ID_TAS2100, -+ .init = {0x67, 0x45, 0x23, 0x01, 0xa8, 0x9b, 0x33}, // 0xb1 -+ .init2 = 0, -+ -+}; -+ -+static struct av201x_config tbs8922_av201x_cfg = { -+ .i2c_address = 0x63, -+ .id = ID_AV2012, -+ .xtal_freq = 27000, /* kHz */ -+}; -+ - static int dvb_register(struct cx8802_dev *dev) - { - struct cx88_core *core = dev->core; -@@ -1541,6 +1558,20 @@ static int dvb_register(struct cx8802_dev *dev) - if (fe0->dvb.frontend) - fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; - break; -+ case CX88_BOARD_TBS_8922: -+ dev->ts_gen_cntrl = 0x04; -+ fe0->dvb.frontend = dvb_attach(tas2101_attach, &tbs8922_demod_cfg, &core->i2c_adap); -+ -+ if (fe0->dvb.frontend != NULL) -+ if (dvb_attach(av201x_attach, fe0->dvb.frontend, &tbs8922_av201x_cfg, -+ tas2101_get_i2c_adapter(fe0->dvb.frontend, 2)) == NULL) { -+ dvb_frontend_detach(fe0->dvb.frontend); -+ //adapter->fe = NULL; -+ //dev_err(&dev->pci_dev->dev, -+ // "TBS_PCIE frontend %d tuner attach failed\n", -+ // adapter->nr); -+ } -+ break; - case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII: - fe0->dvb.frontend = dvb_attach(zl10353_attach, - &cx88_terratec_cinergy_ht_pci_mkii_config, -diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c -index dcfea35..5314b4c 100644 ---- a/drivers/media/pci/cx88/cx88-input.c -+++ b/drivers/media/pci/cx88/cx88-input.c -@@ -396,6 +396,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) - case CX88_BOARD_OMICOM_SS4_PCI: - case CX88_BOARD_SATTRADE_ST4200: - case CX88_BOARD_TBS_8920: -+ case CX88_BOARD_TBS_8922: - case CX88_BOARD_TBS_8910: - case CX88_BOARD_PROF_7300: - case CX88_BOARD_PROF_7301: -diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h -index 115414c..cdf7f86 100644 ---- a/drivers/media/pci/cx88/cx88.h -+++ b/drivers/media/pci/cx88/cx88.h -@@ -237,6 +237,7 @@ extern const struct sram_channel cx88_sram_channels[]; - #define CX88_BOARD_WINFAST_DTV1800H_XC4000 88 - #define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36 89 - #define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43 90 -+#define CX88_BOARD_TBS_8922 91 - - enum cx88_itype { - CX88_VMUX_COMPOSITE1 = 1, -diff --git a/drivers/media/pci/saa716x/Kconfig b/drivers/media/pci/saa716x/Kconfig -new file mode 100644 -index 0000000..618641c ---- /dev/null -+++ b/drivers/media/pci/saa716x/Kconfig -@@ -0,0 +1,84 @@ -+menuconfig SAA716X_SUPPORT -+ bool "Support for SAA716x family from NXP/Philips" -+ depends on PCI && I2C -+ help -+ support for saa716x -+ -+if SAA716X_SUPPORT -+config SAA716X_CORE -+ tristate "SAA7160/1/2 PCI Express bridge based devices" -+ depends on PCI && I2C -+ -+ help -+ Support for PCI cards based on the SAA7160/1/2 PCI Express bridge. -+ -+ Say Y if you own such a device and want to use it. -+ -+config DVB_SAA716X_TBS -+ tristate "SAA7160/1/2 based Budget PCIe cards (DVB only)" -+ depends on SAA716X_CORE && DVB_CORE -+ select DVB_CX24117 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_MB86A16 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STV6110 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_TAS2101 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_ISL6422 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_CXD2820R if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_AV201X if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT -+ -+ -+ help -+ Support for the SAA7160/1/2 based Budget PCIe DVB cards -+ Currently supported devices are: -+ -+ * KNC1 Dual S2 (DVB-S, DVB-S/S2) -+ * Twinhan/Azurewave VP-1028 (DVB-S) -+ * Twinhan/Azurewave VP-3071 (DVB-T x2) -+ * Twinhan/Azurewave VP-6002 (DVB-S) -+ -+ Say Y if you own such a device and want to use it. -+ -+config DVB_SAA716X_HYBRID -+ tristate "SAA7160/1/2 based Hybrid PCIe cards (DVB + Analog)" -+ depends on SAA716X_CORE && DVB_CORE -+ select DVB_MB86A16 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_TDA827X if MEDIA_SUBDRV_AUTOSELECT -+ -+ help -+ Support for the SAA7160/1/2 based Hybrid PCIe DVB cards -+ Currently supported devices are: -+ -+ * Avermedia H-788 (DVB-T) -+ * Avermedia HC-82 (DVB-T) -+ * NXP Reference (Atlantis) (DVB-T x2) -+ * NXP Reference (Nemo) (DVB-T) -+ * Twinhan/Azurewave VP-6090 (DVB-S x2, DVB-T x2) -+ -+ Say Y if you own such a device and want to use it. -+ -+config DVB_SAA716X_FF -+ tristate "SAA7160/1/2 based Full Fledged PCIe cards" -+ depends on SAA716X_CORE && DVB_CORE -+ depends on INPUT # IR -+ -+ select DVB_STV6110 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_ISL6423 if MEDIA_SUBDRV_AUTOSELECT -+ -+ help -+ Support for the SAA7160/1/2 based Full fledged PCIe DVB cards -+ These cards do feature a hardware MPEG decoder and other -+ peripherals. Also known as Premium cards. -+ Currently supported devices are: -+ -+ * Technotrend S2 6400 Dual S2 HD (DVB-S/S2 x2) -+ -+ Say Y if you own such a device and want to use it. -+ -+endif # SAA716X_SUPPORT -diff --git a/drivers/media/pci/saa716x/Makefile b/drivers/media/pci/saa716x/Makefile -new file mode 100644 -index 0000000..87c1bfa ---- /dev/null -+++ b/drivers/media/pci/saa716x/Makefile -@@ -0,0 +1,27 @@ -+saa716x_core-objs := saa716x_pci.o \ -+ saa716x_i2c.o \ -+ saa716x_cgu.o \ -+ saa716x_msi.o \ -+ saa716x_dma.o \ -+ saa716x_vip.o \ -+ saa716x_aip.o \ -+ saa716x_phi.o \ -+ saa716x_boot.o \ -+ saa716x_fgpi.o \ -+ saa716x_adap.o \ -+ saa716x_gpio.o \ -+ saa716x_greg.o \ -+ saa716x_rom.o \ -+ saa716x_spi.o -+ -+saa716x_ff-objs := saa716x_ff_main.o \ -+ saa716x_ff_cmd.o \ -+ saa716x_ff_ir.o -+ -+obj-$(CONFIG_SAA716X_CORE) += saa716x_core.o -+obj-$(CONFIG_DVB_SAA716X_TBS) += saa716x_tbs-dvb.o -+obj-$(CONFIG_DVB_SAA716X_HYBRID) += saa716x_hybrid.o -+obj-$(CONFIG_DVB_SAA716X_FF) += saa716x_ff.o -+saa716x_tbs-dvb-objs += saa716x_budget.o tbsci-i2c.o tbs-ci.o -+ -+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/ -Idrivers/media/tuners/ -diff --git a/drivers/media/pci/saa716x/saa716x_adap.c b/drivers/media/pci/saa716x/saa716x_adap.c -new file mode 100644 -index 0000000..4c95a38 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_adap.c -@@ -0,0 +1,268 @@ -+#include -+ -+#include "dmxdev.h" -+#include "dvbdev.h" -+#include "dvb_demux.h" -+#include "dvb_frontend.h" -+ -+#include "saa716x_mod.h" -+#include "saa716x_spi.h" -+#include "saa716x_adap.h" -+#include "saa716x_i2c.h" -+#include "saa716x_gpio.h" -+#include "saa716x_priv.h" -+ -+ -+#define SAA716X_TS_DMA_BUF_SIZE (16 * SAA716x_PAGE_SIZE) -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+ -+void saa716x_dma_start(struct saa716x_dev *saa716x, u8 adapter) -+{ -+ struct fgpi_stream_params params; -+ -+ dprintk(SAA716x_DEBUG, 1, "SAA716x Start DMA engine for Adapter:%d", adapter); -+ -+ params.bits = 8; -+ params.samples = 188; -+ params.lines = SAA716X_TS_DMA_BUF_SIZE / 188; -+ params.pitch = 188; -+ params.offset = 0; -+ params.page_tables = 0; -+ params.stream_type = FGPI_TRANSPORT_STREAM; -+ params.stream_flags = 0; -+ -+ saa716x_fgpi_start(saa716x, saa716x->config->adap_config[adapter].ts_port, ¶ms); -+} -+ -+void saa716x_dma_stop(struct saa716x_dev *saa716x, u8 adapter) -+{ -+ dprintk(SAA716x_DEBUG, 1, "SAA716x Stop DMA engine for Adapter:%d", adapter); -+ -+ saa716x_fgpi_stop(saa716x, saa716x->config->adap_config[adapter].ts_port); -+} -+ -+static int saa716x_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) -+{ -+ struct dvb_demux *dvbdmx = dvbdmxfeed->demux; -+ struct saa716x_adapter *saa716x_adap = dvbdmx->priv; -+ struct saa716x_dev *saa716x = saa716x_adap->saa716x; -+ -+ dprintk(SAA716x_DEBUG, 1, "SAA716x DVB Start feed"); -+ if (!dvbdmx->dmx.frontend) { -+ dprintk(SAA716x_DEBUG, 1, "no frontend ?"); -+ return -EINVAL; -+ } -+ saa716x_adap->feeds++; -+ dprintk(SAA716x_DEBUG, 1, "SAA716x start feed, feeds=%d", -+ saa716x_adap->feeds); -+ -+ if (saa716x_adap->feeds == 1) { -+ dprintk(SAA716x_DEBUG, 1, "SAA716x start feed & dma"); -+ saa716x_dma_start(saa716x, saa716x_adap->count); -+ } -+ -+ return saa716x_adap->feeds; -+} -+ -+static int saa716x_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) -+{ -+ struct dvb_demux *dvbdmx = dvbdmxfeed->demux; -+ struct saa716x_adapter *saa716x_adap = dvbdmx->priv; -+ struct saa716x_dev *saa716x = saa716x_adap->saa716x; -+ -+ dprintk(SAA716x_DEBUG, 1, "SAA716x DVB Stop feed"); -+ if (!dvbdmx->dmx.frontend) { -+ dprintk(SAA716x_DEBUG, 1, "no frontend ?"); -+ return -EINVAL; -+ } -+ saa716x_adap->feeds--; -+ if (saa716x_adap->feeds == 0) { -+ dprintk(SAA716x_DEBUG, 1, "saa716x stop feed and dma"); -+ saa716x_dma_stop(saa716x, saa716x_adap->count); -+ } -+ -+ return 0; -+} -+ -+int saa716x_dvb_init(struct saa716x_dev *saa716x) -+{ -+ struct saa716x_adapter *saa716x_adap = saa716x->saa716x_adap; -+ struct saa716x_config *config = saa716x->config; -+ int result, i; -+ -+ mutex_init(&saa716x->adap_lock); -+ -+ saa716x->num_adapters = 0; -+ for (i = 0; i < config->adapters; i++) { -+ -+ dprintk(SAA716x_DEBUG, 1, "dvb_register_adapter"); -+ if (dvb_register_adapter(&saa716x_adap->dvb_adapter, -+ "SAA716x dvb adapter", -+ saa716x->module, -+ &saa716x->pdev->dev, -+ adapter_nr) < 0) { -+ -+ dprintk(SAA716x_ERROR, 1, "Error registering adapter"); -+ return -ENODEV; -+ } -+ -+ saa716x_adap->count = i; -+ -+ saa716x_adap->dvb_adapter.priv = saa716x_adap; -+ saa716x_adap->demux.dmx.capabilities = DMX_TS_FILTERING | -+ DMX_SECTION_FILTERING | -+ DMX_MEMORY_BASED_FILTERING; -+ -+ saa716x_adap->demux.priv = saa716x_adap; -+ saa716x_adap->demux.filternum = 256; -+ saa716x_adap->demux.feednum = 256; -+ saa716x_adap->demux.start_feed = saa716x_dvb_start_feed; -+ saa716x_adap->demux.stop_feed = saa716x_dvb_stop_feed; -+ saa716x_adap->demux.write_to_decoder = NULL; -+ -+ dprintk(SAA716x_DEBUG, 1, "dvb_dmx_init"); -+ if ((result = dvb_dmx_init(&saa716x_adap->demux)) < 0) { -+ dprintk(SAA716x_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); -+ goto err0; -+ } -+ -+ saa716x_adap->dmxdev.filternum = 256; -+ saa716x_adap->dmxdev.demux = &saa716x_adap->demux.dmx; -+ saa716x_adap->dmxdev.capabilities = 0; -+ -+ dprintk(SAA716x_DEBUG, 1, "dvb_dmxdev_init"); -+ if ((result = dvb_dmxdev_init(&saa716x_adap->dmxdev, -+ &saa716x_adap->dvb_adapter)) < 0) { -+ -+ dprintk(SAA716x_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result); -+ goto err1; -+ } -+ -+ saa716x_adap->fe_hw.source = DMX_FRONTEND_0; -+ -+ if ((result = saa716x_adap->demux.dmx.add_frontend(&saa716x_adap->demux.dmx, -+ &saa716x_adap->fe_hw)) < 0) { -+ -+ dprintk(SAA716x_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); -+ goto err2; -+ } -+ -+ saa716x_adap->fe_mem.source = DMX_MEMORY_FE; -+ -+ if ((result = saa716x_adap->demux.dmx.add_frontend(&saa716x_adap->demux.dmx, -+ &saa716x_adap->fe_mem)) < 0) { -+ dprintk(SAA716x_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); -+ goto err3; -+ } -+ -+ if ((result = saa716x_adap->demux.dmx.connect_frontend(&saa716x_adap->demux.dmx, -+ &saa716x_adap->fe_hw)) < 0) { -+ -+ dprintk(SAA716x_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); -+ goto err4; -+ } -+ -+ dvb_net_init(&saa716x_adap->dvb_adapter, &saa716x_adap->dvb_net, &saa716x_adap->demux.dmx); -+// tasklet_init(&saa716x_adap->tasklet, saa716x_dma_xfer, (unsigned long) saa716x); -+ dprintk(SAA716x_DEBUG, 1, "Frontend Init"); -+ saa716x_adap->saa716x = saa716x; -+ -+ if (config->frontend_attach) { -+ result = config->frontend_attach(saa716x_adap, i); -+ if (result < 0) -+ dprintk(SAA716x_ERROR, 1, "SAA716x frontend attach failed"); -+ -+ if (saa716x_adap->fe == NULL) { -+ dprintk(SAA716x_ERROR, 1, "A frontend driver was not found for [%04x:%04x] subsystem [%04x:%04x]\n", -+ saa716x->pdev->vendor, -+ saa716x->pdev->device, -+ saa716x->pdev->subsystem_vendor, -+ saa716x->pdev->subsystem_device); -+ } else { -+ result = dvb_register_frontend(&saa716x_adap->dvb_adapter, saa716x_adap->fe); -+ if (result < 0) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x register frontend failed"); -+ goto err6; -+ } -+ } -+ -+ } else { -+ dprintk(SAA716x_ERROR, 1, "Frontend attach = NULL"); -+ } -+ -+ saa716x_fgpi_init(saa716x, config->adap_config[i].ts_port, -+ SAA716X_TS_DMA_BUF_SIZE, -+ config->adap_config[i].worker); -+ -+ saa716x->num_adapters++; -+ saa716x_adap++; -+ } -+ -+ return 0; -+ -+ /* Error conditions */ -+err6: -+ dvb_frontend_detach(saa716x_adap->fe); -+err4: -+ saa716x_adap->demux.dmx.remove_frontend(&saa716x_adap->demux.dmx, &saa716x_adap->fe_mem); -+err3: -+ saa716x_adap->demux.dmx.remove_frontend(&saa716x_adap->demux.dmx, &saa716x_adap->fe_hw); -+err2: -+ dvb_dmxdev_release(&saa716x_adap->dmxdev); -+err1: -+ dvb_dmx_release(&saa716x_adap->demux); -+err0: -+ dvb_unregister_adapter(&saa716x_adap->dvb_adapter); -+ -+ return result; -+} -+EXPORT_SYMBOL(saa716x_dvb_init); -+ -+void saa716x_dvb_exit(struct saa716x_dev *saa716x) -+{ -+ struct saa716x_adapter *saa716x_adap = saa716x->saa716x_adap; -+ struct i2c_client *client; -+ int i, count = saa716x->num_adapters; -+ -+ for (i = 0; i < count; i++) { -+ -+ saa716x_fgpi_exit(saa716x, saa716x->config->adap_config[i].ts_port); -+ -+ /* remove I2C tuner */ -+ client = saa716x_adap->i2c_client_tuner; -+ if (client) { -+ module_put(client->dev.driver->owner); -+ i2c_unregister_device(client); -+ } -+ -+ /* remove I2C demod */ -+ client = saa716x_adap->i2c_client_demod; -+ if (client) { -+ module_put(client->dev.driver->owner); -+ i2c_unregister_device(client); -+ } -+ -+ if (saa716x_adap->fe) { -+ dvb_unregister_frontend(saa716x_adap->fe); -+ dvb_frontend_detach(saa716x_adap->fe); -+ } -+ -+// tasklet_kill(&saa716x->tasklet); -+ dvb_net_release(&saa716x_adap->dvb_net); -+ saa716x_adap->demux.dmx.remove_frontend(&saa716x_adap->demux.dmx, &saa716x_adap->fe_mem); -+ saa716x_adap->demux.dmx.remove_frontend(&saa716x_adap->demux.dmx, &saa716x_adap->fe_hw); -+ dvb_dmxdev_release(&saa716x_adap->dmxdev); -+ dvb_dmx_release(&saa716x_adap->demux); -+ -+ dprintk(SAA716x_DEBUG, 1, "dvb_unregister_adapter"); -+ dvb_unregister_adapter(&saa716x_adap->dvb_adapter); -+ -+ saa716x->num_adapters--; -+ saa716x_adap++; -+ } -+ -+ return; -+} -+EXPORT_SYMBOL(saa716x_dvb_exit); -diff --git a/drivers/media/pci/saa716x/saa716x_adap.h b/drivers/media/pci/saa716x/saa716x_adap.h -new file mode 100644 -index 0000000..7822e36 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_adap.h -@@ -0,0 +1,9 @@ -+#ifndef __SAA716x_ADAP_H -+#define __SAA716x_ADAP_H -+ -+struct saa716x_dev; -+ -+extern int saa716x_dvb_init(struct saa716x_dev *saa716x); -+extern void saa716x_dvb_exit(struct saa716x_dev *saa716x); -+ -+#endif /* __SAA716x_ADAP_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_aip.c b/drivers/media/pci/saa716x/saa716x_aip.c -new file mode 100644 -index 0000000..3bdb265 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_aip.c -@@ -0,0 +1,20 @@ -+#include -+ -+#include "saa716x_mod.h" -+#include "saa716x_aip_reg.h" -+#include "saa716x_spi.h" -+#include "saa716x_aip.h" -+#include "saa716x_priv.h" -+ -+int saa716x_aip_status(struct saa716x_dev *saa716x, u32 dev) -+{ -+ return SAA716x_EPRD(dev, AI_CTL) == 0 ? 0 : -1; -+} -+EXPORT_SYMBOL_GPL(saa716x_aip_status); -+ -+void saa716x_aip_disable(struct saa716x_dev *saa716x) -+{ -+ SAA716x_EPWR(AI0, AI_CTL, 0x00); -+ SAA716x_EPWR(AI1, AI_CTL, 0x00); -+} -+EXPORT_SYMBOL_GPL(saa716x_aip_disable); -diff --git a/drivers/media/pci/saa716x/saa716x_aip.h b/drivers/media/pci/saa716x/saa716x_aip.h -new file mode 100644 -index 0000000..36277b7 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_aip.h -@@ -0,0 +1,9 @@ -+#ifndef __SAA716x_AIP_H -+#define __SAA716x_AIP_H -+ -+struct saa716x_dev; -+ -+extern int saa716x_aip_status(struct saa716x_dev *saa716x, u32 dev); -+extern void saa716x_aip_disable(struct saa716x_dev *saa716x); -+ -+#endif /* __SAA716x_AIP_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_aip_reg.h b/drivers/media/pci/saa716x/saa716x_aip_reg.h -new file mode 100644 -index 0000000..3e0893a ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_aip_reg.h -@@ -0,0 +1,62 @@ -+#ifndef __SAA716x_AIP_REG_H -+#define __SAA716x_AIP_REG_H -+ -+/* -------------- AI Registers ---------------- */ -+ -+#define AI_STATUS 0x000 -+#define AI_BUF1_ACTIVE (0x00000001 << 4) -+#define AI_OVERRUN (0x00000001 << 3) -+#define AI_HBE (0x00000001 << 2) -+#define AI_BUF2_FULL (0x00000001 << 1) -+#define AI_BUF1_FULL (0x00000001 << 0) -+ -+#define AI_CTL 0x004 -+#define AI_RESET (0x00000001 << 31) -+#define AI_CAP_ENABLE (0x00000001 << 30) -+#define AI_CAP_MODE (0x00000003 << 28) -+#define AI_SIGN_CONVERT (0x00000001 << 27) -+#define AI_EARLYMODE (0x00000001 << 26) -+#define AI_DIAGMODE (0x00000001 << 25) -+#define AI_RAWMODE (0x00000001 << 24) -+#define AI_OVR_INTEN (0x00000001 << 7) -+#define AI_HBE_INTEN (0x00000001 << 6) -+#define AI_BUF2_INTEN (0x00000001 << 5) -+#define AI_BUF1_INTEN (0x00000001 << 4) -+#define AI_ACK_OVR (0x00000001 << 3) -+#define AI_ACK_HBE (0x00000001 << 2) -+#define AI_ACK2 (0x00000001 << 1) -+#define AI_ACK1 (0x00000001 << 0) -+ -+#define AI_SERIAL 0x008 -+#define AI_SER_MASTER (0x00000001 << 31) -+#define AI_DATAMODE (0x00000001 << 30) -+#define AI_FRAMEMODE (0x00000003 << 28) -+#define AI_CLOCK_EDGE (0x00000001 << 27) -+#define AI_SSPOS4 (0x00000001 << 19) -+#define AI_NR_CHAN (0x00000003 << 17) -+#define AI_WSDIV (0x000001ff << 8) -+#define AI_SCKDIV (0x000000ff << 0) -+ -+#define AI_FRAMING 0x00c -+#define AI_VALIDPOS (0x000001ff << 22) -+#define AI_LEFTPOS (0x000001ff << 13) -+#define AI_RIGHTPOS (0x000001ff << 4) -+#define AI_SSPOS_3_0 (0x0000000f << 0) -+ -+#define AI_BASE1 0x014 -+#define AI_BASE2 0x018 -+#define AI_BASE (0x03ffffff << 6) -+ -+#define AI_SIZE 0x01c -+#define AI_SAMPLE_SIZE (0x03ffffff << 6) -+ -+#define AI_INT_ACK 0x020 -+#define AI_ACK_OVR (0x00000001 << 3) -+#define AI_ACK_HBE (0x00000001 << 2) -+#define AI_ACK2 (0x00000001 << 1) -+#define AI_ACK1 (0x00000001 << 0) -+ -+#define AI_PWR_DOWN 0xff4 -+#define AI_PWR_DWN (0x00000001 << 0) -+ -+#endif /* __SAA716x_AIP_REG_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_boot.c b/drivers/media/pci/saa716x/saa716x_boot.c -new file mode 100644 -index 0000000..21e59d0 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_boot.c -@@ -0,0 +1,319 @@ -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_greg_reg.h" -+#include "saa716x_cgu_reg.h" -+#include "saa716x_vip_reg.h" -+#include "saa716x_aip_reg.h" -+#include "saa716x_msi_reg.h" -+#include "saa716x_dma_reg.h" -+#include "saa716x_gpio_reg.h" -+#include "saa716x_fgpi_reg.h" -+#include "saa716x_dcs_reg.h" -+ -+#include "saa716x_boot.h" -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+ -+static int saa716x_ext_boot(struct saa716x_dev *saa716x) -+{ -+ /* Write GREG boot_ready to 0 -+ * DW_0 = 0x0001_2018 -+ * DW_1 = 0x0000_0000 -+ */ -+ SAA716x_EPWR(GREG, GREG_RSTU_CTRL, 0x00000000); -+ -+ /* Clear VI0 interrupt -+ * DW_2 = 0x0000_0fe8 -+ * DW_3 = 0x0000_03ff -+ */ -+ SAA716x_EPWR(VI0, INT_CLR_STATUS, 0x000003ff); -+ -+ /* Clear VI1 interrupt -+ * DW_4 = 0x0000_1fe8 -+ * DW_5 = 0x0000_03ff -+ */ -+ SAA716x_EPWR(VI1, INT_CLR_STATUS, 0x000003ff); -+ -+ /* CLear FGPI0 interrupt -+ * DW_6 = 0x0000_2fe8 -+ * DW_7 = 0x0000_007f -+ */ -+ SAA716x_EPWR(FGPI0, INT_CLR_STATUS, 0x0000007f); -+ -+ /* Clear FGPI1 interrupt -+ * DW_8 = 0x0000_3fe8 -+ * DW_9 = 0x0000_007f -+ */ -+ SAA716x_EPWR(FGPI1, INT_CLR_STATUS, 0x0000007f); -+ -+ /* Clear FGPI2 interrupt -+ * DW_10 = 0x0000_4fe8 -+ * DW_11 = 0x0000_007f -+ */ -+ SAA716x_EPWR(FGPI2, INT_CLR_STATUS, 0x0000007f); -+ -+ /* Clear FGPI3 interrupt -+ * DW_12 = 0x0000_5fe8 -+ * DW_13 = 0x0000_007f -+ */ -+ SAA716x_EPWR(FGPI3, INT_CLR_STATUS, 0x0000007f); -+ -+ /* Clear AI0 interrupt -+ * DW_14 = 0x0000_6020 -+ * DW_15 = 0x0000_000f -+ */ -+ SAA716x_EPWR(AI0, AI_INT_ACK, 0x0000000f); -+ -+ /* Clear AI1 interrupt -+ * DW_16 = 0x0000_7020 -+ * DW_17 = 0x0000_200f -+ */ -+ SAA716x_EPWR(AI1, AI_INT_ACK, 0x0000000f); -+ -+ /* Set GREG boot_ready bit to 1 -+ * DW_18 = 0x0001_2018 -+ * DW_19 = 0x0000_2000 -+ */ -+ SAA716x_EPWR(GREG, GREG_RSTU_CTRL, 0x00002000); -+#if 0 -+ /* End of Boot script command -+ * DW_20 = 0x0000_0006 -+ * Where to write this value ?? -+ * This seems very odd an address to trigger the -+ * Boot Control State Machine ! -+ */ -+ SAA716x_EPWR(VI0, 0x00000006, 0xffffffff); -+#endif -+ return 0; -+} -+ -+/* Internal Bootscript configuration */ -+static void saa716x_int_boot(struct saa716x_dev *saa716x) -+{ -+ /* #1 Configure PCI COnfig space -+ * GREG_JETSTR_CONFIG_0 -+ */ -+ SAA716x_EPWR(GREG, GREG_SUBSYS_CONFIG, saa716x->pdev->subsystem_vendor); -+ -+ /* GREG_JETSTR_CONFIG_1 -+ * pmcsr_scale:7 = 0x00 -+ * pmcsr_scale:6 = 0x00 -+ * pmcsr_scale:5 = 0x00 -+ * pmcsr_scale:4 = 0x00 -+ * pmcsr_scale:3 = 0x00 -+ * pmcsr_scale:2 = 0x00 -+ * pmcsr_scale:1 = 0x00 -+ * pmcsr_scale:0 = 0x00 -+ * BAR mask = 20 bit -+ * BAR prefetch = no -+ * MSI capable = 32 messages -+ */ -+ SAA716x_EPWR(GREG, GREG_MSI_BAR_PMCSR, 0x00001005); -+ -+ /* GREG_JETSTR_CONFIG_2 -+ * pmcsr_data:3 = 0x0 -+ * pmcsr_data:2 = 0x0 -+ * pmcsr_data:1 = 0x0 -+ * pmcsr_data:0 = 0x0 -+ */ -+ SAA716x_EPWR(GREG, GREG_PMCSR_DATA_1, 0x00000000); -+ -+ /* GREG_JETSTR_CONFIG_3 -+ * pmcsr_data:7 = 0x0 -+ * pmcsr_data:6 = 0x0 -+ * pmcsr_data:5 = 0x0 -+ * pmcsr_data:4 = 0x0 -+ */ -+ SAA716x_EPWR(GREG, GREG_PMCSR_DATA_2, 0x00000000); -+ -+ /* #2 Release GREG resets -+ * ip_rst_an -+ * dpa1_rst_an -+ * jetsream_reset_an -+ */ -+ SAA716x_EPWR(GREG, GREG_RSTU_CTRL, 0x00000e00); -+ -+ /* #3 GPIO Setup -+ * GPIO 25:24 = Output -+ * GPIO Output "0" after Reset -+ */ -+ SAA716x_EPWR(GPIO, GPIO_OEN, 0xfcffffff); -+ -+ /* #4 Custom stuff goes in here */ -+ -+ /* #5 Disable CGU Clocks -+ * except for PHY, Jetstream, DPA1, DCS, Boot, GREG -+ * CGU_PCR_0_3: pss_mmu_clk:0 = 0x0 -+ */ -+ SAA716x_EPWR(CGU, CGU_PCR_0_3, 0x00000006); -+ -+ /* CGU_PCR_0_4: pss_dtl2mtl_mmu_clk:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_0_4, 0x00000006); -+ -+ /* CGU_PCR_0_5: pss_msi_ck:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_0_5, 0x00000006); -+ -+ /* CGU_PCR_0_7: pss_gpio_clk:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_0_7, 0x00000006); -+ -+ /* CGU_PCR_2_1: spi_clk:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_2_1, 0x00000006); -+ -+ /* CGU_PCR_3_2: i2c_clk:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_3_2, 0x00000006); -+ -+ /* CGU_PCR_4_1: phi_clk:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_4_1, 0x00000006); -+ -+ /* CGU_PCR_5: vip0_clk:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_5, 0x00000006); -+ -+ /* CGU_PCR_6: vip1_clk:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_6, 0x00000006); -+ -+ /* CGU_PCR_7: fgpi0_clk:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_7, 0x00000006); -+ -+ /* CGU_PCR_8: fgpi1_clk:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_8, 0x00000006); -+ -+ /* CGU_PCR_9: fgpi2_clk:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_9, 0x00000006); -+ -+ /* CGU_PCR_10: fgpi3_clk:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_10, 0x00000006); -+ -+ /* CGU_PCR_11: ai0_clk:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_11, 0x00000006); -+ -+ /* CGU_PCR_12: ai1_clk:0 = 0x0 */ -+ SAA716x_EPWR(CGU, CGU_PCR_12, 0x00000006); -+ -+ /* #6 Set GREG boot_ready = 0x1 */ -+ SAA716x_EPWR(GREG, GREG_RSTU_CTRL, 0x00002000); -+ -+ /* #7 Disable GREG CGU Clock */ -+ SAA716x_EPWR(CGU, CGU_PCR_0_6, 0x00000006); -+ -+ /* End of Bootscript command ?? */ -+} -+ -+int saa716x_core_boot(struct saa716x_dev *saa716x) -+{ -+ struct saa716x_config *config = saa716x->config; -+ -+ switch (config->boot_mode) { -+ case SAA716x_EXT_BOOT: -+ dprintk(SAA716x_DEBUG, 1, "Using External Boot from config"); -+ saa716x_ext_boot(saa716x); -+ break; -+ case SAA716x_INT_BOOT: -+ dprintk(SAA716x_DEBUG, 1, "Using Internal Boot from config"); -+ saa716x_int_boot(saa716x); -+ break; -+ default: -+ dprintk(SAA716x_ERROR, 1, "Unknown configuration %d", config->boot_mode); -+ break; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_core_boot); -+ -+static void saa716x_bus_report(struct pci_dev *pdev, int enable) -+{ -+ u32 reg; -+ -+ pci_read_config_dword(pdev, 0x04, ®); -+ if (enable) -+ reg |= 0x00000100; /* enable SERR */ -+ else -+ reg &= 0xfffffeff; /* disable SERR */ -+ pci_write_config_dword(pdev, 0x04, reg); -+ -+ pci_read_config_dword(pdev, 0x58, ®); -+ reg &= 0xfffffffd; -+ pci_write_config_dword(pdev, 0x58, reg); -+} -+ -+int saa716x_jetpack_init(struct saa716x_dev *saa716x) -+{ -+ /* -+ * configure PHY through config space not to report -+ * non-fatal error messages to avoid problems with -+ * quirky BIOS'es -+ */ -+ saa716x_bus_report(saa716x->pdev, 0); -+ -+ /* -+ * create time out for blocks that have no clock -+ * helps with lower bitrates on FGPI -+ */ -+ SAA716x_EPWR(DCS, DCSC_CTRL, ENABLE_TIMEOUT); -+ -+ /* Reset all blocks */ -+ SAA716x_EPWR(MSI, MSI_SW_RST, MSI_SW_RESET); -+ SAA716x_EPWR(MMU, MMU_SW_RST, MMU_SW_RESET); -+ SAA716x_EPWR(BAM, BAM_SW_RST, BAM_SW_RESET); -+ -+ switch (saa716x->pdev->device) { -+ case SAA7162: -+ dprintk(SAA716x_DEBUG, 1, "SAA%02x Decoder disable", saa716x->pdev->device); -+ SAA716x_EPWR(GPIO, GPIO_OEN, 0xfcffffff); -+ SAA716x_EPWR(GPIO, GPIO_WR, 0x00000000); /* Disable decoders */ -+ msleep(10); -+ SAA716x_EPWR(GPIO, GPIO_WR, 0x03000000); /* Enable decoders */ -+ break; -+ case SAA7161: -+ dprintk(SAA716x_DEBUG, 1, "SAA%02x Decoder disable", saa716x->pdev->device); -+ SAA716x_EPWR(GPIO, GPIO_OEN, 0xfeffffff); -+ SAA716x_EPWR(GPIO, GPIO_WR, 0x00000000); /* Disable decoders */ -+ msleep(10); -+ SAA716x_EPWR(GPIO, GPIO_WR, 0x01000000); /* Enable decoder */ -+ break; -+ case SAA7160: -+ saa716x->i2c_rate = SAA716x_I2C_RATE_100; -+ break; -+ default: -+ dprintk(SAA716x_ERROR, 1, "Unknown device (0x%02x)", saa716x->pdev->device); -+ return -ENODEV; -+ } -+ -+ /* General setup for MMU */ -+ SAA716x_EPWR(MMU, MMU_MODE, 0x14); -+ dprintk(SAA716x_DEBUG, 1, "SAA%02x Jetpack Successfully initialized", saa716x->pdev->device); -+ -+ return 0; -+} -+EXPORT_SYMBOL(saa716x_jetpack_init); -+ -+void saa716x_core_reset(struct saa716x_dev *saa716x) -+{ -+ dprintk(SAA716x_DEBUG, 1, "RESET Modules"); -+ -+ /* VIP */ -+ SAA716x_EPWR(VI0, VI_MODE, SOFT_RESET); -+ SAA716x_EPWR(VI1, VI_MODE, SOFT_RESET); -+ -+ /* FGPI */ -+ SAA716x_EPWR(FGPI0, FGPI_SOFT_RESET, FGPI_SOFTWARE_RESET); -+ SAA716x_EPWR(FGPI1, FGPI_SOFT_RESET, FGPI_SOFTWARE_RESET); -+ SAA716x_EPWR(FGPI2, FGPI_SOFT_RESET, FGPI_SOFTWARE_RESET); -+ SAA716x_EPWR(FGPI3, FGPI_SOFT_RESET, FGPI_SOFTWARE_RESET); -+ -+ /* AIP */ -+ SAA716x_EPWR(AI0, AI_CTL, AI_RESET); -+ SAA716x_EPWR(AI1, AI_CTL, AI_RESET); -+ -+ /* BAM */ -+ SAA716x_EPWR(BAM, BAM_SW_RST, BAM_SW_RESET); -+ -+ /* MMU */ -+ SAA716x_EPWR(MMU, MMU_SW_RST, MMU_SW_RESET); -+ -+ /* MSI */ -+ SAA716x_EPWR(MSI, MSI_SW_RST, MSI_SW_RESET); -+} -+EXPORT_SYMBOL_GPL(saa716x_core_reset); -diff --git a/drivers/media/pci/saa716x/saa716x_boot.h b/drivers/media/pci/saa716x/saa716x_boot.h -new file mode 100644 -index 0000000..8102853 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_boot.h -@@ -0,0 +1,18 @@ -+#ifndef __SAA716x_BOOT_H -+#define __SAA716x_BOOT_H -+ -+#define DISABLE_TIMEOUT 0x17 -+#define ENABLE_TIMEOUT 0x16 -+ -+enum saa716x_boot_mode { -+ SAA716x_EXT_BOOT = 1, -+ SAA716x_INT_BOOT, /* GPIO[31:30] = 0x01 */ -+}; -+ -+struct saa716x_dev; -+ -+extern int saa716x_core_boot(struct saa716x_dev *saa716x); -+extern int saa716x_jetpack_init(struct saa716x_dev *saa716x); -+extern void saa716x_core_reset(struct saa716x_dev *saa716x); -+ -+#endif /* __SAA716x_BOOT_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_budget.c b/drivers/media/pci/saa716x/saa716x_budget.c -new file mode 100644 -index 0000000..10629d74 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_budget.c -@@ -0,0 +1,2917 @@ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_gpio_reg.h" -+#include "saa716x_greg_reg.h" -+#include "saa716x_msi_reg.h" -+ -+#include "saa716x_adap.h" -+#include "saa716x_i2c.h" -+#include "saa716x_msi.h" -+#include "saa716x_budget.h" -+#include "saa716x_gpio.h" -+#include "saa716x_rom.h" -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+ -+#include "mb86a16.h" -+#include "stv6110x.h" -+#include "stv090x.h" -+#include "tas2101.h" -+#include "av201x.h" -+#include "cx24117.h" -+#include "isl6422.h" -+#include "stb6100.h" -+#include "stb6100_cfg.h" -+ -+#include "tda18212.h" -+#include "cxd2820r.h" -+ -+#include "si2168.h" -+#include "si2157.h" -+ -+#include "stv6120.h" -+#include "stv0910.h" -+#include "tbsci-i2c.h" -+#include "tbs-ci.h" -+ -+unsigned int verbose; -+module_param(verbose, int, 0644); -+MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); -+ -+unsigned int int_type; -+module_param(int_type, int, 0644); -+MODULE_PARM_DESC(int_type, "force Interrupt Handler type: 0=INT-A, 1=MSI, 2=MSI-X. default INT-A mode"); -+ -+#define DRIVER_NAME "SAA716x Budget" -+ -+static int saa716x_budget_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) -+{ -+ struct saa716x_dev *saa716x; -+ int err = 0; -+ -+ saa716x = kzalloc(sizeof (struct saa716x_dev), GFP_KERNEL); -+ if (saa716x == NULL) { -+ printk(KERN_ERR "saa716x_budget_pci_probe ERROR: out of memory\n"); -+ err = -ENOMEM; -+ goto fail0; -+ } -+ -+ saa716x->verbose = verbose; -+ saa716x->int_type = int_type; -+ saa716x->pdev = pdev; -+ saa716x->module = THIS_MODULE; -+ saa716x->config = (struct saa716x_config *) pci_id->driver_data; -+ -+ err = saa716x_pci_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x PCI Initialization failed"); -+ goto fail1; -+ } -+ -+ err = saa716x_cgu_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x CGU Init failed"); -+ goto fail1; -+ } -+ -+ err = saa716x_core_boot(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x Core Boot failed"); -+ goto fail2; -+ } -+ dprintk(SAA716x_DEBUG, 1, "SAA716x Core Boot Success"); -+ -+ err = saa716x_msi_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x MSI Init failed"); -+ goto fail2; -+ } -+ -+ err = saa716x_jetpack_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x Jetpack core initialization failed"); -+ goto fail2; -+ } -+ -+ err = saa716x_i2c_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x I2C Initialization failed"); -+ goto fail2; -+ } -+ -+ saa716x_gpio_init(saa716x); -+#if 0 -+ err = saa716x_dump_eeprom(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x EEPROM dump failed"); -+ } -+ -+ err = saa716x_eeprom_data(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x EEPROM read failed"); -+ } -+#endif -+ -+ /* set default port mapping */ -+ SAA716x_EPWR(GREG, GREG_VI_CTRL, 0x2C688F0A); -+ /* enable FGPI3, FGPI2, FGPI1 and FGPI0 for TS input from Port 2 and 6 */ -+ SAA716x_EPWR(GREG, GREG_FGPI_CTRL, 0x322); -+ -+ err = saa716x_dvb_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x DVB initialization failed"); -+ goto fail3; -+ } -+ -+ return 0; -+ -+fail3: -+ saa716x_dvb_exit(saa716x); -+ saa716x_i2c_exit(saa716x); -+fail2: -+ saa716x_pci_exit(saa716x); -+fail1: -+ kfree(saa716x); -+fail0: -+ return err; -+} -+ -+static void saa716x_budget_pci_remove(struct pci_dev *pdev) -+{ -+ struct saa716x_dev *saa716x = pci_get_drvdata(pdev); -+ struct saa716x_adapter *saa716x_adap = saa716x->saa716x_adap; -+ int i; -+ -+ for(i = 0;iconfig->adapters; i++) -+ { -+ if(saa716x_adap->tbsci){ -+ tbsci_release(saa716x_adap); -+ tbsci_i2c_remove(saa716x_adap); -+ } -+ -+ saa716x_adap++; -+ } -+ -+ saa716x_dvb_exit(saa716x); -+ saa716x_i2c_exit(saa716x); -+ saa716x_pci_exit(saa716x); -+ kfree(saa716x); -+} -+ -+static irqreturn_t saa716x_budget_pci_irq(int irq, void *dev_id) -+{ -+ struct saa716x_dev *saa716x = (struct saa716x_dev *) dev_id; -+ -+ u32 stat_h, stat_l, mask_h, mask_l; -+ -+ if (unlikely(saa716x == NULL)) { -+ printk("%s: saa716x=NULL", __func__); -+ return IRQ_NONE; -+ } -+ -+ stat_l = SAA716x_EPRD(MSI, MSI_INT_STATUS_L); -+ stat_h = SAA716x_EPRD(MSI, MSI_INT_STATUS_H); -+ mask_l = SAA716x_EPRD(MSI, MSI_INT_ENA_L); -+ mask_h = SAA716x_EPRD(MSI, MSI_INT_ENA_H); -+ -+ dprintk(SAA716x_DEBUG, 1, "MSI STAT L=<%02x> H=<%02x>, CTL L=<%02x> H=<%02x>", -+ stat_l, stat_h, mask_l, mask_h); -+ -+ if (!((stat_l & mask_l) || (stat_h & mask_h))) -+ return IRQ_NONE; -+ -+ if (stat_l) -+ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_L, stat_l); -+ -+ if (stat_h) -+ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_H, stat_h); -+ -+ saa716x_msi_event(saa716x, stat_l, stat_h); -+#if 0 -+ dprintk(SAA716x_DEBUG, 1, "VI STAT 0=<%02x> 1=<%02x>, CTL 1=<%02x> 2=<%02x>", -+ SAA716x_EPRD(VI0, INT_STATUS), -+ SAA716x_EPRD(VI1, INT_STATUS), -+ SAA716x_EPRD(VI0, INT_ENABLE), -+ SAA716x_EPRD(VI1, INT_ENABLE)); -+ -+ dprintk(SAA716x_DEBUG, 1, "FGPI STAT 0=<%02x> 1=<%02x>, CTL 1=<%02x> 2=<%02x>", -+ SAA716x_EPRD(FGPI0, INT_STATUS), -+ SAA716x_EPRD(FGPI1, INT_STATUS), -+ SAA716x_EPRD(FGPI0, INT_ENABLE), -+ SAA716x_EPRD(FGPI0, INT_ENABLE)); -+ -+ dprintk(SAA716x_DEBUG, 1, "FGPI STAT 2=<%02x> 3=<%02x>, CTL 2=<%02x> 3=<%02x>", -+ SAA716x_EPRD(FGPI2, INT_STATUS), -+ SAA716x_EPRD(FGPI3, INT_STATUS), -+ SAA716x_EPRD(FGPI2, INT_ENABLE), -+ SAA716x_EPRD(FGPI3, INT_ENABLE)); -+ -+ dprintk(SAA716x_DEBUG, 1, "AI STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", -+ SAA716x_EPRD(AI0, AI_STATUS), -+ SAA716x_EPRD(AI1, AI_STATUS), -+ SAA716x_EPRD(AI0, AI_CTL), -+ SAA716x_EPRD(AI1, AI_CTL)); -+ -+ dprintk(SAA716x_DEBUG, 1, "I2C STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", -+ SAA716x_EPRD(I2C_A, INT_STATUS), -+ SAA716x_EPRD(I2C_B, INT_STATUS), -+ SAA716x_EPRD(I2C_A, INT_ENABLE), -+ SAA716x_EPRD(I2C_B, INT_ENABLE)); -+ -+ dprintk(SAA716x_DEBUG, 1, "DCS STAT=<%02x>, CTL=<%02x>", -+ SAA716x_EPRD(DCS, DCSC_INT_STATUS), -+ SAA716x_EPRD(DCS, DCSC_INT_ENABLE)); -+#endif -+ -+ if (stat_l) { -+ if (stat_l & MSI_INT_TAGACK_FGPI_0) { -+ tasklet_schedule(&saa716x->fgpi[0].tasklet); -+ } -+ if (stat_l & MSI_INT_TAGACK_FGPI_1) { -+ tasklet_schedule(&saa716x->fgpi[1].tasklet); -+ } -+ if (stat_l & MSI_INT_TAGACK_FGPI_2) { -+ tasklet_schedule(&saa716x->fgpi[2].tasklet); -+ } -+ if (stat_l & MSI_INT_TAGACK_FGPI_3) { -+ tasklet_schedule(&saa716x->fgpi[3].tasklet); -+ } -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static void demux_worker(unsigned long data) -+{ -+ struct saa716x_fgpi_stream_port *fgpi_entry = (struct saa716x_fgpi_stream_port *)data; -+ struct saa716x_dev *saa716x = fgpi_entry->saa716x; -+ struct dvb_demux *demux; -+ u32 fgpi_index; -+ u32 i; -+ u32 write_index; -+ -+ fgpi_index = fgpi_entry->dma_channel - 6; -+ demux = NULL; -+ for (i = 0; i < saa716x->config->adapters; i++) { -+ if (saa716x->config->adap_config[i].ts_port == fgpi_index) { -+ demux = &saa716x->saa716x_adap[i].demux; -+ break; -+ } -+ } -+ if (demux == NULL) { -+ printk(KERN_ERR "%s: unexpected channel %u\n", -+ __func__, fgpi_entry->dma_channel); -+ return; -+ } -+ -+ write_index = saa716x_fgpi_get_write_index(saa716x, fgpi_index); -+ if (write_index < 0) -+ return; -+ -+ dprintk(SAA716x_DEBUG, 1, "dma buffer = %d", write_index); -+ -+ if (write_index == fgpi_entry->read_index) { -+ printk(KERN_DEBUG "%s: called but nothing to do\n", __func__); -+ return; -+ } -+ -+ do { -+ u8 *data = (u8 *)fgpi_entry->dma_buf[fgpi_entry->read_index].mem_virt; -+ -+ pci_dma_sync_sg_for_cpu(saa716x->pdev, -+ fgpi_entry->dma_buf[fgpi_entry->read_index].sg_list, -+ fgpi_entry->dma_buf[fgpi_entry->read_index].list_len, -+ PCI_DMA_FROMDEVICE); -+ -+ dvb_dmx_swfilter(demux, data, 348 * 188); -+ -+ fgpi_entry->read_index = (fgpi_entry->read_index + 1) & 7; -+ } while (write_index != fgpi_entry->read_index); -+} -+ -+ -+#define SAA716x_MODEL_TWINHAN_VP3071 "Twinhan/Azurewave VP-3071" -+#define SAA716x_DEV_TWINHAN_VP3071 "2x DVB-T" -+ -+static int saa716x_vp3071_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *saa716x = adapter->saa716x; -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); -+ -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_vp3071_config = { -+ .model_name = SAA716x_MODEL_TWINHAN_VP3071, -+ .dev_type = SAA716x_DEV_TWINHAN_VP3071, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 2, -+ .frontend_attach = saa716x_vp3071_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+}; -+ -+ -+#define SAA716x_MODEL_TWINHAN_VP1028 "Twinhan/Azurewave VP-1028" -+#define SAA716x_DEV_TWINHAN_VP1028 "DVB-S" -+ -+static int vp1028_dvbs_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) -+{ -+ struct saa716x_dev *saa716x = fe->dvb->priv; -+ -+ switch (voltage) { -+ case SEC_VOLTAGE_13: -+ dprintk(SAA716x_ERROR, 1, "Polarization=[13V]"); -+ break; -+ case SEC_VOLTAGE_18: -+ dprintk(SAA716x_ERROR, 1, "Polarization=[18V]"); -+ break; -+ case SEC_VOLTAGE_OFF: -+ dprintk(SAA716x_ERROR, 1, "Frontend (dummy) POWERDOWN"); -+ break; -+ default: -+ dprintk(SAA716x_ERROR, 1, "Invalid = (%d)", (u32 ) voltage); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+struct mb86a16_config vp1028_mb86a16_config = { -+ .demod_address = 0x08, -+ .set_voltage = vp1028_dvbs_set_voltage, -+}; -+ -+static int saa716x_vp1028_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *saa716x = adapter->saa716x; -+ struct saa716x_i2c *i2c = &saa716x->i2c[1]; -+ -+ if (count == 0) { -+ -+ mutex_lock(&saa716x->adap_lock); -+ -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Power ON", count); -+ saa716x_gpio_set_output(saa716x, 10); -+ msleep(1); -+ -+ /* VP-1028 has inverted power supply control */ -+ saa716x_gpio_write(saa716x, 10, 1); /* set to standby */ -+ saa716x_gpio_write(saa716x, 10, 0); /* switch it on */ -+ msleep(100); -+ -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Reset", count); -+ saa716x_gpio_set_output(saa716x, 12); -+ msleep(1); -+ -+ /* reset demodulator (Active LOW) */ -+ saa716x_gpio_write(saa716x, 12, 1); -+ msleep(100); -+ saa716x_gpio_write(saa716x, 12, 0); -+ msleep(100); -+ saa716x_gpio_write(saa716x, 12, 1); -+ msleep(100); -+ -+ mutex_unlock(&saa716x->adap_lock); -+ -+ dprintk(SAA716x_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)"); -+ adapter->fe = dvb_attach(mb86a16_attach, -+ &vp1028_mb86a16_config, -+ &i2c->i2c_adapter); -+ if (adapter->fe) { -+ dprintk(SAA716x_ERROR, 1, "found MB86A16 DVB-S/DSS frontend @0x%02x", -+ vp1028_mb86a16_config.demod_address); -+ -+ } else { -+ goto exit; -+ } -+ dprintk(SAA716x_ERROR, 1, "Done!"); -+ } -+ -+ return 0; -+exit: -+ dprintk(SAA716x_ERROR, 1, "Frontend attach failed"); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_vp1028_config = { -+ .model_name = SAA716x_MODEL_TWINHAN_VP1028, -+ .dev_type = SAA716x_DEV_TWINHAN_VP1028, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 1, -+ .frontend_attach = saa716x_vp1028_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+}; -+ -+ -+#define SAA716x_MODEL_TWINHAN_VP6002 "Twinhan/Azurewave VP-6002" -+#define SAA716x_DEV_TWINHAN_VP6002 "DVB-S" -+ -+static int saa716x_vp6002_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *saa716x = adapter->saa716x; -+ -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); -+ -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_vp6002_config = { -+ .model_name = SAA716x_MODEL_TWINHAN_VP6002, -+ .dev_type = SAA716x_DEV_TWINHAN_VP6002, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 1, -+ .frontend_attach = saa716x_vp6002_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+}; -+ -+ -+#define SAA716x_MODEL_KNC1_DUALS2 "KNC One Dual S2" -+#define SAA716x_DEV_KNC1_DUALS2 "1xDVB-S + 1xDVB-S/S2" -+ -+static int saa716x_knc1_duals2_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *saa716x = adapter->saa716x; -+ -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); -+ -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_knc1_duals2_config = { -+ .model_name = SAA716x_MODEL_KNC1_DUALS2, -+ .dev_type = SAA716x_DEV_KNC1_DUALS2, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 2, -+ .frontend_attach = saa716x_knc1_duals2_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+}; -+ -+ -+#define SAA716x_MODEL_SKYSTAR2_EXPRESS_HD "SkyStar 2 eXpress HD" -+#define SAA716x_DEV_SKYSTAR2_EXPRESS_HD "DVB-S/S2" -+ -+static struct stv090x_config skystar2_stv090x_config = { -+ .device = STV0903, -+ .demod_mode = STV090x_SINGLE, -+ .clk_mode = STV090x_CLK_EXT, -+ -+ .xtal = 8000000, -+ .address = 0x68, -+ -+ .ts1_mode = STV090x_TSMODE_DVBCI, -+ .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, -+ -+ .repeater_level = STV090x_RPTLEVEL_16, -+ -+ .tuner_init = NULL, -+ .tuner_sleep = NULL, -+ .tuner_set_mode = NULL, -+ .tuner_set_frequency = NULL, -+ .tuner_get_frequency = NULL, -+ .tuner_set_bandwidth = NULL, -+ .tuner_get_bandwidth = NULL, -+ .tuner_set_bbgain = NULL, -+ .tuner_get_bbgain = NULL, -+ .tuner_set_refclk = NULL, -+ .tuner_get_status = NULL, -+}; -+ -+static int skystar2_set_voltage(struct dvb_frontend *fe, -+ enum fe_sec_voltage voltage) -+{ -+ int err; -+ u8 en = 0; -+ u8 sel = 0; -+ -+ switch (voltage) { -+ case SEC_VOLTAGE_OFF: -+ en = 0; -+ break; -+ -+ case SEC_VOLTAGE_13: -+ en = 1; -+ sel = 0; -+ break; -+ -+ case SEC_VOLTAGE_18: -+ en = 1; -+ sel = 1; -+ break; -+ -+ default: -+ break; -+ } -+ -+ err = skystar2_stv090x_config.set_gpio(fe, 2, 0, en, 0); -+ if (err < 0) -+ goto exit; -+ err = skystar2_stv090x_config.set_gpio(fe, 3, 0, sel, 0); -+ if (err < 0) -+ goto exit; -+ -+ return 0; -+exit: -+ return err; -+} -+ -+static int skystar2_voltage_boost(struct dvb_frontend *fe, long arg) -+{ -+ int err; -+ u8 value; -+ -+ if (arg) -+ value = 1; -+ else -+ value = 0; -+ -+ err = skystar2_stv090x_config.set_gpio(fe, 4, 0, value, 0); -+ if (err < 0) -+ goto exit; -+ -+ return 0; -+exit: -+ return err; -+} -+ -+static struct stv6110x_config skystar2_stv6110x_config = { -+ .addr = 0x60, -+ .refclk = 16000000, -+ .clk_div = 2, -+}; -+ -+static int skystar2_express_hd_frontend_attach(struct saa716x_adapter *adapter, -+ int count) -+{ -+ struct saa716x_dev *saa716x = adapter->saa716x; -+ struct saa716x_i2c *i2c = &saa716x->i2c[SAA716x_I2C_BUS_B]; -+ struct stv6110x_devctl *ctl; -+ -+ if (count < saa716x->config->adapters) { -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", -+ count); -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, -+ saa716x->pdev->subsystem_device); -+ -+ saa716x_gpio_set_output(saa716x, 26); -+ -+ /* Reset the demodulator */ -+ saa716x_gpio_write(saa716x, 26, 1); -+ saa716x_gpio_write(saa716x, 26, 0); -+ msleep(10); -+ saa716x_gpio_write(saa716x, 26, 1); -+ msleep(10); -+ -+ adapter->fe = dvb_attach(stv090x_attach, -+ &skystar2_stv090x_config, -+ &i2c->i2c_adapter, -+ STV090x_DEMODULATOR_0); -+ -+ if (adapter->fe) { -+ dprintk(SAA716x_NOTICE, 1, "found STV0903 @0x%02x", -+ skystar2_stv090x_config.address); -+ } else { -+ goto exit; -+ } -+ -+ adapter->fe->ops.set_voltage = skystar2_set_voltage; -+ adapter->fe->ops.enable_high_lnb_voltage = skystar2_voltage_boost; -+ -+ ctl = dvb_attach(stv6110x_attach, -+ adapter->fe, -+ &skystar2_stv6110x_config, -+ &i2c->i2c_adapter); -+ -+ if (ctl) { -+ dprintk(SAA716x_NOTICE, 1, "found STV6110(A) @0x%02x", -+ skystar2_stv6110x_config.addr); -+ -+ skystar2_stv090x_config.tuner_init = ctl->tuner_init; -+ skystar2_stv090x_config.tuner_sleep = ctl->tuner_sleep; -+ skystar2_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; -+ skystar2_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; -+ skystar2_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; -+ skystar2_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; -+ skystar2_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; -+ skystar2_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; -+ skystar2_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; -+ skystar2_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; -+ skystar2_stv090x_config.tuner_get_status = ctl->tuner_get_status; -+ -+ /* call the init function once to initialize -+ tuner's clock output divider and demod's -+ master clock */ -+ if (adapter->fe->ops.init) -+ adapter->fe->ops.init(adapter->fe); -+ } else { -+ goto exit; -+ } -+ -+ dprintk(SAA716x_ERROR, 1, "Done!"); -+ return 0; -+ } -+exit: -+ dprintk(SAA716x_ERROR, 1, "Frontend attach failed"); -+ return -ENODEV; -+} -+ -+static struct saa716x_config skystar2_express_hd_config = { -+ .model_name = SAA716x_MODEL_SKYSTAR2_EXPRESS_HD, -+ .dev_type = SAA716x_DEV_SKYSTAR2_EXPRESS_HD, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 1, -+ .frontend_attach = skystar2_express_hd_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+ .adap_config = { -+ { -+ /* Adapter 0 */ -+ .ts_port = 1, /* using FGPI 1 */ -+ .worker = demux_worker -+ } -+ } -+}; -+ -+ -+#define SAA716x_MODEL_TBS6284 "TurboSight TBS 6284 " -+#define SAA716x_DEV_TBS6284 "DVB-T/T2/C" -+ -+static struct cxd2820r_config cxd2820r_config[] = { -+ { -+ .i2c_address = 0x6c, /* (0xd8 >> 1) */ -+ .ts_mode = 0x38, -+ }, -+ { -+ .i2c_address = 0x6d, /* (0xda >> 1) */ -+ .ts_mode = 0x38, -+ } -+}; -+ -+static struct tda18212_config tda18212_config[] = { -+ { -+ /* .i2c_address = 0x60 (0xc0 >> 1) */ -+ .if_dvbt_6 = 3550, -+ .if_dvbt_7 = 3700, -+ .if_dvbt_8 = 4150, -+ .if_dvbt2_6 = 3250, -+ .if_dvbt2_7 = 4000, -+ .if_dvbt2_8 = 4000, -+ .if_dvbc = 5000, -+ .loop_through = 1, -+ .xtout = 1 -+ }, -+ { -+ /* .i2c_address = 0x63 (0xc6 >> 1) */ -+ .if_dvbt_6 = 3550, -+ .if_dvbt_7 = 3700, -+ .if_dvbt_8 = 4150, -+ .if_dvbt2_6 = 3250, -+ .if_dvbt2_7 = 4000, -+ .if_dvbt2_8 = 4000, -+ .if_dvbc = 5000, -+ .loop_through = 0, -+ .xtout = 0 -+ }, -+}; -+ -+static int saa716x_tbs_read_mac(struct saa716x_dev *saa716x, int count, u8 *mac) -+{ -+ return saa716x_read_rombytes(saa716x, 0x2A0 + count * 16, 6, mac); -+} -+ -+static int saa716x_tbs6284_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ struct saa716x_i2c *i2c = &dev->i2c[1 - (count >> 1)]; -+ struct i2c_adapter *i2cadapter = &i2c->i2c_adapter; -+ u8 mac[6]; -+ -+ struct i2c_client *client; -+ -+ struct i2c_board_info board_info = { -+ .type = "tda18212", -+ .platform_data = &tda18212_config[count & 1], -+ }; -+ -+ -+ if (count > 3) -+ goto err; -+ -+ /* reset */ -+ if (count == 0) { -+ saa716x_gpio_set_output(dev, 22); -+ saa716x_gpio_write(dev, 22, 0); -+ msleep(200); -+ saa716x_gpio_write(dev, 22, 1); -+ msleep(400); -+ } else if (count == 2) { -+ saa716x_gpio_set_output(dev, 12); -+ saa716x_gpio_write(dev, 12, 0); -+ msleep(200); -+ saa716x_gpio_write(dev, 12, 1); -+ msleep(400); -+ } -+ -+ /* attach frontend */ -+ adapter->fe = dvb_attach(cxd2820r_attach, &cxd2820r_config[count & 1], -+ &i2c->i2c_adapter, NULL); -+ if (!adapter->fe) -+ goto err; -+ -+ /* attach tuner */ -+ board_info.addr = (count & 1) ? 0x63 : 0x60; -+ tda18212_config[count & 1].fe = adapter->fe; -+ request_module("tda18212"); -+ client = i2c_new_device(i2cadapter, &board_info); -+ if (client == NULL || client->dev.driver == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ goto err2; -+ } -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ dvb_frontend_detach(adapter->fe); -+ goto err2; -+ } -+ adapter->i2c_client_tuner = client; -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC[%d]=%pM\n", dev->config->model_name, count, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err2: -+ dev_err(&dev->pdev->dev, "%s frontend %d tuner attach failed\n", -+ dev->config->model_name, count); -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ -+ adapter->fe = NULL; -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6284_config = { -+ .model_name = SAA716x_MODEL_TBS6284, -+ .dev_type = SAA716x_DEV_TBS6284, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 4, -+ .frontend_attach = saa716x_tbs6284_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 3, -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 1 */ -+ .ts_port = 2, -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 2 */ -+ .ts_port = 1, -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 3 */ -+ .ts_port = 0, -+ .worker = demux_worker -+ } -+ }, -+}; -+ -+ -+#define SAA716x_MODEL_TBS6280 "TurboSight TBS 6280 " -+#define SAA716x_DEV_TBS6280 "DVB-T/T2/C" -+ -+static int saa716x_tbs6280_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ struct saa716x_i2c *i2c = &dev->i2c[SAA716x_I2C_BUS_A]; -+ struct i2c_adapter *i2cadapter = &i2c->i2c_adapter; -+ u8 mac[6]; -+ -+ struct i2c_client *client; -+ -+ struct i2c_board_info board_info = { -+ .type = "tda18212", -+ .platform_data = &tda18212_config[count & 1], -+ }; -+ -+ if (count > 1) -+ goto err; -+ -+ /* reset */ -+ if (count == 0) { -+ saa716x_gpio_set_output(dev, 2); -+ saa716x_gpio_write(dev, 2, 0); -+ msleep(200); -+ saa716x_gpio_write(dev, 2, 1); -+ msleep(400); -+ } -+ -+ /* attach frontend */ -+ adapter->fe = dvb_attach(cxd2820r_attach, &cxd2820r_config[count], -+ &i2c->i2c_adapter, NULL); -+ if (!adapter->fe) -+ goto err; -+ -+ /* attach tuner */ -+ board_info.addr = (count & 1) ? 0x63 : 0x60; -+ tda18212_config[count & 1].fe = adapter->fe; -+ request_module("tda18212"); -+ client = i2c_new_device(i2cadapter, &board_info); -+ if (client == NULL || client->dev.driver == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ goto err2; -+ } -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ dvb_frontend_detach(adapter->fe); -+ goto err2; -+ } -+ adapter->i2c_client_tuner = client; -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC[%d]=%pM\n", dev->config->model_name, count, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err2: -+ dev_err(&dev->pdev->dev, "%s frontend %d tuner attach failed\n", -+ dev->config->model_name, count); -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ -+ adapter->fe = NULL; -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6280_config = { -+ .model_name = SAA716x_MODEL_TBS6280, -+ .dev_type = SAA716x_DEV_TBS6280, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 2, -+ .frontend_attach = saa716x_tbs6280_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 1, /* using FGPI 1 */ -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 1 */ -+ .ts_port = 3, /* using FGPI 3 */ -+ .worker = demux_worker -+ }, -+ }, -+}; -+ -+ -+#define SAA716x_MODEL_TBS6221 "TurboSight TBS 6221 " -+#define SAA716x_DEV_TBS6221 "DVB-T/T2/C" -+ -+static int saa716x_tbs6221_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ struct saa716x_i2c *i2c = &dev->i2c[SAA716x_I2C_BUS_A]; -+ struct i2c_adapter *i2cadapter = &i2c->i2c_adapter; -+ struct i2c_client *client; -+ struct i2c_board_info info; -+ struct si2168_config si2168_config; -+ struct si2157_config si2157_config; -+ u8 mac[6]; -+ -+ if (count > 0) -+ goto err; -+ -+ /* attach demod */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.i2c_adapter = &i2cadapter; -+ si2168_config.fe = &adapter->fe; -+ si2168_config.ts_mode = SI2168_TS_PARALLEL; -+ si2168_config.ts_clock_gapped = true; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2168", I2C_NAME_SIZE); -+ info.addr = 0x64; -+ info.platform_data = &si2168_config; -+ request_module(info.type); -+ client = i2c_new_device(&i2c->i2c_adapter, &info); -+ if (client == NULL || client->dev.driver == NULL) { -+ goto err; -+ } -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ goto err; -+ } -+ adapter->i2c_client_demod = client; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = adapter->fe; -+ si2157_config.if_port = 1; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client = i2c_new_device(i2cadapter, &info); -+ if (client == NULL || client->dev.driver == NULL) { -+ module_put(adapter->i2c_client_demod->dev.driver->owner); -+ i2c_unregister_device(adapter->i2c_client_demod); -+ goto err; -+ } -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ module_put(adapter->i2c_client_demod->dev.driver->owner); -+ i2c_unregister_device(adapter->i2c_client_demod); -+ goto err; -+ } -+ adapter->i2c_client_tuner = client; -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC[%d]=%pM\n", dev->config->model_name, count, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6221_config = { -+ .model_name = SAA716x_MODEL_TBS6221, -+ .dev_type = SAA716x_DEV_TBS6221, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 1, -+ .frontend_attach = saa716x_tbs6221_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 3, /* using FGPI 3 */ -+ .worker = demux_worker -+ }, -+ }, -+}; -+#define SAA716x_MODEL_TBS7220 "TurboSight TBS 7220 " -+#define SAA716x_DEV_TBS7220 "DVB-T/T2/C" -+ -+static struct saa716x_config saa716x_tbs7220_config = { -+ .model_name = SAA716x_MODEL_TBS7220, -+ .dev_type = SAA716x_DEV_TBS7220, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 1, -+ .frontend_attach = saa716x_tbs6221_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ .ts_port = 1, -+ .worker = demux_worker -+ }, -+ }, -+ -+}; -+#define SAA716x_MODEL_TBS6281 "TurboSight TBS 6281 " -+#define SAA716x_DEV_TBS6281 "DVB-T/T2/C" -+ -+static int saa716x_tbs6281_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ struct i2c_adapter *i2cadapter; -+ struct i2c_client *client; -+ struct i2c_board_info info; -+ struct si2168_config si2168_config; -+ struct si2157_config si2157_config; -+ u8 mac[6]; -+ -+ if (count > 1) -+ goto err; -+ -+ /* reset */ -+ saa716x_gpio_set_output(dev, count ? 2 : 16); -+ saa716x_gpio_write(dev, count ? 2 : 16, 0); -+ msleep(50); -+ saa716x_gpio_write(dev, count ? 2 : 16, 1); -+ msleep(100); -+ -+ /* attach demod */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.i2c_adapter = &i2cadapter; -+ si2168_config.fe = &adapter->fe; -+ si2168_config.ts_mode = SI2168_TS_PARALLEL; -+ si2168_config.ts_clock_gapped = true; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2168", I2C_NAME_SIZE); -+ info.addr = 0x64; -+ info.platform_data = &si2168_config; -+ request_module(info.type); -+ client = i2c_new_device(&dev->i2c[1 - count].i2c_adapter, &info); -+ if (client == NULL || client->dev.driver == NULL) { -+ goto err; -+ } -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ goto err; -+ } -+ adapter->i2c_client_demod = client; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = adapter->fe; -+ si2157_config.if_port = 1; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client = i2c_new_device(i2cadapter, &info); -+ if (client == NULL || client->dev.driver == NULL) { -+ module_put(adapter->i2c_client_demod->dev.driver->owner); -+ i2c_unregister_device(adapter->i2c_client_demod); -+ goto err; -+ } -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ module_put(adapter->i2c_client_demod->dev.driver->owner); -+ i2c_unregister_device(adapter->i2c_client_demod); -+ goto err; -+ } -+ adapter->i2c_client_tuner = client; -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC[%d]=%pM\n", dev->config->model_name, count, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6281_config = { -+ .model_name = SAA716x_MODEL_TBS6281, -+ .dev_type = SAA716x_DEV_TBS6281, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 2, -+ .frontend_attach = saa716x_tbs6281_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_400, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 1, /* using FGPI 1 */ -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 1 */ -+ .ts_port = 3, /* using FGPI 3 */ -+ .worker = demux_worker -+ }, -+ }, -+}; -+ -+ -+#define SAA716x_MODEL_TBS6285 "TurboSight TBS 6285 " -+#define SAA716x_DEV_TBS6285 "DVB-T/T2/C" -+ -+static int saa716x_tbs6285_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ struct i2c_adapter *i2cadapter; -+ struct i2c_client *client; -+ struct i2c_board_info info; -+ struct si2168_config si2168_config; -+ struct si2157_config si2157_config; -+ u8 mac[6]; -+ -+ if (count > 3) -+ goto err; -+ -+ /* attach demod */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.i2c_adapter = &i2cadapter; -+ si2168_config.fe = &adapter->fe; -+ si2168_config.ts_mode = SI2168_TS_SERIAL; -+ si2168_config.ts_clock_gapped = true; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2168", I2C_NAME_SIZE); -+ info.addr = ((count == 0) || (count == 2)) ? 0x64 : 0x66; -+ info.platform_data = &si2168_config; -+ request_module(info.type); -+ client = i2c_new_device( ((count == 0) || (count == 1)) ? -+ &dev->i2c[1].i2c_adapter : &dev->i2c[0].i2c_adapter, -+ &info); -+ if (client == NULL || client->dev.driver == NULL) { -+ goto err; -+ } -+ -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ goto err; -+ } -+ adapter->i2c_client_demod = client; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = adapter->fe; -+ si2157_config.if_port = 1; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = ((count == 0) || (count == 2)) ? 0x62 : 0x60; -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client = i2c_new_device(i2cadapter, &info); -+ if (client == NULL || client->dev.driver == NULL) { -+ module_put(adapter->i2c_client_demod->dev.driver->owner); -+ i2c_unregister_device(adapter->i2c_client_demod); -+ goto err; -+ } -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ module_put(adapter->i2c_client_demod->dev.driver->owner); -+ i2c_unregister_device(adapter->i2c_client_demod); -+ goto err; -+ } -+ adapter->i2c_client_tuner = client; -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC[%d]=%pM\n", dev->config->model_name, count, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6285_config = { -+ .model_name = SAA716x_MODEL_TBS6285, -+ .dev_type = SAA716x_DEV_TBS6285, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 4, -+ .frontend_attach = saa716x_tbs6285_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_400, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 3, -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 1 */ -+ .ts_port = 2, -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 1 */ -+ .ts_port = 1, -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 1 */ -+ .ts_port = 0, -+ .worker = demux_worker -+ }, -+ }, -+}; -+ -+ -+#define SAA716x_MODEL_TBS6220 "TurboSight TBS 6220 " -+#define SAA716x_DEV_TBS6220 "DVB-T/T2/C" -+ -+static int saa716x_tbs6220_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ struct saa716x_i2c *i2c = &dev->i2c[SAA716x_I2C_BUS_A]; -+ struct i2c_adapter *i2cadapter = &i2c->i2c_adapter; -+ u8 mac[6]; -+ -+ struct i2c_client *client; -+ -+ struct i2c_board_info board_info = { -+ .type = "tda18212", -+ .addr = 0x60, -+ .platform_data = &tda18212_config[0], -+ }; -+ -+ -+ if (count > 0) -+ goto err; -+ -+ /* attach frontend */ -+ adapter->fe = dvb_attach(cxd2820r_attach, &cxd2820r_config[0], -+ &i2c->i2c_adapter, NULL); -+ if (!adapter->fe) -+ goto err; -+ -+ /* attach tuner */ -+ tda18212_config[0].fe = adapter->fe; -+ request_module("tda18212"); -+ client = i2c_new_device(i2cadapter, &board_info); -+ if (client == NULL || client->dev.driver == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ goto err2; -+ } -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ dvb_frontend_detach(adapter->fe); -+ goto err2; -+ } -+ adapter->i2c_client_tuner = client; -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC=%pM\n", dev->config->model_name, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err2: -+ dev_err(&dev->pdev->dev, "%s frontend %d tuner attach failed\n", -+ dev->config->model_name, count); -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ -+ adapter->fe = NULL; -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6220_config = { -+ .model_name = SAA716x_MODEL_TBS6220, -+ .dev_type = SAA716x_DEV_TBS6220, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 1, -+ .frontend_attach = saa716x_tbs6220_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 3, /* using FGPI 3 */ -+ .worker = demux_worker -+ }, -+ }, -+}; -+ -+ -+#define SAA716x_MODEL_TBS6922 "TurboSight TBS 6922 " -+#define SAA716x_DEV_TBS6922 "DVB-S/S2" -+ -+static void tbs6922_lnb_power(struct dvb_frontend *fe, int onoff) -+{ -+ struct i2c_adapter *adapter = tas2101_get_i2c_adapter(fe, 0); -+ struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); -+ struct saa716x_dev *dev = i2c->saa716x; -+ int enpwr_pin = 17; -+ -+ /* lnb power, active high */ -+ saa716x_gpio_set_output(dev, enpwr_pin); -+ if (onoff) -+ saa716x_gpio_write(dev, enpwr_pin, 1); -+ else -+ saa716x_gpio_write(dev, enpwr_pin, 0); -+} -+ -+ -+static struct tas2101_config tbs6922_cfg = { -+ .i2c_address = 0x68, -+ .id = ID_TAS2100, -+ .reset_demod = NULL, -+ .lnb_power = tbs6922_lnb_power, -+ .init = {0x10, 0x32, 0x54, 0x76, 0xb8, 0x9a, 0x33}, -+ .init2 = 0, -+}; -+ -+static struct av201x_config tbs6922_av201x_cfg = { -+ .i2c_address = 0x63, -+ .id = ID_AV2012, -+ .xtal_freq = 27000, /* kHz */ -+}; -+ -+static int saa716x_tbs6922_frontend_attach( -+ struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ u8 mac[6]; -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attaching\n", -+ dev->config->model_name, count); -+ if (count > 0) -+ goto err; -+ -+ saa716x_gpio_set_output(dev, 2); -+ saa716x_gpio_write(dev, 2, 0); -+ msleep(60); -+ saa716x_gpio_write(dev, 2, 1); -+ msleep(120); -+ -+ adapter->fe = dvb_attach(tas2101_attach, &tbs6922_cfg, -+ &dev->i2c[SAA716x_I2C_BUS_A].i2c_adapter); -+ if (adapter->fe == NULL) -+ goto err; -+ -+ if (dvb_attach(av201x_attach, adapter->fe, &tbs6922_av201x_cfg, -+ tas2101_get_i2c_adapter(adapter->fe, 2)) == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_dbg(&dev->pdev->dev, -+ "%s frontend %d tuner attach failed\n", -+ dev->config->model_name, count); -+ goto err; -+ } -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC=%pM\n", dev->config->model_name, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6922_config = { -+ .model_name = SAA716x_MODEL_TBS6922, -+ .dev_type = SAA716x_DEV_TBS6922, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 1, -+ .frontend_attach = saa716x_tbs6922_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 3, /* using FGPI 3 */ -+ .worker = demux_worker -+ }, -+ }, -+}; -+ -+ -+#define SAA716x_MODEL_TBS6923 "TurboSight TBS 6923 " -+#define SAA716x_DEV_TBS6923 "DVB-S/S2" -+ -+static void tbs6923_lnb_power(struct dvb_frontend *fe, int onoff) -+{ -+ struct i2c_adapter *adapter = tas2101_get_i2c_adapter(fe, 0); -+ struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); -+ struct saa716x_dev *dev = i2c->saa716x; -+ int enpwr_pin = 3; -+ -+ /* lnb power, active low */ -+ saa716x_gpio_set_output(dev, enpwr_pin); -+ if (onoff) -+ saa716x_gpio_write(dev, enpwr_pin, 0); -+ else -+ saa716x_gpio_write(dev, enpwr_pin, 1); -+} -+ -+static struct tas2101_config tbs6923_cfg = { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .reset_demod = NULL, -+ .lnb_power = tbs6923_lnb_power, -+ .init = {0x10, 0x32, 0x54, 0x76, 0xb8, 0x9a, 0x33}, -+ .init2 = 0, -+}; -+ -+static struct av201x_config tbs6923_av201x_cfg = { -+ .i2c_address = 0x63, -+ .id = ID_AV2012, -+ .xtal_freq = 27000, /* kHz */ -+}; -+ -+static int saa716x_tbs6923_frontend_attach( -+ struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ u8 mac[6]; -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attaching\n", -+ dev->config->model_name, count); -+ if (count > 0) -+ goto err; -+ -+ saa716x_gpio_set_output(dev, 2); -+ saa716x_gpio_write(dev, 2, 0); -+ msleep(60); -+ saa716x_gpio_write(dev, 2, 1); -+ msleep(120); -+ -+ adapter->fe = dvb_attach(tas2101_attach, &tbs6923_cfg, -+ &dev->i2c[SAA716x_I2C_BUS_A].i2c_adapter); -+ if (adapter->fe == NULL) -+ goto err; -+ -+ if (dvb_attach(av201x_attach, adapter->fe, &tbs6923_av201x_cfg, -+ tas2101_get_i2c_adapter(adapter->fe, 2)) == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_dbg(&dev->pdev->dev, -+ "%s frontend %d tuner attach failed\n", -+ dev->config->model_name, count); -+ goto err; -+ } -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC=%pM\n", dev->config->model_name, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6923_config = { -+ .model_name = SAA716x_MODEL_TBS6923, -+ .dev_type = SAA716x_DEV_TBS6923, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 1, -+ .frontend_attach = saa716x_tbs6923_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 3, /* using FGPI 3 */ -+ .worker = demux_worker -+ }, -+ }, -+}; -+ -+ -+#define SAA716x_MODEL_TBS6925 "TurboSight TBS 6925 " -+#define SAA716x_DEV_TBS6925 "DVB-S/S2" -+ -+static struct stv090x_config tbs6925_stv090x_cfg = { -+ .device = STV0900, -+ .demod_mode = STV090x_SINGLE, -+ .clk_mode = STV090x_CLK_EXT, -+ -+ .xtal = 27000000, -+ .address = 0x68, -+ -+ .ts1_mode = STV090x_TSMODE_PARALLEL_PUNCTURED, -+ .ts2_mode = STV090x_TSMODE_PARALLEL_PUNCTURED, -+ -+ .repeater_level = STV090x_RPTLEVEL_16, -+ .adc1_range = STV090x_ADC_1Vpp, -+ .tuner_bbgain = 6, -+ -+ .tuner_get_frequency = stb6100_get_frequency, -+ .tuner_set_frequency = stb6100_set_frequency, -+ .tuner_set_bandwidth = stb6100_set_bandwidth, -+ .tuner_get_bandwidth = stb6100_get_bandwidth, -+}; -+ -+static struct stb6100_config tbs6925_stb6100_cfg = { -+ .tuner_address = 0x60, -+ .refclock = 27000000 -+}; -+ -+static int tbs6925_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) -+{ -+ struct saa716x_adapter *adapter = fe->dvb->priv; -+ struct saa716x_dev *saa716x = adapter->saa716x; -+ -+ saa716x_gpio_set_output(saa716x, 16); -+ msleep(1); -+ switch (voltage) { -+ case SEC_VOLTAGE_13: -+ saa716x_gpio_write(saa716x, 16, 0); -+ break; -+ case SEC_VOLTAGE_18: -+ saa716x_gpio_write(saa716x, 16, 1); -+ break; -+ case SEC_VOLTAGE_OFF: -+ break; -+ default: -+ return -EINVAL; -+ } -+ msleep(100); -+ -+ return 0; -+} -+ -+static int tbs6925_frontend_attach(struct saa716x_adapter *adapter, -+ int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ u8 mac[6]; -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attaching\n", -+ dev->config->model_name, count); -+ -+ if (count > 0) -+ goto err; -+ -+ /* Reset the demodulator */ -+ saa716x_gpio_set_output(dev, 2); -+ saa716x_gpio_write(dev, 2, 0); -+ msleep(50); -+ saa716x_gpio_write(dev, 2, 1); -+ msleep(100); -+ -+ adapter->fe = dvb_attach(stv090x_attach, &tbs6925_stv090x_cfg, -+ &dev->i2c[SAA716x_I2C_BUS_A].i2c_adapter, -+ STV090x_DEMODULATOR_0); -+ -+ if (adapter->fe == NULL) -+ goto err; -+ -+ adapter->fe->ops.set_voltage = tbs6925_set_voltage; -+ -+ if (dvb_attach(stb6100_attach, adapter->fe, -+ &tbs6925_stb6100_cfg, &dev->i2c[SAA716x_I2C_BUS_A].i2c_adapter) == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_dbg(&dev->pdev->dev, -+ "%s frontend %d tuner attach failed\n", -+ dev->config->model_name, count); -+ goto err; -+ } -+ -+ if (adapter->fe->ops.init) -+ adapter->fe->ops.init(adapter->fe); -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC=%pM\n", dev->config->model_name, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6925_config = { -+ .model_name = SAA716x_MODEL_TBS6925, -+ .dev_type = SAA716x_DEV_TBS6925, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 1, -+ .frontend_attach = tbs6925_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* Adapter 0 */ -+ .ts_port = 3, /* using FGPI 1 */ -+ .worker = demux_worker -+ } -+ } -+}; -+ -+ -+#define SAA716x_MODEL_TBS6982 "TurboSight TBS 6982 " -+#define SAA716x_DEV_TBS6982 "DVB-S/S2" -+ -+static void tbs6982_reset_fe(struct dvb_frontend *fe, int reset_pin) -+{ -+ struct i2c_adapter *adapter = tas2101_get_i2c_adapter(fe, 0); -+ struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); -+ struct saa716x_dev *dev = i2c->saa716x; -+ -+ /* reset frontend, active low */ -+ saa716x_gpio_set_output(dev, reset_pin); -+ saa716x_gpio_write(dev, reset_pin, 0); -+ msleep(60); -+ saa716x_gpio_write(dev, reset_pin, 1); -+ msleep(120); -+} -+ -+static void tbs6982_reset_fe0(struct dvb_frontend *fe) -+{ -+ tbs6982_reset_fe(fe, 2); -+} -+ -+static void tbs6982_reset_fe1(struct dvb_frontend *fe) -+{ -+ tbs6982_reset_fe(fe, 17); -+} -+ -+static void tbs6982_lnb_power(struct dvb_frontend *fe, -+ int enpwr_pin, int onoff) -+{ -+ struct i2c_adapter *adapter = tas2101_get_i2c_adapter(fe, 0); -+ struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); -+ struct saa716x_dev *dev = i2c->saa716x; -+ -+ /* lnb power, active low */ -+ saa716x_gpio_set_output(dev, enpwr_pin); -+ if (onoff) -+ saa716x_gpio_write(dev, enpwr_pin, 0); -+ else -+ saa716x_gpio_write(dev, enpwr_pin, 1); -+} -+ -+static void tbs6982_lnb0_power(struct dvb_frontend *fe, int onoff) -+{ -+ tbs6982_lnb_power(fe, 5, onoff); -+} -+ -+static void tbs6982_lnb1_power(struct dvb_frontend *fe, int onoff) -+{ -+ tbs6982_lnb_power(fe, 3, onoff); -+} -+ -+static struct tas2101_config tbs6982_cfg[] = { -+ { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .reset_demod = tbs6982_reset_fe0, -+ .lnb_power = tbs6982_lnb0_power, -+ .init = {0x10, 0x32, 0x54, 0x76, 0xb8, 0x9a, 0x33}, -+ .init2 = 0, -+ }, -+ { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .reset_demod = tbs6982_reset_fe1, -+ .lnb_power = tbs6982_lnb1_power, -+ .init = {0x8a, 0x6b, 0x13, 0x70, 0x45, 0x92, 0x33}, -+ .init2 = 0, -+ } -+}; -+ -+static struct av201x_config tbs6982_av201x_cfg = { -+ .i2c_address = 0x63, -+ .id = ID_AV2012, -+ .xtal_freq = 27000, /* kHz */ -+}; -+ -+static int saa716x_tbs6982_frontend_attach( -+ struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ u8 mac[6]; -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attaching\n", -+ dev->config->model_name, count); -+ if (count > 1) -+ goto err; -+ -+ saa716x_gpio_set_output(dev, 16); -+ saa716x_gpio_write(dev, 16, 0); -+ msleep(60); -+ saa716x_gpio_write(dev, 16, 1); -+ msleep(120); -+ -+ adapter->fe = dvb_attach(tas2101_attach, &tbs6982_cfg[count], -+ &dev->i2c[1 - count].i2c_adapter); -+ if (adapter->fe == NULL) -+ goto err; -+ -+ if (dvb_attach(av201x_attach, adapter->fe, &tbs6982_av201x_cfg, -+ tas2101_get_i2c_adapter(adapter->fe, 2)) == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_dbg(&dev->pdev->dev, -+ "%s frontend %d tuner attach failed\n", -+ dev->config->model_name, count); -+ goto err; -+ } -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC=%pM\n", dev->config->model_name, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6982_config = { -+ .model_name = SAA716x_MODEL_TBS6982, -+ .dev_type = SAA716x_DEV_TBS6982, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 2, -+ .frontend_attach = saa716x_tbs6982_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_400, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 3, /* using FGPI 3 */ -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 1 */ -+ .ts_port = 1, /* using FGPI 1 */ -+ .worker = demux_worker -+ }, -+ }, -+}; -+ -+ -+#define SAA716x_MODEL_TBS6982SE "TurboSight TBS 6982SE " -+#define SAA716x_DEV_TBS6982SE "DVB-S/S2" -+ -+static void tbs6982se_reset_fe(struct dvb_frontend *fe, int reset_pin) -+{ -+ struct i2c_adapter *adapter = tas2101_get_i2c_adapter(fe, 0); -+ struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); -+ struct saa716x_dev *dev = i2c->saa716x; -+ -+ /* reset frontend, active low */ -+ saa716x_gpio_set_output(dev, reset_pin); -+ saa716x_gpio_write(dev, reset_pin, 0); -+ msleep(60); -+ saa716x_gpio_write(dev, reset_pin, 1); -+ msleep(120); -+} -+ -+static void tbs6982se_reset_fe0(struct dvb_frontend *fe) -+{ -+ tbs6982se_reset_fe(fe, 2); -+} -+ -+static void tbs6982se_reset_fe1(struct dvb_frontend *fe) -+{ -+ tbs6982se_reset_fe(fe, 17); -+} -+ -+static void tbs6982se_lnb_power(struct dvb_frontend *fe, -+ int enpwr_pin, int onoff) -+{ -+ struct i2c_adapter *adapter = tas2101_get_i2c_adapter(fe, 0); -+ struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); -+ struct saa716x_dev *dev = i2c->saa716x; -+ -+ /* lnb power, active low */ -+ saa716x_gpio_set_output(dev, enpwr_pin); -+ if (onoff) -+ saa716x_gpio_write(dev, enpwr_pin, 0); -+ else -+ saa716x_gpio_write(dev, enpwr_pin, 1); -+} -+ -+static void tbs6982se_lnb0_power(struct dvb_frontend *fe, int onoff) -+{ -+ tbs6982se_lnb_power(fe, 3, onoff); -+} -+ -+static void tbs6982se_lnb1_power(struct dvb_frontend *fe, int onoff) -+{ -+ tbs6982se_lnb_power(fe, 16, onoff); -+} -+ -+static struct tas2101_config tbs6982se_cfg[] = { -+ { -+ .i2c_address = 0x60, -+ .id = ID_TAS2101, -+ .reset_demod = tbs6982se_reset_fe0, -+ .lnb_power = tbs6982se_lnb0_power, -+ .init = {0x10, 0x32, 0x54, 0x76, 0xb8, 0x9a, 0x33}, -+ .init2 = 0, -+ }, -+ { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .reset_demod = tbs6982se_reset_fe1, -+ .lnb_power = tbs6982se_lnb1_power, -+ .init = {0x8a, 0x6b, 0x13, 0x70, 0x45, 0x92, 0x33}, -+ .init2 = 0, -+ } -+}; -+ -+static struct av201x_config tbs6982se_av201x_cfg = { -+ .i2c_address = 0x63, -+ .id = ID_AV2012, -+ .xtal_freq = 27000, /* kHz */ -+}; -+ -+static int saa716x_tbs6982se_frontend_attach( -+ struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ u8 mac[6]; -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attaching\n", -+ dev->config->model_name, count); -+ if (count > 1) -+ goto err; -+ -+ adapter->fe = dvb_attach(tas2101_attach, &tbs6982se_cfg[count], -+ &dev->i2c[count].i2c_adapter); -+ if (adapter->fe == NULL) -+ goto err; -+ -+ if (dvb_attach(av201x_attach, adapter->fe, &tbs6982se_av201x_cfg, -+ tas2101_get_i2c_adapter(adapter->fe, 2)) == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_dbg(&dev->pdev->dev, -+ "%s frontend %d tuner attach failed\n", -+ dev->config->model_name, count); -+ goto err; -+ } -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC=%pM\n", dev->config->model_name, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6982se_config = { -+ .model_name = SAA716x_MODEL_TBS6982SE, -+ .dev_type = SAA716x_DEV_TBS6982SE, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 2, -+ .frontend_attach = saa716x_tbs6982se_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_400, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 3, /* using FGPI 3 */ -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 1 */ -+ .ts_port = 1, /* using FGPI 1 */ -+ .worker = demux_worker -+ }, -+ }, -+}; -+ -+ -+#define SAA716x_MODEL_TBS6984 "TurboSight TBS 6984 " -+#define SAA716x_DEV_TBS6984 "DVB-S/S2" -+ -+static void saa716x_tbs6984_init(struct saa716x_dev *saa716x) -+{ -+ int i; -+ const u8 buf[] = { -+ 0xe0, 0x06, 0x66, 0x33, 0x65, -+ 0x01, 0x17, 0x06, 0xde}; -+ -+#define TBS_CK 7 -+#define TBS_CS 8 -+#define TBS_DT 11 -+ -+ /* send init bitstream through a bitbanged spi */ -+ /* set pins as output */ -+ saa716x_gpio_set_output(saa716x, TBS_CK); -+ saa716x_gpio_set_output(saa716x, TBS_CS); -+ saa716x_gpio_set_output(saa716x, TBS_DT); -+ -+ /* set all pins high */ -+ saa716x_gpio_write(saa716x, TBS_CK, 1); -+ saa716x_gpio_write(saa716x, TBS_CS, 1); -+ saa716x_gpio_write(saa716x, TBS_DT, 1); -+ msleep(20); -+ -+ /* CS low */ -+ saa716x_gpio_write(saa716x, TBS_CS, 0); -+ msleep(20); -+ /* send bitstream */ -+ for (i = 0; i < 9 * 8; i++) { -+ /* clock low */ -+ saa716x_gpio_write(saa716x, TBS_CK, 0); -+ msleep(20); -+ /* set data pin */ -+ saa716x_gpio_write(saa716x, TBS_DT, -+ ((buf[i >> 3] >> (7 - (i & 7))) & 1)); -+ /* clock high */ -+ saa716x_gpio_write(saa716x, TBS_CK, 1); -+ msleep(20); -+ } -+ /* raise cs, clk and data */ -+ saa716x_gpio_write(saa716x, TBS_CS, 1); -+ saa716x_gpio_write(saa716x, TBS_CK, 1); -+ saa716x_gpio_write(saa716x, TBS_DT, 1); -+ -+ /* power up LNB supply and control chips */ -+ saa716x_gpio_set_output(saa716x, 19); /* a0 */ -+ saa716x_gpio_set_output(saa716x, 2); /* a1 */ -+ saa716x_gpio_set_output(saa716x, 5); /* a2 */ -+ saa716x_gpio_set_output(saa716x, 3); /* a3 */ -+ -+ /* power off */ -+ saa716x_gpio_write(saa716x, 19, 1); /* a0 */ -+ saa716x_gpio_write(saa716x, 2, 1); /* a1 */ -+ saa716x_gpio_write(saa716x, 5, 1); /* a2 */ -+ saa716x_gpio_write(saa716x, 3, 1); /* a3 */ -+} -+ -+ -+static void tbs6984_lnb_pwr(struct dvb_frontend *fe, int pin, int onoff) -+{ -+ struct i2c_adapter *adapter = cx24117_get_i2c_adapter(fe); -+ struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); -+ struct saa716x_dev *dev = i2c->saa716x; -+ -+ /* lnb power, active low */ -+ if (onoff) -+ saa716x_gpio_write(dev, pin , 0); -+ else -+ saa716x_gpio_write(dev, pin, 1); -+} -+ -+void tbs6984_lnb_pwr0(struct dvb_frontend *fe, int demod, int onoff) -+{ -+ tbs6984_lnb_pwr(fe, (demod == 0) ? 19 : 2, onoff); -+} -+ -+void tbs6984_lnb_pwr1(struct dvb_frontend *fe, int demod, int onoff) -+{ -+ tbs6984_lnb_pwr(fe, (demod == 0) ? 5 : 3, onoff); -+} -+ -+static struct cx24117_config tbs6984_cx24117_cfg[] = { -+ { -+ .demod_address = 0x55, -+ .lnb_power = tbs6984_lnb_pwr0, -+ }, -+ { -+ .demod_address = 0x05, -+ .lnb_power = tbs6984_lnb_pwr1, -+ }, -+}; -+ -+static struct isl6422_config tbs6984_isl6422_cfg[] = { -+ { -+ .current_max = SEC_CURRENT_570m, -+ .curlim = SEC_CURRENT_LIM_ON, -+ .mod_extern = 1, -+ .addr = 0x08, -+ .id = 0, -+ }, -+ { -+ .current_max = SEC_CURRENT_570m, -+ .curlim = SEC_CURRENT_LIM_ON, -+ .mod_extern = 1, -+ .addr = 0x08, -+ .id = 1, -+ } -+ -+}; -+ -+static int saa716x_tbs6984_frontend_attach( -+ struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ struct saa716x_i2c *i2c = &dev->i2c[1 - (count >> 1)]; -+ u8 mac[6]; -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attaching\n", -+ dev->config->model_name, count); -+ -+ if (count > 3) -+ goto err; -+ -+ if (count == 0) -+ saa716x_tbs6984_init(dev); -+ -+ adapter->fe = dvb_attach(cx24117_attach, &tbs6984_cx24117_cfg[count >> 1], -+ &i2c->i2c_adapter); -+ if (adapter->fe == NULL) -+ goto err; -+ -+ if (dvb_attach(isl6422_attach, adapter->fe, &i2c->i2c_adapter, -+ &tbs6984_isl6422_cfg[count & 0x01]) == NULL) -+ dev_info(&dev->pdev->dev, -+ "%s frontend %d doesn't seem to have a isl6422b on the i2c bus.\n", -+ dev->config->model_name, count); -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC=%pM\n", dev->config->model_name, adapter->dvb_adapter.proposed_mac); -+ } -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6984_config = { -+ .model_name = SAA716x_MODEL_TBS6984, -+ .dev_type = SAA716x_DEV_TBS6984, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 4, -+ .frontend_attach = saa716x_tbs6984_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_400, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 2, -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 1 */ -+ .ts_port = 3, -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 2 */ -+ .ts_port = 0, -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 3 */ -+ .ts_port = 1, -+ .worker = demux_worker -+ }, -+ }, -+}; -+ -+ -+#define SAA716x_MODEL_TBS6985 "TurboSight TBS 6985 " -+#define SAA716x_DEV_TBS6985 "DVB-S/S2" -+ -+static void tbs6985_reset_fe(struct dvb_frontend *fe, int reset_pin) -+{ -+ struct i2c_adapter *adapter = tas2101_get_i2c_adapter(fe, 0); -+ struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); -+ struct saa716x_dev *dev = i2c->saa716x; -+ -+ /* reset frontend, active low */ -+ saa716x_gpio_set_output(dev, reset_pin); -+ saa716x_gpio_write(dev, reset_pin, 0); -+ msleep(60); -+ saa716x_gpio_write(dev, reset_pin, 1); -+ msleep(120); -+} -+ -+static void tbs6985_reset_fe0(struct dvb_frontend *fe) -+{ -+ tbs6985_reset_fe(fe, 5); -+} -+ -+static void tbs6985_reset_fe1(struct dvb_frontend *fe) -+{ -+ tbs6985_reset_fe(fe, 2); -+} -+ -+static void tbs6985_reset_fe2(struct dvb_frontend *fe) -+{ -+ tbs6985_reset_fe(fe, 13); -+} -+ -+static void tbs6985_reset_fe3(struct dvb_frontend *fe) -+{ -+ tbs6985_reset_fe(fe, 3); -+} -+ -+static void tbs6985_lnb_power(struct dvb_frontend *fe, -+ int enpwr_pin, int onoff) -+{ -+ struct i2c_adapter *adapter = tas2101_get_i2c_adapter(fe, 0); -+ struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); -+ struct saa716x_dev *dev = i2c->saa716x; -+ -+ /* lnb power, active low */ -+ saa716x_gpio_set_output(dev, enpwr_pin); -+ if (onoff) -+ saa716x_gpio_write(dev, enpwr_pin, 0); -+ else -+ saa716x_gpio_write(dev, enpwr_pin, 1); -+} -+ -+static void tbs6985_lnb0_power(struct dvb_frontend *fe, int onoff) -+{ -+ tbs6985_lnb_power(fe, 27, onoff); -+} -+ -+static void tbs6985_lnb1_power(struct dvb_frontend *fe, int onoff) -+{ -+ tbs6985_lnb_power(fe, 22, onoff); -+} -+ -+static void tbs6985_lnb2_power(struct dvb_frontend *fe, int onoff) -+{ -+ tbs6985_lnb_power(fe, 19, onoff); -+} -+ -+static void tbs6985_lnb3_power(struct dvb_frontend *fe, int onoff) -+{ -+ tbs6985_lnb_power(fe, 15, onoff); -+} -+ -+#undef TBS6985_TSMODE0 -+static struct tas2101_config tbs6985_cfg[] = { -+ { -+ .i2c_address = 0x60, -+ .id = ID_TAS2101, -+ .reset_demod = tbs6985_reset_fe0, -+ .lnb_power = tbs6985_lnb0_power, -+#ifdef TBS6985_TSMODE0 -+ .init = {0x01, 0x32, 0x65, 0x74, 0xab, 0x98, 0x33}, -+#else -+ .init = {0x0b, 0x8a, 0x65, 0x74, 0xab, 0x98, 0xb1}, -+#endif -+ .init2 = 0, -+ }, -+ { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .reset_demod = tbs6985_reset_fe1, -+ .lnb_power = tbs6985_lnb1_power, -+#ifdef TBS6985_TSMODE0 -+ .init = {0x10, 0x32, 0x54, 0xb7, 0x86, 0x9a, 0x33}, -+#else -+ .init = {0x0a, 0x8b, 0x54, 0xb7, 0x86, 0x9a, 0xb1}, -+#endif -+ .init2 = 0, -+ }, -+ { -+ .i2c_address = 0x60, -+ .id = ID_TAS2101, -+ .reset_demod = tbs6985_reset_fe2, -+ .lnb_power = tbs6985_lnb2_power, -+#ifdef TBS6985_TSMODE0 -+ .init = {0x25, 0x36, 0x40, 0xb1, 0x87, 0x9a, 0x33}, -+#else -+ .init = {0xba, 0x80, 0x40, 0xb1, 0x87, 0x9a, 0xb1}, -+#endif -+ .init2 = 0, -+ }, -+ { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .reset_demod = tbs6985_reset_fe3, -+ .lnb_power = tbs6985_lnb3_power, -+#ifdef TBS6985_TSMODE0 -+ .init = {0x80, 0xba, 0x21, 0x53, 0x74, 0x96, 0x33}, -+#else -+ .init = {0xba, 0x80, 0x21, 0x53, 0x74, 0x96, 0xb1}, -+#endif -+ .init2 = 0, -+ } -+}; -+ -+static struct av201x_config tbs6985_av201x_cfg = { -+ .i2c_address = 0x63, -+ .id = ID_AV2012, -+ .xtal_freq = 27000, /* kHz */ -+}; -+ -+static int saa716x_tbs6985_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ u8 mac[6]; -+ -+ if (count > 3) -+ goto err; -+ -+ adapter->fe = dvb_attach(tas2101_attach, &tbs6985_cfg[count], -+ &dev->i2c[1 - (count >> 1)].i2c_adapter); -+ if (adapter->fe == NULL) -+ goto err; -+ -+ if (dvb_attach(av201x_attach, adapter->fe, &tbs6985_av201x_cfg, -+ tas2101_get_i2c_adapter(adapter->fe, 2)) == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_dbg(&dev->pdev->dev, -+ "%s frontend %d tuner attach failed\n", -+ dev->config->model_name, count); -+ goto err; -+ } -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC=%pM\n", dev->config->model_name, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6985_config = { -+ .model_name = SAA716x_MODEL_TBS6985, -+ .dev_type = SAA716x_DEV_TBS6985, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 4, -+ .frontend_attach = saa716x_tbs6985_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_400, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 2, -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 1 */ -+ .ts_port = 3, -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 2 */ -+ .ts_port = 0, -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 3 */ -+ .ts_port = 1, -+ .worker = demux_worker -+ } -+ }, -+}; -+ -+ -+#define SAA716x_MODEL_TBS6991 "TurboSight TBS 6991 " -+#define SAA716x_DEV_TBS6991 "DVB-S/S2" -+ -+static void tbs6991_reset_fe(struct dvb_frontend *fe, int reset_pin) -+{ -+ struct i2c_adapter *adapter = tas2101_get_i2c_adapter(fe, 0); -+ struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); -+ struct saa716x_dev *dev = i2c->saa716x; -+ -+ /* reset frontend, active low */ -+ saa716x_gpio_set_output(dev, reset_pin); -+ saa716x_gpio_write(dev, reset_pin, 0); -+ msleep(60); -+ saa716x_gpio_write(dev, reset_pin, 1); -+ msleep(120); -+} -+ -+static void tbs6991_reset_fe0(struct dvb_frontend *fe) -+{ -+ tbs6991_reset_fe(fe, 20); -+} -+ -+static void tbs6991_reset_fe1(struct dvb_frontend *fe) -+{ -+ tbs6991_reset_fe(fe, 17); -+} -+ -+static void tbs6991_lnb_power(struct dvb_frontend *fe, -+ int enpwr_pin, int onoff) -+{ -+ struct i2c_adapter *adapter = tas2101_get_i2c_adapter(fe, 0); -+ struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); -+ struct saa716x_dev *dev = i2c->saa716x; -+ -+ /* lnb power, active low */ -+ saa716x_gpio_set_output(dev, enpwr_pin); -+ if (onoff) -+ saa716x_gpio_write(dev, enpwr_pin, 0); -+ else -+ saa716x_gpio_write(dev, enpwr_pin, 1); -+} -+ -+static void tbs6991_lnb0_power(struct dvb_frontend *fe, int onoff) -+{ -+ tbs6991_lnb_power(fe, 5, onoff); -+} -+ -+static void tbs6991_lnb1_power(struct dvb_frontend *fe, int onoff) -+{ -+ tbs6991_lnb_power(fe, 26, onoff); -+} -+ -+/* -+ tbs6991 seems to have different settings depending on a value that the closed -+ source driver reads from the eeprom. This is probabbly related to card HW revisons. -+ Details: -+ eeprom i2c addr = 0x1a -+ mem addr = 0xc201 -+ if value == 0x66 or value == 0x68 then tsmode = 1 else 0 -+ -+ This needs to be tested and if needed implement a function to get that value -+ and set the proper tsmode -+*/ -+#define TBS6991_TSMODE0 (0x33) -+#define TBS6991_TSMODE1 (0x31) -+#define TBS6991_TSMODE TBS6991_TSMODE0 -+static struct tas2101_config tbs6991_cfg[] = { -+ { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .reset_demod = tbs6991_reset_fe0, -+ .lnb_power = tbs6991_lnb0_power, -+ .init = {0x10, 0x32, 0x54, 0x76, 0xa8, 0x9b, TBS6991_TSMODE}, -+ .init2 = 0, -+ }, -+ { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .reset_demod = tbs6991_reset_fe1, -+ .lnb_power = tbs6991_lnb1_power, -+ .init = {0x30, 0x21, 0x54, 0x76, 0xb8, 0x9a, TBS6991_TSMODE}, -+ .init2 = 0, -+ } -+}; -+ -+static struct av201x_config tbs6991_av201x_cfg = { -+ .i2c_address = 0x63, -+ .id = ID_AV2012, -+ .xtal_freq = 27000, /* kHz */ -+}; -+ -+static int saa716x_tbs6991_frontend_attach( -+ struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ u8 mac[6]; -+ int ret; -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attaching\n", -+ dev->config->model_name, count); -+ if (count > 1) -+ goto err; -+ -+ adapter->fe = dvb_attach(tas2101_attach, &tbs6991_cfg[count], -+ &dev->i2c[1-count].i2c_adapter); -+ if (adapter->fe == NULL) -+ goto err; -+ -+ if (dvb_attach(av201x_attach, adapter->fe, &tbs6991_av201x_cfg, -+ tas2101_get_i2c_adapter(adapter->fe, 2)) == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_dbg(&dev->pdev->dev, -+ "%s frontend %d tuner attach failed\n", -+ dev->config->model_name, count); -+ goto err; -+ } -+ -+ saa716x_gpio_set_input(dev,count?3:14); -+ msleep(1); -+ saa716x_gpio_set_input(dev,count?6:2); -+ msleep(1); -+ ret = tbsci_i2c_probe(adapter,count?4:3); -+ if(!ret) -+ tbsci_init(adapter,count,2); -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC=%pM\n", dev->config->model_name, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6991_config = { -+ .model_name = SAA716x_MODEL_TBS6991, -+ .dev_type = SAA716x_DEV_TBS6991, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 2, -+ .frontend_attach = saa716x_tbs6991_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_400, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 1, /* using FGPI 3 */ -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 1 */ -+ .ts_port = 3, /* using FGPI 1 */ -+ .worker = demux_worker -+ }, -+ }, -+}; -+ -+ -+#define SAA716x_MODEL_TBS6991SE "TurboSight TBS 6991SE " -+#define SAA716x_DEV_TBS6991SE "DVB-S/S2 " -+ -+static struct tas2101_config tbs6991se_cfg[] = { -+ { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .reset_demod = NULL, -+ .lnb_power = tbs6991_lnb0_power, -+ .init = {0x10, 0x32, 0x54, 0x76, 0x8b, 0x9a, 0x33}, -+ .init2 = 0, -+ }, -+ { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .reset_demod = NULL, -+ .lnb_power = tbs6991_lnb1_power, -+ .init = {0x10, 0x32, 0x54, 0x76, 0x8b, 0x9a, 0x33}, -+ .init2 = 0, -+ } -+}; -+ -+static int saa716x_tbs6991se_frontend_attach( -+ struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ u8 mac[6]; -+ int ret; -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attaching\n", -+ dev->config->model_name, count); -+ if (count > 1) -+ goto err; -+ -+ adapter->fe = dvb_attach(tas2101_attach, &tbs6991se_cfg[count], -+ &dev->i2c[1-count].i2c_adapter); -+ if (adapter->fe == NULL) -+ goto err; -+ -+ if (dvb_attach(av201x_attach, adapter->fe, &tbs6991_av201x_cfg, -+ tas2101_get_i2c_adapter(adapter->fe, 2)) == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_dbg(&dev->pdev->dev, -+ "%s frontend %d tuner attach failed\n", -+ dev->config->model_name, count); -+ goto err; -+ } -+ saa716x_gpio_set_input(dev,count ?6:2); -+ msleep(1); -+ saa716x_gpio_set_input(dev,count?3:14); -+ msleep(1); -+ saa716x_gpio_set_output(dev,count?17:20); -+ msleep(1); -+ ret = tbsci_i2c_probe(adapter,count?4:3); -+ if(!ret) -+ tbsci_init(adapter,count,8); -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC=%pM\n", dev->config->model_name, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6991se_config = { -+ .model_name = SAA716x_MODEL_TBS6991SE, -+ .dev_type = SAA716x_DEV_TBS6991SE, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 2, -+ .frontend_attach = saa716x_tbs6991se_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_400, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { -+ /* adapter 0 */ -+ .ts_port = 1, /* using FGPI 3 */ -+ .worker = demux_worker -+ }, -+ { -+ /* adapter 1 */ -+ .ts_port = 3, /* using FGPI 1 */ -+ .worker = demux_worker -+ }, -+ }, -+}; -+ -+#define SAA716x_MODEL_TBS6983 "TurboSight TBS 6983 " -+#define SAA716x_DEV_TBS6983 "DVB-S/S2" -+ -+static struct stv0910_cfg tbs6983_stv0910_cfg = { -+ .adr = 0x68, -+ .parallel = 1, -+ .rptlvl = 3, -+ .clk = 30000000, -+ .dual_tuner = 1, -+}; -+ -+static struct stv6120_cfg tbs6983_stv6120_cfg = { -+ .adr = 0x60, -+ .xtal = 30000, -+ .Rdiv = 2, -+}; -+ -+static int saa716x_tbs6983_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) -+{ -+ struct saa716x_adapter *adapter = fe->dvb->priv; -+ struct saa716x_dev *saa716x = adapter->saa716x; -+ -+ u8 adapter_gpio_0 = adapter->count ? 16 : 5; -+ u8 adapter_gpio_1 = adapter->count ? 2 : 3; -+ -+ saa716x_gpio_set_output(saa716x, adapter_gpio_0); -+ saa716x_gpio_set_output(saa716x, adapter_gpio_1); -+ msleep(1); -+ -+ switch (voltage) { -+ case SEC_VOLTAGE_13: -+ saa716x_gpio_write(saa716x, adapter_gpio_0, 0); -+ saa716x_gpio_write(saa716x, adapter_gpio_1, 0); -+ break; -+ case SEC_VOLTAGE_18: -+ saa716x_gpio_write(saa716x, adapter_gpio_0, 1); -+ saa716x_gpio_write(saa716x, adapter_gpio_1, 0); -+ break; -+ case SEC_VOLTAGE_OFF: -+ saa716x_gpio_write(saa716x, adapter_gpio_0, 1); -+ saa716x_gpio_write(saa716x, adapter_gpio_1, 1); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int saa716x_tbs6983_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ u8 mac[6]; -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attaching\n", -+ dev->config->model_name, count); -+ -+ if (count == 0) { -+ saa716x_gpio_set_output(dev, 17); -+ msleep(1); -+ saa716x_gpio_write(dev, 17, 0); -+ msleep(50); -+ saa716x_gpio_write(dev, 17, 1); -+ msleep(100); -+ } -+ -+ adapter->fe = dvb_attach(stv0910_attach, -+ &dev->i2c[1].i2c_adapter, -+ &tbs6983_stv0910_cfg, -+ count & 1); -+ -+ if (adapter->fe == NULL) { -+ goto err; -+ } -+ -+ if (dvb_attach(stv6120_attach, adapter->fe, &dev->i2c[1].i2c_adapter, -+ &tbs6983_stv6120_cfg,1 - (count & 1)) == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_dbg(&dev->pdev->dev, -+ "%s frontend %d tuner attach failed\n", -+ dev->config->model_name, count); -+ goto err; -+ } -+ -+ if (adapter->fe->ops.init) -+ adapter->fe->ops.init(adapter->fe); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ adapter->fe->ops.set_voltage = saa716x_tbs6983_set_voltage; -+ saa716x_gpio_write(dev, count ? 2 : 3, 1); /* LNB power off */ -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC[%d]=%pM\n", dev->config->model_name, count, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_tbs6983_config = { -+ .model_name = SAA716x_MODEL_TBS6983, -+ .dev_type = SAA716x_DEV_TBS6983, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 2, -+ .frontend_attach = saa716x_tbs6983_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_400, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config = { -+ { // adapter 0 -+ .ts_port = 3, -+ .worker = demux_worker -+ }, -+ { // adapter 1 -+ .ts_port = 1, -+ .worker = demux_worker -+ }, -+ } -+}; -+#define SAA716x_MODEL_TBS6290 "TurboSight TBS 6290 " -+#define SAA716x_DEV_TBS6290 "DVB-T/T2/C+2xCI" -+ -+static int saa716x_tbs6290_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *dev = adapter->saa716x; -+ struct i2c_adapter *i2cadapter; -+ struct i2c_client *client; -+ struct i2c_board_info info; -+ struct si2168_config si2168_config; -+ struct si2157_config si2157_config; -+ u8 mac[6]; -+ int ret; -+ if (count > 1) -+ goto err; -+ -+ /* attach demod */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.i2c_adapter = &i2cadapter; -+ si2168_config.fe = &adapter->fe; -+ si2168_config.ts_mode = SI2168_TS_PARALLEL; -+ si2168_config.ts_clock_gapped = true; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2168", I2C_NAME_SIZE); -+ info.addr = 0x64; -+ info.platform_data = &si2168_config; -+ request_module(info.type); -+ client = i2c_new_device(&dev->i2c[1 - count].i2c_adapter, &info); -+ if (client == NULL || client->dev.driver == NULL) { -+ goto err; -+ } -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ goto err; -+ } -+ adapter->i2c_client_demod = client; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = adapter->fe; -+ si2157_config.if_port = 1; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client = i2c_new_device(i2cadapter, &info); -+ if (client == NULL || client->dev.driver == NULL) { -+ module_put(adapter->i2c_client_demod->dev.driver->owner); -+ i2c_unregister_device(adapter->i2c_client_demod); -+ goto err; -+ } -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ module_put(adapter->i2c_client_demod->dev.driver->owner); -+ i2c_unregister_device(adapter->i2c_client_demod); -+ goto err; -+ } -+ adapter->i2c_client_tuner = client; -+ -+ saa716x_gpio_set_input(dev,count?2:6); -+ msleep(1); -+ saa716x_gpio_set_input(dev,count?14:3); -+ msleep(1); -+ saa716x_gpio_set_input(dev,count?20:14); -+ msleep(1); -+ ret = tbsci_i2c_probe(adapter,count?4:3); -+ if(!ret) -+ tbsci_init(adapter,count,9); -+ -+ strlcpy(adapter->fe->ops.info.name,dev->config->model_name,52); -+ strlcat(adapter->fe->ops.info.name,dev->config->dev_type,52); -+ -+ dev_dbg(&dev->pdev->dev, "%s frontend %d attached\n", -+ dev->config->model_name, count); -+ -+ if (!saa716x_tbs_read_mac(dev,count,mac)) { -+ memcpy(adapter->dvb_adapter.proposed_mac, mac, 6); -+ dev_notice(&dev->pdev->dev, "%s MAC[%d]=%pM\n", dev->config->model_name, count, adapter->dvb_adapter.proposed_mac); -+ } -+ -+ return 0; -+err: -+ dev_err(&dev->pdev->dev, "%s frontend %d attach failed\n", -+ dev->config->model_name, count); -+ return -ENODEV; -+ -+ -+} -+ -+static struct saa716x_config saa716x_tbs6290_config = { -+ .model_name = SAA716x_MODEL_TBS6290, -+ .dev_type = SAA716x_DEV_TBS6290, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 2, -+ .frontend_attach = saa716x_tbs6290_frontend_attach, -+ .irq_handler = saa716x_budget_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+ .i2c_mode = SAA716x_I2C_MODE_POLLING, -+ .adap_config ={ -+ { -+ .ts_port = 1, -+ .worker = demux_worker -+ }, -+ { -+ .ts_port = 3, -+ .worker = demux_worker -+ }, -+ -+ } -+ -+}; -+static struct pci_device_id saa716x_budget_pci_table[] = { -+ MAKE_ENTRY(TWINHAN_TECHNOLOGIES, TWINHAN_VP_1028, SAA7160, &saa716x_vp1028_config), /* VP-1028 */ -+ MAKE_ENTRY(TWINHAN_TECHNOLOGIES, TWINHAN_VP_3071, SAA7160, &saa716x_vp3071_config), /* VP-3071 */ -+ MAKE_ENTRY(TWINHAN_TECHNOLOGIES, TWINHAN_VP_6002, SAA7160, &saa716x_vp6002_config), /* VP-6002 */ -+ MAKE_ENTRY(KNC_One, KNC_Dual_S2, SAA7160, &saa716x_knc1_duals2_config), -+ MAKE_ENTRY(TECHNISAT, SKYSTAR2_EXPRESS_HD, SAA7160, &skystar2_express_hd_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6284, TBS6284, SAA7160, &saa716x_tbs6284_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6280, TBS6280, SAA7160, &saa716x_tbs6280_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6281, TBS6281, SAA7160, &saa716x_tbs6281_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6285, TBS6285, SAA7160, &saa716x_tbs6285_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6220, TBS6220, SAA7160, &saa716x_tbs6220_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6221, TBS6221, SAA7160, &saa716x_tbs6221_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6922, TBS6922, SAA7160, &saa716x_tbs6922_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6923, TBS6923, SAA7160, &saa716x_tbs6923_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6925, TBS6925, SAA7160, &saa716x_tbs6925_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6982, TBS6982, SAA7160, &saa716x_tbs6982_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6982, TBS6982SE, SAA7160, &saa716x_tbs6982se_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6984, TBS6984, SAA7160, &saa716x_tbs6984_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6985, TBS6985, SAA7160, &saa716x_tbs6985_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6985, TBS6985+1, SAA7160, &saa716x_tbs6985_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6991, TBS6991, SAA7160, &saa716x_tbs6991_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6991, TBS6991+1, SAA7160, &saa716x_tbs6991se_config), -+ MAKE_ENTRY(TECHNOTREND, TT4100, SAA7160, &saa716x_tbs6922_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6983, TBS6983, SAA7160, &saa716x_tbs6983_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6983, TBS6983+1, SAA7160, &saa716x_tbs6983_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS7220, TBS7220, SAA7160, &saa716x_tbs7220_config), -+ MAKE_ENTRY(TURBOSIGHT_TBS6290, TBS6290, SAA7160, &saa716x_tbs6290_config), -+ { } -+}; -+MODULE_DEVICE_TABLE(pci, saa716x_budget_pci_table); -+ -+static struct pci_driver saa716x_budget_pci_driver = { -+ .name = DRIVER_NAME, -+ .id_table = saa716x_budget_pci_table, -+ .probe = saa716x_budget_pci_probe, -+ .remove = saa716x_budget_pci_remove, -+}; -+ -+module_pci_driver(saa716x_budget_pci_driver); -+ -+MODULE_DESCRIPTION("SAA716x Budget driver"); -+MODULE_AUTHOR("Manu Abraham"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/pci/saa716x/saa716x_budget.h b/drivers/media/pci/saa716x/saa716x_budget.h -new file mode 100644 -index 0000000..d3082fe ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_budget.h -@@ -0,0 +1,67 @@ -+#ifndef __SAA716x_BUDGET_H -+#define __SAA716x_BUDGET_H -+ -+#define TWINHAN_TECHNOLOGIES 0x1822 -+#define TWINHAN_VP_3071 0x0039 -+#define TWINHAN_VP_1028 0x0044 -+#define TWINHAN_VP_6002 0x0047 -+ -+#define KNC_One 0x1894 -+#define KNC_Dual_S2 0x0110 -+ -+#define TECHNISAT 0x1AE4 -+#define SKYSTAR2_EXPRESS_HD 0x0700 -+ -+#define TURBOSIGHT_TBS6284 0x6284 -+#define TBS6284 0x0001 -+ -+#define TURBOSIGHT_TBS6280 0x6280 -+#define TBS6280 0x0011 -+ -+#define TURBOSIGHT_TBS6281 0x6281 -+#define TBS6281 0x0001 -+ -+#define TURBOSIGHT_TBS6285 0x6285 -+#define TBS6285 0x0001 -+ -+#define TURBOSIGHT_TBS6220 0x6220 -+#define TBS6220 0x0002 -+ -+#define TURBOSIGHT_TBS6221 0x6221 -+#define TBS6221 0x0001 -+ -+#define TURBOSIGHT_TBS6922 0x6922 -+#define TBS6922 0x0001 -+ -+#define TURBOSIGHT_TBS6923 0x6923 -+#define TBS6923 0x0001 -+ -+#define TURBOSIGHT_TBS6925 0x6925 -+#define TBS6925 0x0001 -+ -+#define TURBOSIGHT_TBS6982 0x6982 -+#define TBS6982 0x0001 -+#define TBS6982SE 0x0002 -+ -+#define TURBOSIGHT_TBS6984 0x6984 -+#define TBS6984 0x0013 -+ -+#define TURBOSIGHT_TBS6985 0x6985 -+#define TBS6985 0x0001 -+ -+#define TURBOSIGHT_TBS6991 0x6991 -+#define TBS6991 0x0001 -+ -+#define TURBOSIGHT_TBS6983 0x6983 -+#define TBS6983 0x0001 -+ -+#define TECHNOTREND 0x13c2 -+#define TT4100 0x3010 -+ -+#define TURBOSIGHT_TBS7220 0x7220 -+#define TBS7220 0x0001 -+ -+#define TURBOSIGHT_TBS6290 0x6290 -+#define TBS6290 0x0001 -+ -+#endif /* __SAA716x_BUDGET_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_cgu.c b/drivers/media/pci/saa716x/saa716x_cgu.c -new file mode 100644 -index 0000000..f3af28f ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_cgu.c -@@ -0,0 +1,539 @@ -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_cgu_reg.h" -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+ -+u32 cgu_clk[14] = { -+ CGU_FDC_0, -+ CGU_FDC_1, -+ CGU_FDC_2, -+ CGU_FDC_3, -+ CGU_FDC_4, -+ CGU_FDC_5, -+ CGU_FDC_6, -+ CGU_FDC_7, -+ CGU_FDC_8, -+ CGU_FDC_9, -+ CGU_FDC_10, -+ CGU_FDC_11, -+ CGU_FDC_12, -+ CGU_FDC_13 -+}; -+ -+char *clk_desc[14] = { -+ "Clk PSS", -+ "Clk DCS", -+ "Clk SPI", -+ "Clk I2C/Boot", -+ "Clk PHI", -+ "Clk VI0", -+ "Clk VI1", -+ "Clk FGPI0", -+ "Clk FGPI1", -+ "Clk FGPI2", -+ "Clk FGPI3", -+ "Clk AI0", -+ "Clk AI1", -+ "Clk Phy" -+}; -+ -+int saa716x_getbootscript_setup(struct saa716x_dev *saa716x) -+{ -+ struct saa716x_cgu *cgu = &saa716x->cgu; -+ -+ u8 i; -+ s8 N = 0; -+ s16 M = 0; -+ -+ SAA716x_EPWR(CGU, CGU_PCR_0_6, CGU_PCR_RUN); /* GREG */ -+ SAA716x_EPWR(CGU, CGU_PCR_0_3, CGU_PCR_RUN); /* PSS_MMU */ -+ SAA716x_EPWR(CGU, CGU_PCR_0_4, CGU_PCR_RUN); /* PSS_DTL2MTL */ -+ SAA716x_EPWR(CGU, CGU_PCR_0_5, CGU_PCR_RUN); /* MSI */ -+ SAA716x_EPWR(CGU, CGU_PCR_3_2, CGU_PCR_RUN); /* I2C */ -+ SAA716x_EPWR(CGU, CGU_PCR_4_1, CGU_PCR_RUN); /* PHI */ -+ SAA716x_EPWR(CGU, CGU_PCR_0_7, CGU_PCR_RUN); /* GPIO */ -+ SAA716x_EPWR(CGU, CGU_PCR_2_1, CGU_PCR_RUN); /* SPI */ -+ SAA716x_EPWR(CGU, CGU_PCR_1_1, CGU_PCR_RUN); /* DCS */ -+ SAA716x_EPWR(CGU, CGU_PCR_3_1, CGU_PCR_RUN); /* BOOT */ -+ -+ /* get all dividers */ -+ for (i = 0; i < CGU_CLKS; i++) { -+ cgu->clk_boot_div[i] = SAA716x_EPRD(CGU, cgu_clk[i]); -+ cgu->clk_curr_div[i] = cgu->clk_boot_div[i]; -+ -+ N = (cgu->clk_boot_div[i] >> 11) & 0xff; -+ N *= -1; -+ M = ((cgu->clk_boot_div[i] >> 3) & 0xff) + N; -+ -+ if (M) -+ cgu->clk_freq[i] = (u32 ) N * PLL_FREQ / (u32 ) M; -+ else -+ cgu->clk_freq[i] = 0; -+ -+ dprintk(SAA716x_DEBUG, 1, "Domain %d: %s <0x%02x> Divider: 0x%x --> N=%d, M=%d, freq=%d", -+ i, clk_desc[i], cgu_clk[i], cgu->clk_boot_div[i], N, M, cgu->clk_freq[i]); -+ } -+ /* store clock settings */ -+ cgu->clk_vi_0[0] = cgu->clk_freq[CLK_DOMAIN_VI0]; -+ cgu->clk_vi_0[1] = cgu->clk_freq[CLK_DOMAIN_VI0]; -+ cgu->clk_vi_0[2] = cgu->clk_freq[CLK_DOMAIN_VI0]; -+ cgu->clk_vi_1[0] = cgu->clk_freq[CLK_DOMAIN_VI1]; -+ cgu->clk_vi_1[1] = cgu->clk_freq[CLK_DOMAIN_VI1]; -+ cgu->clk_vi_1[2] = cgu->clk_freq[CLK_DOMAIN_VI1]; -+ -+ return 0; -+} -+ -+int saa716x_set_clk_internal(struct saa716x_dev *saa716x, u32 port) -+{ -+ struct saa716x_cgu *cgu = &saa716x->cgu; -+ -+ u8 delay = 1; -+ -+ switch (port) { -+ case PORT_VI0_VIDEO: -+ cgu->clk_int_port[PORT_VI0_VIDEO] = 1; -+ -+ if (!cgu->clk_int_port[PORT_VI0_VBI]) { -+ delay = 0; -+ break; -+ } -+ -+ SAA716x_CGU_CLKRUN(5); -+ break; -+ -+ case PORT_VI0_VBI: -+ cgu->clk_int_port[PORT_VI0_VBI] = 1; -+ -+ if (!cgu->clk_int_port[PORT_VI0_VIDEO]) { -+ delay = 0; -+ break; -+ } -+ -+ SAA716x_CGU_CLKRUN(5); -+ break; -+ -+ case PORT_VI1_VIDEO: -+ cgu->clk_int_port[PORT_VI1_VIDEO] = 1; -+ -+ if (!cgu->clk_int_port[PORT_VI1_VBI]) { -+ delay = 0; -+ break; -+ } -+ -+ SAA716x_CGU_CLKRUN(6); -+ break; -+ -+ case PORT_VI1_VBI: -+ cgu->clk_int_port[PORT_VI1_VBI] = 1; -+ -+ if (!cgu->clk_int_port[PORT_VI1_VIDEO]) { -+ delay = 0; -+ break; -+ } -+ -+ SAA716x_CGU_CLKRUN(6); -+ break; -+ -+ case PORT_FGPI0: -+ cgu->clk_int_port[PORT_FGPI0] = 1; -+ SAA716x_CGU_CLKRUN(7); -+ break; -+ -+ case PORT_FGPI1: -+ cgu->clk_int_port[PORT_FGPI1] = 1; -+ SAA716x_CGU_CLKRUN(8); -+ break; -+ -+ case PORT_FGPI2: -+ cgu->clk_int_port[PORT_FGPI2] = 1; -+ SAA716x_CGU_CLKRUN(9); -+ break; -+ -+ case PORT_FGPI3: -+ cgu->clk_int_port[PORT_FGPI3] = 1; -+ SAA716x_CGU_CLKRUN(10); -+ break; -+ -+ case PORT_AI0: -+ cgu->clk_int_port[PORT_AI0] = 1; -+ SAA716x_CGU_CLKRUN(11); -+ break; -+ -+ case PORT_AI1: -+ cgu->clk_int_port[PORT_AI1] = 1; -+ SAA716x_CGU_CLKRUN(12); -+ break; -+ -+ case PORT_ALL: -+ SAA716x_CGU_CLKRUN(5); -+ SAA716x_CGU_CLKRUN(6); -+ SAA716x_CGU_CLKRUN(7); -+ SAA716x_CGU_CLKRUN(8); -+ SAA716x_CGU_CLKRUN(9); -+ SAA716x_CGU_CLKRUN(10); -+ SAA716x_CGU_CLKRUN(11); -+ SAA716x_CGU_CLKRUN(12); -+ -+ cgu->clk_int_port[PORT_VI0_VIDEO] = 1; -+ cgu->clk_int_port[PORT_VI0_VBI] = 1; -+ cgu->clk_int_port[PORT_VI1_VIDEO] = 1; -+ cgu->clk_int_port[PORT_VI1_VBI] = 1; -+ cgu->clk_int_port[PORT_FGPI0] = 1; -+ cgu->clk_int_port[PORT_FGPI1] = 1; -+ cgu->clk_int_port[PORT_FGPI2] = 1; -+ cgu->clk_int_port[PORT_FGPI3] = 1; -+ cgu->clk_int_port[PORT_AI0] = 1; -+ cgu->clk_int_port[PORT_AI1] = 1; -+ break; -+ -+ default: -+ dprintk(SAA716x_ERROR, 1, "Unknown port <%02x>", port); -+ delay = 0; -+ break; -+ } -+ -+ /* wait for PLL */ -+ if (delay) -+ msleep(1); -+ -+ return 0; -+} -+ -+int saa716x_set_clk_external(struct saa716x_dev *saa716x, u32 port) -+{ -+ struct saa716x_cgu *cgu = &saa716x->cgu; -+ -+ u8 delay = 1; -+ -+ switch (port) { -+ case PORT_VI0_VIDEO: -+ cgu->clk_int_port[PORT_VI0_VIDEO] = 0; -+ -+ if (!cgu->clk_int_port[PORT_VI0_VBI]) { -+ delay = 0; -+ break; -+ } -+ -+ SAA716x_EPWR(CGU, CGU_FS1_5, 0x2); /* VI 0 clk */ -+ SAA716x_EPWR(CGU, CGU_ESR_5, 0x0); /* disable divider */ -+ break; -+ -+ case PORT_VI0_VBI: -+ cgu->clk_int_port[PORT_VI0_VBI] = 0; -+ -+ if (!cgu->clk_int_port[PORT_VI0_VIDEO]) { -+ delay = 0; -+ break; -+ } -+ -+ SAA716x_EPWR(CGU, CGU_FS1_5, 0x2); /* VI 0 clk */ -+ SAA716x_EPWR(CGU, CGU_ESR_5, 0x0); /* disable divider */ -+ break; -+ -+ case PORT_VI1_VIDEO: -+ cgu->clk_int_port[PORT_VI1_VIDEO] = 0; -+ -+ if (!cgu->clk_int_port[PORT_VI1_VBI]) { -+ delay = 0; -+ break; -+ } -+ -+ SAA716x_EPWR(CGU, CGU_FS1_6, 0x3); /* VI 1 clk */ -+ SAA716x_EPWR(CGU, CGU_ESR_6, 0x0); /* disable divider */ -+ break; -+ -+ case PORT_VI1_VBI: -+ cgu->clk_int_port[PORT_VI1_VBI] = 0; -+ -+ if (!cgu->clk_int_port[PORT_VI1_VIDEO]) { -+ delay = 0; -+ break; -+ } -+ -+ SAA716x_EPWR(CGU, CGU_FS1_6, 0x3); /* VI 1 clk */ -+ SAA716x_EPWR(CGU, CGU_ESR_6, 0x0); /* disable divider */ -+ break; -+ -+ case PORT_FGPI0: -+ cgu->clk_int_port[PORT_FGPI0] = 0; -+ -+ SAA716x_EPWR(CGU, CGU_FS1_7, 0x4); /* FGPI 0 clk */ -+ SAA716x_EPWR(CGU, CGU_ESR_7, 0x0); /* disable divider */ -+ break; -+ -+ case PORT_FGPI1: -+ cgu->clk_int_port[PORT_FGPI1] = 0; -+ -+ SAA716x_EPWR(CGU, CGU_FS1_8, 0x5); /* FGPI 1 clk */ -+ SAA716x_EPWR(CGU, CGU_ESR_8, 0x0); /* disable divider */ -+ break; -+ -+ case PORT_FGPI2: -+ cgu->clk_int_port[PORT_FGPI2] = 0; -+ -+ SAA716x_EPWR(CGU, CGU_FS1_9, 0x6); /* FGPI 2 clk */ -+ SAA716x_EPWR(CGU, CGU_ESR_9, 0x0); /* disable divider */ -+ break; -+ -+ case PORT_FGPI3: -+ cgu->clk_int_port[PORT_FGPI3] = 0; -+ -+ SAA716x_EPWR(CGU, CGU_FS1_10, 0x7); /* FGPI 3 clk */ -+ SAA716x_EPWR(CGU, CGU_ESR_10, 0x0); /* disable divider */ -+ break; -+ -+ case PORT_AI0: -+ cgu->clk_int_port[PORT_AI0] = 1; -+ -+ SAA716x_EPWR(CGU, CGU_FS1_11, 0x8); /* AI 0 clk */ -+ SAA716x_EPWR(CGU, CGU_ESR_11, 0x0); /* disable divider */ -+ break; -+ -+ case PORT_AI1: -+ cgu->clk_int_port[PORT_AI1] = 1; -+ -+ SAA716x_EPWR(CGU, CGU_FS1_12, 0x9); /* AI 1 clk */ -+ SAA716x_EPWR(CGU, CGU_ESR_12, 0x0); /* disable divider */ -+ break; -+ -+ default: -+ dprintk(SAA716x_ERROR, 1, "Unknown port <%02x>", port); -+ delay = 0; -+ break; -+ -+ } -+ -+ if (delay) -+ msleep(1); -+ -+ return 0; -+} -+ -+int saa716x_get_clk(struct saa716x_dev *saa716x, -+ enum saa716x_clk_domain domain, -+ u32 *frequency) -+{ -+ struct saa716x_cgu *cgu = &saa716x->cgu; -+ -+ switch (domain) { -+ case CLK_DOMAIN_PSS: -+ case CLK_DOMAIN_DCS: -+ case CLK_DOMAIN_SPI: -+ case CLK_DOMAIN_I2C: -+ case CLK_DOMAIN_PHI: -+ case CLK_DOMAIN_VI0: -+ case CLK_DOMAIN_VI1: -+ case CLK_DOMAIN_FGPI0: -+ case CLK_DOMAIN_FGPI1: -+ case CLK_DOMAIN_FGPI2: -+ case CLK_DOMAIN_FGPI3: -+ case CLK_DOMAIN_AI0: -+ case CLK_DOMAIN_AI1: -+ case CLK_DOMAIN_PHY: -+ *frequency = cgu->clk_freq[domain]; -+ break; -+ -+ case CLK_DOMAIN_VI0VBI: -+ *frequency = cgu->clk_freq[CLK_DOMAIN_VI0]; -+ break; -+ -+ case CLK_DOMAIN_VI1VBI: -+ *frequency =cgu->clk_freq[CLK_DOMAIN_VI1]; -+ break; -+ default: -+ dprintk(SAA716x_ERROR, 1, "Error Clock domain <%02x>", domain); -+ break; -+ } -+ -+ return 0; -+} -+ -+int saa716x_set_clk(struct saa716x_dev *saa716x, -+ enum saa716x_clk_domain domain, -+ u32 frequency) -+{ -+ struct saa716x_cgu *cgu = &saa716x->cgu; -+ -+ u32 M = 1, N = 1, reset, i; -+ s8 N_tmp, M_tmp, sub, add, lsb; -+ -+ -+ if (cgu->clk_freq_min > frequency) -+ frequency = cgu->clk_freq_min; -+ -+ if (cgu->clk_freq_max < frequency) -+ frequency = cgu->clk_freq_max; -+ -+ switch (domain) { -+ case CLK_DOMAIN_PSS: -+ case CLK_DOMAIN_DCS: -+ case CLK_DOMAIN_SPI: -+ case CLK_DOMAIN_I2C: -+ case CLK_DOMAIN_PHI: -+ case CLK_DOMAIN_FGPI0: -+ case CLK_DOMAIN_FGPI1: -+ case CLK_DOMAIN_FGPI2: -+ case CLK_DOMAIN_FGPI3: -+ case CLK_DOMAIN_AI0: -+ case CLK_DOMAIN_AI1: -+ case CLK_DOMAIN_PHY: -+ -+ if (frequency == cgu->clk_freq[domain]) -+ return 0; /* same frequency */ -+ break; -+ -+ case CLK_DOMAIN_VI0: -+ -+ if (frequency == cgu->clk_vi_0[1]) { -+ return 0; -+ -+ } else if (frequency == cgu->clk_vi_0[0]) { -+ cgu->clk_vi_0[1] = frequency; /* store */ -+ -+ if (frequency == cgu->clk_vi_0[2]) -+ return 0; -+ -+ } else { -+ cgu->clk_vi_0[1] = frequency; -+ -+ if (frequency != cgu->clk_vi_0[2]) -+ return 0; -+ -+ } -+ break; -+ -+ case CLK_DOMAIN_VI1: -+ if (frequency == cgu->clk_vi_1[1]) { -+ return 0; -+ -+ } else if (frequency == cgu->clk_vi_1[0]) { -+ cgu->clk_vi_1[1] = frequency; /* store */ -+ -+ if (frequency == cgu->clk_vi_1[2]) -+ return 0; -+ -+ } else { -+ cgu->clk_vi_1[1] = frequency; -+ -+ if (frequency != cgu->clk_vi_1[2]) -+ return 0; -+ -+ } -+ break; -+ -+ case CLK_DOMAIN_VI0VBI: -+ if (frequency == cgu->clk_vi_0[2]) { -+ return 0; -+ -+ } else if (frequency == cgu->clk_vi_0[0]) { -+ cgu->clk_vi_0[2] = frequency; /* store */ -+ -+ if (frequency == cgu->clk_vi_0[1]) -+ return 0; -+ -+ } else { -+ cgu->clk_vi_0[2] = frequency; /* store */ -+ -+ if (frequency != cgu->clk_vi_0[1]) -+ return 0; -+ -+ } -+ domain = CLK_DOMAIN_VI0; /* change domain */ -+ break; -+ -+ case CLK_DOMAIN_VI1VBI: -+ if (frequency == cgu->clk_vi_1[2]) { -+ return 0; -+ -+ } else if (frequency == cgu->clk_vi_1[0]) { -+ cgu->clk_vi_1[2] = frequency; /* store */ -+ -+ if (frequency == cgu->clk_vi_1[1]) -+ return 0; -+ -+ } else { -+ cgu->clk_vi_1[2] = frequency; /* store */ -+ -+ if (frequency != cgu->clk_vi_1[1]) -+ return 0; -+ -+ } -+ domain = CLK_DOMAIN_VI1; /* change domain */ -+ break; -+ } -+ -+ /* calculate divider */ -+ do { -+ M = (N * PLL_FREQ) / frequency; -+ if (M == 0) -+ N++; -+ -+ } while (M == 0); -+ -+ /* calculate frequency */ -+ cgu->clk_freq[domain] = (N * PLL_FREQ) / M; -+ -+ N_tmp = N & 0xff; -+ M_tmp = M & 0xff; -+ sub = -N_tmp; -+ add = M_tmp - N_tmp; -+ lsb = 4; /* run */ -+ -+ if (((10 * N) / M) <= 5) -+ lsb |= 1; /* stretch */ -+ -+ /* store new divider */ -+ cgu->clk_curr_div[domain] = sub & 0xff; -+ cgu->clk_curr_div[domain] <<= 8; -+ cgu->clk_curr_div[domain] |= add & 0xff; -+ cgu->clk_curr_div[domain] <<= 3; -+ cgu->clk_curr_div[domain] |= lsb; -+ -+ dprintk(SAA716x_DEBUG, 1, "Domain <0x%02x> Frequency <%d> Set Freq <%d> N=%d M=%d Divider <0x%02x>", -+ domain, -+ frequency, -+ cgu->clk_freq[domain], -+ N, -+ M, -+ cgu->clk_curr_div[domain]); -+ -+ reset = 0; -+ -+ /* Reset */ -+ SAA716x_EPWR(CGU, cgu_clk[domain], cgu->clk_curr_div[domain] | 0x2); -+ -+ /* Reset disable */ -+ for (i = 0; i < 1000; i++) { -+ udelay(10); -+ reset = SAA716x_EPRD(CGU, cgu_clk[domain]); -+ -+ if (cgu->clk_curr_div[domain] == reset) -+ break; -+ } -+ -+ if (cgu->clk_curr_div[domain] != reset) -+ SAA716x_EPWR(CGU, cgu_clk[domain], cgu->clk_curr_div[domain]); -+ -+ return 0; -+} -+ -+int saa716x_cgu_init(struct saa716x_dev *saa716x) -+{ -+ struct saa716x_cgu *cgu = &saa716x->cgu; -+ -+ cgu->clk_freq_min = PLL_FREQ / 255; -+ if (PLL_FREQ > (cgu->clk_freq_min * 255)) -+ cgu->clk_freq_min++; -+ -+ cgu->clk_freq_max = PLL_FREQ; -+ -+ saa716x_getbootscript_setup(saa716x); -+ saa716x_set_clk_internal(saa716x, PORT_ALL); -+ -+ return 0; -+} -+EXPORT_SYMBOL(saa716x_cgu_init); -diff --git a/drivers/media/pci/saa716x/saa716x_cgu.h b/drivers/media/pci/saa716x/saa716x_cgu.h -new file mode 100644 -index 0000000..5353cf2 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_cgu.h -@@ -0,0 +1,61 @@ -+#ifndef __SAA716x_CGU_H -+#define __SAA716x_CGU_H -+ -+#define PLL_FREQ 2500 -+ -+#define SAA716x_CGU_CLKRUN(__reg) do { \ -+ SAA716x_EPWR(CGU, CGU_PCR_##__reg, CGU_PCR_RUN); /* Run */ \ -+ SAA716x_EPWR(CGU, CGU_SCR_##__reg, CGU_SCR_ENF1); /* Switch */ \ -+ SAA716x_EPWR(CGU, CGU_FS1_##__reg, 0x00000000); /* PLL Clk */ \ -+ SAA716x_EPWR(CGU, CGU_ESR_##__reg, CGU_ESR_FD_EN); /* Frac div */ \ -+} while (0) -+ -+enum saa716x_clk_domain { -+ CLK_DOMAIN_PSS = 0, -+ CLK_DOMAIN_DCS = 1, -+ CLK_DOMAIN_SPI = 2, -+ CLK_DOMAIN_I2C = 3, -+ CLK_DOMAIN_PHI = 4, -+ CLK_DOMAIN_VI0 = 5, -+ CLK_DOMAIN_VI1 = 6, -+ CLK_DOMAIN_FGPI0 = 7, -+ CLK_DOMAIN_FGPI1 = 8, -+ CLK_DOMAIN_FGPI2 = 9, -+ CLK_DOMAIN_FGPI3 = 10, -+ CLK_DOMAIN_AI0 = 11, -+ CLK_DOMAIN_AI1 = 12, -+ CLK_DOMAIN_PHY = 13, -+ CLK_DOMAIN_VI0VBI = 14, -+ CLK_DOMAIN_VI1VBI = 15 -+}; -+ -+#define PORT_VI0_VIDEO 0 -+#define PORT_VI0_VBI 2 -+#define PORT_VI1_VIDEO 3 -+#define PORT_VI1_VBI 5 -+#define PORT_FGPI0 6 -+#define PORT_FGPI1 7 -+#define PORT_FGPI2 8 -+#define PORT_FGPI3 9 -+#define PORT_AI0 10 -+#define PORT_AI1 11 -+#define PORT_ALL 12 -+ -+#define CGU_CLKS 14 -+ -+struct saa716x_cgu { -+ u8 clk_int_port[12]; -+ u32 clk_vi_0[3]; -+ u32 clk_vi_1[3]; -+ u32 clk_boot_div[CGU_CLKS]; -+ u32 clk_curr_div[CGU_CLKS]; -+ u32 clk_freq[CGU_CLKS]; -+ u32 clk_freq_min; -+ u32 clk_freq_max; -+}; -+ -+extern int saa716x_cgu_init(struct saa716x_dev *saa716x); -+extern int saa716x_set_clk_internal(struct saa716x_dev *saa716x, u32 port); -+extern int saa716x_set_clk_external(struct saa716x_dev *saa716x, u32 port); -+ -+#endif /* __SAA716x_CGU_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_cgu_reg.h b/drivers/media/pci/saa716x/saa716x_cgu_reg.h -new file mode 100644 -index 0000000..f7d82ae ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_cgu_reg.h -@@ -0,0 +1,178 @@ -+#ifndef __SAA716x_CGU_REG_H -+#define __SAA716x_CGU_REG_H -+ -+/* -------------- CGU Registers -------------- */ -+ -+#define CGU_SCR_0 0x000 -+#define CGU_SCR_1 0x004 -+#define CGU_SCR_2 0x008 -+#define CGU_SCR_3 0x00c -+#define CGU_SCR_4 0x010 -+#define CGU_SCR_5 0x014 -+#define CGU_SCR_6 0x018 -+#define CGU_SCR_7 0x01c -+#define CGU_SCR_8 0x020 -+#define CGU_SCR_9 0x024 -+#define CGU_SCR_10 0x028 -+#define CGU_SCR_11 0x02c -+#define CGU_SCR_12 0x030 -+#define CGU_SCR_13 0x034 -+#define CGU_SCR_STOP (0x00000001 << 3) -+#define CGU_SCR_RESET (0x00000001 << 2) -+#define CGU_SCR_ENF2 (0x00000001 << 1) -+#define CGU_SCR_ENF1 (0x00000001 << 0) -+ -+#define CGU_FS1_0 0x038 -+#define CGU_FS1_1 0x03c -+#define CGU_FS1_2 0x040 -+#define CGU_FS1_3 0x044 -+#define CGU_FS1_4 0x048 -+#define CGU_FS1_5 0x04c -+#define CGU_FS1_6 0x050 -+#define CGU_FS1_7 0x054 -+#define CGU_FS1_8 0x058 -+#define CGU_FS1_9 0x05c -+#define CGU_FS1_10 0x060 -+#define CGU_FS1_11 0x064 -+#define CGU_FS1_12 0x068 -+#define CGU_FS1_13 0x06c -+#define CGU_FS1_PLL (0x00000000 << 0) -+ -+ -+#define CGU_FS2_0 0x070 -+#define CGU_FS2_1 0x074 -+#define CGU_FS2_2 0x078 -+#define CGU_FS2_3 0x07c -+#define CGU_FS2_4 0x080 -+#define CGU_FS2_5 0x084 -+#define CGU_FS2_6 0x088 -+#define CGU_FS2_7 0x08c -+#define CGU_FS2_8 0x090 -+#define CGU_FS2_9 0x094 -+#define CGU_FS2_10 0x098 -+#define CGU_FS2_11 0x09c -+#define CGU_FS2_12 0x0a0 -+#define CGU_FS2_13 0x0a4 -+ -+#define CGU_SSR_0 0x0a8 -+#define CGU_SSR_1 0x0ac -+#define CGU_SSR_2 0x0b0 -+#define CGU_SSR_3 0x0b4 -+#define CGU_SSR_4 0x0b8 -+#define CGU_SSR_5 0x0bc -+#define CGU_SSR_6 0x0c0 -+#define CGU_SSR_7 0x0c4 -+#define CGU_SSR_8 0x0c8 -+#define CGU_SSR_9 0x0cc -+#define CGU_SSR_10 0x0d0 -+#define CGU_SSR_11 0x0d4 -+#define CGU_SSR_12 0x0d8 -+#define CGU_SSR_13 0x0dc -+ -+#define CGU_PCR_0_0 0x0e0 -+#define CGU_PCR_0_1 0x0e4 -+#define CGU_PCR_0_2 0x0e8 -+#define CGU_PCR_0_3 0x0ec -+#define CGU_PCR_0_4 0x0f0 -+#define CGU_PCR_0_5 0x0f4 -+#define CGU_PCR_0_6 0x0f8 -+#define CGU_PCR_0_7 0x0fc -+#define CGU_PCR_1_0 0x100 -+#define CGU_PCR_1_1 0x104 -+#define CGU_PCR_2_0 0x108 -+#define CGU_PCR_2_1 0x10c -+#define CGU_PCR_3_0 0x110 -+#define CGU_PCR_3_1 0x114 -+#define CGU_PCR_3_2 0x118 -+#define CGU_PCR_4_0 0x11c -+#define CGU_PCR_4_1 0x120 -+#define CGU_PCR_5 0x124 -+#define CGU_PCR_6 0x128 -+#define CGU_PCR_7 0x12c -+#define CGU_PCR_8 0x130 -+#define CGU_PCR_9 0x134 -+#define CGU_PCR_10 0x138 -+#define CGU_PCR_11 0x13c -+#define CGU_PCR_12 0x140 -+#define CGU_PCR_13 0x144 -+#define CGU_PCR_WAKE_EN (0x00000001 << 2) -+#define CGU_PCR_AUTO (0x00000001 << 1) -+#define CGU_PCR_RUN (0x00000001 << 0) -+ -+ -+#define CGU_PSR_0_0 0x148 -+#define CGU_PSR_0_1 0x14c -+#define CGU_PSR_0_2 0x150 -+#define CGU_PSR_0_3 0x154 -+#define CGU_PSR_0_4 0x158 -+#define CGU_PSR_0_5 0x15c -+#define CGU_PSR_0_6 0x160 -+#define CGU_PSR_0_7 0x164 -+#define CGU_PSR_1_0 0x168 -+#define CGU_PSR_1_1 0x16c -+#define CGU_PSR_2_0 0x170 -+#define CGU_PSR_2_1 0x174 -+#define CGU_PSR_3_0 0x178 -+#define CGU_PSR_3_1 0x17c -+#define CGU_PSR_3_2 0x180 -+#define CGU_PSR_4_0 0x184 -+#define CGU_PSR_4_1 0x188 -+#define CGU_PSR_5 0x18c -+#define CGU_PSR_6 0x190 -+#define CGU_PSR_7 0x194 -+#define CGU_PSR_8 0x198 -+#define CGU_PSR_9 0x19c -+#define CGU_PSR_10 0x1a0 -+#define CGU_PSR_11 0x1a4 -+#define CGU_PSR_12 0x1a8 -+#define CGU_PSR_13 0x1ac -+ -+#define CGU_ESR_0_0 0x1b0 -+#define CGU_ESR_0_1 0x1b4 -+#define CGU_ESR_0_2 0x1b8 -+#define CGU_ESR_0_3 0x1bc -+#define CGU_ESR_0_4 0x1c0 -+#define CGU_ESR_0_5 0x1c4 -+#define CGU_ESR_0_6 0x1c8 -+#define CGU_ESR_0_7 0x1cc -+#define CGU_ESR_1_0 0x1d0 -+#define CGU_ESR_1_1 0x1d4 -+#define CGU_ESR_2_0 0x1d8 -+#define CGU_ESR_2_1 0x1dc -+#define CGU_ESR_3_0 0x1e0 -+#define CGU_ESR_3_1 0x1e4 -+#define CGU_ESR_3_2 0x1e8 -+#define CGU_ESR_4_0 0x1ec -+#define CGU_ESR_4_1 0x1f0 -+#define CGU_ESR_5 0x1f4 -+#define CGU_ESR_6 0x1f8 -+#define CGU_ESR_7 0x1fc -+#define CGU_ESR_8 0x200 -+#define CGU_ESR_9 0x204 -+#define CGU_ESR_10 0x208 -+#define CGU_ESR_11 0x20c -+#define CGU_ESR_12 0x210 -+#define CGU_ESR_13 0x214 -+#define CGU_ESR_FD_EN (0x00000001 << 0) -+ -+#define CGU_FDC_0 0x218 -+#define CGU_FDC_1 0x21c -+#define CGU_FDC_2 0x220 -+#define CGU_FDC_3 0x224 -+#define CGU_FDC_4 0x228 -+#define CGU_FDC_5 0x22c -+#define CGU_FDC_6 0x230 -+#define CGU_FDC_7 0x234 -+#define CGU_FDC_8 0x238 -+#define CGU_FDC_9 0x23c -+#define CGU_FDC_10 0x240 -+#define CGU_FDC_11 0x244 -+#define CGU_FDC_12 0x248 -+#define CGU_FDC_13 0x24c -+#define CGU_FDC_STRETCH (0x00000001 << 0) -+#define CGU_FDC_RESET (0x00000001 << 1) -+#define CGU_FDC_RUN1 (0x00000001 << 2) -+#define CGU_FDC_MADD (0x000000ff << 3) -+#define CGU_FDC_MSUB (0x000000ff << 11) -+ -+#endif /* __SAA716x_CGU_REG_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_dcs_reg.h b/drivers/media/pci/saa716x/saa716x_dcs_reg.h -new file mode 100644 -index 0000000..26dba68 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_dcs_reg.h -@@ -0,0 +1,56 @@ -+#ifndef __SAA716x_DCS_REG_H -+#define __SAA716x_DCS_REG_H -+ -+/* -------------- DCS Registers -------------- */ -+ -+#define DCSC_CTRL 0x000 -+#define DCSC_SEL_PLLDI (0x03ffffff << 5) -+#define DCSC_TOUT_SEL (0x0000000f << 1) -+#define DCSC_TOUT_OFF (0x00000001 << 0) -+ -+#define DCSC_ADDR 0x00c -+#define DCSC_ERR_TOUT_ADDR (0x3fffffff << 2) -+ -+#define DCSC_STAT 0x010 -+#define DCSC_ERR_TOUT_GNT (0x0000001f << 24) -+#define DCSC_ERR_TOUT_SEL (0x0000007f << 10) -+#define DCSC_ERR_TOUT_READ (0x00000001 << 8) -+#define DCSC_ERR_TOUT_MASK (0x0000000f << 4) -+#define DCSC_ERR_ACK (0x00000001 << 1) -+ -+#define DCSC_FEATURES 0x040 -+#define DCSC_UNIQUE_ID (0x00000007 << 16) -+#define DCSC_SECURITY (0x00000001 << 14) -+#define DCSC_NUM_BASE_REGS (0x00000003 << 11) -+#define DCSC_NUM_TARGETS (0x0000001f << 5) -+#define DCSC_NUM_INITIATORS (0x0000001f << 0) -+ -+#define DCSC_BASE_REG0 0x100 -+#define DCSC_BASE_N_REG (0x00000fff << 20) -+ -+#define DCSC_INT_CLR_ENABLE 0xfd8 -+#define DCSC_INT_CLR_ENABLE_TOUT (0x00000001 << 1) -+#define DCSC_INT_CLR_ENABLE_ERROR (0x00000001 << 0) -+ -+#define DCSC_INT_SET_ENABLE 0xfdc -+#define DCSC_INT_SET_ENABLE_TOUT (0x00000001 << 1) -+#define DCSC_INT_SET_ENABLE_ERROR (0x00000001 << 0) -+ -+#define DCSC_INT_STATUS 0xfe0 -+#define DCSC_INT_STATUS_TOUT (0x00000001 << 1) -+#define DCSC_INT_STATUS_ERROR (0x00000001 << 0) -+ -+#define DCSC_INT_ENABLE 0xfe4 -+#define DCSC_INT_ENABLE_TOUT (0x00000001 << 1) -+#define DCSC_INT_ENABLE_ERROR (0x00000001 << 0) -+ -+#define DCSC_INT_CLR_STATUS 0xfe8 -+#define DCSC_INT_CLEAR_TOUT (0x00000001 << 1) -+#define DCSC_INT_CLEAR_ERROR (0x00000001 << 0) -+ -+#define DCSC_INT_SET_STATUS 0xfec -+#define DCSC_INT_SET_TOUT (0x00000001 << 1) -+#define DCSC_INT_SET_ERROR (0x00000001 << 0) -+ -+ -+#endif /* __SAA716x_DCS_REG_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_dma.c b/drivers/media/pci/saa716x/saa716x_dma.c -new file mode 100644 -index 0000000..5404654 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_dma.c -@@ -0,0 +1,310 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "saa716x_dma.h" -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+ -+/* Allocates one page of memory, which is stores the data of one -+ * 716x page table. The result gets stored in the passed DMA buffer -+ * structure. -+ */ -+static int saa716x_allocate_ptable(struct saa716x_dmabuf *dmabuf) -+{ -+ struct saa716x_dev *saa716x = dmabuf->saa716x; -+ struct pci_dev *pdev = saa716x->pdev; -+ -+ dprintk(SAA716x_DEBUG, 1, "SG Page table allocate"); -+ dmabuf->mem_ptab_virt = (void *) __get_free_page(GFP_KERNEL); -+ -+ if (dmabuf->mem_ptab_virt == NULL) { -+ dprintk(SAA716x_ERROR, 1, "ERROR: Out of pages !"); -+ return -ENOMEM; -+ } -+ -+ dmabuf->mem_ptab_phys = dma_map_single(&pdev->dev, -+ dmabuf->mem_ptab_virt, -+ SAA716x_PAGE_SIZE, -+ DMA_TO_DEVICE); -+ -+ if (dmabuf->mem_ptab_phys == 0) { -+ dprintk(SAA716x_ERROR, 1, "ERROR: map memory failed !"); -+ return -ENOMEM; -+ } -+ -+ BUG_ON(!(((unsigned long) dmabuf->mem_ptab_phys % SAA716x_PAGE_SIZE) == 0)); -+ -+ return 0; -+} -+ -+static void saa716x_free_ptable(struct saa716x_dmabuf *dmabuf) -+{ -+ struct saa716x_dev *saa716x = dmabuf->saa716x; -+ struct pci_dev *pdev = saa716x->pdev; -+ -+ BUG_ON(dmabuf == NULL); -+ dprintk(SAA716x_DEBUG, 1, "SG Page table free"); -+ -+ /* free physical PCI memory */ -+ if (dmabuf->mem_ptab_phys != 0) { -+ dma_unmap_single(&pdev->dev, -+ dmabuf->mem_ptab_phys, -+ SAA716x_PAGE_SIZE, -+ DMA_TO_DEVICE); -+ -+ dmabuf->mem_ptab_phys = 0; -+ } -+ -+ /* free kernel memory */ -+ if (dmabuf->mem_ptab_virt != NULL) { -+ free_page((unsigned long) dmabuf->mem_ptab_virt); -+ dmabuf->mem_ptab_virt = NULL; -+ } -+} -+ -+static void saa716x_dmabuf_sgfree(struct saa716x_dmabuf *dmabuf) -+{ -+ struct saa716x_dev *saa716x = dmabuf->saa716x; -+ -+ BUG_ON(dmabuf == NULL); -+ dprintk(SAA716x_DEBUG, 1, "SG free"); -+ -+ dmabuf->mem_virt = NULL; -+ if (dmabuf->mem_virt_noalign != NULL) { -+ if (dmabuf->dma_type == SAA716x_DMABUF_INT) -+ vfree(dmabuf->mem_virt_noalign); -+ -+ dmabuf->mem_virt_noalign = NULL; -+ } -+ -+ if (dmabuf->sg_list != NULL) { -+ kfree(dmabuf->sg_list); -+ dmabuf->sg_list = NULL; -+ } -+} -+ -+/* -+ * Create a SG, when an allocated buffer is passed to it, -+ * otherwise the needed memory gets allocated by itself -+ */ -+static int saa716x_dmabuf_sgalloc(struct saa716x_dmabuf *dmabuf, void *buf, int size) -+{ -+ struct saa716x_dev *saa716x = dmabuf->saa716x; -+ struct scatterlist *list; -+ struct page *pg; -+ -+ int i, pages; -+ -+ BUG_ON(!(size > 0)); -+ BUG_ON(dmabuf == NULL); -+ dprintk(SAA716x_DEBUG, 1, "SG allocate"); -+ -+ if ((size % SAA716x_PAGE_SIZE) != 0) /* calculate required pages */ -+ pages = size / SAA716x_PAGE_SIZE + 1; -+ else -+ pages = size / SAA716x_PAGE_SIZE; -+ -+ /* Allocate memory for SG list */ -+ dmabuf->sg_list = kzalloc(sizeof (struct scatterlist) * pages, GFP_KERNEL); -+ if (dmabuf->sg_list == NULL) { -+ dprintk(SAA716x_ERROR, 1, "Failed to allocate memory for scatterlist."); -+ return -ENOMEM; -+ } -+ -+ dprintk(SAA716x_DEBUG, 1, "Initializing SG table"); -+ sg_init_table(dmabuf->sg_list, pages); -+ -+ if (buf == NULL) { -+ -+ /* allocate memory, unaligned */ -+ dmabuf->mem_virt_noalign = vmalloc((pages + 1) * SAA716x_PAGE_SIZE); -+ if (dmabuf->mem_virt_noalign == NULL) { -+ dprintk(SAA716x_ERROR, 1, "Failed to allocate memory for buffer"); -+ return -ENOMEM; -+ } -+ //memset(dmabuf->mem_virt_noalign, 0, (pages + 1) * SAA716x_PAGE_SIZE); -+ -+ /* align memory to page */ -+ dmabuf->mem_virt = (void *) PAGE_ALIGN (((unsigned long) dmabuf->mem_virt_noalign)); -+ -+ BUG_ON(!((((unsigned long) dmabuf->mem_virt) % SAA716x_PAGE_SIZE) == 0)); -+ } else { -+ dmabuf->mem_virt = buf; -+ } -+ -+ dmabuf->list_len = pages; /* scatterlist length */ -+ list = dmabuf->sg_list; -+ -+ dprintk(SAA716x_DEBUG, 1, "Allocating SG pages"); -+ for (i = 0; i < pages; i++) { -+ if (buf == NULL) -+ pg = vmalloc_to_page(dmabuf->mem_virt + i * SAA716x_PAGE_SIZE); -+ else -+ pg = virt_to_page(dmabuf->mem_virt + i * SAA716x_PAGE_SIZE); -+ -+ BUG_ON(pg == NULL); -+ sg_set_page(list, pg, SAA716x_PAGE_SIZE, 0); -+ list = sg_next(list); -+ } -+ -+ dprintk(SAA716x_DEBUG, 1, "Done!"); -+ return 0; -+} -+ -+/* Fill the "page table" page with the pointers to the specified SG buffer */ -+static void saa716x_dmabuf_sgpagefill(struct saa716x_dmabuf *dmabuf, struct scatterlist *sg_list, int pages, int offset) -+{ -+ struct saa716x_dev *saa716x = dmabuf->saa716x; -+ struct pci_dev *pdev = saa716x->pdev; -+ struct scatterlist *sg_cur; -+ -+ u32 *page; -+ int i, j, k = 0; -+ dma_addr_t addr = 0; -+ -+ BUG_ON(dmabuf == NULL); -+ BUG_ON(sg_list == NULL); -+ BUG_ON(pages == 0); -+ dprintk(SAA716x_DEBUG, 1, "SG page fill"); -+ -+ /* make page writable for the PC */ -+ dma_sync_single_for_cpu(&pdev->dev, dmabuf->mem_ptab_phys, SAA716x_PAGE_SIZE, DMA_TO_DEVICE); -+ page = dmabuf->mem_ptab_virt; -+ -+ sg_cur = sg_list; -+ /* create page table */ -+ for (i = 0; i < pages; i++) { -+ BUG_ON(!(((sg_cur->length + sg_cur->offset) % SAA716x_PAGE_SIZE) == 0)); -+ -+ if (i == 0) -+ dmabuf->offset = (sg_cur->length + sg_cur->offset) % SAA716x_PAGE_SIZE; -+ else -+ BUG_ON(sg_cur->offset != 0); -+ -+ for (j = 0; (j * SAA716x_PAGE_SIZE) < sg_dma_len(sg_cur); j++) { -+ -+ if ((offset + sg_cur->offset) >= SAA716x_PAGE_SIZE) { -+ offset -= SAA716x_PAGE_SIZE; -+ continue; -+ } -+ -+ addr = ((u64)sg_dma_address(sg_cur)) + (j * SAA716x_PAGE_SIZE) - sg_cur->offset; -+ -+ BUG_ON(addr == 0); -+ page[k * 2] = (u32) addr; /* Low */ -+ page[k * 2 + 1] = (u32 )(((u64) addr) >> 32); /* High */ -+ BUG_ON(page[k * 2] % SAA716x_PAGE_SIZE); -+ k++; -+ } -+ sg_cur = sg_next(sg_cur); -+ } -+ -+ for (; k < (SAA716x_PAGE_SIZE / 8); k++) { -+ page[k * 2] = (u32 ) addr; -+ page[k * 2 + 1] = (u32 ) (((u64 ) addr) >> 32); -+ } -+ -+ /* make "page table" page writable for the PC */ -+ dma_sync_single_for_device(&pdev->dev, -+ dmabuf->mem_ptab_phys, -+ SAA716x_PAGE_SIZE, -+ DMA_TO_DEVICE); -+ -+} -+ -+void saa716x_dmabufsync_dev(struct saa716x_dmabuf *dmabuf) -+{ -+ struct saa716x_dev *saa716x = dmabuf->saa716x; -+ struct pci_dev *pdev = saa716x->pdev; -+ -+ dprintk(SAA716x_DEBUG, 1, "DMABUF sync DEVICE"); -+ BUG_ON(dmabuf->sg_list == NULL); -+ -+ dma_sync_sg_for_device(&pdev->dev, -+ dmabuf->sg_list, -+ dmabuf->list_len, -+ DMA_FROM_DEVICE); -+ -+} -+ -+void saa716x_dmabufsync_cpu(struct saa716x_dmabuf *dmabuf) -+{ -+ struct saa716x_dev *saa716x = dmabuf->saa716x; -+ struct pci_dev *pdev = saa716x->pdev; -+ -+ dprintk(SAA716x_DEBUG, 1, "DMABUF sync CPU"); -+ BUG_ON(dmabuf->sg_list == NULL); -+ -+ dma_sync_sg_for_cpu(&pdev->dev, -+ dmabuf->sg_list, -+ dmabuf->list_len, -+ DMA_FROM_DEVICE); -+} -+ -+/* Allocates a DMA buffer for the specified external linear buffer. */ -+int saa716x_dmabuf_alloc(struct saa716x_dev *saa716x, struct saa716x_dmabuf *dmabuf, int size) -+{ -+ struct pci_dev *pdev = saa716x->pdev; -+ -+ int ret; -+ -+ BUG_ON(saa716x == NULL); -+ BUG_ON(dmabuf == NULL); -+ BUG_ON(! (size > 0)); -+ -+ dmabuf->dma_type = SAA716x_DMABUF_INT; -+ -+ dmabuf->mem_virt_noalign = NULL; -+ dmabuf->mem_virt = NULL; -+ dmabuf->mem_ptab_phys = 0; -+ dmabuf->mem_ptab_virt = NULL; -+ -+ dmabuf->list_len = 0; -+ dmabuf->saa716x = saa716x; -+ -+ /* Allocate page table */ -+ ret = saa716x_allocate_ptable(dmabuf); -+ if (ret < 0) { -+ dprintk(SAA716x_ERROR, 1, "PT alloc failed, Out of memory"); -+ goto err1; -+ } -+ -+ /* Allocate buffer as SG */ -+ ret = saa716x_dmabuf_sgalloc(dmabuf, NULL, size); -+ if (ret < 0) { -+ dprintk(SAA716x_ERROR, 1, "SG alloc failed"); -+ goto err2; -+ } -+ -+ ret = dma_map_sg(&pdev->dev, dmabuf->sg_list, dmabuf->list_len, DMA_FROM_DEVICE); -+ if (ret < 0) { -+ dprintk(SAA716x_ERROR, 1, "SG map failed"); -+ goto err3; -+ } -+ -+ saa716x_dmabuf_sgpagefill(dmabuf, dmabuf->sg_list, ret, 0); -+ -+ return 0; -+err3: -+ saa716x_dmabuf_sgfree(dmabuf); -+err2: -+ saa716x_free_ptable(dmabuf); -+err1: -+ return ret; -+} -+ -+void saa716x_dmabuf_free(struct saa716x_dev *saa716x, struct saa716x_dmabuf *dmabuf) -+{ -+ struct pci_dev *pdev = saa716x->pdev; -+ -+ BUG_ON(saa716x == NULL); -+ BUG_ON(dmabuf == NULL); -+ -+ dma_unmap_sg(&pdev->dev, dmabuf->sg_list, dmabuf->list_len, DMA_FROM_DEVICE); -+ saa716x_dmabuf_sgfree(dmabuf); -+ saa716x_free_ptable(dmabuf); -+} -diff --git a/drivers/media/pci/saa716x/saa716x_dma.h b/drivers/media/pci/saa716x/saa716x_dma.h -new file mode 100644 -index 0000000..a56b351 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_dma.h -@@ -0,0 +1,61 @@ -+#ifndef __SAA716x_DMA_H -+#define __SAA716x_DMA_H -+ -+#define SAA716x_PAGE_SIZE 4096 -+ -+#define PTA_LSB(__mem) ((u32 ) (__mem)) -+#define PTA_MSB(__mem) ((u32 ) ((u64)(__mem) >> 32)) -+ -+#define BAM_DMA_BUF_MODE_BASE 0x00 -+#define BAM_DMA_BUF_MODE_OFFSET 0x24 -+ -+#define BAM_DMA_BUF_MODE(__ch) (BAM_DMA_BUF_MODE_BASE + (BAM_DMA_BUF_MODE_OFFSET * __ch)) -+ -+#define BAM_ADDR_OFFSET_BASE 0x04 -+#define BAM_ADDR_OFFSET_OFFSET 0x24 -+ -+#define BAM_ADDR_OFFSET(__ch) (BAM_ADDR_OFFSET_BASE + (BAM_ADDR_OFFSET_OFFSET * __ch)) -+ -+#define BAM_ADDR_OFFSET_0(__ch) (BAM_ADDR_OFFSET(__ch) + 0x00) -+#define BAM_ADDR_OFFSET_1(__ch) (BAM_ADDR_OFFSET(__ch) + 0x04) -+#define BAM_ADDR_OFFSET_2(__ch) (BAM_ADDR_OFFSET(__ch) + 0x08) -+#define BAM_ADDR_OFFSET_3(__ch) (BAM_ADDR_OFFSET(__ch) + 0x0c) -+#define BAM_ADDR_OFFSET_4(__ch) (BAM_ADDR_OFFSET(__ch) + 0x10) -+#define BAM_ADDR_OFFSET_5(__ch) (BAM_ADDR_OFFSET(__ch) + 0x14) -+#define BAM_ADDR_OFFSET_6(__ch) (BAM_ADDR_OFFSET(__ch) + 0x18) -+#define BAM_ADDR_OFFSET_7(__ch) (BAM_ADDR_OFFSET(__ch) + 0x1c) -+ -+ -+enum saa716x_dma_type { -+ SAA716x_DMABUF_EXT_LIN, /* Linear external */ -+ SAA716x_DMABUF_EXT_SG, /* SG external */ -+ SAA716x_DMABUF_INT /* Linear internal */ -+}; -+ -+struct saa716x_dev; -+ -+struct saa716x_dmabuf { -+ enum saa716x_dma_type dma_type; -+ -+ void *mem_virt_noalign; -+ void *mem_virt; /* page aligned */ -+ dma_addr_t mem_ptab_phys; -+ void *mem_ptab_virt; -+ void *sg_list; /* SG list */ -+ -+ struct saa716x_dev *saa716x; -+ -+ int list_len; /* buffer len */ -+ int offset; /* page offset */ -+}; -+ -+extern int saa716x_dmabuf_alloc(struct saa716x_dev *saa716x, -+ struct saa716x_dmabuf *dmabuf, -+ int size); -+extern void saa716x_dmabuf_free(struct saa716x_dev *saa716x, -+ struct saa716x_dmabuf *dmabuf); -+ -+extern void saa716x_dmabufsync_dev(struct saa716x_dmabuf *dmabuf); -+extern void saa716x_dmabufsync_cpu(struct saa716x_dmabuf *dmabuf); -+ -+#endif /* __SAA716x_DMA_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_dma_reg.h b/drivers/media/pci/saa716x/saa716x_dma_reg.h -new file mode 100644 -index 0000000..5867854 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_dma_reg.h -@@ -0,0 +1,201 @@ -+#ifndef __SAA716x_DMA_REG_H -+#define __SAA716x_DMA_REG_H -+ -+/* -------------- BAM Registers -------------- */ -+ -+#define BAM_VI0_0_DMA_BUF_MODE 0x000 -+ -+#define BAM_VI0_0_ADDR_OFFST_0 0x004 -+#define BAM_VI0_0_ADDR_OFFST_1 0x008 -+#define BAM_VI0_0_ADDR_OFFST_2 0x00c -+#define BAM_VI0_0_ADDR_OFFST_3 0x010 -+#define BAM_VI0_0_ADDR_OFFST_4 0x014 -+#define BAM_VI0_0_ADDR_OFFST_5 0x018 -+#define BAM_VI0_0_ADDR_OFFST_6 0x01c -+#define BAM_VI0_0_ADDR_OFFST_7 0x020 -+ -+#define BAM_VI0_1_DMA_BUF_MODE 0x024 -+#define BAM_VI0_1_ADDR_OFFST_0 0x028 -+#define BAM_VI0_1_ADDR_OFFST_1 0x02c -+#define BAM_VI0_1_ADDR_OFFST_2 0x030 -+#define BAM_VI0_1_ADDR_OFFST_3 0x034 -+#define BAM_VI0_1_ADDR_OFFST_4 0x038 -+#define BAM_VI0_1_ADDR_OFFST_5 0x03c -+#define BAM_VI0_1_ADDR_OFFST_6 0x040 -+#define BAM_VI0_1_ADDR_OFFST_7 0x044 -+ -+#define BAM_VI0_2_DMA_BUF_MODE 0x048 -+#define BAM_VI0_2_ADDR_OFFST_0 0x04c -+#define BAM_VI0_2_ADDR_OFFST_1 0x050 -+#define BAM_VI0_2_ADDR_OFFST_2 0x054 -+#define BAM_VI0_2_ADDR_OFFST_3 0x058 -+#define BAM_VI0_2_ADDR_OFFST_4 0x05c -+#define BAM_VI0_2_ADDR_OFFST_5 0x060 -+#define BAM_VI0_2_ADDR_OFFST_6 0x064 -+#define BAM_VI0_2_ADDR_OFFST_7 0x068 -+ -+ -+#define BAM_VI1_0_DMA_BUF_MODE 0x06c -+#define BAM_VI1_0_ADDR_OFFST_0 0x070 -+#define BAM_VI1_0_ADDR_OFFST_1 0x074 -+#define BAM_VI1_0_ADDR_OFFST_2 0x078 -+#define BAM_VI1_0_ADDR_OFFST_3 0x07c -+#define BAM_VI1_0_ADDR_OFFST_4 0x080 -+#define BAM_VI1_0_ADDR_OFFST_5 0x084 -+#define BAM_VI1_0_ADDR_OFFST_6 0x088 -+#define BAM_VI1_0_ADDR_OFFST_7 0x08c -+ -+#define BAM_VI1_1_DMA_BUF_MODE 0x090 -+#define BAM_VI1_1_ADDR_OFFST_0 0x094 -+#define BAM_VI1_1_ADDR_OFFST_1 0x098 -+#define BAM_VI1_1_ADDR_OFFST_2 0x09c -+#define BAM_VI1_1_ADDR_OFFST_3 0x0a0 -+#define BAM_VI1_1_ADDR_OFFST_4 0x0a4 -+#define BAM_VI1_1_ADDR_OFFST_5 0x0a8 -+#define BAM_VI1_1_ADDR_OFFST_6 0x0ac -+#define BAM_VI1_1_ADDR_OFFST_7 0x0b0 -+ -+#define BAM_VI1_2_DMA_BUF_MODE 0x0b4 -+#define BAM_VI1_2_ADDR_OFFST_0 0x0b8 -+#define BAM_VI1_2_ADDR_OFFST_1 0x0bc -+#define BAM_VI1_2_ADDR_OFFST_2 0x0c0 -+#define BAM_VI1_2_ADDR_OFFST_3 0x0c4 -+#define BAM_VI1_2_ADDR_OFFST_4 0x0c8 -+#define BAM_VI1_2_ADDR_OFFST_5 0x0cc -+#define BAM_VI1_2_ADDR_OFFST_6 0x0d0 -+#define BAM_VI1_2_ADDR_OFFST_7 0x0d4 -+ -+ -+#define BAM_FGPI0_DMA_BUF_MODE 0x0d8 -+#define BAM_FGPI0_ADDR_OFFST_0 0x0dc -+#define BAM_FGPI0_ADDR_OFFST_1 0x0e0 -+#define BAM_FGPI0_ADDR_OFFST_2 0x0e4 -+#define BAM_FGPI0_ADDR_OFFST_3 0x0e8 -+#define BAM_FGPI0_ADDR_OFFST_4 0x0ec -+#define BAM_FGPI0_ADDR_OFFST_5 0x0f0 -+#define BAM_FGPI0_ADDR_OFFST_6 0x0f4 -+#define BAM_FGPI0_ADDR_OFFST_7 0x0f8 -+ -+#define BAM_FGPI1_DMA_BUF_MODE 0x0fc -+#define BAM_FGPI1_ADDR_OFFST_0 0x100 -+#define BAM_FGPI1_ADDR_OFFST_1 0x104 -+#define BAM_FGPI1_ADDR_OFFST_2 0x108 -+#define BAM_FGPI1_ADDR_OFFST_3 0x10c -+#define BAM_FGPI1_ADDR_OFFST_4 0x110 -+#define BAM_FGPI1_ADDR_OFFST_5 0x114 -+#define BAM_FGPI1_ADDR_OFFST_6 0x118 -+#define BAM_FGPI1_ADDR_OFFST_7 0x11c -+ -+#define BAM_FGPI2_DMA_BUF_MODE 0x120 -+#define BAM_FGPI2_ADDR_OFFST_0 0x124 -+#define BAM_FGPI2_ADDR_OFFST_1 0x128 -+#define BAM_FGPI2_ADDR_OFFST_2 0x12c -+#define BAM_FGPI2_ADDR_OFFST_3 0x130 -+#define BAM_FGPI2_ADDR_OFFST_4 0x134 -+#define BAM_FGPI2_ADDR_OFFST_5 0x138 -+#define BAM_FGPI2_ADDR_OFFST_6 0x13c -+#define BAM_FGPI2_ADDR_OFFST_7 0x140 -+ -+#define BAM_FGPI3_DMA_BUF_MODE 0x144 -+#define BAM_FGPI3_ADDR_OFFST_0 0x148 -+#define BAM_FGPI3_ADDR_OFFST_1 0x14c -+#define BAM_FGPI3_ADDR_OFFST_2 0x150 -+#define BAM_FGPI3_ADDR_OFFST_3 0x154 -+#define BAM_FGPI3_ADDR_OFFST_4 0x158 -+#define BAM_FGPI3_ADDR_OFFST_5 0x15c -+#define BAM_FGPI3_ADDR_OFFST_6 0x160 -+#define BAM_FGPI3_ADDR_OFFST_7 0x164 -+ -+ -+#define BAM_AI0_DMA_BUF_MODE 0x168 -+#define BAM_AI0_ADDR_OFFST_0 0x16c -+#define BAM_AI0_ADDR_OFFST_1 0x170 -+#define BAM_AI0_ADDR_OFFST_2 0x174 -+#define BAM_AI0_ADDR_OFFST_3 0x178 -+#define BAM_AI0_ADDR_OFFST_4 0x17c -+#define BAM_AIO_ADDR_OFFST_5 0x180 -+#define BAM_AI0_ADDR_OFFST_6 0x184 -+#define BAM_AIO_ADDR_OFFST_7 0x188 -+ -+#define BAM_AI1_DMA_BUF_MODE 0x18c -+#define BAM_AI1_ADDR_OFFST_0 0x190 -+#define BAM_AI1_ADDR_OFFST_1 0x194 -+#define BAM_AI1_ADDR_OFFST_2 0x198 -+#define BAM_AI1_ADDR_OFFST_3 0x19c -+#define BAM_AI1_ADDR_OFFST_4 0x1a0 -+#define BAM_AI1_ADDR_OFFST_5 0x1a4 -+#define BAM_AI1_ADDR_OFFST_6 0x1a8 -+#define BAM_AI1_ADDR_OFFST_7 0x1ac -+ -+#define BAM_SW_RST 0xff0 -+#define BAM_SW_RESET (0x00000001 << 0) -+ -+ -+ -+ -+ -+/* -------------- MMU Registers -------------- */ -+ -+#define MMU_MODE 0x000 -+ -+#define MMU_DMA_CONFIG0 0x004 -+#define MMU_DMA_CONFIG1 0x008 -+#define MMU_DMA_CONFIG2 0x00c -+#define MMU_DMA_CONFIG3 0x010 -+#define MMU_DMA_CONFIG4 0x014 -+#define MMU_DMA_CONFIG5 0x018 -+#define MMU_DMA_CONFIG6 0x01c -+#define MMU_DMA_CONFIG7 0x020 -+#define MMU_DMA_CONFIG8 0x024 -+#define MMU_DMA_CONFIG9 0x028 -+#define MMU_DMA_CONFIG10 0x02c -+#define MMU_DMA_CONFIG11 0x030 -+#define MMU_DMA_CONFIG12 0x034 -+#define MMU_DMA_CONFIG13 0x038 -+#define MMU_DMA_CONFIG14 0x03c -+#define MMU_DMA_CONFIG15 0x040 -+ -+#define MMU_DMA_CONFIG(__ch) (MMU_DMA_CONFIG0 + (4 * __ch)) -+ -+#define MMU_SW_RST 0xff0 -+#define MMU_SW_RESET (0x0001 << 0) -+ -+#define MMU_PTA_BASE0 0x044 /* DMA 0 */ -+#define MMU_PTA_BASE1 0x084 /* DMA 1 */ -+#define MMU_PTA_BASE2 0x0c4 /* DMA 2 */ -+#define MMU_PTA_BASE3 0x104 /* DMA 3 */ -+#define MMU_PTA_BASE4 0x144 /* DMA 4 */ -+#define MMU_PTA_BASE5 0x184 /* DMA 5 */ -+#define MMU_PTA_BASE6 0x1c4 /* DMA 6 */ -+#define MMU_PTA_BASE7 0x204 /* DMA 7 */ -+#define MMU_PTA_BASE8 0x244 /* DMA 8 */ -+#define MMU_PTA_BASE9 0x284 /* DMA 9 */ -+#define MMU_PTA_BASE10 0x2c4 /* DMA 10 */ -+#define MMU_PTA_BASE11 0x304 /* DMA 11 */ -+#define MMU_PTA_BASE12 0x344 /* DMA 12 */ -+#define MMU_PTA_BASE13 0x384 /* DMA 13 */ -+#define MMU_PTA_BASE14 0x3c4 /* DMA 14 */ -+#define MMU_PTA_BASE15 0x404 /* DMA 15 */ -+ -+#define MMU_PTA_OFFSET 0x40 -+ -+#define MMU_PTA_BASE(__ch) (MMU_PTA_BASE0 + (MMU_PTA_OFFSET * __ch)) -+ -+#define MMU_PTA0_LSB(__ch) MMU_PTA_BASE(__ch) + 0x00 -+#define MMU_PTA0_MSB(__ch) MMU_PTA_BASE(__ch) + 0x04 -+#define MMU_PTA1_LSB(__ch) MMU_PTA_BASE(__ch) + 0x08 -+#define MMU_PTA1_MSB(__ch) MMU_PTA_BASE(__ch) + 0x0c -+#define MMU_PTA2_LSB(__ch) MMU_PTA_BASE(__ch) + 0x10 -+#define MMU_PTA2_MSB(__ch) MMU_PTA_BASE(__ch) + 0x14 -+#define MMU_PTA3_LSB(__ch) MMU_PTA_BASE(__ch) + 0x18 -+#define MMU_PTA3_MSB(__ch) MMU_PTA_BASE(__ch) + 0x1c -+#define MMU_PTA4_LSB(__ch) MMU_PTA_BASE(__ch) + 0x20 -+#define MMU_PTA4_MSB(__ch) MMU_PTA_BASE(__ch) + 0x24 -+#define MMU_PTA5_LSB(__ch) MMU_PTA_BASE(__ch) + 0x28 -+#define MMU_PTA5_MSB(__ch) MMU_PTA_BASE(__ch) + 0x2c -+#define MMU_PTA6_LSB(__ch) MMU_PTA_BASE(__ch) + 0x30 -+#define MMU_PTA6_MSB(__ch) MMU_PTA_BASE(__ch) + 0x34 -+#define MMU_PTA7_LSB(__ch) MMU_PTA_BASE(__ch) + 0x38 -+#define MMU_PTA7_MSB(__ch) MMU_PTA_BASE(__ch) + 0x3c -+ -+#endif /* __SAA716x_DMA_REG_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_ff.h b/drivers/media/pci/saa716x/saa716x_ff.h -new file mode 100644 -index 0000000..ed06380 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_ff.h -@@ -0,0 +1,173 @@ -+#ifndef __SAA716x_FF_H -+#define __SAA716x_FF_H -+ -+#include "dvb_filter.h" -+#include "dvb_ringbuffer.h" -+#include -+#include -+ -+#define TECHNOTREND 0x13c2 -+#define S2_6400_DUAL_S2_PREMIUM_DEVEL 0x3009 -+#define S2_6400_DUAL_S2_PREMIUM_PROD 0x300A -+ -+#define TT_PREMIUM_GPIO_POWER_ENABLE 27 -+#define TT_PREMIUM_GPIO_RESET_BACKEND 26 -+#define TT_PREMIUM_GPIO_FPGA_CS1 17 -+#define TT_PREMIUM_GPIO_FPGA_CS0 16 -+#define TT_PREMIUM_GPIO_FPGA_PROGRAMN 15 -+#define TT_PREMIUM_GPIO_FPGA_DONE 14 -+#define TT_PREMIUM_GPIO_FPGA_INITN 13 -+ -+/* fpga interrupt register addresses */ -+#define FPGA_ADDR_PHI_ICTRL 0x8000 /* PHI General control of the PC => STB interrupt controller */ -+#define FPGA_ADDR_PHI_ISR 0x8010 /* PHI Interrupt Status Register */ -+#define FPGA_ADDR_PHI_ISET 0x8020 /* PHI Interrupt Set Register */ -+#define FPGA_ADDR_PHI_ICLR 0x8030 /* PHI Interrupt Clear Register */ -+#define FPGA_ADDR_EMI_ICTRL 0x8100 /* EMI General control of the STB => PC interrupt controller */ -+#define FPGA_ADDR_EMI_ISR 0x8110 /* EMI Interrupt Status Register */ -+#define FPGA_ADDR_EMI_ISET 0x8120 /* EMI Interrupt Set Register */ -+#define FPGA_ADDR_EMI_ICLR 0x8130 /* EMI Interrupt Clear Register */ -+ -+/* fpga TS router register addresses */ -+#define FPGA_ADDR_TSR_CTRL 0x8200 /* TS router control register */ -+#define FPGA_ADDR_TSR_MUX1 0x8210 /* TS multiplexer 1 selection register */ -+#define FPGA_ADDR_TSR_MUX2 0x8220 /* TS multiplexer 2 selection register */ -+#define FPGA_ADDR_TSR_MUX3 0x8230 /* TS multiplexer 3 selection register */ -+#define FPGA_ADDR_TSR_MUXCI1 0x8240 /* TS multiplexer CI 1 selection register */ -+#define FPGA_ADDR_TSR_MUXCI2 0x8250 /* TS multiplexer CI 2 selection register */ -+ -+#define FPGA_ADDR_TSR_BRFE1 0x8280 /* bit rate for TS coming from frontend 1 */ -+#define FPGA_ADDR_TSR_BRFE2 0x8284 /* bit rate for TS coming from frontend 2 */ -+#define FPGA_ADDR_TSR_BRFF1 0x828C /* bit rate for TS coming from FIFO 1 */ -+#define FPGA_ADDR_TSR_BRO1 0x8294 /* bit rate for TS going to output 1 */ -+#define FPGA_ADDR_TSR_BRO2 0x8298 /* bit rate for TS going to output 2 */ -+#define FPGA_ADDR_TSR_BRO3 0x829C /* bit rate for TS going to output 3 */ -+ -+/* fpga TS FIFO register addresses */ -+#define FPGA_ADDR_FIFO_CTRL 0x8300 /* FIFO control register */ -+#define FPGA_ADDR_FIFO_STAT 0x8310 /* FIFO status register */ -+ -+#define FPGA_ADDR_VERSION 0x80F0 /* FPGA bitstream version register */ -+ -+#define FPGA_ADDR_PIO_CTRL 0x8500 /* FPGA GPIO control register */ -+ -+#define ISR_CMD_MASK 0x0001 /* interrupt source for normal cmds (osd, fre, av, ...) */ -+#define ISR_READY_MASK 0x0002 /* interrupt source for command acknowledge */ -+#define ISR_BLOCK_MASK 0x0004 /* interrupt source for single block transfers and acknowledge */ -+#define ISR_DATA_MASK 0x0008 /* interrupt source for data transfer acknowledge */ -+#define ISR_BOOT_FINISH_MASK 0x0010 /* interrupt source for boot finish indication */ -+#define ISR_AUDIO_PTS_MASK 0x0020 /* interrupt source for audio PTS */ -+#define ISR_VIDEO_PTS_MASK 0x0040 /* interrupt source for video PTS */ -+#define ISR_CURRENT_STC_MASK 0x0080 /* interrupt source for current system clock */ -+#define ISR_REMOTE_EVENT_MASK 0x0100 /* interrupt source for remote events */ -+#define ISR_DVO_FORMAT_MASK 0x0200 /* interrupt source for DVO format change */ -+#define ISR_OSD_CMD_MASK 0x0400 /* interrupt source for OSD cmds */ -+#define ISR_OSD_READY_MASK 0x0800 /* interrupt source for OSD command acknowledge */ -+#define ISR_FE_CMD_MASK 0x1000 /* interrupt source for frontend cmds */ -+#define ISR_FE_READY_MASK 0x2000 /* interrupt source for frontend command acknowledge */ -+#define ISR_LOG_MESSAGE_MASK 0x4000 /* interrupt source for log messages */ -+#define ISR_FIFO1_EMPTY_MASK 0x8000 /* interrupt source for FIFO1 empty */ -+ -+#define ADDR_CMD_DATA 0x0000 /* address for cmd data in fpga dpram */ -+#define ADDR_OSD_CMD_DATA 0x01A0 /* address for OSD cmd data */ -+#define ADDR_FE_CMD_DATA 0x05C0 /* address for frontend cmd data */ -+#define ADDR_BLOCK_DATA 0x0600 /* address for block data */ -+#define ADDR_AUDIO_PTS 0x3E00 /* address for audio PTS (64 Bits) */ -+#define ADDR_VIDEO_PTS 0x3E08 /* address for video PTS (64 Bits) */ -+#define ADDR_CURRENT_STC 0x3E10 /* address for system clock (64 Bits) */ -+#define ADDR_DVO_FORMAT 0x3E18 /* address for DVO format 32 Bits) */ -+#define ADDR_REMOTE_EVENT 0x3F00 /* address for remote events (32 Bits) */ -+#define ADDR_LOG_MESSAGE 0x3F80 /* address for log messages */ -+ -+#define SIZE_CMD_DATA 0x01A0 /* maximum size for command data (416 Bytes) */ -+#define SIZE_OSD_CMD_DATA 0x0420 /* maximum size for OSD command data (1056 Bytes) */ -+#define SIZE_FE_CMD_DATA 0x0040 /* maximum size for frontend command data (64 Bytes) */ -+#define SIZE_BLOCK_DATA 0x3800 /* maximum size for block data (14 kB) */ -+#define SIZE_LOG_MESSAGE_DATA 0x0080 /* maximum size for log message data (128 Bytes) */ -+ -+#define SIZE_BLOCK_HEADER 8 /* block header size */ -+ -+#define MAX_RESULT_LEN 256 -+#define MAX_DATA_LEN (1024 * 1024) -+ -+#define TSOUT_LEN (1024 * TS_SIZE) -+ -+#define TSOUT_STAT_RESET 0 -+#define TSOUT_STAT_FILL 1 -+#define TSOUT_STAT_RUN 2 -+ -+#define VIDEO_CAPTURE_OFF 0 -+#define VIDEO_CAPTURE_ONE_SHOT 1 -+ -+ -+/* place to store all the necessary device information */ -+struct sti7109_dev { -+ struct saa716x_dev *dev; -+ struct dvb_device *osd_dev; -+ struct dvb_device *video_dev; -+ struct dvb_device *audio_dev; -+ -+ void *iobuf; /* memory for all buffers */ -+ struct dvb_ringbuffer tsout; /* buffer for TS output */ -+ u32 tsout_stat; -+ -+ struct workqueue_struct *fifo_workq; -+ struct work_struct fifo_work; -+ -+ wait_queue_head_t boot_finish_wq; -+ int boot_finished; -+ -+ wait_queue_head_t cmd_ready_wq; -+ int cmd_ready; -+ u8 cmd_data[SIZE_CMD_DATA]; -+ u32 cmd_len; -+ -+ wait_queue_head_t result_avail_wq; -+ int result_avail; -+ u8 result_data[MAX_RESULT_LEN]; -+ u32 result_len; -+ u32 result_max_len; -+ -+ wait_queue_head_t osd_cmd_ready_wq; -+ int osd_cmd_ready; -+ u8 osd_cmd_data[SIZE_OSD_CMD_DATA]; -+ u32 osd_cmd_len; -+ -+ wait_queue_head_t osd_result_avail_wq; -+ int osd_result_avail; -+ u8 osd_result_data[MAX_RESULT_LEN]; -+ u32 osd_result_len; -+ u32 osd_result_max_len; -+ -+ u16 data_handle; -+ u8 *data_buffer; /* raw data transfer buffer */ -+ wait_queue_head_t data_ready_wq; -+ int data_ready; -+ wait_queue_head_t block_done_wq; -+ int block_done; -+ -+ struct mutex cmd_lock; -+ struct mutex osd_cmd_lock; -+ struct mutex data_lock; -+ struct mutex video_lock; -+ -+ u64 audio_pts; -+ u64 video_pts; -+ u64 current_stc; -+ -+ u32 video_capture; -+ u32 video_format; -+ -+ u32 int_count_enable; -+ u32 total_int_count; -+ u32 vi_int_count[2]; -+ u32 fgpi_int_count[4]; -+ u32 i2c_int_count[2]; -+ u32 ext_int_total_count; -+ u32 ext_int_source_count[16]; -+ u32 last_int_ticks; -+ -+ u16 fpga_version; -+}; -+ -+#endif /* __SAA716x_FF_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_ff_cmd.c b/drivers/media/pci/saa716x/saa716x_ff_cmd.c -new file mode 100644 -index 0000000..430dd47 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_ff_cmd.c -@@ -0,0 +1,421 @@ -+#include -+ -+#include -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_phi_reg.h" -+ -+#include "saa716x_phi.h" -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+#include "saa716x_ff.h" -+#include "saa716x_ff_cmd.h" -+ -+ -+int sti7109_cmd_init(struct sti7109_dev *sti7109) -+{ -+ mutex_init(&sti7109->cmd_lock); -+ mutex_init(&sti7109->osd_cmd_lock); -+ mutex_init(&sti7109->data_lock); -+ -+ init_waitqueue_head(&sti7109->boot_finish_wq); -+ sti7109->boot_finished = 0; -+ -+ init_waitqueue_head(&sti7109->cmd_ready_wq); -+ sti7109->cmd_ready = 0; -+ -+ init_waitqueue_head(&sti7109->result_avail_wq); -+ sti7109->result_avail = 0; -+ -+ init_waitqueue_head(&sti7109->osd_cmd_ready_wq); -+ sti7109->osd_cmd_ready = 0; -+ init_waitqueue_head(&sti7109->osd_result_avail_wq); -+ sti7109->osd_result_avail = 0; -+ -+ sti7109->data_handle = 0; -+ sti7109->data_buffer = (u8 *) (sti7109->iobuf + TSOUT_LEN); -+ init_waitqueue_head(&sti7109->data_ready_wq); -+ sti7109->data_ready = 0; -+ init_waitqueue_head(&sti7109->block_done_wq); -+ sti7109->block_done = 0; -+ return 0; -+} -+ -+static int sti7109_do_raw_cmd(struct sti7109_dev * sti7109) -+{ -+ struct saa716x_dev * saa716x = sti7109->dev; -+ unsigned long timeout; -+ -+ timeout = 1 * HZ; -+ timeout = wait_event_interruptible_timeout(sti7109->cmd_ready_wq, -+ sti7109->cmd_ready == 1, -+ timeout); -+ -+ if (timeout == -ERESTARTSYS || sti7109->cmd_ready == 0) { -+ if (timeout == -ERESTARTSYS) { -+ /* a signal arrived */ -+ dprintk(SAA716x_ERROR, 1, "cmd ERESTARTSYS"); -+ return -ERESTARTSYS; -+ } -+ dprintk(SAA716x_ERROR, 1, -+ "timed out waiting for command ready"); -+ return -EIO; -+ } -+ -+ sti7109->cmd_ready = 0; -+ sti7109->result_avail = 0; -+ saa716x_phi_write(saa716x, ADDR_CMD_DATA, sti7109->cmd_data, -+ sti7109->cmd_len); -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_PHI_ISET, ISR_CMD_MASK); -+ -+ if (sti7109->result_max_len > 0) { -+ timeout = 1 * HZ; -+ timeout = wait_event_interruptible_timeout( -+ sti7109->result_avail_wq, -+ sti7109->result_avail == 1, -+ timeout); -+ -+ if (timeout == -ERESTARTSYS || sti7109->result_avail == 0) { -+ sti7109->result_len = 0; -+ if (timeout == -ERESTARTSYS) { -+ /* a signal arrived */ -+ dprintk(SAA716x_ERROR, 1, "result ERESTARTSYS"); -+ return -ERESTARTSYS; -+ } -+ dprintk(SAA716x_ERROR, 1, -+ "timed out waiting for command result"); -+ return -EIO; -+ } -+ -+ if (sti7109->result_len > sti7109->result_max_len) { -+ sti7109->result_len = sti7109->result_max_len; -+ dprintk(SAA716x_NOTICE, 1, -+ "not enough space in result buffer"); -+ } -+ } -+ -+ return 0; -+} -+ -+int sti7109_raw_cmd(struct sti7109_dev * sti7109, osd_raw_cmd_t * cmd) -+{ -+ struct saa716x_dev * saa716x = sti7109->dev; -+ int err; -+ -+ if (cmd->cmd_len > SIZE_CMD_DATA) { -+ dprintk(SAA716x_ERROR, 1, "command too long"); -+ return -EFAULT; -+ } -+ -+ mutex_lock(&sti7109->cmd_lock); -+ -+ err = -EFAULT; -+ if (copy_from_user(sti7109->cmd_data, (void __user *)cmd->cmd_data, -+ cmd->cmd_len)) -+ goto out; -+ -+ sti7109->cmd_len = cmd->cmd_len; -+ sti7109->result_max_len = cmd->result_len; -+ -+ err = sti7109_do_raw_cmd(sti7109); -+ if (err) -+ goto out; -+ -+ cmd->result_len = sti7109->result_len; -+ if (sti7109->result_len > 0) { -+ if (copy_to_user((void __user *)cmd->result_data, -+ sti7109->result_data, -+ sti7109->result_len)) -+ err = -EFAULT; -+ } -+ -+out: -+ mutex_unlock(&sti7109->cmd_lock); -+ return err; -+} -+ -+static int sti7109_do_raw_osd_cmd(struct sti7109_dev * sti7109) -+{ -+ struct saa716x_dev * saa716x = sti7109->dev; -+ unsigned long timeout; -+ -+ timeout = 1 * HZ; -+ timeout = wait_event_interruptible_timeout(sti7109->osd_cmd_ready_wq, -+ sti7109->osd_cmd_ready == 1, -+ timeout); -+ -+ if (timeout == -ERESTARTSYS || sti7109->osd_cmd_ready == 0) { -+ if (timeout == -ERESTARTSYS) { -+ /* a signal arrived */ -+ dprintk(SAA716x_ERROR, 1, "osd cmd ERESTARTSYS"); -+ return -ERESTARTSYS; -+ } -+ dprintk(SAA716x_ERROR, 1, -+ "timed out waiting for osd command ready"); -+ return -EIO; -+ } -+ -+ sti7109->osd_cmd_ready = 0; -+ sti7109->osd_result_avail = 0; -+ saa716x_phi_write(saa716x, ADDR_OSD_CMD_DATA, sti7109->osd_cmd_data, -+ sti7109->osd_cmd_len); -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_PHI_ISET, ISR_OSD_CMD_MASK); -+ -+ if (sti7109->osd_result_max_len > 0) { -+ timeout = 1 * HZ; -+ timeout = wait_event_interruptible_timeout( -+ sti7109->osd_result_avail_wq, -+ sti7109->osd_result_avail == 1, -+ timeout); -+ -+ if (timeout == -ERESTARTSYS || sti7109->osd_result_avail == 0) { -+ sti7109->osd_result_len = 0; -+ if (timeout == -ERESTARTSYS) { -+ /* a signal arrived */ -+ dprintk(SAA716x_ERROR, 1, -+ "osd result ERESTARTSYS"); -+ return -ERESTARTSYS; -+ } -+ dprintk(SAA716x_ERROR, 1, -+ "timed out waiting for osd command result"); -+ return -EIO; -+ } -+ -+ if (sti7109->osd_result_len > sti7109->osd_result_max_len) { -+ sti7109->osd_result_len = sti7109->osd_result_max_len; -+ dprintk(SAA716x_NOTICE, 1, -+ "not enough space in result buffer"); -+ } -+ } -+ -+ return 0; -+} -+ -+int sti7109_raw_osd_cmd(struct sti7109_dev * sti7109, osd_raw_cmd_t * cmd) -+{ -+ struct saa716x_dev * saa716x = sti7109->dev; -+ int err; -+ -+ if (cmd->cmd_len > SIZE_OSD_CMD_DATA) { -+ dprintk(SAA716x_ERROR, 1, "command too long"); -+ return -EFAULT; -+ } -+ -+ mutex_lock(&sti7109->osd_cmd_lock); -+ -+ err = -EFAULT; -+ if (copy_from_user(sti7109->osd_cmd_data, (void __user *)cmd->cmd_data, -+ cmd->cmd_len)) -+ goto out; -+ -+ sti7109->osd_cmd_len = cmd->cmd_len; -+ sti7109->osd_result_max_len = cmd->result_len; -+ -+ err = sti7109_do_raw_osd_cmd(sti7109); -+ if (err) -+ goto out; -+ -+ cmd->result_len = sti7109->osd_result_len; -+ if (sti7109->osd_result_len > 0) { -+ if (copy_to_user((void __user *)cmd->result_data, -+ sti7109->osd_result_data, -+ sti7109->osd_result_len)) -+ err = -EFAULT; -+ } -+ -+out: -+ mutex_unlock(&sti7109->osd_cmd_lock); -+ return err; -+} -+ -+static int sti7109_do_raw_data(struct sti7109_dev * sti7109, osd_raw_data_t * data) -+{ -+ struct saa716x_dev * saa716x = sti7109->dev; -+ unsigned long timeout; -+ u16 blockSize; -+ u16 lastBlockSize; -+ u16 numBlocks; -+ u16 blockIndex; -+ u8 blockHeader[SIZE_BLOCK_HEADER]; -+ u8 * blockPtr; -+ int activeBlock; -+ -+ timeout = 1 * HZ; -+ timeout = wait_event_interruptible_timeout(sti7109->data_ready_wq, -+ sti7109->data_ready == 1, -+ timeout); -+ -+ if (timeout == -ERESTARTSYS || sti7109->data_ready == 0) { -+ if (timeout == -ERESTARTSYS) { -+ /* a signal arrived */ -+ dprintk(SAA716x_ERROR, 1, "data ERESTARTSYS"); -+ return -ERESTARTSYS; -+ } -+ dprintk(SAA716x_ERROR, 1, "timed out waiting for data ready"); -+ return -EIO; -+ } -+ -+ sti7109->data_ready = 0; -+ -+ /* -+ * 8 bytes is the size of the block header. Block header structure is: -+ * 16 bit - block index -+ * 16 bit - number of blocks -+ * 16 bit - current block data size -+ * 16 bit - block handle. This is used to reference the data in the -+ * command that uses it. -+ */ -+ blockSize = (SIZE_BLOCK_DATA / 2) - SIZE_BLOCK_HEADER; -+ numBlocks = data->data_length / blockSize; -+ lastBlockSize = data->data_length % blockSize; -+ if (lastBlockSize > 0) -+ numBlocks++; -+ -+ blockHeader[2] = (u8) (numBlocks >> 8); -+ blockHeader[3] = (u8) numBlocks; -+ blockHeader[6] = (u8) (sti7109->data_handle >> 8); -+ blockHeader[7] = (u8) sti7109->data_handle; -+ blockPtr = sti7109->data_buffer; -+ activeBlock = 0; -+ for (blockIndex = 0; blockIndex < numBlocks; blockIndex++) { -+ u32 addr; -+ -+ if (lastBlockSize && (blockIndex == (numBlocks - 1))) -+ blockSize = lastBlockSize; -+ -+ blockHeader[0] = (uint8_t) (blockIndex >> 8); -+ blockHeader[1] = (uint8_t) blockIndex; -+ blockHeader[4] = (uint8_t) (blockSize >> 8); -+ blockHeader[5] = (uint8_t) blockSize; -+ -+ addr = ADDR_BLOCK_DATA + activeBlock * (SIZE_BLOCK_DATA / 2); -+ saa716x_phi_write(saa716x, addr, blockHeader, -+ SIZE_BLOCK_HEADER); -+ saa716x_phi_write(saa716x, addr + SIZE_BLOCK_HEADER, blockPtr, -+ blockSize); -+ activeBlock = (activeBlock + 1) & 1; -+ if (blockIndex > 0) { -+ timeout = 1 * HZ; -+ timeout = wait_event_timeout(sti7109->block_done_wq, -+ sti7109->block_done == 1, -+ timeout); -+ -+ if (sti7109->block_done == 0) { -+ dprintk(SAA716x_ERROR, 1, -+ "timed out waiting for block done"); -+ /* send a data interrupt to cancel the transfer -+ and reset the data handling */ -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_PHI_ISET, -+ ISR_DATA_MASK); -+ return -EIO; -+ } -+ } -+ sti7109->block_done = 0; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_PHI_ISET, ISR_BLOCK_MASK); -+ blockPtr += blockSize; -+ } -+ timeout = 1 * HZ; -+ timeout = wait_event_timeout(sti7109->block_done_wq, -+ sti7109->block_done == 1, -+ timeout); -+ -+ if (sti7109->block_done == 0) { -+ dprintk(SAA716x_ERROR, 1, "timed out waiting for block done"); -+ /* send a data interrupt to cancel the transfer and reset the -+ data handling */ -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_PHI_ISET, ISR_DATA_MASK); -+ return -EIO; -+ } -+ sti7109->block_done = 0; -+ -+ data->data_handle = sti7109->data_handle; -+ sti7109->data_handle++; -+ return 0; -+} -+ -+int sti7109_raw_data(struct sti7109_dev * sti7109, osd_raw_data_t * data) -+{ -+ struct saa716x_dev * saa716x = sti7109->dev; -+ int err; -+ -+ if (data->data_length > MAX_DATA_LEN) { -+ dprintk(SAA716x_ERROR, 1, "data too big"); -+ return -EFAULT; -+ } -+ -+ mutex_lock(&sti7109->data_lock); -+ -+ err = -EFAULT; -+ if (copy_from_user(sti7109->data_buffer, -+ (void __user *)data->data_buffer, -+ data->data_length)) -+ goto out; -+ -+ err = sti7109_do_raw_data(sti7109, data); -+ if (err) -+ goto out; -+ -+out: -+ mutex_unlock(&sti7109->data_lock); -+ return err; -+} -+ -+int sti7109_cmd_get_fw_version(struct sti7109_dev *sti7109, u32 *fw_version) -+{ -+ int ret_val = -EINVAL; -+ -+ mutex_lock(&sti7109->cmd_lock); -+ -+ sti7109->cmd_data[0] = 0x00; -+ sti7109->cmd_data[1] = 0x04; -+ sti7109->cmd_data[2] = 0x00; -+ sti7109->cmd_data[3] = 0x00; -+ sti7109->cmd_data[4] = 0x00; -+ sti7109->cmd_data[5] = 0x00; -+ sti7109->cmd_len = 6; -+ sti7109->result_max_len = MAX_RESULT_LEN; -+ -+ ret_val = sti7109_do_raw_cmd(sti7109); -+ if (ret_val == 0) { -+ *fw_version = (sti7109->result_data[6] << 16) -+ | (sti7109->result_data[7] << 8) -+ | sti7109->result_data[8]; -+ } -+ -+ mutex_unlock(&sti7109->cmd_lock); -+ -+ return ret_val; -+} -+ -+int sti7109_cmd_get_video_format(struct sti7109_dev *sti7109, video_size_t *vs) -+{ -+ int ret_val = -EINVAL; -+ -+ mutex_lock(&sti7109->cmd_lock); -+ -+ sti7109->cmd_data[0] = 0x00; -+ sti7109->cmd_data[1] = 0x05; /* command length */ -+ sti7109->cmd_data[2] = 0x00; -+ sti7109->cmd_data[3] = 0x01; /* A/V decoder command group */ -+ sti7109->cmd_data[4] = 0x00; -+ sti7109->cmd_data[5] = 0x10; /* get video format info command */ -+ sti7109->cmd_data[6] = 0x00; /* decoder index 0 */ -+ sti7109->cmd_len = 7; -+ sti7109->result_max_len = MAX_RESULT_LEN; -+ -+ ret_val = sti7109_do_raw_cmd(sti7109); -+ if (ret_val == 0) { -+ vs->w = (sti7109->result_data[7] << 8) -+ | sti7109->result_data[8]; -+ vs->h = (sti7109->result_data[9] << 8) -+ | sti7109->result_data[10]; -+ vs->aspect_ratio = sti7109->result_data[11] >> 4; -+ } -+ -+ mutex_unlock(&sti7109->cmd_lock); -+ -+ return ret_val; -+} -+ -diff --git a/drivers/media/pci/saa716x/saa716x_ff_cmd.h b/drivers/media/pci/saa716x/saa716x_ff_cmd.h -new file mode 100644 -index 0000000..7798ec3 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_ff_cmd.h -@@ -0,0 +1,34 @@ -+#ifndef __SAA716x_FF_CMD_H -+#define __SAA716x_FF_CMD_H -+ -+#if !defined OSD_RAW_CMD -+typedef struct osd_raw_cmd_s { -+ const void *cmd_data; -+ int cmd_len; -+ void *result_data; -+ int result_len; -+} osd_raw_cmd_t; -+ -+typedef struct osd_raw_data_s { -+ const void *data_buffer; -+ int data_length; -+ int data_handle; -+} osd_raw_data_t; -+ -+#define OSD_RAW_CMD _IOWR('o', 162, osd_raw_cmd_t) -+#define OSD_RAW_DATA _IOWR('o', 163, osd_raw_data_t) -+#endif -+ -+extern int sti7109_cmd_init(struct sti7109_dev *sti7109); -+extern int sti7109_raw_cmd(struct sti7109_dev * sti7109, -+ osd_raw_cmd_t * cmd); -+extern int sti7109_raw_osd_cmd(struct sti7109_dev * sti7109, -+ osd_raw_cmd_t * cmd); -+extern int sti7109_raw_data(struct sti7109_dev * sti7109, -+ osd_raw_data_t * data); -+extern int sti7109_cmd_get_fw_version(struct sti7109_dev *sti7109, -+ u32 *fw_version); -+extern int sti7109_cmd_get_video_format(struct sti7109_dev *sti7109, -+ video_size_t *vs); -+ -+#endif /* __SAA716x_FF_CMD_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_ff_ir.c b/drivers/media/pci/saa716x/saa716x_ff_ir.c -new file mode 100644 -index 0000000..3562478 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_ff_ir.c -@@ -0,0 +1,265 @@ -+/* -+ * Driver for the remote control of the TT6400 DVB-S2 card -+ * -+ * Copyright (C) 2010 Oliver Endriss -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html -+ * -+ */ -+ -+#include -+#include -+ -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+#include "saa716x_ff.h" -+ -+ -+/* infrared remote control */ -+struct infrared { -+ u16 key_map[128]; -+ struct input_dev *input_dev; -+ char input_phys[32]; -+ struct timer_list keyup_timer; -+ struct tasklet_struct tasklet; -+ u32 command; -+ u32 device_mask; -+ u8 protocol; -+ u16 last_key; -+ u16 last_toggle; -+ bool delay_timer_finished; -+}; -+ -+#define IR_RC5 0 -+#define UP_TIMEOUT (HZ*7/25) -+ -+ -+/* key-up timer */ -+static void ir_emit_keyup(unsigned long parm) -+{ -+ struct infrared *ir = (struct infrared *) parm; -+ -+ if (!ir || !test_bit(ir->last_key, ir->input_dev->key)) -+ return; -+ -+ input_report_key(ir->input_dev, ir->last_key, 0); -+ input_sync(ir->input_dev); -+} -+ -+ -+/* tasklet */ -+static void ir_emit_key(unsigned long parm) -+{ -+ struct saa716x_dev *saa716x = (struct saa716x_dev *) parm; -+ struct infrared *ir = saa716x->ir_priv; -+ u32 ircom = ir->command; -+ u8 data; -+ u8 addr; -+ u16 toggle; -+ u16 keycode; -+ -+ /* extract device address and data */ -+ if (ircom & 0x80000000) { /* CEC remote command */ -+ addr = 0; -+ data = ircom & 0x7F; -+ toggle = 0; -+ } else { -+ switch (ir->protocol) { -+ case IR_RC5: /* extended RC5: 5 bits device address, 7 bits data */ -+ addr = (ircom >> 6) & 0x1f; -+ /* data bits 1..6 */ -+ data = ircom & 0x3f; -+ /* data bit 7 (inverted) */ -+ if (!(ircom & 0x1000)) -+ data |= 0x40; -+ toggle = ircom & 0x0800; -+ break; -+ -+ default: -+ printk(KERN_ERR "%s: invalid protocol %x\n", -+ __func__, ir->protocol); -+ return; -+ } -+ } -+ -+ input_event(ir->input_dev, EV_MSC, MSC_RAW, (addr << 16) | data); -+ input_event(ir->input_dev, EV_MSC, MSC_SCAN, data); -+ -+ keycode = ir->key_map[data]; -+ -+ dprintk(SAA716x_DEBUG, 0, -+ "%s: code %08x -> addr %i data 0x%02x -> keycode %i\n", -+ __func__, ircom, addr, data, keycode); -+ -+ /* check device address */ -+ if (!(ir->device_mask & (1 << addr))) -+ return; -+ -+ if (!keycode) { -+ printk(KERN_WARNING "%s: code %08x -> addr %i data 0x%02x -> unknown key!\n", -+ __func__, ircom, addr, data); -+ return; -+ } -+ -+ if (timer_pending(&ir->keyup_timer)) { -+ del_timer(&ir->keyup_timer); -+ if (ir->last_key != keycode || toggle != ir->last_toggle) { -+ ir->delay_timer_finished = false; -+ input_event(ir->input_dev, EV_KEY, ir->last_key, 0); -+ input_event(ir->input_dev, EV_KEY, keycode, 1); -+ input_sync(ir->input_dev); -+ } else if (ir->delay_timer_finished) { -+ input_event(ir->input_dev, EV_KEY, keycode, 2); -+ input_sync(ir->input_dev); -+ } -+ } else { -+ ir->delay_timer_finished = false; -+ input_event(ir->input_dev, EV_KEY, keycode, 1); -+ input_sync(ir->input_dev); -+ } -+ -+ ir->last_key = keycode; -+ ir->last_toggle = toggle; -+ -+ ir->keyup_timer.expires = jiffies + UP_TIMEOUT; -+ add_timer(&ir->keyup_timer); -+ -+} -+ -+ -+/* register with input layer */ -+static void ir_register_keys(struct infrared *ir) -+{ -+ int i; -+ -+ set_bit(EV_KEY, ir->input_dev->evbit); -+ set_bit(EV_REP, ir->input_dev->evbit); -+ set_bit(EV_MSC, ir->input_dev->evbit); -+ -+ set_bit(MSC_RAW, ir->input_dev->mscbit); -+ set_bit(MSC_SCAN, ir->input_dev->mscbit); -+ -+ memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit)); -+ -+ for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) { -+ if (ir->key_map[i] > KEY_MAX) -+ ir->key_map[i] = 0; -+ else if (ir->key_map[i] > KEY_RESERVED) -+ set_bit(ir->key_map[i], ir->input_dev->keybit); -+ } -+ -+ ir->input_dev->keycode = ir->key_map; -+ ir->input_dev->keycodesize = sizeof(ir->key_map[0]); -+ ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map); -+} -+ -+ -+/* called by the input driver after rep[REP_DELAY] ms */ -+static void ir_repeat_key(unsigned long parm) -+{ -+ struct infrared *ir = (struct infrared *) parm; -+ -+ ir->delay_timer_finished = true; -+} -+ -+ -+/* interrupt handler */ -+void saa716x_ir_handler(struct saa716x_dev *saa716x, u32 ir_cmd) -+{ -+ struct infrared *ir = saa716x->ir_priv; -+ -+ if (!ir) -+ return; -+ -+ ir->command = ir_cmd; -+ tasklet_schedule(&ir->tasklet); -+} -+ -+ -+int saa716x_ir_init(struct saa716x_dev *saa716x) -+{ -+ struct input_dev *input_dev; -+ struct infrared *ir; -+ int rc; -+ int i; -+ -+ if (!saa716x) -+ return -ENOMEM; -+ -+ ir = kzalloc(sizeof(struct infrared), GFP_KERNEL); -+ if (!ir) -+ return -ENOMEM; -+ -+ init_timer(&ir->keyup_timer); -+ ir->keyup_timer.function = ir_emit_keyup; -+ ir->keyup_timer.data = (unsigned long) ir; -+ -+ input_dev = input_allocate_device(); -+ if (!input_dev) -+ goto err; -+ -+ ir->input_dev = input_dev; -+ input_dev->name = "TT6400 DVB IR receiver"; -+ snprintf(ir->input_phys, sizeof(ir->input_phys), -+ "pci-%s/ir0", pci_name(saa716x->pdev)); -+ input_dev->phys = ir->input_phys; -+ input_dev->id.bustype = BUS_PCI; -+ input_dev->id.version = 1; -+ input_dev->id.vendor = saa716x->pdev->subsystem_vendor; -+ input_dev->id.product = saa716x->pdev->subsystem_device; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) -+ input_dev->dev.parent = &saa716x->pdev->dev; -+#else -+ input_dev->cdev.dev = &saa716x->pdev->dev; -+#endif -+ rc = input_register_device(input_dev); -+ if (rc) -+ goto err; -+ -+ /* TODO: fix setup/keymap */ -+ ir->protocol = IR_RC5; -+ ir->device_mask = 0xffffffff; -+ for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) -+ ir->key_map[i] = i+1; -+ ir_register_keys(ir); -+ -+ /* override repeat timer */ -+ input_dev->timer.function = ir_repeat_key; -+ input_dev->timer.data = (unsigned long) ir; -+ -+ tasklet_init(&ir->tasklet, ir_emit_key, (unsigned long) saa716x); -+ saa716x->ir_priv = ir; -+ -+ return 0; -+ -+err: -+ if (ir->input_dev) -+ input_free_device(ir->input_dev); -+ kfree(ir); -+ return -ENOMEM; -+} -+ -+ -+void saa716x_ir_exit(struct saa716x_dev *saa716x) -+{ -+ struct infrared *ir = saa716x->ir_priv; -+ -+ saa716x->ir_priv = NULL; -+ tasklet_kill(&ir->tasklet); -+ del_timer_sync(&ir->keyup_timer); -+ input_unregister_device(ir->input_dev); -+ kfree(ir); -+} -diff --git a/drivers/media/pci/saa716x/saa716x_ff_main.c b/drivers/media/pci/saa716x/saa716x_ff_main.c -new file mode 100644 -index 0000000..7e94302 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_ff_main.c -@@ -0,0 +1,1807 @@ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_dma_reg.h" -+#include "saa716x_fgpi_reg.h" -+#include "saa716x_greg_reg.h" -+#include "saa716x_phi_reg.h" -+#include "saa716x_spi_reg.h" -+#include "saa716x_msi_reg.h" -+ -+#include "saa716x_msi.h" -+#include "saa716x_adap.h" -+#include "saa716x_gpio.h" -+#include "saa716x_phi.h" -+#include "saa716x_rom.h" -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+ -+#include "saa716x_ff.h" -+#include "saa716x_ff_cmd.h" -+ -+#include "stv6110x.h" -+#include "stv090x.h" -+#include "isl6423.h" -+ -+unsigned int verbose; -+module_param(verbose, int, 0644); -+MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); -+ -+unsigned int int_type; -+module_param(int_type, int, 0644); -+MODULE_PARM_DESC(int_type, "force Interrupt Handler type: 0=INT-A, 1=MSI, 2=MSI-X. default INT-A mode"); -+ -+unsigned int int_count_enable; -+module_param(int_count_enable, int, 0644); -+MODULE_PARM_DESC(int_count_enable, "enable counting of interrupts"); -+ -+unsigned int video_capture; -+module_param(video_capture, int, 0644); -+MODULE_PARM_DESC(video_capture, "capture digital video coming from STi7109: 0=off, 1=one-shot. default off"); -+ -+#define DRIVER_NAME "SAA716x FF" -+ -+static int saa716x_ff_fpga_init(struct saa716x_dev *saa716x) -+{ -+ struct sti7109_dev *sti7109 = saa716x->priv; -+ int fpgaInit; -+ int fpgaDone; -+ int rounds; -+ int ret; -+ const struct firmware *fw; -+ -+ /* request the FPGA firmware, this will block until someone uploads it */ -+ ret = request_firmware(&fw, "dvb-ttpremium-fpga-01.fw", &saa716x->pdev->dev); -+ if (ret) { -+ if (ret == -ENOENT) { -+ printk(KERN_ERR "dvb-ttpremium: could not load FPGA firmware," -+ " file not found: dvb-ttpremium-fpga-01.fw\n"); -+ printk(KERN_ERR "dvb-ttpremium: usually this should be in " -+ "/usr/lib/hotplug/firmware or /lib/firmware\n"); -+ } else -+ printk(KERN_ERR "dvb-ttpremium: cannot request firmware" -+ " (error %i)\n", ret); -+ return -EINVAL; -+ } -+ -+ /* set FPGA PROGRAMN high */ -+ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_FPGA_PROGRAMN, 1); -+ msleep(10); -+ -+ /* set FPGA PROGRAMN low to set it into configuration mode */ -+ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_FPGA_PROGRAMN, 0); -+ msleep(10); -+ -+ /* set FPGA PROGRAMN high to start configuration process */ -+ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_FPGA_PROGRAMN, 1); -+ -+ rounds = 0; -+ fpgaInit = saa716x_gpio_read(saa716x, TT_PREMIUM_GPIO_FPGA_INITN); -+ while (fpgaInit == 0 && rounds < 5000) { -+ //msleep(1); -+ fpgaInit = saa716x_gpio_read(saa716x, TT_PREMIUM_GPIO_FPGA_INITN); -+ rounds++; -+ } -+ dprintk(SAA716x_INFO, 1, "SAA716x FF FPGA INITN=%d, rounds=%d", -+ fpgaInit, rounds); -+ -+ SAA716x_EPWR(SPI, SPI_CLOCK_COUNTER, 0x08); -+ SAA716x_EPWR(SPI, SPI_CONTROL_REG, SPI_MODE_SELECT); -+ -+ msleep(10); -+ -+ fpgaDone = saa716x_gpio_read(saa716x, TT_PREMIUM_GPIO_FPGA_DONE); -+ dprintk(SAA716x_INFO, 1, "SAA716x FF FPGA DONE=%d", fpgaDone); -+ dprintk(SAA716x_INFO, 1, "SAA716x FF FPGA write bitstream"); -+ saa716x_spi_write(saa716x, fw->data, fw->size); -+ dprintk(SAA716x_INFO, 1, "SAA716x FF FPGA write bitstream done"); -+ fpgaDone = saa716x_gpio_read(saa716x, TT_PREMIUM_GPIO_FPGA_DONE); -+ dprintk(SAA716x_INFO, 1, "SAA716x FF FPGA DONE=%d", fpgaDone); -+ -+ msleep(10); -+ -+ release_firmware(fw); -+ -+ if (!fpgaDone) { -+ printk(KERN_ERR "SAA716x FF FPGA is not responding, did you " -+ "connect the power supply?\n"); -+ return -EINVAL; -+ } -+ -+ sti7109->fpga_version = SAA716x_EPRD(PHI_1, FPGA_ADDR_VERSION); -+ printk(KERN_INFO "SAA716x FF FPGA version %X.%02X\n", -+ sti7109->fpga_version >> 8, sti7109->fpga_version & 0xFF); -+ -+ return 0; -+} -+ -+static int saa716x_ff_st7109_init(struct saa716x_dev *saa716x) -+{ -+ int i; -+ int length; -+ u32 requestedBlock; -+ u32 writtenBlock; -+ u32 numBlocks; -+ u32 blockSize; -+ u32 lastBlockSize; -+ u64 startTime; -+ u64 currentTime; -+ u64 waitTime; -+ int ret; -+ const struct firmware *fw; -+ u32 loaderVersion; -+ -+ /* request the st7109 loader, this will block until someone uploads it */ -+ ret = request_firmware(&fw, "dvb-ttpremium-loader-01.fw", &saa716x->pdev->dev); -+ if (ret) { -+ if (ret == -ENOENT) { -+ printk(KERN_ERR "dvb-ttpremium: could not load ST7109 loader," -+ " file not found: dvb-ttpremium-loader-01.fw\n"); -+ printk(KERN_ERR "dvb-ttpremium: usually this should be in " -+ "/usr/lib/hotplug/firmware or /lib/firmware\n"); -+ } else -+ printk(KERN_ERR "dvb-ttpremium: cannot request firmware" -+ " (error %i)\n", ret); -+ return -EINVAL; -+ } -+ loaderVersion = (fw->data[0x1385] << 8) | fw->data[0x1384]; -+ printk(KERN_INFO "SAA716x FF loader version %X.%02X\n", -+ loaderVersion >> 8, loaderVersion & 0xFF); -+ -+ saa716x_phi_write(saa716x, 0, fw->data, fw->size); -+ msleep(10); -+ -+ release_firmware(fw); -+ -+ /* take ST out of reset */ -+ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_RESET_BACKEND, 1); -+ -+ startTime = jiffies; -+ waitTime = 0; -+ do { -+ requestedBlock = SAA716x_EPRD(PHI_1, 0x3ffc); -+ if (requestedBlock == 1) -+ break; -+ -+ currentTime = jiffies; -+ waitTime = currentTime - startTime; -+ } while (waitTime < (1 * HZ)); -+ -+ if (waitTime >= 1 * HZ) { -+ dprintk(SAA716x_ERROR, 1, "STi7109 seems to be DEAD!"); -+ return -1; -+ } -+ dprintk(SAA716x_INFO, 1, "STi7109 ready after %llu ticks", waitTime); -+ -+ /* request the st7109 firmware, this will block until someone uploads it */ -+ ret = request_firmware(&fw, "dvb-ttpremium-st7109-01.fw", &saa716x->pdev->dev); -+ if (ret) { -+ if (ret == -ENOENT) { -+ printk(KERN_ERR "dvb-ttpremium: could not load ST7109 firmware," -+ " file not found: dvb-ttpremium-st7109-01.fw\n"); -+ printk(KERN_ERR "dvb-ttpremium: usually this should be in " -+ "/usr/lib/hotplug/firmware or /lib/firmware\n"); -+ } else -+ printk(KERN_ERR "dvb-ttpremium: cannot request firmware" -+ " (error %i)\n", ret); -+ return -EINVAL; -+ } -+ -+ dprintk(SAA716x_INFO, 1, "SAA716x FF download ST7109 firmware"); -+ writtenBlock = 0; -+ blockSize = 0x3c00; -+ length = fw->size; -+ numBlocks = length / blockSize; -+ lastBlockSize = length % blockSize; -+ for (i = 0; i < length; i += blockSize) { -+ writtenBlock++; -+ /* write one block (last may differ from blockSize) */ -+ if (lastBlockSize && writtenBlock == (numBlocks + 1)) -+ saa716x_phi_write(saa716x, 0, &fw->data[i], lastBlockSize); -+ else -+ saa716x_phi_write(saa716x, 0, &fw->data[i], blockSize); -+ -+ SAA716x_EPWR(PHI_1, 0x3ff8, writtenBlock); -+ startTime = jiffies; -+ waitTime = 0; -+ do { -+ requestedBlock = SAA716x_EPRD(PHI_1, 0x3ffc); -+ if (requestedBlock == (writtenBlock + 1)) -+ break; -+ -+ currentTime = jiffies; -+ waitTime = currentTime - startTime; -+ } while (waitTime < (1 * HZ)); -+ -+ if (waitTime >= 1 * HZ) { -+ dprintk(SAA716x_ERROR, 1, "STi7109 seems to be DEAD!"); -+ release_firmware(fw); -+ return -1; -+ } -+ } -+ -+ /* disable frontend support through ST firmware */ -+ SAA716x_EPWR(PHI_1, 0x3ff4, 1); -+ -+ /* indicate end of transfer */ -+ writtenBlock++; -+ writtenBlock |= 0x80000000; -+ SAA716x_EPWR(PHI_1, 0x3ff8, writtenBlock); -+ -+ dprintk(SAA716x_INFO, 1, "SAA716x FF download ST7109 firmware done"); -+ -+ release_firmware(fw); -+ -+ return 0; -+} -+ -+static int saa716x_usercopy(struct dvb_device *dvbdev, -+ unsigned int cmd, unsigned long arg, -+ int (*func)(struct dvb_device *dvbdev, -+ unsigned int cmd, void *arg)) -+{ -+ char sbuf[128]; -+ void *mbuf = NULL; -+ void *parg = NULL; -+ int err = -EINVAL; -+ -+ /* Copy arguments into temp kernel buffer */ -+ switch (_IOC_DIR(cmd)) { -+ case _IOC_NONE: -+ /* -+ * For this command, the pointer is actually an integer -+ * argument. -+ */ -+ parg = (void *) arg; -+ break; -+ case _IOC_READ: /* some v4l ioctls are marked wrong ... */ -+ case _IOC_WRITE: -+ case (_IOC_WRITE | _IOC_READ): -+ if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { -+ parg = sbuf; -+ } else { -+ /* too big to allocate from stack */ -+ mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); -+ if (NULL == mbuf) -+ return -ENOMEM; -+ parg = mbuf; -+ } -+ -+ err = -EFAULT; -+ if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) -+ goto out; -+ break; -+ } -+ -+ /* call driver */ -+ if ((err = func(dvbdev, cmd, parg)) == -ENOIOCTLCMD) -+ err = -EINVAL; -+ -+ if (err < 0) -+ goto out; -+ -+ /* Copy results into user buffer */ -+ switch (_IOC_DIR(cmd)) -+ { -+ case _IOC_READ: -+ case (_IOC_WRITE | _IOC_READ): -+ if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) -+ err = -EFAULT; -+ break; -+ } -+ -+out: -+ kfree(mbuf); -+ return err; -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) && !defined(EXPERIMENTAL_TREE) -+static int dvb_osd_ioctl(struct inode *inode, struct file *file, -+#else -+static long dvb_osd_ioctl(struct file *file, -+#endif -+ unsigned int cmd, unsigned long arg) -+{ -+ struct dvb_device *dvbdev = file->private_data; -+ struct sti7109_dev *sti7109 = dvbdev->priv; -+ int err = -EINVAL; -+ -+ if (!dvbdev) -+ return -ENODEV; -+ -+ if (cmd == OSD_RAW_CMD) { -+ osd_raw_cmd_t raw_cmd; -+ u8 hdr[4]; -+ -+ err = -EFAULT; -+ if (copy_from_user(&raw_cmd, (void __user *)arg, -+ _IOC_SIZE(cmd))) -+ goto out; -+ -+ if (copy_from_user(hdr, (void __user *)raw_cmd.cmd_data, 4)) -+ goto out; -+ -+ if (hdr[3] == 4) -+ err = sti7109_raw_osd_cmd(sti7109, &raw_cmd); -+ else -+ err = sti7109_raw_cmd(sti7109, &raw_cmd); -+ -+ if (err) -+ goto out; -+ -+ if (copy_to_user((void __user *)arg, &raw_cmd, _IOC_SIZE(cmd))) -+ err = -EFAULT; -+ } -+ else if (cmd == OSD_RAW_DATA) { -+ osd_raw_data_t raw_data; -+ -+ err = -EFAULT; -+ if (copy_from_user(&raw_data, (void __user *)arg, -+ _IOC_SIZE(cmd))) -+ goto out; -+ -+ err = sti7109_raw_data(sti7109, &raw_data); -+ if (err) -+ goto out; -+ -+ if (copy_to_user((void __user *)arg, &raw_data, _IOC_SIZE(cmd))) -+ err = -EFAULT; -+ } -+ -+out: -+ return err; -+} -+ -+static struct file_operations dvb_osd_fops = { -+ .owner = THIS_MODULE, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) && !defined(EXPERIMENTAL_TREE) -+ .ioctl = dvb_osd_ioctl, -+#else -+ .unlocked_ioctl = dvb_osd_ioctl, -+#endif -+ .open = dvb_generic_open, -+ .release = dvb_generic_release, -+}; -+ -+static struct dvb_device dvbdev_osd = { -+ .priv = NULL, -+ .users = 2, -+ .writers = 2, -+ .fops = &dvb_osd_fops, -+ .kernel_ioctl = NULL, -+}; -+ -+static int saa716x_ff_osd_exit(struct saa716x_dev *saa716x) -+{ -+ struct sti7109_dev *sti7109 = saa716x->priv; -+ -+ dvb_unregister_device(sti7109->osd_dev); -+ return 0; -+} -+ -+static int saa716x_ff_osd_init(struct saa716x_dev *saa716x) -+{ -+ struct saa716x_adapter *saa716x_adap = saa716x->saa716x_adap; -+ struct sti7109_dev *sti7109 = saa716x->priv; -+ -+ dvb_register_device(&saa716x_adap->dvb_adapter, -+ &sti7109->osd_dev, -+ &dvbdev_osd, -+ sti7109, -+ DVB_DEVICE_OSD, 0); -+ -+ return 0; -+} -+ -+static int do_dvb_audio_ioctl(struct dvb_device *dvbdev, -+ unsigned int cmd, void *parg) -+{ -+ struct sti7109_dev *sti7109 = dvbdev->priv; -+ //struct saa716x_dev *saa716x = sti7109->dev; -+ int ret = 0; -+ -+ switch (cmd) { -+ case AUDIO_GET_PTS: -+ { -+ *(u64 *)parg = sti7109->audio_pts; -+ break; -+ } -+ default: -+ ret = -ENOIOCTLCMD; -+ break; -+ } -+ return ret; -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) && !defined(EXPERIMENTAL_TREE) -+static int dvb_audio_ioctl(struct inode *inode, struct file *file, -+#else -+static long dvb_audio_ioctl(struct file *file, -+#endif -+ unsigned int cmd, unsigned long arg) -+{ -+ struct dvb_device *dvbdev = file->private_data; -+ -+ if (!dvbdev) -+ return -ENODEV; -+ -+ return saa716x_usercopy (dvbdev, cmd, arg, do_dvb_audio_ioctl); -+} -+ -+static struct file_operations dvb_audio_fops = { -+ .owner = THIS_MODULE, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) && !defined(EXPERIMENTAL_TREE) -+ .ioctl = dvb_audio_ioctl, -+#else -+ .unlocked_ioctl = dvb_audio_ioctl, -+#endif -+ .open = dvb_generic_open, -+ .release = dvb_generic_release, -+}; -+ -+static struct dvb_device dvbdev_audio = { -+ .priv = NULL, -+ .users = 1, -+ .writers = 1, -+ .fops = &dvb_audio_fops, -+ .kernel_ioctl = NULL, -+}; -+ -+static int saa716x_ff_audio_exit(struct saa716x_dev *saa716x) -+{ -+ struct sti7109_dev *sti7109 = saa716x->priv; -+ -+ dvb_unregister_device(sti7109->audio_dev); -+ return 0; -+} -+ -+static int saa716x_ff_audio_init(struct saa716x_dev *saa716x) -+{ -+ struct saa716x_adapter *saa716x_adap = saa716x->saa716x_adap; -+ struct sti7109_dev *sti7109 = saa716x->priv; -+ -+ dvb_register_device(&saa716x_adap->dvb_adapter, -+ &sti7109->audio_dev, -+ &dvbdev_audio, -+ sti7109, -+ DVB_DEVICE_AUDIO, 0); -+ -+ return 0; -+} -+ -+static ssize_t ringbuffer_write_user(struct dvb_ringbuffer *rbuf, const u8 __user *buf, size_t len) -+{ -+ size_t todo = len; -+ size_t split; -+ -+ split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0; -+ -+ if (split > 0) { -+ if (copy_from_user(rbuf->data+rbuf->pwrite, buf, split)) { -+ return -EFAULT; -+ } -+ buf += split; -+ todo -= split; -+ rbuf->pwrite = 0; -+ } -+ if (copy_from_user(rbuf->data+rbuf->pwrite, buf, todo)) { -+ return -EFAULT; -+ } -+ rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size; -+ -+ return len; -+} -+ -+static void ringbuffer_read_io32(struct dvb_ringbuffer *rbuf, u32 __iomem *buf, size_t len) -+{ -+ size_t todo = len; -+ size_t split; -+ -+ split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; -+ if (split > 0) { -+ iowrite32_rep(buf, rbuf->data+rbuf->pread, split/4); -+ buf += split; -+ todo -= split; -+ rbuf->pread = 0; -+ } -+ iowrite32_rep(buf, rbuf->data+rbuf->pread, todo/4); -+ -+ rbuf->pread = (rbuf->pread + todo) % rbuf->size; -+} -+ -+static void fifo_worker(struct work_struct *work) -+{ -+ struct sti7109_dev *sti7109 = container_of(work, struct sti7109_dev, fifo_work); -+ struct saa716x_dev *saa716x = sti7109->dev; -+ u32 fifoCtrl; -+ u32 fifoStat; -+ u16 fifoSize; -+ u16 fifoUsage; -+ u16 fifoFree; -+ int len; -+ -+ if (sti7109->tsout_stat == TSOUT_STAT_RESET) -+ return; -+ -+ fifoStat = SAA716x_EPRD(PHI_1, FPGA_ADDR_FIFO_STAT); -+ fifoSize = (u16) (fifoStat >> 16); -+ fifoUsage = (u16) fifoStat; -+ fifoFree = fifoSize - fifoUsage - 1; -+ len = dvb_ringbuffer_avail(&sti7109->tsout); -+ if (len > fifoFree) -+ len = fifoFree; -+ if (len < TS_SIZE) -+ return; -+ -+ while (len >= TS_SIZE) -+ { -+ ringbuffer_read_io32(&sti7109->tsout, saa716x->mmio + PHI_0 + PHI_0_0_RW_0, (size_t) TS_SIZE); -+ len -= TS_SIZE; -+ } -+ wake_up(&sti7109->tsout.queue); -+ -+ spin_lock(&sti7109->tsout.lock); -+ if (sti7109->tsout_stat != TSOUT_STAT_RESET) { -+ sti7109->tsout_stat = TSOUT_STAT_RUN; -+ -+ fifoCtrl = SAA716x_EPRD(PHI_1, FPGA_ADDR_FIFO_CTRL); -+ fifoCtrl |= 0x4; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_FIFO_CTRL, fifoCtrl); -+ } -+ spin_unlock(&sti7109->tsout.lock); -+} -+ -+static void video_vip_worker(unsigned long data) -+{ -+ struct saa716x_vip_stream_port *vip_entry = (struct saa716x_vip_stream_port *)data; -+ struct saa716x_dev *saa716x = vip_entry->saa716x; -+ u32 vip_index; -+ u32 write_index; -+ -+ vip_index = vip_entry->dma_channel[0]; -+ if (vip_index != 0) { -+ printk(KERN_ERR "%s: unexpected channel %u\n", -+ __func__, vip_entry->dma_channel[0]); -+ return; -+ } -+ -+ write_index = saa716x_vip_get_write_index(saa716x, vip_index); -+ if (write_index < 0) -+ return; -+ -+ dprintk(SAA716x_DEBUG, 1, "dma buffer = %d", write_index); -+ -+ if (write_index == vip_entry->read_index) { -+ printk(KERN_DEBUG "%s: called but nothing to do\n", __func__); -+ return; -+ } -+ -+ do { -+ pci_dma_sync_sg_for_cpu(saa716x->pdev, -+ vip_entry->dma_buf[0][vip_entry->read_index].sg_list, -+ vip_entry->dma_buf[0][vip_entry->read_index].list_len, -+ PCI_DMA_FROMDEVICE); -+ if (vip_entry->dual_channel) { -+ pci_dma_sync_sg_for_cpu(saa716x->pdev, -+ vip_entry->dma_buf[1][vip_entry->read_index].sg_list, -+ vip_entry->dma_buf[1][vip_entry->read_index].list_len, -+ PCI_DMA_FROMDEVICE); -+ } -+ -+ vip_entry->read_index = (vip_entry->read_index + 1) & 7; -+ } while (write_index != vip_entry->read_index); -+} -+ -+static int video_vip_get_stream_params(struct vip_stream_params * params, -+ u32 mode) -+{ -+ switch (mode) -+ { -+ case 4: /* 1280x720p60 */ -+ case 19: /* 1280x720p50 */ -+ params->bits = 16; -+ params->samples = 1280; -+ params->lines = 720; -+ params->pitch = 1280 * 2; -+ params->offset_x = 32; -+ params->offset_y = 30; -+ params->stream_flags = VIP_HD; -+ break; -+ -+ case 5: /* 1920x1080i60 */ -+ case 20: /* 1920x1080i50 */ -+ params->bits = 16; -+ params->samples = 1920; -+ params->lines = 1080; -+ params->pitch = 1920 * 2; -+ params->offset_x = 0; -+ params->offset_y = 20; -+ params->stream_flags = VIP_ODD_FIELD -+ | VIP_EVEN_FIELD -+ | VIP_INTERLACED -+ | VIP_HD -+ | VIP_NO_SCALER; -+ break; -+ -+ case 32: /* 1920x1080p24 */ -+ case 33: /* 1920x1080p25 */ -+ case 34: /* 1920x1080p30 */ -+ params->bits = 16; -+ params->samples = 1920; -+ params->lines = 1080; -+ params->pitch = 1920 * 2; -+ params->offset_x = 0; -+ params->offset_y = 0; -+ params->stream_flags = VIP_HD; -+ break; -+ -+ default: -+ return -1; -+ } -+ return 0; -+} -+ -+static ssize_t video_vip_read(struct sti7109_dev *sti7109, -+ struct vip_stream_params * stream_params, -+ char __user *buf, size_t count) -+{ -+ struct saa716x_dev *saa716x = sti7109->dev; -+ struct v4l2_pix_format pix_format; -+ int one_shot = 0; -+ size_t num_bytes; -+ size_t copy_bytes; -+ u32 read_index; -+ u8 *data; -+ int err = 0; -+ -+ if (sti7109->video_capture == VIDEO_CAPTURE_ONE_SHOT) -+ one_shot = 1; -+ -+ /* put a v4l2_pix_format header at the beginning of the returned data */ -+ memset(&pix_format, 0, sizeof(pix_format)); -+ pix_format.width = stream_params->samples; -+ pix_format.height = stream_params->lines; -+ pix_format.pixelformat = V4L2_PIX_FMT_UYVY; -+ pix_format.bytesperline = stream_params->pitch; -+ pix_format.sizeimage = stream_params->lines * stream_params->pitch; -+ -+ if (count > (sizeof(pix_format) + pix_format.sizeimage)) -+ count = sizeof(pix_format) + pix_format.sizeimage; -+ -+ if (count < sizeof(pix_format)) { -+ err = -EFAULT; -+ goto out; -+ } -+ -+ saa716x_vip_start(saa716x, 0, one_shot, stream_params); -+ /* Sleep long enough to be sure to capture at least one frame. -+ TODO: Change this in a way that it just waits the required time. */ -+ msleep(100); -+ saa716x_vip_stop(saa716x, 0); -+ -+ read_index = saa716x->vip[0].read_index; -+ if ((stream_params->stream_flags & VIP_INTERLACED) && -+ (stream_params->stream_flags & VIP_ODD_FIELD) && -+ (stream_params->stream_flags & VIP_EVEN_FIELD)) { -+ read_index = read_index & ~1; -+ read_index = (read_index + 7) & 7; -+ read_index = read_index / 2; -+ } else { -+ read_index = (read_index + 7) & 7; -+ } -+ -+ if (copy_to_user((void __user *)buf, &pix_format, sizeof(pix_format))) { -+ err = -EFAULT; -+ goto out; -+ } -+ num_bytes = sizeof(pix_format); -+ -+ copy_bytes = count - num_bytes; -+ if (copy_bytes > (SAA716x_PAGE_SIZE / 8 * SAA716x_PAGE_SIZE)) -+ copy_bytes = SAA716x_PAGE_SIZE / 8 * SAA716x_PAGE_SIZE; -+ data = (u8 *)saa716x->vip[0].dma_buf[0][read_index].mem_virt; -+ if (copy_to_user((void __user *)(buf + num_bytes), data, copy_bytes)) { -+ err = -EFAULT; -+ goto out; -+ } -+ num_bytes += copy_bytes; -+ if (saa716x->vip[0].dual_channel && -+ count - num_bytes > 0) { -+ copy_bytes = count - num_bytes; -+ if (copy_bytes > (SAA716x_PAGE_SIZE / 8 * SAA716x_PAGE_SIZE)) -+ copy_bytes = SAA716x_PAGE_SIZE / 8 * SAA716x_PAGE_SIZE; -+ data = (u8 *)saa716x->vip[0].dma_buf[1][read_index].mem_virt; -+ if (copy_to_user((void __user *)(buf + num_bytes), data, -+ copy_bytes)) { -+ err = -EFAULT; -+ goto out; -+ } -+ num_bytes += copy_bytes; -+ } -+ -+ return num_bytes; -+ -+out: -+ return err; -+} -+ -+static ssize_t dvb_video_read(struct file *file, char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct dvb_device *dvbdev = file->private_data; -+ struct sti7109_dev *sti7109 = dvbdev->priv; -+ struct vip_stream_params stream_params; -+ ssize_t ret = -ENODATA; -+ -+ if ((file->f_flags & O_ACCMODE) == O_WRONLY) -+ return -EPERM; -+ -+ mutex_lock(&sti7109->video_lock); -+ -+ if (sti7109->video_capture != VIDEO_CAPTURE_OFF) { -+ if (video_vip_get_stream_params(&stream_params, -+ sti7109->video_format) == 0) { -+ ret = video_vip_read(sti7109, &stream_params, -+ buf, count); -+ } -+ } -+ -+ mutex_unlock(&sti7109->video_lock); -+ return ret; -+} -+ -+#define FREE_COND_TS (dvb_ringbuffer_free(&sti7109->tsout) >= TS_SIZE) -+ -+static ssize_t dvb_video_write(struct file *file, const char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct dvb_device *dvbdev = file->private_data; -+ struct sti7109_dev *sti7109 = dvbdev->priv; -+ struct saa716x_dev *saa716x = sti7109->dev; -+ unsigned long todo = count; -+ -+ if ((file->f_flags & O_ACCMODE) == O_RDONLY) -+ return -EPERM; -+/* -+ if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY) -+ return -EPERM; -+*/ -+ if (sti7109->tsout_stat == TSOUT_STAT_RESET) -+ return count; -+ -+ if ((file->f_flags & O_NONBLOCK) && !FREE_COND_TS) -+ return -EWOULDBLOCK; -+ -+ while (todo >= TS_SIZE) { -+ if (!FREE_COND_TS) { -+ if (file->f_flags & O_NONBLOCK) -+ break; -+ if (wait_event_interruptible(sti7109->tsout.queue, FREE_COND_TS)) -+ break; -+ } -+ ringbuffer_write_user(&sti7109->tsout, buf, TS_SIZE); -+ todo -= TS_SIZE; -+ buf += TS_SIZE; -+ } -+ -+ if ((sti7109->tsout_stat == TSOUT_STAT_RUN) || -+ (dvb_ringbuffer_avail(&sti7109->tsout) > TSOUT_LEN/3)) { -+ u32 fifoCtrl = SAA716x_EPRD(PHI_1, FPGA_ADDR_FIFO_CTRL); -+ fifoCtrl |= 0x4; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_FIFO_CTRL, fifoCtrl); -+ } -+ -+ return count - todo; -+} -+ -+static unsigned int dvb_video_poll(struct file *file, poll_table *wait) -+{ -+ struct dvb_device *dvbdev = file->private_data; -+ struct sti7109_dev *sti7109 = dvbdev->priv; -+ unsigned int mask = 0; -+ -+ if ((file->f_flags & O_ACCMODE) != O_RDONLY) { -+ poll_wait(file, &sti7109->tsout.queue, wait); -+ -+ if (FREE_COND_TS) -+ mask |= (POLLOUT | POLLWRNORM); -+ } -+ -+ return mask; -+} -+ -+static int do_dvb_video_ioctl(struct dvb_device *dvbdev, -+ unsigned int cmd, void *parg) -+{ -+ struct sti7109_dev *sti7109 = dvbdev->priv; -+ struct saa716x_dev *saa716x = sti7109->dev; -+ int ret = 0; -+ -+ switch (cmd) { -+ case VIDEO_SELECT_SOURCE: -+ { -+ video_stream_source_t stream_source; -+ -+ stream_source = (video_stream_source_t) parg; -+ if (stream_source == VIDEO_SOURCE_DEMUX) { -+ /* stop and reset FIFO 1 */ -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_FIFO_CTRL, 1); -+ sti7109->tsout_stat = TSOUT_STAT_RESET; -+ break; -+ } -+ /* fall through */ -+ } -+ case VIDEO_CLEAR_BUFFER: -+ { -+ /* reset FIFO 1 */ -+ spin_lock(&sti7109->tsout.lock); -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_FIFO_CTRL, 1); -+ sti7109->tsout_stat = TSOUT_STAT_RESET; -+ spin_unlock(&sti7109->tsout.lock); -+ msleep(50); -+ cancel_work_sync(&sti7109->fifo_work); -+ /* start FIFO 1 */ -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_FIFO_CTRL, 2); -+ dvb_ringbuffer_flush(&sti7109->tsout); -+ sti7109->tsout_stat = TSOUT_STAT_FILL; -+ wake_up(&sti7109->tsout.queue); -+ break; -+ } -+ case VIDEO_GET_PTS: -+ { -+ *(u64 *)parg = sti7109->video_pts; -+ break; -+ } -+ case VIDEO_GET_SIZE: -+ { -+ ret = sti7109_cmd_get_video_format(sti7109, (video_size_t *) parg); -+ break; -+ } -+ default: -+ ret = -ENOIOCTLCMD; -+ break; -+ } -+ return ret; -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) && !defined(EXPERIMENTAL_TREE) -+static int dvb_video_ioctl(struct inode *inode, struct file *file, -+#else -+static long dvb_video_ioctl(struct file *file, -+#endif -+ unsigned int cmd, unsigned long arg) -+{ -+ struct dvb_device *dvbdev = file->private_data; -+ -+ if (!dvbdev) -+ return -ENODEV; -+ -+ return saa716x_usercopy (dvbdev, cmd, arg, do_dvb_video_ioctl); -+} -+ -+static struct file_operations dvb_video_fops = { -+ .owner = THIS_MODULE, -+ .read = dvb_video_read, -+ .write = dvb_video_write, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) && !defined(EXPERIMENTAL_TREE) -+ .ioctl = dvb_video_ioctl, -+#else -+ .unlocked_ioctl = dvb_video_ioctl, -+#endif -+ .open = dvb_generic_open, -+ .release = dvb_generic_release, -+ .poll = dvb_video_poll, -+}; -+ -+static struct dvb_device dvbdev_video = { -+ .priv = NULL, -+ .users = 5, -+ .readers = 5, -+ .writers = 1, -+ .fops = &dvb_video_fops, -+ .kernel_ioctl = NULL, -+}; -+ -+static int saa716x_ff_video_exit(struct saa716x_dev *saa716x) -+{ -+ struct sti7109_dev *sti7109 = saa716x->priv; -+ -+ if (sti7109->video_capture != VIDEO_CAPTURE_OFF) -+ saa716x_vip_exit(saa716x, 0); -+ -+ cancel_work_sync(&sti7109->fifo_work); -+ destroy_workqueue(sti7109->fifo_workq); -+ dvb_unregister_device(sti7109->video_dev); -+ return 0; -+} -+ -+static int saa716x_ff_video_init(struct saa716x_dev *saa716x) -+{ -+ struct saa716x_adapter *saa716x_adap = saa716x->saa716x_adap; -+ struct sti7109_dev *sti7109 = saa716x->priv; -+ -+ dvb_ringbuffer_init(&sti7109->tsout, sti7109->iobuf, TSOUT_LEN); -+ -+ dvb_register_device(&saa716x_adap->dvb_adapter, -+ &sti7109->video_dev, -+ &dvbdev_video, -+ sti7109, -+ DVB_DEVICE_VIDEO, 0); -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) -+ sti7109->fifo_workq = create_singlethread_workqueue("saa716x_fifo_wq"); -+#else -+ sti7109->fifo_workq = alloc_workqueue("saa716x_fifo_wq%d", WQ_UNBOUND, 1, SAA716x_DEV); -+#endif -+ INIT_WORK(&sti7109->fifo_work, fifo_worker); -+ -+ if (sti7109->video_capture != VIDEO_CAPTURE_OFF) -+ saa716x_vip_init(saa716x, 0, video_vip_worker); -+ -+ return 0; -+} -+ -+static int saa716x_ff_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) -+{ -+ struct saa716x_dev *saa716x; -+ struct sti7109_dev *sti7109; -+ int err = 0; -+ u32 value; -+ unsigned long timeout; -+ u32 fw_version; -+ -+ saa716x = kzalloc(sizeof (struct saa716x_dev), GFP_KERNEL); -+ if (saa716x == NULL) { -+ printk(KERN_ERR "saa716x_budget_pci_probe ERROR: out of memory\n"); -+ err = -ENOMEM; -+ goto fail0; -+ } -+ -+ saa716x->verbose = verbose; -+ saa716x->int_type = int_type; -+ saa716x->pdev = pdev; -+ saa716x->module = THIS_MODULE; -+ saa716x->config = (struct saa716x_config *) pci_id->driver_data; -+ -+ err = saa716x_pci_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x PCI Initialization failed"); -+ goto fail1; -+ } -+ -+ err = saa716x_cgu_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x CGU Init failed"); -+ goto fail1; -+ } -+ -+ err = saa716x_core_boot(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x Core Boot failed"); -+ goto fail2; -+ } -+ dprintk(SAA716x_DEBUG, 1, "SAA716x Core Boot Success"); -+ -+ err = saa716x_msi_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x MSI Init failed"); -+ goto fail2; -+ } -+ -+ err = saa716x_jetpack_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x Jetpack core initialization failed"); -+ goto fail2; -+ } -+ -+ err = saa716x_i2c_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x I2C Initialization failed"); -+ goto fail2; -+ } -+ -+ err = saa716x_phi_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x PHI Initialization failed"); -+ goto fail3; -+ } -+ -+ saa716x_gpio_init(saa716x); -+ -+ /* prepare the sti7109 device struct */ -+ sti7109 = kzalloc(sizeof(struct sti7109_dev), GFP_KERNEL); -+ if (!sti7109) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x: out of memory"); -+ goto fail3; -+ } -+ -+ sti7109->dev = saa716x; -+ -+ sti7109->iobuf = vmalloc(TSOUT_LEN + MAX_DATA_LEN); -+ if (!sti7109->iobuf) -+ goto fail4; -+ -+ sti7109_cmd_init(sti7109); -+ -+ sti7109->video_capture = video_capture; -+ mutex_init(&sti7109->video_lock); -+ -+ sti7109->int_count_enable = int_count_enable; -+ sti7109->total_int_count = 0; -+ memset(sti7109->vi_int_count, 0, sizeof(sti7109->vi_int_count)); -+ memset(sti7109->fgpi_int_count, 0, sizeof(sti7109->fgpi_int_count)); -+ memset(sti7109->i2c_int_count, 0, sizeof(sti7109->i2c_int_count)); -+ sti7109->ext_int_total_count = 0; -+ memset(sti7109->ext_int_source_count, 0, sizeof(sti7109->ext_int_source_count)); -+ sti7109->last_int_ticks = jiffies; -+ -+ saa716x->priv = sti7109; -+ -+ saa716x_gpio_set_output(saa716x, TT_PREMIUM_GPIO_POWER_ENABLE); -+ saa716x_gpio_set_output(saa716x, TT_PREMIUM_GPIO_RESET_BACKEND); -+ saa716x_gpio_set_output(saa716x, TT_PREMIUM_GPIO_FPGA_CS0); -+ saa716x_gpio_set_mode(saa716x, TT_PREMIUM_GPIO_FPGA_CS0, 1); -+ saa716x_gpio_set_output(saa716x, TT_PREMIUM_GPIO_FPGA_CS1); -+ saa716x_gpio_set_mode(saa716x, TT_PREMIUM_GPIO_FPGA_CS1, 1); -+ saa716x_gpio_set_output(saa716x, TT_PREMIUM_GPIO_FPGA_PROGRAMN); -+ saa716x_gpio_set_input(saa716x, TT_PREMIUM_GPIO_FPGA_DONE); -+ saa716x_gpio_set_input(saa716x, TT_PREMIUM_GPIO_FPGA_INITN); -+ -+ /* hold ST in reset */ -+ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_RESET_BACKEND, 0); -+ -+ /* enable board power */ -+ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_POWER_ENABLE, 1); -+ msleep(100); -+ -+ err = saa716x_ff_fpga_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x FF FPGA Initialization failed"); -+ goto fail5; -+ } -+ -+ /* configure TS muxer */ -+ if (sti7109->fpga_version < 0x110) { -+ /* select FIFO 1 for TS mux 3 */ -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_TSR_MUX3, 4); -+ } else { -+ /* select FIFO 1 for TS mux 3 */ -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_TSR_MUX3, 1); -+ } -+ -+ /* enable interrupts from ST7109 -> PC */ -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICTRL, 0x3); -+ -+ value = SAA716x_EPRD(MSI, MSI_CONFIG33); -+ value &= 0xFCFFFFFF; -+ value |= MSI_INT_POL_EDGE_FALL; -+ SAA716x_EPWR(MSI, MSI_CONFIG33, value); -+ SAA716x_EPWR(MSI, MSI_INT_ENA_SET_H, MSI_INT_EXTINT_0); -+ -+ /* enable tuner reset */ -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_PIO_CTRL, 0); -+ msleep(50); -+ /* disable tuner reset */ -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_PIO_CTRL, 1); -+ -+ err = saa716x_ff_st7109_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x FF STi7109 initialization failed"); -+ goto fail5; -+ } -+ -+ err = saa716x_dump_eeprom(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x EEPROM dump failed"); -+ } -+ -+ err = saa716x_eeprom_data(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x EEPROM dump failed"); -+ } -+ -+ /* enable FGPI2 and FGPI3 for TS inputs */ -+ SAA716x_EPWR(GREG, GREG_VI_CTRL, 0x0689F04); -+ SAA716x_EPWR(GREG, GREG_FGPI_CTRL, 0x280); -+ SAA716x_EPWR(GREG, GREG_VIDEO_IN_CTRL, 0xC0); -+ -+ err = saa716x_dvb_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x DVB initialization failed"); -+ goto fail6; -+ } -+ -+ /* wait a maximum of 10 seconds for the STi7109 to boot */ -+ timeout = 10 * HZ; -+ timeout = wait_event_interruptible_timeout(sti7109->boot_finish_wq, -+ sti7109->boot_finished == 1, -+ timeout); -+ -+ if (timeout == -ERESTARTSYS || sti7109->boot_finished == 0) { -+ if (timeout == -ERESTARTSYS) { -+ /* a signal arrived */ -+ goto fail6; -+ } -+ dprintk(SAA716x_ERROR, 1, "timed out waiting for boot finish"); -+ err = -1; -+ goto fail6; -+ } -+ dprintk(SAA716x_INFO, 1, "STi7109 finished booting"); -+ -+ err = saa716x_ff_video_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x FF VIDEO initialization failed"); -+ goto fail7; -+ } -+ -+ err = saa716x_ff_audio_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x FF AUDIO initialization failed"); -+ goto fail8; -+ } -+ -+ err = saa716x_ff_osd_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x FF OSD initialization failed"); -+ goto fail9; -+ } -+ -+ err = sti7109_cmd_get_fw_version(sti7109, &fw_version); -+ if (!err) { -+ printk(KERN_INFO "SAA716x FF firmware version %d.%d.%d\n", -+ (fw_version >> 16) & 0xFF, (fw_version >> 8) & 0xFF, -+ fw_version & 0xFF); -+ } -+ -+ err = saa716x_ir_init(saa716x); -+ if (err) -+ goto fail9; -+ -+ return 0; -+ -+fail9: -+ saa716x_ff_osd_exit(saa716x); -+fail8: -+ saa716x_ff_audio_exit(saa716x); -+fail7: -+ saa716x_ff_video_exit(saa716x); -+fail6: -+ saa716x_dvb_exit(saa716x); -+fail5: -+ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_H, MSI_INT_EXTINT_0); -+ -+ /* disable board power */ -+ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_POWER_ENABLE, 0); -+ -+ vfree(sti7109->iobuf); -+fail4: -+ kfree(sti7109); -+fail3: -+ saa716x_i2c_exit(saa716x); -+fail2: -+ saa716x_pci_exit(saa716x); -+fail1: -+ kfree(saa716x); -+fail0: -+ return err; -+} -+ -+static void saa716x_ff_pci_remove(struct pci_dev *pdev) -+{ -+ struct saa716x_dev *saa716x = pci_get_drvdata(pdev); -+ struct sti7109_dev *sti7109 = saa716x->priv; -+ -+ saa716x_ir_exit(saa716x); -+ -+ saa716x_ff_osd_exit(saa716x); -+ -+ saa716x_ff_audio_exit(saa716x); -+ -+ saa716x_ff_video_exit(saa716x); -+ -+ saa716x_dvb_exit(saa716x); -+ -+ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_H, MSI_INT_EXTINT_0); -+ -+ /* disable board power */ -+ saa716x_gpio_write(saa716x, TT_PREMIUM_GPIO_POWER_ENABLE, 0); -+ -+ vfree(sti7109->iobuf); -+ -+ saa716x->priv = NULL; -+ kfree(sti7109); -+ -+ saa716x_i2c_exit(saa716x); -+ saa716x_pci_exit(saa716x); -+ kfree(saa716x); -+} -+ -+static void demux_worker(unsigned long data) -+{ -+ struct saa716x_fgpi_stream_port *fgpi_entry = (struct saa716x_fgpi_stream_port *)data; -+ struct saa716x_dev *saa716x = fgpi_entry->saa716x; -+ struct dvb_demux *demux; -+ u32 fgpi_index; -+ u32 i; -+ u32 write_index; -+ -+ fgpi_index = fgpi_entry->dma_channel - 6; -+ demux = NULL; -+ for (i = 0; i < saa716x->config->adapters; i++) { -+ if (saa716x->config->adap_config[i].ts_port == fgpi_index) { -+ demux = &saa716x->saa716x_adap[i].demux; -+ break; -+ } -+ } -+ if (demux == NULL) { -+ printk(KERN_ERR "%s: unexpected channel %u\n", -+ __func__, fgpi_entry->dma_channel); -+ return; -+ } -+ -+ write_index = saa716x_fgpi_get_write_index(saa716x, fgpi_index); -+ if (write_index < 0) -+ return; -+ -+ dprintk(SAA716x_DEBUG, 1, "dma buffer = %d", write_index); -+ -+ if (write_index == fgpi_entry->read_index) { -+ printk(KERN_DEBUG "%s: called but nothing to do\n", __func__); -+ return; -+ } -+ -+ do { -+ u8 *data = (u8 *)fgpi_entry->dma_buf[fgpi_entry->read_index].mem_virt; -+ -+ pci_dma_sync_sg_for_cpu(saa716x->pdev, -+ fgpi_entry->dma_buf[fgpi_entry->read_index].sg_list, -+ fgpi_entry->dma_buf[fgpi_entry->read_index].list_len, -+ PCI_DMA_FROMDEVICE); -+ -+ dvb_dmx_swfilter(demux, data, 348 * 188); -+ -+ fgpi_entry->read_index = (fgpi_entry->read_index + 1) & 7; -+ } while (write_index != fgpi_entry->read_index); -+} -+ -+static irqreturn_t saa716x_ff_pci_irq(int irq, void *dev_id) -+{ -+ struct saa716x_dev *saa716x = (struct saa716x_dev *) dev_id; -+ struct sti7109_dev *sti7109; -+ u32 msiStatusL; -+ u32 msiStatusH; -+ u32 phiISR; -+ -+ if (unlikely(saa716x == NULL)) { -+ printk("%s: saa716x=NULL", __func__); -+ return IRQ_NONE; -+ } -+ sti7109 = saa716x->priv; -+ if (unlikely(sti7109 == NULL)) { -+ printk("%s: sti7109=NULL", __func__); -+ return IRQ_NONE; -+ } -+ if (sti7109->int_count_enable) -+ sti7109->total_int_count++; -+#if 0 -+ dprintk(SAA716x_DEBUG, 1, "VI STAT 0=<%02x> 1=<%02x>, CTL 1=<%02x> 2=<%02x>", -+ SAA716x_EPRD(VI0, INT_STATUS), -+ SAA716x_EPRD(VI1, INT_STATUS), -+ SAA716x_EPRD(VI0, INT_ENABLE), -+ SAA716x_EPRD(VI1, INT_ENABLE)); -+ -+ dprintk(SAA716x_DEBUG, 1, "FGPI STAT 0=<%02x> 1=<%02x>, CTL 1=<%02x> 2=<%02x>", -+ SAA716x_EPRD(FGPI0, INT_STATUS), -+ SAA716x_EPRD(FGPI1, INT_STATUS), -+ SAA716x_EPRD(FGPI0, INT_ENABLE), -+ SAA716x_EPRD(FGPI0, INT_ENABLE)); -+ -+ dprintk(SAA716x_DEBUG, 1, "FGPI STAT 2=<%02x> 3=<%02x>, CTL 2=<%02x> 3=<%02x>", -+ SAA716x_EPRD(FGPI2, INT_STATUS), -+ SAA716x_EPRD(FGPI3, INT_STATUS), -+ SAA716x_EPRD(FGPI2, INT_ENABLE), -+ SAA716x_EPRD(FGPI3, INT_ENABLE)); -+ -+ dprintk(SAA716x_DEBUG, 1, "AI STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", -+ SAA716x_EPRD(AI0, AI_STATUS), -+ SAA716x_EPRD(AI1, AI_STATUS), -+ SAA716x_EPRD(AI0, AI_CTL), -+ SAA716x_EPRD(AI1, AI_CTL)); -+ -+ dprintk(SAA716x_DEBUG, 1, "MSI STAT L=<%02x> H=<%02x>, CTL L=<%02x> H=<%02x>", -+ SAA716x_EPRD(MSI, MSI_INT_STATUS_L), -+ SAA716x_EPRD(MSI, MSI_INT_STATUS_H), -+ SAA716x_EPRD(MSI, MSI_INT_ENA_L), -+ SAA716x_EPRD(MSI, MSI_INT_ENA_H)); -+ -+ dprintk(SAA716x_DEBUG, 1, "I2C STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", -+ SAA716x_EPRD(I2C_A, INT_STATUS), -+ SAA716x_EPRD(I2C_B, INT_STATUS), -+ SAA716x_EPRD(I2C_A, INT_ENABLE), -+ SAA716x_EPRD(I2C_B, INT_ENABLE)); -+ -+ dprintk(SAA716x_DEBUG, 1, "DCS STAT=<%02x>, CTL=<%02x>", -+ SAA716x_EPRD(DCS, DCSC_INT_STATUS), -+ SAA716x_EPRD(DCS, DCSC_INT_ENABLE)); -+#endif -+ msiStatusL = SAA716x_EPRD(MSI, MSI_INT_STATUS_L); -+ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_L, msiStatusL); -+ msiStatusH = SAA716x_EPRD(MSI, MSI_INT_STATUS_H); -+ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_H, msiStatusH); -+ -+ if (msiStatusL) { -+ if (msiStatusL & MSI_INT_TAGACK_VI0_0) { -+ if (sti7109->int_count_enable) -+ sti7109->vi_int_count[0]++; -+ tasklet_schedule(&saa716x->vip[0].tasklet); -+ } -+ if (msiStatusL & MSI_INT_TAGACK_FGPI_2) { -+ if (sti7109->int_count_enable) -+ sti7109->fgpi_int_count[2]++; -+ tasklet_schedule(&saa716x->fgpi[2].tasklet); -+ } -+ if (msiStatusL & MSI_INT_TAGACK_FGPI_3) { -+ if (sti7109->int_count_enable) -+ sti7109->fgpi_int_count[3]++; -+ tasklet_schedule(&saa716x->fgpi[3].tasklet); -+ } -+ } -+ if (msiStatusH) { -+ //dprintk(SAA716x_INFO, 1, "msiStatusH: %08X", msiStatusH); -+ } -+ -+ if (msiStatusH & MSI_INT_I2CINT_0) { -+ if (sti7109->int_count_enable) -+ sti7109->i2c_int_count[0]++; -+ saa716x->i2c[0].i2c_op = 0; -+ wake_up(&saa716x->i2c[0].i2c_wq); -+ } -+ if (msiStatusH & MSI_INT_I2CINT_1) { -+ if (sti7109->int_count_enable) -+ sti7109->i2c_int_count[1]++; -+ saa716x->i2c[1].i2c_op = 0; -+ wake_up(&saa716x->i2c[1].i2c_wq); -+ } -+ -+ if (msiStatusH & MSI_INT_EXTINT_0) { -+ -+ phiISR = SAA716x_EPRD(PHI_1, FPGA_ADDR_EMI_ISR); -+ //dprintk(SAA716x_INFO, 1, "interrupt status register: %08X", phiISR); -+ -+ if (sti7109->int_count_enable) { -+ int i; -+ sti7109->ext_int_total_count++; -+ for (i = 0; i < 16; i++) -+ if (phiISR & (1 << i)) -+ sti7109->ext_int_source_count[i]++; -+ } -+ -+ if (phiISR & ISR_CMD_MASK) { -+ -+ u32 value; -+ u32 length; -+ /*dprintk(SAA716x_INFO, 1, "CMD interrupt source");*/ -+ -+ value = SAA716x_EPRD(PHI_1, ADDR_CMD_DATA); -+ value = __cpu_to_be32(value); -+ length = (value >> 16) + 2; -+ -+ /*dprintk(SAA716x_INFO, 1, "CMD length: %d", length);*/ -+ -+ if (length > MAX_RESULT_LEN) { -+ dprintk(SAA716x_ERROR, 1, "CMD length %d > %d", length, MAX_RESULT_LEN); -+ length = MAX_RESULT_LEN; -+ } -+ -+ saa716x_phi_read(saa716x, ADDR_CMD_DATA, sti7109->result_data, length); -+ sti7109->result_len = length; -+ sti7109->result_avail = 1; -+ wake_up(&sti7109->result_avail_wq); -+ -+ phiISR &= ~ISR_CMD_MASK; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_CMD_MASK); -+ } -+ -+ if (phiISR & ISR_READY_MASK) { -+ /*dprintk(SAA716x_INFO, 1, "READY interrupt source");*/ -+ sti7109->cmd_ready = 1; -+ wake_up(&sti7109->cmd_ready_wq); -+ phiISR &= ~ISR_READY_MASK; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_READY_MASK); -+ } -+ -+ if (phiISR & ISR_OSD_CMD_MASK) { -+ -+ u32 value; -+ u32 length; -+ /*dprintk(SAA716x_INFO, 1, "OSD CMD interrupt source");*/ -+ -+ value = SAA716x_EPRD(PHI_1, ADDR_OSD_CMD_DATA); -+ value = __cpu_to_be32(value); -+ length = (value >> 16) + 2; -+ -+ /*dprintk(SAA716x_INFO, 1, "OSD CMD length: %d", length);*/ -+ -+ if (length > MAX_RESULT_LEN) { -+ dprintk(SAA716x_ERROR, 1, "OSD CMD length %d > %d", length, MAX_RESULT_LEN); -+ length = MAX_RESULT_LEN; -+ } -+ -+ saa716x_phi_read(saa716x, ADDR_OSD_CMD_DATA, sti7109->osd_result_data, length); -+ sti7109->osd_result_len = length; -+ sti7109->osd_result_avail = 1; -+ wake_up(&sti7109->osd_result_avail_wq); -+ -+ phiISR &= ~ISR_OSD_CMD_MASK; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_OSD_CMD_MASK); -+ } -+ -+ if (phiISR & ISR_OSD_READY_MASK) { -+ /*dprintk(SAA716x_INFO, 1, "OSD_READY interrupt source");*/ -+ sti7109->osd_cmd_ready = 1; -+ wake_up(&sti7109->osd_cmd_ready_wq); -+ phiISR &= ~ISR_OSD_READY_MASK; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_OSD_READY_MASK); -+ } -+ -+ if (phiISR & ISR_BLOCK_MASK) { -+ /*dprintk(SAA716x_INFO, 1, "BLOCK interrupt source");*/ -+ sti7109->block_done = 1; -+ wake_up(&sti7109->block_done_wq); -+ phiISR &= ~ISR_BLOCK_MASK; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_BLOCK_MASK); -+ } -+ -+ if (phiISR & ISR_DATA_MASK) { -+ /*dprintk(SAA716x_INFO, 1, "DATA interrupt source");*/ -+ sti7109->data_ready = 1; -+ wake_up(&sti7109->data_ready_wq); -+ phiISR &= ~ISR_DATA_MASK; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_DATA_MASK); -+ } -+ -+ if (phiISR & ISR_BOOT_FINISH_MASK) { -+ /*dprintk(SAA716x_INFO, 1, "BOOT FINISH interrupt source");*/ -+ sti7109->boot_finished = 1; -+ wake_up(&sti7109->boot_finish_wq); -+ phiISR &= ~ISR_BOOT_FINISH_MASK; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_BOOT_FINISH_MASK); -+ } -+ -+ if (phiISR & ISR_AUDIO_PTS_MASK) { -+ u8 data[8]; -+ -+ saa716x_phi_read(saa716x, ADDR_AUDIO_PTS, data, 8); -+ sti7109->audio_pts = (((u64) data[3] & 0x01) << 32) -+ | ((u64) data[4] << 24) -+ | ((u64) data[5] << 16) -+ | ((u64) data[6] << 8) -+ | ((u64) data[7]); -+ -+ phiISR &= ~ISR_AUDIO_PTS_MASK; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_AUDIO_PTS_MASK); -+ -+ /*dprintk(SAA716x_INFO, 1, "AUDIO PTS: %llX", sti7109->audio_pts);*/ -+ } -+ -+ if (phiISR & ISR_VIDEO_PTS_MASK) { -+ u8 data[8]; -+ -+ saa716x_phi_read(saa716x, ADDR_VIDEO_PTS, data, 8); -+ sti7109->video_pts = (((u64) data[3] & 0x01) << 32) -+ | ((u64) data[4] << 24) -+ | ((u64) data[5] << 16) -+ | ((u64) data[6] << 8) -+ | ((u64) data[7]); -+ -+ phiISR &= ~ISR_VIDEO_PTS_MASK; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_VIDEO_PTS_MASK); -+ -+ /*dprintk(SAA716x_INFO, 1, "VIDEO PTS: %llX", sti7109->video_pts);*/ -+ } -+ -+ if (phiISR & ISR_CURRENT_STC_MASK) { -+ u8 data[8]; -+ -+ saa716x_phi_read(saa716x, ADDR_CURRENT_STC, data, 8); -+ sti7109->current_stc = (((u64) data[3] & 0x01) << 32) -+ | ((u64) data[4] << 24) -+ | ((u64) data[5] << 16) -+ | ((u64) data[6] << 8) -+ | ((u64) data[7]); -+ -+ phiISR &= ~ISR_CURRENT_STC_MASK; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_CURRENT_STC_MASK); -+ -+ /*dprintk(SAA716x_INFO, 1, "CURRENT STC: %llu", sti7109->current_stc);*/ -+ } -+ -+ if (phiISR & ISR_REMOTE_EVENT_MASK) { -+ u8 data[4]; -+ u32 remote_event; -+ -+ saa716x_phi_read(saa716x, ADDR_REMOTE_EVENT, data, 4); -+ remote_event = (data[3] << 24) -+ | (data[2] << 16) -+ | (data[1] << 8) -+ | (data[0]); -+ memset(data, 0, sizeof(data)); -+ saa716x_phi_write(saa716x, ADDR_REMOTE_EVENT, data, 4); -+ -+ phiISR &= ~ISR_REMOTE_EVENT_MASK; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_REMOTE_EVENT_MASK); -+ -+ if (remote_event == 0) { -+ dprintk(SAA716x_ERROR, 1, "REMOTE EVENT: %X ignored", remote_event); -+ } else { -+ dprintk(SAA716x_INFO, 1, "REMOTE EVENT: %X", remote_event); -+ saa716x_ir_handler(saa716x, remote_event); -+ } -+ } -+ -+ if (phiISR & ISR_DVO_FORMAT_MASK) { -+ u8 data[4]; -+ u32 format; -+ -+ saa716x_phi_read(saa716x, ADDR_DVO_FORMAT, data, 4); -+ format = (data[0] << 24) -+ | (data[1] << 16) -+ | (data[2] << 8) -+ | (data[3]); -+ -+ phiISR &= ~ISR_DVO_FORMAT_MASK; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_DVO_FORMAT_MASK); -+ -+ dprintk(SAA716x_INFO, 1, "DVO FORMAT CHANGE: %u", format); -+ sti7109->video_format = format; -+ } -+ -+ if (phiISR & ISR_LOG_MESSAGE_MASK) { -+ char message[SIZE_LOG_MESSAGE_DATA]; -+ -+ saa716x_phi_read(saa716x, ADDR_LOG_MESSAGE, message, -+ SIZE_LOG_MESSAGE_DATA); -+ -+ phiISR &= ~ISR_LOG_MESSAGE_MASK; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, ISR_LOG_MESSAGE_MASK); -+ -+ dprintk(SAA716x_INFO, 1, "LOG MESSAGE: %.*s", -+ SIZE_LOG_MESSAGE_DATA, message); -+ } -+ -+ if (phiISR & ISR_FIFO1_EMPTY_MASK) { -+ u32 fifoCtrl; -+ -+ /*dprintk(SAA716x_INFO, 1, "FIFO EMPTY interrupt source");*/ -+ fifoCtrl = SAA716x_EPRD(PHI_1, FPGA_ADDR_FIFO_CTRL); -+ fifoCtrl &= ~0x4; -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_FIFO_CTRL, fifoCtrl); -+ queue_work(sti7109->fifo_workq, &sti7109->fifo_work); -+ phiISR &= ~ISR_FIFO1_EMPTY_MASK; -+ } -+ -+ if (phiISR) { -+ dprintk(SAA716x_INFO, 1, "unknown interrupt source"); -+ SAA716x_EPWR(PHI_1, FPGA_ADDR_EMI_ICLR, phiISR); -+ } -+ } -+ -+ if (sti7109->int_count_enable) { -+ if (jiffies - sti7109->last_int_ticks >= HZ) { -+ dprintk(SAA716x_INFO, 1, -+ "int count: t: %d, v: %d %d, f:%d %d %d %d, i:%d %d," -+ "e: %d (%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d)", -+ sti7109->total_int_count, -+ sti7109->vi_int_count[0], -+ sti7109->vi_int_count[1], -+ sti7109->fgpi_int_count[0], -+ sti7109->fgpi_int_count[1], -+ sti7109->fgpi_int_count[2], -+ sti7109->fgpi_int_count[3], -+ sti7109->i2c_int_count[0], -+ sti7109->i2c_int_count[1], -+ sti7109->ext_int_total_count, -+ sti7109->ext_int_source_count[0], -+ sti7109->ext_int_source_count[1], -+ sti7109->ext_int_source_count[2], -+ sti7109->ext_int_source_count[3], -+ sti7109->ext_int_source_count[4], -+ sti7109->ext_int_source_count[5], -+ sti7109->ext_int_source_count[6], -+ sti7109->ext_int_source_count[7], -+ sti7109->ext_int_source_count[8], -+ sti7109->ext_int_source_count[9], -+ sti7109->ext_int_source_count[10], -+ sti7109->ext_int_source_count[11], -+ sti7109->ext_int_source_count[12], -+ sti7109->ext_int_source_count[13], -+ sti7109->ext_int_source_count[14], -+ sti7109->ext_int_source_count[15]); -+ sti7109->total_int_count = 0; -+ memset(sti7109->vi_int_count, 0, sizeof(sti7109->vi_int_count)); -+ memset(sti7109->fgpi_int_count, 0, sizeof(sti7109->fgpi_int_count)); -+ memset(sti7109->i2c_int_count, 0, sizeof(sti7109->i2c_int_count)); -+ sti7109->ext_int_total_count = 0; -+ memset(sti7109->ext_int_source_count, 0, sizeof(sti7109->ext_int_source_count)); -+ sti7109->last_int_ticks = jiffies; -+ } -+ } -+ return IRQ_HANDLED; -+} -+ -+#define SAA716x_MODEL_S2_6400_DUAL "Technotrend S2 6400 Dual S2 Premium" -+#define SAA716x_DEV_S2_6400_DUAL "2x DVB-S/S2 + Hardware decode" -+ -+static struct stv090x_config tt6400_stv090x_config = { -+ .device = STV0900, -+ .demod_mode = STV090x_DUAL, -+ .clk_mode = STV090x_CLK_EXT, -+ -+ .xtal = 13500000, -+ .address = 0x68, -+ -+ .ts1_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, -+ .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, -+ .ts1_clk = 135000000, -+ .ts2_clk = 135000000, -+ -+ .repeater_level = STV090x_RPTLEVEL_16, -+ -+ .tuner_init = NULL, -+ .tuner_set_mode = NULL, -+ .tuner_set_frequency = NULL, -+ .tuner_get_frequency = NULL, -+ .tuner_set_bandwidth = NULL, -+ .tuner_get_bandwidth = NULL, -+ .tuner_set_bbgain = NULL, -+ .tuner_get_bbgain = NULL, -+ .tuner_set_refclk = NULL, -+ .tuner_get_status = NULL, -+}; -+ -+static struct stv6110x_config tt6400_stv6110x_config = { -+ .addr = 0x60, -+ .refclk = 27000000, -+ .clk_div = 2, -+}; -+ -+static struct isl6423_config tt6400_isl6423_config[2] = { -+ { -+ .current_max = SEC_CURRENT_515m, -+ .curlim = SEC_CURRENT_LIM_ON, -+ .mod_extern = 1, -+ .addr = 0x09, -+ }, -+ { -+ .current_max = SEC_CURRENT_515m, -+ .curlim = SEC_CURRENT_LIM_ON, -+ .mod_extern = 1, -+ .addr = 0x08, -+ } -+}; -+ -+ -+static int saa716x_s26400_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *saa716x = adapter->saa716x; -+ struct saa716x_i2c *i2c = saa716x->i2c; -+ struct i2c_adapter *i2c_adapter = &i2c[SAA716x_I2C_BUS_A].i2c_adapter; -+ -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); -+ -+ if (count == 0 || count == 1) { -+ adapter->fe = dvb_attach(stv090x_attach, -+ &tt6400_stv090x_config, -+ i2c_adapter, -+ STV090x_DEMODULATOR_0 + count); -+ -+ if (adapter->fe) { -+ struct stv6110x_devctl *ctl; -+ ctl = dvb_attach(stv6110x_attach, -+ adapter->fe, -+ &tt6400_stv6110x_config, -+ i2c_adapter); -+ -+ tt6400_stv090x_config.tuner_init = ctl->tuner_init; -+ tt6400_stv090x_config.tuner_sleep = ctl->tuner_sleep; -+ tt6400_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; -+ tt6400_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; -+ tt6400_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; -+ tt6400_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; -+ tt6400_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; -+ tt6400_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; -+ tt6400_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; -+ tt6400_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; -+ tt6400_stv090x_config.tuner_get_status = ctl->tuner_get_status; -+ -+ if (count == 1) { -+ /* call the init function once to initialize -+ tuner's clock output divider and demod's -+ master clock */ -+ /* The second tuner drives the STV0900 so -+ call it only for adapter 1 */ -+ if (adapter->fe->ops.init) -+ adapter->fe->ops.init(adapter->fe); -+ } -+ -+ dvb_attach(isl6423_attach, -+ adapter->fe, -+ i2c_adapter, -+ &tt6400_isl6423_config[count]); -+ -+ } -+ } -+ return 0; -+} -+ -+static struct saa716x_config saa716x_s26400_config = { -+ .model_name = SAA716x_MODEL_S2_6400_DUAL, -+ .dev_type = SAA716x_DEV_S2_6400_DUAL, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 2, -+ .frontend_attach = saa716x_s26400_frontend_attach, -+ .irq_handler = saa716x_ff_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+ .i2c_mode = SAA716x_I2C_MODE_IRQ_BUFFERED, -+ -+ .adap_config = { -+ { -+ /* Adapter 0 */ -+ .ts_port = 2, -+ .worker = demux_worker -+ },{ -+ /* Adapter 1 */ -+ .ts_port = 3, -+ .worker = demux_worker -+ } -+ } -+}; -+ -+ -+static struct pci_device_id saa716x_ff_pci_table[] = { -+ -+ MAKE_ENTRY(TECHNOTREND, S2_6400_DUAL_S2_PREMIUM_DEVEL, SAA7160, &saa716x_s26400_config), /* S2 6400 Dual development version */ -+ MAKE_ENTRY(TECHNOTREND, S2_6400_DUAL_S2_PREMIUM_PROD, SAA7160, &saa716x_s26400_config), /* S2 6400 Dual production version */ -+ { } -+}; -+MODULE_DEVICE_TABLE(pci, saa716x_ff_pci_table); -+ -+static struct pci_driver saa716x_ff_pci_driver = { -+ .name = DRIVER_NAME, -+ .id_table = saa716x_ff_pci_table, -+ .probe = saa716x_ff_pci_probe, -+ .remove = saa716x_ff_pci_remove, -+}; -+ -+module_pci_driver(saa716x_ff_pci_driver); -+ -+MODULE_DESCRIPTION("SAA716x FF driver"); -+MODULE_AUTHOR("Manu Abraham"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/pci/saa716x/saa716x_fgpi.c b/drivers/media/pci/saa716x/saa716x_fgpi.c -new file mode 100644 -index 0000000..ec21dd5 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_fgpi.c -@@ -0,0 +1,386 @@ -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_fgpi_reg.h" -+#include "saa716x_dma_reg.h" -+#include "saa716x_msi_reg.h" -+ -+#include "saa716x_dma.h" -+#include "saa716x_fgpi.h" -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+ -+static const u32 fgpi_ch[] = { -+ FGPI0, -+ FGPI1, -+ FGPI2, -+ FGPI3 -+}; -+ -+static const u32 bamdma_bufmode[] = { -+ BAM_FGPI0_DMA_BUF_MODE, -+ BAM_FGPI1_DMA_BUF_MODE, -+ BAM_FGPI2_DMA_BUF_MODE, -+ BAM_FGPI3_DMA_BUF_MODE -+}; -+ -+static const u32 msi_int_tagack[] = { -+ MSI_INT_TAGACK_FGPI_0, -+ MSI_INT_TAGACK_FGPI_1, -+ MSI_INT_TAGACK_FGPI_2, -+ MSI_INT_TAGACK_FGPI_3 -+}; -+ -+static const u32 msi_int_ovrflw[] = { -+ MSI_INT_OVRFLW_FGPI_0, -+ MSI_INT_OVRFLW_FGPI_1, -+ MSI_INT_OVRFLW_FGPI_2, -+ MSI_INT_OVRFLW_FGPI_3 -+}; -+ -+static const u32 msi_int_avint[] = { -+ MSI_INT_AVINT_FGPI_0, -+ MSI_INT_AVINT_FGPI_1, -+ MSI_INT_AVINT_FGPI_2, -+ MSI_INT_AVINT_FGPI_3 -+}; -+ -+void saa716x_fgpiint_disable(struct saa716x_dmabuf *dmabuf, int channel) -+{ -+ struct saa716x_dev *saa716x = dmabuf->saa716x; -+ -+ u32 fgpi_port; -+ -+ fgpi_port = fgpi_ch[channel]; -+ -+ SAA716x_EPWR(fgpi_port, INT_ENABLE, 0); /* disable FGPI IRQ */ -+ SAA716x_EPWR(fgpi_port, INT_CLR_STATUS, 0x7f); /* clear status */ -+} -+EXPORT_SYMBOL_GPL(saa716x_fgpiint_disable); -+ -+int saa716x_fgpi_get_write_index(struct saa716x_dev *saa716x, u32 fgpi_index) -+{ -+ u32 fgpi_base; -+ u32 buf_mode_reg; -+ u32 buf_mode; -+ -+ switch (fgpi_index) { -+ case 0: /* FGPI_0 */ -+ fgpi_base = FGPI0; -+ buf_mode_reg = BAM_FGPI0_DMA_BUF_MODE; -+ break; -+ -+ case 1: /* FGPI_1 */ -+ fgpi_base = FGPI1; -+ buf_mode_reg = BAM_FGPI1_DMA_BUF_MODE; -+ break; -+ -+ case 2: /* FGPI_2 */ -+ fgpi_base = FGPI2; -+ buf_mode_reg = BAM_FGPI2_DMA_BUF_MODE; -+ break; -+ -+ case 3: /* FGPI_3 */ -+ fgpi_base = FGPI3; -+ buf_mode_reg = BAM_FGPI3_DMA_BUF_MODE; -+ break; -+ -+ default: -+ printk(KERN_ERR "%s: unexpected fgpi %u\n", -+ __func__, fgpi_index); -+ return -1; -+ } -+ -+ buf_mode = SAA716x_EPRD(BAM, buf_mode_reg); -+ if (saa716x->revision < 2) { -+ /* workaround for revision 1: restore buffer numbers on BAM */ -+ SAA716x_EPWR(fgpi_base, INT_CLR_STATUS, 0x7F); -+ SAA716x_EPWR(BAM, buf_mode_reg, buf_mode | 7); -+ } -+ return (buf_mode >> 3) & 0x7; -+} -+EXPORT_SYMBOL_GPL(saa716x_fgpi_get_write_index); -+ -+static u32 saa716x_init_ptables(struct saa716x_dmabuf *dmabuf, int channel, -+ struct fgpi_stream_params *stream_params) -+{ -+ struct saa716x_dev *saa716x = dmabuf->saa716x; -+ -+ u32 config, i; -+ -+ for (i = 0; i < FGPI_BUFFERS; i++) -+ BUG_ON((dmabuf[i].mem_ptab_phys == 0)); -+ -+ config = MMU_DMA_CONFIG(channel); /* DMACONFIGx */ -+ -+ SAA716x_EPWR(MMU, config, (FGPI_BUFFERS - 1)); -+ -+ if ((stream_params->stream_flags & FGPI_INTERLACED) && -+ (stream_params->stream_flags & FGPI_ODD_FIELD) && -+ (stream_params->stream_flags & FGPI_EVEN_FIELD)) { -+ /* In interlaced mode the same buffer is written twice, once -+ the odd field and once the even field */ -+ SAA716x_EPWR(MMU, MMU_PTA0_LSB(channel), PTA_LSB(dmabuf[0].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA0_MSB(channel), PTA_MSB(dmabuf[0].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA1_LSB(channel), PTA_LSB(dmabuf[0].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA1_MSB(channel), PTA_MSB(dmabuf[0].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA2_LSB(channel), PTA_LSB(dmabuf[1].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA2_MSB(channel), PTA_MSB(dmabuf[1].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA3_LSB(channel), PTA_LSB(dmabuf[1].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA3_MSB(channel), PTA_MSB(dmabuf[1].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA4_LSB(channel), PTA_LSB(dmabuf[2].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA4_MSB(channel), PTA_MSB(dmabuf[2].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA5_LSB(channel), PTA_LSB(dmabuf[2].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA5_MSB(channel), PTA_MSB(dmabuf[2].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA6_LSB(channel), PTA_LSB(dmabuf[3].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA6_MSB(channel), PTA_MSB(dmabuf[3].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA7_LSB(channel), PTA_LSB(dmabuf[3].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA7_MSB(channel), PTA_MSB(dmabuf[3].mem_ptab_phys)); /* High */ -+ } else { -+ SAA716x_EPWR(MMU, MMU_PTA0_LSB(channel), PTA_LSB(dmabuf[0].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA0_MSB(channel), PTA_MSB(dmabuf[0].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA1_LSB(channel), PTA_LSB(dmabuf[1].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA1_MSB(channel), PTA_MSB(dmabuf[1].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA2_LSB(channel), PTA_LSB(dmabuf[2].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA2_MSB(channel), PTA_MSB(dmabuf[2].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA3_LSB(channel), PTA_LSB(dmabuf[3].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA3_MSB(channel), PTA_MSB(dmabuf[3].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA4_LSB(channel), PTA_LSB(dmabuf[4].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA4_MSB(channel), PTA_MSB(dmabuf[4].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA5_LSB(channel), PTA_LSB(dmabuf[5].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA5_MSB(channel), PTA_MSB(dmabuf[5].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA6_LSB(channel), PTA_LSB(dmabuf[6].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA6_MSB(channel), PTA_MSB(dmabuf[6].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA7_LSB(channel), PTA_LSB(dmabuf[7].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA7_MSB(channel), PTA_MSB(dmabuf[7].mem_ptab_phys)); /* High */ -+ } -+ -+ return 0; -+} -+ -+int saa716x_fgpi_setparams(struct saa716x_dmabuf *dmabuf, -+ struct fgpi_stream_params *stream_params, -+ int port) -+{ -+ struct saa716x_dev *saa716x = dmabuf->saa716x; -+ -+ u32 fgpi_port, buf_mode, val, mid; -+ u32 D1_XY_END, offst_1, offst_2; -+ int i = 0; -+ u8 dma_channel; -+ -+ fgpi_port = fgpi_ch[port]; -+ buf_mode = bamdma_bufmode[port]; -+ dma_channel = saa716x->fgpi[port].dma_channel; -+ -+ /* Reset FGPI block */ -+ SAA716x_EPWR(fgpi_port, FGPI_SOFT_RESET, FGPI_SOFTWARE_RESET); -+ -+ /* Reset DMA channel */ -+ SAA716x_EPWR(BAM, buf_mode, 0x00000040); -+ saa716x_init_ptables(dmabuf, dma_channel, stream_params); -+ -+ -+ /* monitor BAM reset */ -+ val = SAA716x_EPRD(BAM, buf_mode); -+ while (val && (i < 100)) { -+ msleep(30); -+ val = SAA716x_EPRD(BAM, buf_mode); -+ i++; -+ } -+ -+ if (val) { -+ dprintk(SAA716x_ERROR, 1, "Error: BAM FGPI Reset failed!"); -+ return -EIO; -+ } -+ -+ /* set buffer count */ -+ SAA716x_EPWR(BAM, buf_mode, FGPI_BUFFERS - 1); -+ -+ /* initialize all available address offsets */ -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_0(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_1(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_2(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_3(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_4(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_5(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_6(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_7(dma_channel), 0x0); -+ -+ /* get module ID */ -+ mid = SAA716x_EPRD(fgpi_port, FGPI_MODULE_ID); -+ if (mid != 0x14b0100) -+ dprintk(SAA716x_ERROR, 1, "FGPI Id<%04x> is not supported", mid); -+ -+ /* Initialize FGPI block */ -+ SAA716x_EPWR(fgpi_port, FGPI_REC_SIZE, stream_params->samples * (stream_params->bits / 8)); -+ SAA716x_EPWR(fgpi_port, FGPI_STRIDE, stream_params->pitch); -+ -+ offst_1 = 0; -+ offst_2 = 0; -+ switch (stream_params->stream_type) { -+ case FGPI_TRANSPORT_STREAM: -+ SAA716x_EPWR(fgpi_port, FGPI_CONTROL, 0x00000080); -+ SAA716x_EPWR(fgpi_port, FGPI_SIZE, stream_params->lines); -+ break; -+ -+ case FGPI_RAW_STREAM: -+ case FGPI_PROGRAM_STREAM: -+ SAA716x_EPWR(fgpi_port, FGPI_CONTROL, 0x00000088); -+ SAA716x_EPWR(fgpi_port, FGPI_SIZE, stream_params->lines); -+ break; -+ -+ case FGPI_VIDEO_STREAM: -+ SAA716x_EPWR(fgpi_port, FGPI_CONTROL, 0x00000040); -+ SAA716x_EPWR(fgpi_port, FGPI_D1_XY_START, stream_params->offset); -+ -+ if ((stream_params->stream_flags & FGPI_INTERLACED) && -+ (stream_params->stream_flags & FGPI_ODD_FIELD) && -+ (stream_params->stream_flags & FGPI_EVEN_FIELD)) { -+ -+ SAA716x_EPWR(fgpi_port, FGPI_SIZE, stream_params->lines / 2); -+ SAA716x_EPWR(fgpi_port, FGPI_STRIDE, stream_params->pitch * 2); /* interlaced stride of 2 lines */ -+ -+ D1_XY_END = (stream_params->samples << 16); -+ D1_XY_END |= (stream_params->lines / 2) + stream_params->offset; -+ -+ if (stream_params->stream_flags & FGPI_PAL) -+ offst_2 = stream_params->pitch; -+ else -+ offst_1 = stream_params->pitch; -+ -+ } else { -+ SAA716x_EPWR(fgpi_port, FGPI_SIZE, stream_params->lines); -+ SAA716x_EPWR(fgpi_port, FGPI_STRIDE, stream_params->pitch); /* stride of 1 line */ -+ -+ D1_XY_END = stream_params->samples << 16; -+ D1_XY_END |= stream_params->lines + stream_params->offset; -+ } -+ -+ SAA716x_EPWR(fgpi_port, FGPI_D1_XY_END, D1_XY_END); -+ break; -+ -+ default: -+ SAA716x_EPWR(fgpi_port, FGPI_CONTROL, 0x00000080); -+ break; -+ } -+ -+ SAA716x_EPWR(fgpi_port, FGPI_BASE_1, (dma_channel << 21) + offst_1); -+ SAA716x_EPWR(fgpi_port, FGPI_BASE_2, (dma_channel << 21) + offst_2); -+ -+ return 0; -+} -+ -+int saa716x_fgpi_start(struct saa716x_dev *saa716x, int port, -+ struct fgpi_stream_params *stream_params) -+{ -+ u32 fgpi_port; -+ u32 config; -+ u32 val; -+ u32 i; -+ -+ fgpi_port = fgpi_ch[port]; -+ -+ SAA716x_EPWR(fgpi_port, FGPI_INTERFACE, 0); -+ msleep(10); -+ -+ if (saa716x_fgpi_setparams(saa716x->fgpi[port].dma_buf, stream_params, port) != 0) { -+ return -EIO; -+ } -+ -+ saa716x->fgpi[port].read_index = 0; -+ -+ config = MMU_DMA_CONFIG(saa716x->fgpi[port].dma_channel); /* DMACONFIGx */ -+ -+ val = SAA716x_EPRD(MMU, config); -+ SAA716x_EPWR(MMU, config, val & ~0x40); -+ SAA716x_EPWR(MMU, config, val | 0x40); -+ -+ SAA716x_EPWR(fgpi_port, INT_ENABLE, 0x7F); -+ -+ val = SAA716x_EPRD(MMU, config); -+ i = 0; -+ while (i < 500) { -+ if (val & 0x80) -+ break; -+ msleep(10); -+ val = SAA716x_EPRD(MMU, config); -+ i++; -+ } -+ -+ if (!(val & 0x80)) { -+ dprintk(SAA716x_ERROR, 1, "Error: PTE pre-fetch failed!"); -+ return -EIO; -+ } -+ -+ val = SAA716x_EPRD(fgpi_port, FGPI_CONTROL); -+ val |= 0x3000; -+ -+ saa716x_set_clk_external(saa716x, saa716x->fgpi[port].dma_channel); -+ -+ SAA716x_EPWR(fgpi_port, FGPI_CONTROL, val); -+ -+ SAA716x_EPWR(MSI, MSI_INT_ENA_SET_L, msi_int_tagack[port]); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_fgpi_start); -+ -+int saa716x_fgpi_stop(struct saa716x_dev *saa716x, int port) -+{ -+ u32 fgpi_port; -+ u32 val; -+ -+ fgpi_port = fgpi_ch[port]; -+ -+ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_L, msi_int_tagack[port]); -+ -+ val = SAA716x_EPRD(fgpi_port, FGPI_CONTROL); -+ val &= ~0x3000; -+ SAA716x_EPWR(fgpi_port, FGPI_CONTROL, val); -+ -+ saa716x_set_clk_internal(saa716x, saa716x->fgpi[port].dma_channel); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_fgpi_stop); -+ -+int saa716x_fgpi_init(struct saa716x_dev *saa716x, int port, int dma_buf_size, -+ void (*worker)(unsigned long)) -+{ -+ int i; -+ int ret; -+ -+ saa716x->fgpi[port].dma_channel = port + 6; -+ for (i = 0; i < FGPI_BUFFERS; i++) -+ { -+ ret = saa716x_dmabuf_alloc(saa716x, -+ &saa716x->fgpi[port].dma_buf[i], -+ dma_buf_size); -+ if (ret < 0) { -+ return ret; -+ } -+ } -+ saa716x->fgpi[port].saa716x = saa716x; -+ tasklet_init(&saa716x->fgpi[port].tasklet, worker, -+ (unsigned long)&saa716x->fgpi[port]); -+ saa716x->fgpi[port].read_index = 0; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_fgpi_init); -+ -+int saa716x_fgpi_exit(struct saa716x_dev *saa716x, int port) -+{ -+ int i; -+ -+ tasklet_kill(&saa716x->fgpi[port].tasklet); -+ for (i = 0; i < FGPI_BUFFERS; i++) -+ { -+ saa716x_dmabuf_free(saa716x, &saa716x->fgpi[port].dma_buf[i]); -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_fgpi_exit); -diff --git a/drivers/media/pci/saa716x/saa716x_fgpi.h b/drivers/media/pci/saa716x/saa716x_fgpi.h -new file mode 100644 -index 0000000..47f9a9c ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_fgpi.h -@@ -0,0 +1,92 @@ -+#ifndef __SAA716x_FGPI_H -+#define __SAA716x_FGPI_H -+ -+#include -+ -+#define FGPI_BUFFERS 8 -+ -+ -+/* -+ * Port supported streams -+ * -+ * FGPI_AUDIO_STREAM -+ * FGPI_VIDEO_STREAM -+ * FGPI_VBI_STREAM -+ * FGPI_TRANSPORT_STREAM -+ * FGPI_PROGRAM_STREAM -+ */ -+enum fgpi_stream_type { -+ FGPI_RAW_STREAM = 0x00, -+ FGPI_AUDIO_STREAM = 0x01, -+ FGPI_VIDEO_STREAM = 0x02, -+ FGPI_VBI_STREAM = 0x04, -+ FGPI_TRANSPORT_STREAM = 0x08, -+ FGPI_PROGRAM_STREAM = 0x10 -+}; -+ -+/* -+ * Stream port flags -+ * -+ * FGPI_ODD_FIELD -+ * FGPI_EVEN_FIELD -+ * FGPI_HD_0 -+ * FGPI_HD_1 -+ * FGPI_PAL -+ * FGPI_NTSC -+ */ -+enum fgpi_stream_flags { -+ FGPI_ODD_FIELD = 0x0001, -+ FGPI_EVEN_FIELD = 0x0002, -+ FGPI_INTERLACED = 0x0004, -+ FGPI_HD0 = 0x0010, -+ FGPI_HD1 = 0x0020, -+ FGPI_PAL = 0x0040, -+ FGPI_NTSC = 0x0080, -+ FGPI_NO_SCALER = 0x0100, -+}; -+ -+/* -+ * Stream port parameters -+ * bits: Bits per sample -+ * samples: samples perline -+ * lines: number of lines -+ * pitch: stream pitch in bytes -+ * offset: offset to first valid line -+ */ -+struct fgpi_stream_params { -+ u32 bits; -+ u32 samples; -+ u32 lines; -+ -+ s32 pitch; -+ -+ u32 offset; -+ u32 page_tables; -+ -+ enum fgpi_stream_flags stream_flags; -+ enum fgpi_stream_type stream_type; -+}; -+ -+struct saa716x_dmabuf; -+ -+struct saa716x_fgpi_stream_port { -+ u8 dma_channel; -+ struct saa716x_dmabuf dma_buf[FGPI_BUFFERS]; -+ struct saa716x_dev *saa716x; -+ struct tasklet_struct tasklet; -+ u8 read_index; -+}; -+ -+extern void saa716x_fgpiint_disable(struct saa716x_dmabuf *dmabuf, int channel); -+extern int saa716x_fgpi_get_write_index(struct saa716x_dev *saa716x, -+ u32 fgpi_index); -+extern int saa716x_fgpi_start(struct saa716x_dev *saa716x, int port, -+ struct fgpi_stream_params *stream_params); -+extern int saa716x_fgpi_stop(struct saa716x_dev *saa716x, int port); -+ -+extern int saa716x_fgpi_init(struct saa716x_dev *saa716x, int port, -+ int dma_buf_size, -+ void (*worker)(unsigned long)); -+extern int saa716x_fgpi_exit(struct saa716x_dev *saa716x, int port); -+ -+#endif /* __SAA716x_FGPI_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_fgpi_reg.h b/drivers/media/pci/saa716x/saa716x_fgpi_reg.h -new file mode 100644 -index 0000000..1193016 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_fgpi_reg.h -@@ -0,0 +1,74 @@ -+#ifndef __SAA716x_FGPI_REG_H -+#define __SAA716x_FGPI_REG_H -+ -+/* -------------- FGPI Registers -------------- */ -+ -+#define FGPI_CONTROL 0x000 -+#define FGPI_CAPTURE_ENABLE_2 (0x00000001 << 13) -+#define FGPI_CAPTURE_ENABLE_1 (0x00000001 << 12) -+#define FGPI_MODE (0x00000001 << 11) -+#define FGPI_SAMPLE_SIZE (0x00000003 << 8) -+#define FGPI_BUF_SYNC_MSG_STOP (0x00000003 << 5) -+#define FGPI_REC_START_MSG_START (0x00000003 << 2) -+#define FGPI_TSTAMP_SELECT (0x00000001 << 1) -+#define FGPI_VAR_LENGTH (0x00000001 << 0) -+ -+#define FGPI_BASE_1 0x004 -+#define FGPI_BASE_2 0x008 -+#define FGPI_SIZE 0x00c -+#define FGPI_REC_SIZE 0x010 -+#define FGPI_STRIDE 0x014 -+#define FGPI_NUM_RECORD_1 0x018 -+#define FGPI_NUM_RECORD_2 0x01c -+#define FGPI_THRESHOLD_1 0x020 -+#define FGPI_THRESHOLD_2 0x024 -+#define FGPI_D1_XY_START 0x028 -+#define FGPI_D1_XY_END 0x02c -+ -+#define INT_STATUS 0xfe0 -+#define FGPI_BUF1_ACTIVE (0x00000001 << 7) -+#define FGPI_OVERFLOW (0x00000001 << 6) -+#define FGPI_MBE (0x00000001 << 5) -+#define FGPI_UNDERRUN (0x00000001 << 4) -+#define FGPI_THRESH2_REACHED (0x00000001 << 3) -+#define FGPI_THRESH1_REACHED (0x00000001 << 2) -+#define FGPI_BUF2_FULL (0x00000001 << 1) -+#define FGPI_BUF1_FULL (0x00000001 << 0) -+ -+#define INT_ENABLE 0xfe4 -+#define FGPI_OVERFLOW_ENA (0x00000001 << 6) -+#define FGPI_MBE_ENA (0x00000001 << 5) -+#define FGPI_UNDERRUN_ENA (0x00000001 << 4) -+#define FGPI_THRESH2_REACHED_ENA (0x00000001 << 3) -+#define FGPI_THRESH1_REACHED_ENA (0x00000001 << 2) -+#define FGPI_BUF2_FULL_ENA (0x00000001 << 1) -+#define FGPI_BUF1_FULL_ENA (0x00000001 << 0) -+ -+#define INT_CLR_STATUS 0xfe8 -+#define FGPI_OVERFLOW_ACK (0x00000001 << 6) -+#define FGPI_MBE_ACK (0x00000001 << 5) -+#define FGPI_UNDERRUN_ACK (0x00000001 << 4) -+#define FGPI_THRESH2_REACHED_ACK (0x00000001 << 3) -+#define FGPI_THRESH1_REACHED_ACK (0x00000001 << 2) -+#define FGPI_BUF2_DONE_ACK (0x00000001 << 1) -+#define FGPI_BUF1_DONE_ACK (0x00000001 << 0) -+ -+#define INT_SET_STATUS 0xfec -+#define FGPI_OVERFLOW_SET (0x00000001 << 6) -+#define FGPI_MBE_SET (0x00000001 << 5) -+#define FGPI_UNDERRUN_SET (0x00000001 << 4) -+#define FGPI_THRESH2_REACHED_SET (0x00000001 << 3) -+#define FGPI_THRESH1_REACHED_SET (0x00000001 << 2) -+#define FGPI_BUF2_DONE_SET (0x00000001 << 1) -+#define FGPI_BUF1_DONE_SET (0x00000001 << 0) -+ -+#define FGPI_SOFT_RESET 0xff0 -+#define FGPI_SOFTWARE_RESET (0x00000001 << 0) -+ -+#define FGPI_INTERFACE 0xff4 -+#define FGPI_DISABLE_BUS_IF (0x00000001 << 0) -+ -+#define FGPI_MOD_ID_EXT 0xff8 -+#define FGPI_MODULE_ID 0xffc -+ -+#endif /* __SAA716x_FGPI_REG_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_gpio.c b/drivers/media/pci/saa716x/saa716x_gpio.c -new file mode 100644 -index 0000000..62b6112 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_gpio.c -@@ -0,0 +1,140 @@ -+#include -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_gpio_reg.h" -+ -+#include "saa716x_gpio.h" -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+ -+void saa716x_gpio_init(struct saa716x_dev *saa716x) -+{ -+ spin_lock_init(&saa716x->gpio_lock); -+} -+EXPORT_SYMBOL_GPL(saa716x_gpio_init); -+ -+int saa716x_get_gpio_mode(struct saa716x_dev *saa716x, u32 *config) -+{ -+ *config = SAA716x_EPRD(GPIO, GPIO_WR_MODE); -+ -+ return 0; -+} -+ -+int saa716x_set_gpio_mode(struct saa716x_dev *saa716x, u32 mask, u32 config) -+{ -+ unsigned long flags; -+ u32 reg; -+ -+ spin_lock_irqsave(&saa716x->gpio_lock, flags); -+ reg = SAA716x_EPRD(GPIO, GPIO_WR_MODE); -+ reg &= ~mask; -+ reg |= (config & mask); -+ SAA716x_EPWR(GPIO, GPIO_WR_MODE, reg); -+ spin_unlock_irqrestore(&saa716x->gpio_lock, flags); -+ -+ return 0; -+} -+ -+u32 saa716x_gpio_rd(struct saa716x_dev *saa716x) -+{ -+ return SAA716x_EPRD(GPIO, GPIO_RD); -+} -+ -+void saa716x_gpio_wr(struct saa716x_dev *saa716x, u32 data) -+{ -+ SAA716x_EPWR(GPIO, GPIO_WR, data); -+} -+ -+void saa716x_gpio_ctl(struct saa716x_dev *saa716x, u32 mask, u32 bits) -+{ -+ unsigned long flags; -+ u32 reg; -+ -+ spin_lock_irqsave(&saa716x->gpio_lock, flags); -+ -+ reg = SAA716x_EPRD(GPIO, GPIO_OEN); -+ reg &= mask; -+ reg |= bits; -+ SAA716x_EPWR(GPIO, GPIO_OEN, reg); -+ -+ spin_unlock_irqrestore(&saa716x->gpio_lock, flags); -+} -+ -+void saa716x_gpio_bits(struct saa716x_dev *saa716x, u32 bits) -+{ -+ unsigned long flags; -+ u32 reg; -+ -+ spin_lock_irqsave(&saa716x->gpio_lock, flags); -+ -+ reg = SAA716x_EPRD(GPIO, GPIO_WR); -+ reg &= ~bits; -+ /* TODO ! add maskable config bits in here */ -+ /* reg |= (config->mask & bits) */ -+ reg |= bits; -+ SAA716x_EPWR(GPIO, GPIO_WR, reg); -+ -+ spin_unlock_irqrestore(&saa716x->gpio_lock, flags); -+} -+ -+void saa716x_gpio_set_output(struct saa716x_dev *saa716x, int gpio) -+{ -+ uint32_t value; -+ -+ value = SAA716x_EPRD(GPIO, GPIO_OEN); -+ value &= ~(1 << gpio); -+ SAA716x_EPWR(GPIO, GPIO_OEN, value); -+} -+EXPORT_SYMBOL_GPL(saa716x_gpio_set_output); -+ -+void saa716x_gpio_set_input(struct saa716x_dev *saa716x, int gpio) -+{ -+ uint32_t value; -+ -+ value = SAA716x_EPRD(GPIO, GPIO_OEN); -+ value |= 1 << gpio; -+ SAA716x_EPWR(GPIO, GPIO_OEN, value); -+} -+EXPORT_SYMBOL_GPL(saa716x_gpio_set_input); -+ -+void saa716x_gpio_set_mode(struct saa716x_dev *saa716x, int gpio, int mode) -+{ -+ uint32_t value; -+ -+ value = SAA716x_EPRD(GPIO, GPIO_WR_MODE); -+ if (mode) -+ value |= 1 << gpio; -+ else -+ value &= ~(1 << gpio); -+ SAA716x_EPWR(GPIO, GPIO_WR_MODE, value); -+} -+EXPORT_SYMBOL_GPL(saa716x_gpio_set_mode); -+ -+void saa716x_gpio_write(struct saa716x_dev *saa716x, int gpio, int set) -+{ -+ uint32_t value; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&saa716x->gpio_lock, flags); -+ value = SAA716x_EPRD(GPIO, GPIO_WR); -+ if (set) -+ value |= 1 << gpio; -+ else -+ value &= ~(1 << gpio); -+ SAA716x_EPWR(GPIO, GPIO_WR, value); -+ spin_unlock_irqrestore(&saa716x->gpio_lock, flags); -+} -+EXPORT_SYMBOL_GPL(saa716x_gpio_write); -+ -+int saa716x_gpio_read(struct saa716x_dev *saa716x, int gpio) -+{ -+ uint32_t value; -+ -+ value = SAA716x_EPRD(GPIO, GPIO_RD); -+ if (value & (1 << gpio)) -+ return 1; -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_gpio_read); -diff --git a/drivers/media/pci/saa716x/saa716x_gpio.h b/drivers/media/pci/saa716x/saa716x_gpio.h -new file mode 100644 -index 0000000..a82580b ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_gpio.h -@@ -0,0 +1,26 @@ -+#ifndef __SAA716x_GPIO_H -+#define __SAA716x_GPIO_H -+ -+#define BOOT_MODE GPIO_31 | GPIO_30 -+#define AV_UNIT_B GPIO_25 -+#define AV_UNIT_A GPIO_24 -+#define AV_INTR_B GPIO_01 -+#define AV_INTR_A GPIO_00 -+ -+struct saa716x_dev; -+ -+extern void saa716x_gpio_init(struct saa716x_dev *saa716x); -+ -+extern u32 saa716x_gpio_rd(struct saa716x_dev *saa716x); -+extern void saa716x_gpio_wr(struct saa716x_dev *saa716x, u32 data); -+extern void saa716x_gpio_ctl(struct saa716x_dev *saa716x, u32 mask, u32 bits); -+ -+extern void saa716x_gpio_bits(struct saa716x_dev *saa716x, u32 bits); -+ -+extern void saa716x_gpio_set_output(struct saa716x_dev *saa716x, int gpio); -+extern void saa716x_gpio_set_input(struct saa716x_dev *saa716x, int gpio); -+extern void saa716x_gpio_set_mode(struct saa716x_dev *saa716x, int gpio, int mode); -+extern void saa716x_gpio_write(struct saa716x_dev *saa716x, int gpio, int set); -+extern int saa716x_gpio_read(struct saa716x_dev *saa716x, int gpio); -+ -+#endif /* __SAA716x_GPIO_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_gpio_reg.h b/drivers/media/pci/saa716x/saa716x_gpio_reg.h -new file mode 100644 -index 0000000..f36184a ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_gpio_reg.h -@@ -0,0 +1,47 @@ -+#ifndef __SAA716x_GPIO_REG_H -+#define __SAA716x_GPIO_REG_H -+ -+/* -------------- GPIO Registers -------------- */ -+ -+#define GPIO_RD 0x000 -+#define GPIO_WR 0x004 -+#define GPIO_WR_MODE 0x008 -+#define GPIO_OEN 0x00c -+ -+#define GPIO_SW_RST 0xff0 -+#define GPIO_SW_RESET (0x00000001 << 0) -+ -+#define GPIO_31 (1 << 31) -+#define GPIO_30 (1 << 30) -+#define GPIO_29 (1 << 29) -+#define GPIO_28 (1 << 28) -+#define GPIO_27 (1 << 27) -+#define GPIO_26 (1 << 26) -+#define GPIO_25 (1 << 25) -+#define GPIO_24 (1 << 24) -+#define GPIO_23 (1 << 23) -+#define GPIO_22 (1 << 22) -+#define GPIO_21 (1 << 21) -+#define GPIO_20 (1 << 20) -+#define GPIO_19 (1 << 19) -+#define GPIO_18 (1 << 18) -+#define GPIO_17 (1 << 17) -+#define GPIO_16 (1 << 16) -+#define GPIO_15 (1 << 15) -+#define GPIO_14 (1 << 14) -+#define GPIO_13 (1 << 13) -+#define GPIO_12 (1 << 12) -+#define GPIO_11 (1 << 11) -+#define GPIO_10 (1 << 10) -+#define GPIO_09 (1 << 9) -+#define GPIO_08 (1 << 8) -+#define GPIO_07 (1 << 7) -+#define GPIO_06 (1 << 6) -+#define GPIO_05 (1 << 5) -+#define GPIO_04 (1 << 4) -+#define GPIO_03 (1 << 3) -+#define GPIO_02 (1 << 2) -+#define GPIO_01 (1 << 1) -+#define GPIO_00 (1 << 0) -+ -+#endif /* __SAA716x_GPIO_REG_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_greg.c b/drivers/media/pci/saa716x/saa716x_greg.c -new file mode 100644 -index 0000000..d93a3b8 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_greg.c -@@ -0,0 +1,42 @@ -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_greg_reg.h" -+#include "saa716x_greg.h" -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+ -+static u32 g_save[12]; -+ -+void saa716x_greg_save(struct saa716x_dev *saa716x) -+{ -+ g_save[0] = SAA716x_EPRD(GREG, GREG_SUBSYS_CONFIG); -+ g_save[1] = SAA716x_EPRD(GREG, GREG_MSI_BAR_PMCSR); -+ g_save[2] = SAA716x_EPRD(GREG, GREG_PMCSR_DATA_1); -+ g_save[3] = SAA716x_EPRD(GREG, GREG_PMCSR_DATA_2); -+ g_save[4] = SAA716x_EPRD(GREG, GREG_VI_CTRL); -+ g_save[5] = SAA716x_EPRD(GREG, GREG_FGPI_CTRL); -+ g_save[6] = SAA716x_EPRD(GREG, GREG_RSTU_CTRL); -+ g_save[7] = SAA716x_EPRD(GREG, GREG_I2C_CTRL); -+ g_save[8] = SAA716x_EPRD(GREG, GREG_OVFLW_CTRL); -+ g_save[9] = SAA716x_EPRD(GREG, GREG_TAG_ACK_FLEN); -+ -+ g_save[10] = SAA716x_EPRD(GREG, GREG_VIDEO_IN_CTRL); -+} -+ -+void saa716x_greg_restore(struct saa716x_dev *saa716x) -+{ -+ SAA716x_EPWR(GREG, GREG_SUBSYS_CONFIG, g_save[0]); -+ SAA716x_EPWR(GREG, GREG_MSI_BAR_PMCSR, g_save[1]); -+ SAA716x_EPWR(GREG, GREG_PMCSR_DATA_1, g_save[2]); -+ SAA716x_EPWR(GREG, GREG_PMCSR_DATA_2, g_save[3]); -+ SAA716x_EPWR(GREG, GREG_VI_CTRL, g_save[4]); -+ SAA716x_EPWR(GREG, GREG_FGPI_CTRL, g_save[5]); -+ SAA716x_EPWR(GREG, GREG_RSTU_CTRL, g_save[6]); -+ SAA716x_EPWR(GREG, GREG_I2C_CTRL, g_save[7]); -+ SAA716x_EPWR(GREG, GREG_OVFLW_CTRL, g_save[8]); -+ SAA716x_EPWR(GREG, GREG_TAG_ACK_FLEN, g_save[9]); -+ -+ SAA716x_EPWR(GREG, GREG_VIDEO_IN_CTRL, g_save[10]); -+} -diff --git a/drivers/media/pci/saa716x/saa716x_greg.h b/drivers/media/pci/saa716x/saa716x_greg.h -new file mode 100644 -index 0000000..487595e ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_greg.h -@@ -0,0 +1,9 @@ -+#ifndef __SAA716x_GREG_H -+#define __SAA716x_GREG_H -+ -+struct saa716x_dev; -+ -+extern void saa716x_greg_save(struct saa716x_dev *saa716x); -+extern void saa716x_greg_restore(struct saa716x_dev *saa716x); -+ -+#endif /* __SAA716x_GREG_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_greg_reg.h b/drivers/media/pci/saa716x/saa716x_greg_reg.h -new file mode 100644 -index 0000000..052e8cd ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_greg_reg.h -@@ -0,0 +1,91 @@ -+#ifndef __SAA716x_GREG_REG_H -+#define __SAA716x_GREG_REG_H -+ -+/* -------------- GREG Registers -------------- */ -+ -+#define GREG_SUBSYS_CONFIG 0x000 -+#define GREG_SUBSYS_ID (0x0000ffff << 16) -+#define GREG_SUBSYS_VID (0x0000ffff << 0) -+ -+#define GREG_MSI_BAR_PMCSR 0x004 -+#define GREG_PMCSR_SCALE_7 (0x00000003 << 30) -+#define GREG_PMCSR_SCALE_6 (0x00000003 << 28) -+#define GREG_PMCSR_SCALE_5 (0x00000003 << 26) -+#define GREG_PMCSR_SCALE_4 (0x00000003 << 24) -+#define GREG_PMCSR_SCALE_3 (0x00000003 << 22) -+#define GREG_PMCSR_SCALE_2 (0x00000003 << 20) -+#define GREG_PMCSR_SCALE_1 (0x00000003 << 18) -+#define GREG_PMCSR_SCALE_0 (0x00000003 << 16) -+ -+#define GREG_BAR_WIDTH_17 (0x0000001e << 8) -+#define GREG_BAR_WIDTH_18 (0x0000001c << 8) -+#define GREG_BAR_WIDTH_19 (0x00000018 << 8) -+#define GREG_BAR_WIDTH_20 (0x00000010 << 8) -+ -+#define GREG_BAR_PREFETCH (0x00000001 << 3) -+#define GREG_MSI_MM_CAP1 (0x00000000 << 0) // FIXME ! -+#define GREG_MSI_MM_CAP2 (0x00000001 << 0) -+#define GREG_MSI_MM_CAP4 (0x00000002 << 0) -+#define GREG_MSI_MM_CAP8 (0x00000003 << 0) -+#define GREG_MSI_MM_CAP16 (0x00000004 << 0) -+#define GREG_MSI_MM_CAP32 (0x00000005 << 0) -+ -+#define GREG_PMCSR_DATA_1 0x008 -+#define GREG_PMCSR_DATA_2 0x00c -+#define GREG_VI_CTRL 0x010 -+#define GREG_FGPI_CTRL 0x014 -+ -+#define GREG_RSTU_CTRL 0x018 -+#define GREG_BOOT_READY (0x00000001 << 13) -+#define GREG_RESET_REQ (0x00000001 << 12) -+#define GREG_IP_RST_RELEASE (0x00000001 << 11) -+#define GREG_ADAPTER_RST_RELEASE (0x00000001 << 10) -+#define GREG_PCIE_CORE_RST_RELEASE (0x00000001 << 9) -+#define GREG_BOOT_IP_RST_RELEASE (0x00000001 << 8) -+#define GREG_BOOT_RST_RELEASE (0x00000001 << 7) -+#define GREG_CGU_RST_RELEASE (0x00000001 << 6) -+#define GREG_IP_RST_ASSERT (0x00000001 << 5) -+#define GREG_ADAPTER_RST_ASSERT (0x00000001 << 4) -+#define GREG_RST_ASSERT (0x00000001 << 3) -+#define GREG_BOOT_IP_RST_ASSERT (0x00000001 << 2) -+#define GREG_BOOT_RST_ASSERT (0x00000001 << 1) -+#define GREG_CGU_RST_ASSERT (0x00000001 << 0) -+ -+#define GREG_I2C_CTRL 0x01c -+#define GREG_I2C_SLAVE_ADDR (0x0000007f << 0) -+ -+#define GREG_OVFLW_CTRL 0x020 -+#define GREG_OVERFLOW_ENABLE (0x00001fff << 0) -+ -+#define GREG_TAG_ACK_FLEN 0x024 -+#define GREG_TAG_ACK_FLEN_1B (0x00000000 << 0) -+#define GREG_TAG_ACK_FLEN_2B (0x00000001 << 0) -+#define GREG_TAG_ACK_FLEN_4B (0x00000002 << 0) -+#define GREG_TAG_ACK_FLEN_8B (0x00000003 << 0) -+ -+#define GREG_VIDEO_IN_CTRL 0x028 -+ -+#define GREG_SPARE_1 0x02c -+#define GREG_SPARE_2 0x030 -+#define GREG_SPARE_3 0x034 -+#define GREG_SPARE_4 0x038 -+#define GREG_SPARE_5 0x03c -+#define GREG_SPARE_6 0x040 -+#define GREG_SPARE_7 0x044 -+#define GREG_SPARE_8 0x048 -+#define GREG_SPARE_9 0x04c -+#define GREG_SPARE_10 0x050 -+#define GREG_SPARE_11 0x054 -+#define GREG_SPARE_12 0x058 -+#define GREG_SPARE_13 0x05c -+#define GREG_SPARE_14 0x060 -+#define GREG_SPARE_15 0x064 -+ -+#define GREG_FAIL_DISABLE 0x068 -+#define GREG_BOOT_FAIL_DISABLE (0x00000001 << 0) -+ -+#define GREG_SW_RST 0xff0 -+#define GREG_SW_RESET (0x00000001 << 0) -+ -+ -+#endif /* __SAA716x_GREG_REG_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_hybrid.c b/drivers/media/pci/saa716x/saa716x_hybrid.c -new file mode 100644 -index 0000000..b84d7ba ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_hybrid.c -@@ -0,0 +1,718 @@ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_gpio_reg.h" -+#include "saa716x_greg_reg.h" -+#include "saa716x_msi_reg.h" -+ -+#include "saa716x_adap.h" -+#include "saa716x_i2c.h" -+#include "saa716x_msi.h" -+#include "saa716x_hybrid.h" -+#include "saa716x_gpio.h" -+#include "saa716x_rom.h" -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+ -+#include "zl10353.h" -+#include "mb86a16.h" -+#include "tda1004x.h" -+#include "tda827x.h" -+ -+unsigned int verbose; -+module_param(verbose, int, 0644); -+MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); -+ -+unsigned int int_type; -+module_param(int_type, int, 0644); -+MODULE_PARM_DESC(int_type, "force Interrupt Handler type: 0=INT-A, 1=MSI, 2=MSI-X. default INT-A mode"); -+ -+#define DRIVER_NAME "SAA716x Hybrid" -+ -+static int saa716x_hybrid_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) -+{ -+ struct saa716x_dev *saa716x; -+ int err = 0; -+ -+ saa716x = kzalloc(sizeof (struct saa716x_dev), GFP_KERNEL); -+ if (saa716x == NULL) { -+ printk(KERN_ERR "saa716x_hybrid_pci_probe ERROR: out of memory\n"); -+ err = -ENOMEM; -+ goto fail0; -+ } -+ -+ saa716x->verbose = verbose; -+ saa716x->int_type = int_type; -+ saa716x->pdev = pdev; -+ saa716x->module = THIS_MODULE; -+ saa716x->config = (struct saa716x_config *) pci_id->driver_data; -+ -+ err = saa716x_pci_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x PCI Initialization failed"); -+ goto fail1; -+ } -+ -+ err = saa716x_cgu_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x CGU Init failed"); -+ goto fail1; -+ } -+ -+ err = saa716x_core_boot(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x Core Boot failed"); -+ goto fail2; -+ } -+ dprintk(SAA716x_DEBUG, 1, "SAA716x Core Boot Success"); -+ -+ err = saa716x_msi_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x MSI Init failed"); -+ goto fail2; -+ } -+ -+ err = saa716x_jetpack_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x Jetpack core Initialization failed"); -+ goto fail2; -+ } -+ -+ err = saa716x_i2c_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x I2C Initialization failed"); -+ goto fail2; -+ } -+ -+ saa716x_gpio_init(saa716x); -+ -+ err = saa716x_dump_eeprom(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x EEPROM dump failed"); -+ } -+ -+ err = saa716x_eeprom_data(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x EEPROM dump failed"); -+ } -+ -+ /* enable decoders on 7162 */ -+ if (pdev->device == SAA7162) { -+ saa716x_gpio_set_output(saa716x, 24); -+ saa716x_gpio_set_output(saa716x, 25); -+ -+ saa716x_gpio_write(saa716x, 24, 0); -+ saa716x_gpio_write(saa716x, 25, 0); -+ -+ msleep(10); -+ -+ saa716x_gpio_write(saa716x, 24, 1); -+ saa716x_gpio_write(saa716x, 25, 1); -+ } -+ -+ /* set default port mapping */ -+ SAA716x_EPWR(GREG, GREG_VI_CTRL, 0x2C688F44); -+ /* enable FGPI3 and FGPI0 for TS input from Port 3 and 6 */ -+ SAA716x_EPWR(GREG, GREG_FGPI_CTRL, 0x894); -+ -+ err = saa716x_dvb_init(saa716x); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x DVB initialization failed"); -+ goto fail3; -+ } -+ -+ return 0; -+ -+fail3: -+ saa716x_dvb_exit(saa716x); -+ saa716x_i2c_exit(saa716x); -+fail2: -+ saa716x_pci_exit(saa716x); -+fail1: -+ kfree(saa716x); -+fail0: -+ return err; -+} -+ -+static void saa716x_hybrid_pci_remove(struct pci_dev *pdev) -+{ -+ struct saa716x_dev *saa716x = pci_get_drvdata(pdev); -+ -+ saa716x_dvb_exit(saa716x); -+ saa716x_i2c_exit(saa716x); -+ saa716x_pci_exit(saa716x); -+ kfree(saa716x); -+} -+ -+static irqreturn_t saa716x_hybrid_pci_irq(int irq, void *dev_id) -+{ -+ struct saa716x_dev *saa716x = (struct saa716x_dev *) dev_id; -+ -+ u32 stat_h, stat_l, mask_h, mask_l; -+ -+ if (unlikely(saa716x == NULL)) { -+ printk("%s: saa716x=NULL", __func__); -+ return IRQ_NONE; -+ } -+ -+ stat_l = SAA716x_EPRD(MSI, MSI_INT_STATUS_L); -+ stat_h = SAA716x_EPRD(MSI, MSI_INT_STATUS_H); -+ mask_l = SAA716x_EPRD(MSI, MSI_INT_ENA_L); -+ mask_h = SAA716x_EPRD(MSI, MSI_INT_ENA_H); -+ -+ dprintk(SAA716x_DEBUG, 1, "MSI STAT L=<%02x> H=<%02x>, CTL L=<%02x> H=<%02x>", -+ stat_l, stat_h, mask_l, mask_h); -+ -+ if (!((stat_l & mask_l) || (stat_h & mask_h))) -+ return IRQ_NONE; -+ -+ if (stat_l) -+ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_L, stat_l); -+ -+ if (stat_h) -+ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_H, stat_h); -+ -+ saa716x_msi_event(saa716x, stat_l, stat_h); -+#if 0 -+ dprintk(SAA716x_DEBUG, 1, "VI STAT 0=<%02x> 1=<%02x>, CTL 1=<%02x> 2=<%02x>", -+ SAA716x_EPRD(VI0, INT_STATUS), -+ SAA716x_EPRD(VI1, INT_STATUS), -+ SAA716x_EPRD(VI0, INT_ENABLE), -+ SAA716x_EPRD(VI1, INT_ENABLE)); -+ -+ dprintk(SAA716x_DEBUG, 1, "FGPI STAT 0=<%02x> 1=<%02x>, CTL 1=<%02x> 2=<%02x>", -+ SAA716x_EPRD(FGPI0, INT_STATUS), -+ SAA716x_EPRD(FGPI1, INT_STATUS), -+ SAA716x_EPRD(FGPI0, INT_ENABLE), -+ SAA716x_EPRD(FGPI0, INT_ENABLE)); -+ -+ dprintk(SAA716x_DEBUG, 1, "FGPI STAT 2=<%02x> 3=<%02x>, CTL 2=<%02x> 3=<%02x>", -+ SAA716x_EPRD(FGPI2, INT_STATUS), -+ SAA716x_EPRD(FGPI3, INT_STATUS), -+ SAA716x_EPRD(FGPI2, INT_ENABLE), -+ SAA716x_EPRD(FGPI3, INT_ENABLE)); -+ -+ dprintk(SAA716x_DEBUG, 1, "AI STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", -+ SAA716x_EPRD(AI0, AI_STATUS), -+ SAA716x_EPRD(AI1, AI_STATUS), -+ SAA716x_EPRD(AI0, AI_CTL), -+ SAA716x_EPRD(AI1, AI_CTL)); -+ -+ dprintk(SAA716x_DEBUG, 1, "I2C STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", -+ SAA716x_EPRD(I2C_A, INT_STATUS), -+ SAA716x_EPRD(I2C_B, INT_STATUS), -+ SAA716x_EPRD(I2C_A, INT_ENABLE), -+ SAA716x_EPRD(I2C_B, INT_ENABLE)); -+ -+ dprintk(SAA716x_DEBUG, 1, "DCS STAT=<%02x>, CTL=<%02x>", -+ SAA716x_EPRD(DCS, DCSC_INT_STATUS), -+ SAA716x_EPRD(DCS, DCSC_INT_ENABLE)); -+#endif -+ -+ if (stat_l) { -+ if (stat_l & MSI_INT_TAGACK_FGPI_0) { -+ tasklet_schedule(&saa716x->fgpi[0].tasklet); -+ } -+ if (stat_l & MSI_INT_TAGACK_FGPI_1) { -+ tasklet_schedule(&saa716x->fgpi[1].tasklet); -+ } -+ if (stat_l & MSI_INT_TAGACK_FGPI_2) { -+ tasklet_schedule(&saa716x->fgpi[2].tasklet); -+ } -+ if (stat_l & MSI_INT_TAGACK_FGPI_3) { -+ tasklet_schedule(&saa716x->fgpi[3].tasklet); -+ } -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static void demux_worker(unsigned long data) -+{ -+ struct saa716x_fgpi_stream_port *fgpi_entry = (struct saa716x_fgpi_stream_port *)data; -+ struct saa716x_dev *saa716x = fgpi_entry->saa716x; -+ struct dvb_demux *demux; -+ u32 fgpi_index; -+ u32 i; -+ u32 write_index; -+ -+ fgpi_index = fgpi_entry->dma_channel - 6; -+ demux = NULL; -+ for (i = 0; i < saa716x->config->adapters; i++) { -+ if (saa716x->config->adap_config[i].ts_port == fgpi_index) { -+ demux = &saa716x->saa716x_adap[i].demux; -+ break; -+ } -+ } -+ if (demux == NULL) { -+ printk(KERN_ERR "%s: unexpected channel %u\n", -+ __func__, fgpi_entry->dma_channel); -+ return; -+ } -+ -+ write_index = saa716x_fgpi_get_write_index(saa716x, fgpi_index); -+ if (write_index < 0) -+ return; -+ -+ dprintk(SAA716x_DEBUG, 1, "dma buffer = %d", write_index); -+ -+ if (write_index == fgpi_entry->read_index) { -+ printk(KERN_DEBUG "%s: called but nothing to do\n", __func__); -+ return; -+ } -+ -+ do { -+ u8 *data = (u8 *)fgpi_entry->dma_buf[fgpi_entry->read_index].mem_virt; -+ -+ pci_dma_sync_sg_for_cpu(saa716x->pdev, -+ fgpi_entry->dma_buf[fgpi_entry->read_index].sg_list, -+ fgpi_entry->dma_buf[fgpi_entry->read_index].list_len, -+ PCI_DMA_FROMDEVICE); -+ -+ dvb_dmx_swfilter(demux, data, 348 * 188); -+ -+ fgpi_entry->read_index = (fgpi_entry->read_index + 1) & 7; -+ } while (write_index != fgpi_entry->read_index); -+} -+ -+/* -+ * Twinhan/Azurewave VP-6090 -+ * DVB-S Frontend: 2x MB86A16 -+ * DVB-T Frontend: 2x TDA10046 + TDA8275 -+ */ -+#define SAA716x_MODEL_TWINHAN_VP6090 "Twinhan/Azurewave VP-6090" -+#define SAA716x_DEV_TWINHAN_VP6090 "2xDVB-S + 2xDVB-T + 2xAnalog" -+ -+static int tda1004x_vp6090_request_firmware(struct dvb_frontend *fe, -+ const struct firmware **fw, -+ char *name) -+{ -+ struct saa716x_adapter *adapter = fe->dvb->priv; -+ -+ return request_firmware(fw, name, &adapter->saa716x->pdev->dev); -+} -+ -+static struct tda1004x_config tda1004x_vp6090_config = { -+ .demod_address = 0x8, -+ .invert = 0, -+ .invert_oclk = 0, -+ .xtal_freq = TDA10046_XTAL_4M, -+ .agc_config = TDA10046_AGC_DEFAULT, -+ .if_freq = TDA10046_FREQ_3617, -+ .request_firmware = tda1004x_vp6090_request_firmware, -+}; -+ -+static int vp6090_dvbs_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) -+{ -+ struct saa716x_dev *saa716x = fe->dvb->priv; -+ -+ switch (voltage) { -+ case SEC_VOLTAGE_13: -+ dprintk(SAA716x_ERROR, 1, "Polarization=[13V]"); -+ break; -+ case SEC_VOLTAGE_18: -+ dprintk(SAA716x_ERROR, 1, "Polarization=[18V]"); -+ break; -+ case SEC_VOLTAGE_OFF: -+ dprintk(SAA716x_ERROR, 1, "Frontend (dummy) POWERDOWN"); -+ break; -+ default: -+ dprintk(SAA716x_ERROR, 1, "Invalid = (%d)", (u32 ) voltage); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+struct mb86a16_config vp6090_mb86a16_config = { -+ .demod_address = 0x08, -+ .set_voltage = vp6090_dvbs_set_voltage, -+}; -+ -+static int saa716x_vp6090_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *saa716x = adapter->saa716x; -+ struct saa716x_i2c *i2c = &saa716x->i2c[count]; -+ -+ dprintk(SAA716x_ERROR, 1, "Adapter (%d) SAA716x frontend Init", count); -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); -+ -+ dprintk(SAA716x_ERROR, 1, "Adapter (%d) Power ON", count); -+ -+ saa716x_gpio_set_output(saa716x, 11); -+ saa716x_gpio_set_output(saa716x, 10); -+ saa716x_gpio_write(saa716x, 11, 1); -+ saa716x_gpio_write(saa716x, 10, 1); -+ msleep(100); -+#if 0 -+ dprintk(SAA716x_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)"); -+ adapter->fe = mb86a16_attach(&vp6090_mb86a16_config, &i2c->i2c_adapter); -+ if (adapter->fe) { -+ dprintk(SAA716x_ERROR, 1, "found MB86A16 DVB-S/DSS frontend @0x%02x", -+ vp6090_mb86a16_config.demod_address); -+ -+ } else { -+ goto exit; -+ } -+#endif -+ adapter->fe = dvb_attach(tda10046_attach, &tda1004x_vp6090_config, -+ &i2c->i2c_adapter); -+ if (adapter->fe == NULL) { -+ dprintk(SAA716x_ERROR, 1, "Frontend attach failed"); -+ return -ENODEV; -+ } else { -+ dprintk(SAA716x_ERROR, 1, "Done!"); -+ return 0; -+ } -+ -+ return 0; -+} -+ -+static struct saa716x_config saa716x_vp6090_config = { -+ .model_name = SAA716x_MODEL_TWINHAN_VP6090, -+ .dev_type = SAA716x_DEV_TWINHAN_VP6090, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 1, -+ .frontend_attach = saa716x_vp6090_frontend_attach, -+ .irq_handler = saa716x_hybrid_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+}; -+ -+/* -+ * NXP Reference design (Atlantis) -+ * 2x DVB-T Frontend: 2x TDA10046 -+ * Analog Decoder: 2x Internal -+ */ -+#define SAA716x_MODEL_NXP_ATLANTIS "Atlantis reference board" -+#define SAA716x_DEV_NXP_ATLANTIS "2x DVB-T + 2x Analog" -+ -+static int tda1004x_atlantis_request_firmware(struct dvb_frontend *fe, -+ const struct firmware **fw, -+ char *name) -+{ -+ struct saa716x_adapter *adapter = fe->dvb->priv; -+ -+ return request_firmware(fw, name, &adapter->saa716x->pdev->dev); -+} -+ -+static struct tda1004x_config tda1004x_atlantis_config = { -+ .demod_address = 0x8, -+ .invert = 0, -+ .invert_oclk = 0, -+ .xtal_freq = TDA10046_XTAL_16M, -+ .agc_config = TDA10046_AGC_TDA827X, -+ .if_freq = TDA10046_FREQ_045, -+ .request_firmware = tda1004x_atlantis_request_firmware, -+ .tuner_address = 0x60, -+}; -+ -+static struct tda827x_config tda827x_atlantis_config = { -+ .init = NULL, -+ .sleep = NULL, -+ .config = 0, -+ .switch_addr = 0, -+ .agcf = NULL, -+}; -+ -+static int saa716x_atlantis_frontend_attach(struct saa716x_adapter *adapter, -+ int count) -+{ -+ struct saa716x_dev *saa716x = adapter->saa716x; -+ struct saa716x_i2c *i2c; -+ u8 i2c_buf[3] = { 0x05, 0x23, 0x01 }; /* activate the silent I2C bus */ -+ struct i2c_msg msg = { -+ .addr = 0x42 >> 1, -+ .flags = 0, -+ .buf = i2c_buf, -+ .len = sizeof(i2c_buf) -+ }; -+ -+ if (count < saa716x->config->adapters) { -+ u32 reset_gpio; -+ -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", -+ count); -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, -+ saa716x->pdev->subsystem_device); -+ -+ if (count == 0) { -+ reset_gpio = 14; -+ i2c = &saa716x->i2c[SAA716x_I2C_BUS_A]; -+ } else { -+ reset_gpio = 15; -+ i2c = &saa716x->i2c[SAA716x_I2C_BUS_B]; -+ } -+ -+ /* activate the silent I2C bus */ -+ i2c_transfer(&i2c->i2c_adapter, &msg, 1); -+ -+ saa716x_gpio_set_output(saa716x, reset_gpio); -+ -+ /* Reset the demodulator */ -+ saa716x_gpio_write(saa716x, reset_gpio, 1); -+ msleep(10); -+ saa716x_gpio_write(saa716x, reset_gpio, 0); -+ msleep(10); -+ saa716x_gpio_write(saa716x, reset_gpio, 1); -+ msleep(10); -+ -+ adapter->fe = dvb_attach(tda10046_attach, -+ &tda1004x_atlantis_config, -+ &i2c->i2c_adapter); -+ if (adapter->fe == NULL) -+ goto exit; -+ -+ dprintk(SAA716x_ERROR, 1, -+ "found TDA10046 DVB-T frontend @0x%02x", -+ tda1004x_atlantis_config.demod_address); -+ -+ if (dvb_attach(tda827x_attach, adapter->fe, -+ tda1004x_atlantis_config.tuner_address, -+ &i2c->i2c_adapter, &tda827x_atlantis_config)) { -+ dprintk(SAA716x_ERROR, 1, "found TDA8275 tuner @0x%02x", -+ tda1004x_atlantis_config.tuner_address); -+ } else { -+ goto exit; -+ } -+ -+ dprintk(SAA716x_ERROR, 1, "Done!"); -+ return 0; -+ } -+ -+exit: -+ dprintk(SAA716x_ERROR, 1, "Frontend attach failed"); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_atlantis_config = { -+ .model_name = SAA716x_MODEL_NXP_ATLANTIS, -+ .dev_type = SAA716x_DEV_NXP_ATLANTIS, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 2, -+ .frontend_attach = saa716x_atlantis_frontend_attach, -+ .irq_handler = saa716x_hybrid_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+ .adap_config = { -+ { -+ /* Adapter 0 */ -+ .ts_port = 3, /* using FGPI 3 */ -+ .worker = demux_worker -+ }, -+ { -+ /* Adapter 1 */ -+ .ts_port = 0, /* using FGPI 0 */ -+ .worker = demux_worker -+ } -+ } -+}; -+ -+/* -+ * NXP Reference design (NEMO) -+ * DVB-T Frontend: 1x TDA10046 + TDA8275 -+ * Analog Decoder: External SAA7136 -+ */ -+#define SAA716x_MODEL_NXP_NEMO "NEMO reference board" -+#define SAA716x_DEV_NXP_NEMO "DVB-T + Analog" -+ -+static int tda1004x_nemo_request_firmware(struct dvb_frontend *fe, -+ const struct firmware **fw, -+ char *name) -+{ -+ struct saa716x_adapter *adapter = fe->dvb->priv; -+ -+ return request_firmware(fw, name, &adapter->saa716x->pdev->dev); -+} -+ -+static struct tda1004x_config tda1004x_nemo_config = { -+ .demod_address = 0x8, -+ .invert = 0, -+ .invert_oclk = 0, -+ .xtal_freq = TDA10046_XTAL_16M, -+ .agc_config = TDA10046_AGC_TDA827X, -+ .if_freq = TDA10046_FREQ_045, -+ .request_firmware = tda1004x_nemo_request_firmware, -+ .tuner_address = 0x60, -+}; -+ -+static struct tda827x_config tda827x_nemo_config = { -+ .init = NULL, -+ .sleep = NULL, -+ .config = 0, -+ .switch_addr = 0, -+ .agcf = NULL, -+}; -+ -+static int saa716x_nemo_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *saa716x = adapter->saa716x; -+ struct saa716x_i2c *demod_i2c = &saa716x->i2c[SAA716x_I2C_BUS_B]; -+ struct saa716x_i2c *tuner_i2c = &saa716x->i2c[SAA716x_I2C_BUS_A]; -+ -+ -+ if (count == 0) { -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); -+ dprintk(SAA716x_ERROR, 1, "Adapter (%d) Power ON", count); -+ -+ /* GPIO 26 controls a +15dB gain */ -+ saa716x_gpio_set_output(saa716x, 26); -+ saa716x_gpio_write(saa716x, 26, 0); -+ -+ saa716x_gpio_set_output(saa716x, 14); -+ -+ /* Reset the demodulator */ -+ saa716x_gpio_write(saa716x, 14, 1); -+ msleep(10); -+ saa716x_gpio_write(saa716x, 14, 0); -+ msleep(10); -+ saa716x_gpio_write(saa716x, 14, 1); -+ msleep(10); -+ -+ adapter->fe = dvb_attach(tda10046_attach, -+ &tda1004x_nemo_config, -+ &demod_i2c->i2c_adapter); -+ if (adapter->fe) { -+ dprintk(SAA716x_ERROR, 1, "found TDA10046 DVB-T frontend @0x%02x", -+ tda1004x_nemo_config.demod_address); -+ -+ } else { -+ goto exit; -+ } -+ if (dvb_attach(tda827x_attach, adapter->fe, -+ tda1004x_nemo_config.tuner_address, -+ &tuner_i2c->i2c_adapter, &tda827x_nemo_config)) { -+ dprintk(SAA716x_ERROR, 1, "found TDA8275 tuner @0x%02x", -+ tda1004x_nemo_config.tuner_address); -+ } else { -+ goto exit; -+ } -+ dprintk(SAA716x_ERROR, 1, "Done!"); -+ } -+ -+ return 0; -+exit: -+ dprintk(SAA716x_ERROR, 1, "Frontend attach failed"); -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_nemo_config = { -+ .model_name = SAA716x_MODEL_NXP_NEMO, -+ .dev_type = SAA716x_DEV_NXP_NEMO, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 1, -+ .frontend_attach = saa716x_nemo_frontend_attach, -+ .irq_handler = saa716x_hybrid_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+ -+ .adap_config = { -+ { -+ /* Adapter 0 */ -+ .ts_port = 3, /* using FGPI 3 */ -+ .worker = demux_worker -+ } -+ } -+}; -+ -+ -+#define SAA716x_MODEL_AVERMEDIA_HC82 "Avermedia HC82 Express-54" -+#define SAA716x_DEV_AVERMEDIA_HC82 "DVB-T + Analog" -+ -+#if 0 -+static struct zl10353_config saa716x_averhc82_zl10353_config = { -+ .demod_address = 0x1f, -+ .adc_clock = 450560, -+ .if2 = 361667, -+ .no_tuner = 1, -+ .parallel_ts = 1, -+}; -+#endif -+ -+static int saa716x_averhc82_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *saa716x = adapter->saa716x; -+ -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); -+ -+// adapter->fe = zl10353_attach(&saa716x_averhc82_zl10353_config, &i2c->i2c_adapter); -+ -+ -+ return 0; -+} -+ -+static struct saa716x_config saa716x_averhc82_config = { -+ .model_name = SAA716x_MODEL_AVERMEDIA_HC82, -+ .dev_type = SAA716x_DEV_AVERMEDIA_HC82, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 1, -+ .frontend_attach = saa716x_averhc82_frontend_attach, -+ .irq_handler = saa716x_hybrid_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+}; -+ -+#define SAA716x_MODEL_AVERMEDIA_H788 "Avermedia H788" -+#define SAA716x_DEV_AVERMEDIA_H788 "DVB-T + Analaog" -+ -+static int saa716x_averh88_frontend_attach(struct saa716x_adapter *adapter, int count) -+{ -+ struct saa716x_dev *saa716x = adapter->saa716x; -+ -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) SAA716x frontend Init", count); -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%d) Device ID=%02x", count, saa716x->pdev->subsystem_device); -+ -+ return -ENODEV; -+} -+ -+static struct saa716x_config saa716x_averh788_config = { -+ .model_name = SAA716x_MODEL_AVERMEDIA_H788, -+ .dev_type = SAA716x_DEV_AVERMEDIA_H788, -+ .boot_mode = SAA716x_EXT_BOOT, -+ .adapters = 1, -+ .frontend_attach = saa716x_averh88_frontend_attach, -+ .irq_handler = saa716x_hybrid_pci_irq, -+ .i2c_rate = SAA716x_I2C_RATE_100, -+}; -+ -+static struct pci_device_id saa716x_hybrid_pci_table[] = { -+ -+ MAKE_ENTRY(TWINHAN_TECHNOLOGIES, TWINHAN_VP_6090, SAA7162, &saa716x_vp6090_config), -+ MAKE_ENTRY(AVERMEDIA, AVERMEDIA_HC82, SAA7160, &saa716x_averhc82_config), -+ MAKE_ENTRY(AVERMEDIA, AVERMEDIA_H788, SAA7160, &saa716x_averh788_config), -+ MAKE_ENTRY(KWORLD, KWORLD_DVB_T_PE310, SAA7162, &saa716x_atlantis_config), -+ MAKE_ENTRY(NXP_REFERENCE_BOARD, PCI_ANY_ID, SAA7162, &saa716x_atlantis_config), -+ MAKE_ENTRY(NXP_REFERENCE_BOARD, PCI_ANY_ID, SAA7160, &saa716x_nemo_config), -+ { } -+}; -+MODULE_DEVICE_TABLE(pci, saa716x_hybrid_pci_table); -+ -+static struct pci_driver saa716x_hybrid_pci_driver = { -+ .name = DRIVER_NAME, -+ .id_table = saa716x_hybrid_pci_table, -+ .probe = saa716x_hybrid_pci_probe, -+ .remove = saa716x_hybrid_pci_remove, -+}; -+ -+module_pci_driver(saa716x_hybrid_pci_driver); -+ -+MODULE_DESCRIPTION("SAA716x Hybrid driver"); -+MODULE_AUTHOR("Manu Abraham"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/pci/saa716x/saa716x_hybrid.h b/drivers/media/pci/saa716x/saa716x_hybrid.h -new file mode 100644 -index 0000000..df34a59 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_hybrid.h -@@ -0,0 +1,13 @@ -+#ifndef __SAA716x_HYBRID_H -+#define __SAA716x_HYBRID_H -+ -+#define TWINHAN_TECHNOLOGIES 0x1822 -+#define AVERMEDIA 0x1461 -+#define KWORLD 0x17DE -+ -+#define TWINHAN_VP_6090 0x0027 -+#define AVERMEDIA_HC82 0x2355 -+#define AVERMEDIA_H788 0x1455 -+#define KWORLD_DVB_T_PE310 0x7521 -+ -+#endif /* __SAA716x_HYBRID_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_i2c.c b/drivers/media/pci/saa716x/saa716x_i2c.c -new file mode 100644 -index 0000000..d65edf8 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_i2c.c -@@ -0,0 +1,739 @@ -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_i2c_reg.h" -+#include "saa716x_msi_reg.h" -+#include "saa716x_cgu_reg.h" -+ -+#include "saa716x_i2c.h" -+#include "saa716x_msi.h" -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+ -+#define SAA716x_I2C_TXFAIL (I2C_ERROR_IBE | \ -+ I2C_ACK_INTER_MTNA | \ -+ I2C_FAILURE_INTER_MAF) -+ -+#define SAA716x_I2C_TXBUSY (I2C_TRANSMIT | \ -+ I2C_TRANSMIT_PROG) -+ -+#define SAA716x_I2C_RXBUSY (I2C_RECEIVE | \ -+ I2C_RECEIVE_CLEAR) -+ -+static const char* state[] = { -+ "Idle", -+ "DoneStop", -+ "Busy", -+ "TOscl", -+ "TOarb", -+ "DoneWrite", -+ "DoneRead", -+ "DoneWriteTO", -+ "DoneReadTO", -+ "NoDevice", -+ "NoACK", -+ "BUSErr", -+ "ArbLost", -+ "SEQErr", -+ "STErr" -+}; -+ -+int saa716x_i2c_irqevent(struct saa716x_dev *saa716x, u8 bus) -+{ -+ u32 stat, mask; -+ u32 *I2C_DEV; -+ -+ BUG_ON(saa716x == NULL); -+ I2C_DEV = saa716x->I2C_DEV; -+ -+ stat = SAA716x_EPRD(I2C_DEV[bus], INT_STATUS); -+ mask = SAA716x_EPRD(I2C_DEV[bus], INT_ENABLE); -+ saa716x->i2c[bus].i2c_stat = stat; -+ dprintk(SAA716x_DEBUG, 0, "Bus(%d) I2C event: Status=<%s> --> Stat=<%02x> Mask=<%02x>", -+ bus, state[stat], stat, mask); -+ -+ if (!(stat & mask)) -+ return -1; -+ -+ SAA716x_EPWR(I2C_DEV[bus], INT_CLR_STATUS, stat); -+ -+ if (stat & I2C_INTERRUPT_STFNF) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ -+ if (stat & I2C_INTERRUPT_MTFNF) { -+ dprintk(SAA716x_DEBUG, 0, " "); -+ } -+ -+ if (stat & I2C_INTERRUPT_RFDA) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ -+ if (stat & I2C_INTERRUPTE_RFF) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ -+ if (stat & I2C_SLAVE_INTERRUPT_STDR) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ -+ if (stat & I2C_MASTER_INTERRUPT_MTDR) { -+ dprintk(SAA716x_DEBUG, 0, " "); -+ } -+ -+ if (stat & I2C_ERROR_IBE) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ -+ if (stat & I2C_MODE_CHANGE_INTER_MSMC) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ -+ if (stat & I2C_SLAVE_RECEIVE_INTER_SRSD) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ -+ if (stat & I2C_SLAVE_TRANSMIT_INTER_STSD) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ -+ if (stat & I2C_ACK_INTER_MTNA) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ -+ if (stat & I2C_FAILURE_INTER_MAF) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ -+ if (stat & I2C_INTERRUPT_MTD) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ -+ return 0; -+} -+ -+static irqreturn_t saa716x_i2c_irq(int irq, void *dev_id) -+{ -+ struct saa716x_dev *saa716x = (struct saa716x_dev *) dev_id; -+ -+ if (unlikely(saa716x == NULL)) { -+ printk("%s: saa716x=NULL", __func__); -+ return IRQ_NONE; -+ } -+ dprintk(SAA716x_DEBUG, 1, "MSI STAT L=<%02x> H=<%02x>, CTL L=<%02x> H=<%02x>", -+ SAA716x_EPRD(MSI, MSI_INT_STATUS_L), -+ SAA716x_EPRD(MSI, MSI_INT_STATUS_H), -+ SAA716x_EPRD(MSI, MSI_INT_ENA_L), -+ SAA716x_EPRD(MSI, MSI_INT_ENA_H)); -+ -+ dprintk(SAA716x_DEBUG, 1, "I2C STAT 0=<%02x> 1=<%02x>, CTL 0=<%02x> 1=<%02x>", -+ SAA716x_EPRD(I2C_A, INT_STATUS), -+ SAA716x_EPRD(I2C_B, INT_STATUS), -+ SAA716x_EPRD(I2C_A, INT_CLR_STATUS), -+ SAA716x_EPRD(I2C_B, INT_CLR_STATUS)); -+ -+ return IRQ_HANDLED; -+} -+ -+static void saa716x_term_xfer(struct saa716x_i2c *i2c, u32 I2C_DEV) -+{ -+ struct saa716x_dev *saa716x = i2c->saa716x; -+ -+ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0xc0); /* Start: SCL/SDA High */ -+ msleep(10); -+ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0x80); -+ msleep(10); -+ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0x00); -+ msleep(10); -+ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0x80); -+ msleep(10); -+ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0xc0); -+ -+ return; -+} -+ -+static void saa716x_i2c_hwdeinit(struct saa716x_i2c *i2c, u32 I2C_DEV) -+{ -+ struct saa716x_dev *saa716x = i2c->saa716x; -+ -+ /* Disable all interrupts and clear status */ -+ SAA716x_EPWR(I2C_DEV, INT_CLR_ENABLE, 0x1fff); -+ SAA716x_EPWR(I2C_DEV, INT_CLR_STATUS, 0x1fff); -+} -+ -+static int saa716x_i2c_hwinit(struct saa716x_i2c *i2c, u32 I2C_DEV) -+{ -+ struct saa716x_dev *saa716x = i2c->saa716x; -+ struct i2c_adapter *adapter = &i2c->i2c_adapter; -+ -+ int i, err = 0; -+ u32 reg; -+ -+ reg = SAA716x_EPRD(I2C_DEV, I2C_STATUS); -+ if (!(reg & 0xd)) { -+ dprintk(SAA716x_ERROR, 1, "Adapter (%02x) %s RESET failed, Exiting !", -+ I2C_DEV, adapter->name); -+ err = -EIO; -+ goto exit; -+ } -+ -+ /* Flush queue */ -+ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0xcc); -+ -+ /* Disable all interrupts and clear status */ -+ SAA716x_EPWR(I2C_DEV, INT_CLR_ENABLE, 0x1fff); -+ SAA716x_EPWR(I2C_DEV, INT_CLR_STATUS, 0x1fff); -+ -+ /* Reset I2C Core and generate a delay */ -+ SAA716x_EPWR(I2C_DEV, I2C_CONTROL, 0xc1); -+ -+ for (i = 0; i < 100; i++) { -+ reg = SAA716x_EPRD(I2C_DEV, I2C_CONTROL); -+ if (reg == 0xc0) { -+ dprintk(SAA716x_ERROR, 1, "Adapter (%02x) %s RESET", -+ I2C_DEV, adapter->name); -+ break; -+ } -+ msleep(1); -+ -+ if (i == 99) -+ err = -EIO; -+ } -+ -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "Adapter (%02x) %s RESET failed", -+ I2C_DEV, adapter->name); -+ -+ saa716x_term_xfer(i2c, I2C_DEV); -+ err = -EIO; -+ goto exit; -+ } -+ -+ /* I2C Rate Setup */ -+ switch (i2c->i2c_rate) { -+ case SAA716x_I2C_RATE_400: -+ -+ dprintk(SAA716x_DEBUG, 1, "Initializing Adapter %s @ 400k", adapter->name); -+ SAA716x_EPWR(I2C_DEV, I2C_CLOCK_DIVISOR_HIGH, 0x1a); /* 0.5 * 27MHz/400kHz */ -+ SAA716x_EPWR(I2C_DEV, I2C_CLOCK_DIVISOR_LOW, 0x21); /* 0.5 * 27MHz/400kHz */ -+ SAA716x_EPWR(I2C_DEV, I2C_SDA_HOLD, 0x10); -+ break; -+ -+ case SAA716x_I2C_RATE_100: -+ -+ dprintk(SAA716x_DEBUG, 1, "Initializing Adapter %s @ 100k", adapter->name); -+ SAA716x_EPWR(I2C_DEV, I2C_CLOCK_DIVISOR_HIGH, 0x68); /* 0.5 * 27MHz/100kHz */ -+ SAA716x_EPWR(I2C_DEV, I2C_CLOCK_DIVISOR_LOW, 0x87); /* 0.5 * 27MHz/100kHz */ -+ SAA716x_EPWR(I2C_DEV, I2C_SDA_HOLD, 0x60); -+ break; -+ -+ default: -+ -+ dprintk(SAA716x_ERROR, 1, "Adapter %s Unknown Rate (Rate=0x%02x)", -+ adapter->name, -+ i2c->i2c_rate); -+ -+ break; -+ } -+ -+ /* Disable all interrupts and clear status */ -+ SAA716x_EPWR(I2C_DEV, INT_CLR_ENABLE, 0x1fff); -+ SAA716x_EPWR(I2C_DEV, INT_CLR_STATUS, 0x1fff); -+ -+ if (i2c->i2c_mode >= SAA716x_I2C_MODE_IRQ) { -+ /* Enabled interrupts: -+ * Master Transaction Done, -+ * Master Transaction Data Request -+ * (0x81) -+ */ -+ msleep(5); -+ -+ SAA716x_EPWR(I2C_DEV, INT_SET_ENABLE, -+ I2C_SET_ENABLE_MTDR | I2C_SET_ENABLE_MTD); -+ -+ /* Check interrupt enable status */ -+ reg = SAA716x_EPRD(I2C_DEV, INT_ENABLE); -+ if (reg != 0x81) { -+ -+ dprintk(SAA716x_ERROR, 1, -+ "Adapter (%d) %s Interrupt enable failed, Exiting !", -+ i, -+ adapter->name); -+ -+ err = -EIO; -+ goto exit; -+ } -+ } -+ -+ /* Check status */ -+ reg = SAA716x_EPRD(I2C_DEV, I2C_STATUS); -+ if (!(reg & 0xd)) { -+ -+ dprintk(SAA716x_ERROR, 1, -+ "Adapter (%02x) %s has bad state, Exiting !", -+ I2C_DEV, -+ adapter->name); -+ -+ err = -EIO; -+ goto exit; -+ } -+#if 0 -+ saa716x_add_irqvector(saa716x, -+ i2c_vec[i].vector, -+ i2c_vec[i].edge, -+ i2c_vec[i].handler, -+ SAA716x_I2C_ADAPTER(i)); -+#endif -+ reg = SAA716x_EPRD(CGU, CGU_SCR_3); -+ dprintk(SAA716x_DEBUG, 1, "Adapter (%02x) Autowake <%d> Active <%d>", -+ I2C_DEV, -+ (reg >> 1) & 0x01, -+ reg & 0x01); -+ -+ return 0; -+exit: -+ return err; -+} -+ -+static int saa716x_i2c_send(struct saa716x_i2c *i2c, u32 I2C_DEV, u32 data) -+{ -+ struct saa716x_dev *saa716x = i2c->saa716x; -+ int i, err = 0; -+ u32 reg; -+ -+ if (i2c->i2c_mode >= SAA716x_I2C_MODE_IRQ) { -+ /* Write to FIFO */ -+ SAA716x_EPWR(I2C_DEV, TX_FIFO, data); -+ return 0; -+ } -+ -+ /* Check FIFO status before TX */ -+ reg = SAA716x_EPRD(I2C_DEV, I2C_STATUS); -+ i2c->stat_tx_prior = reg; -+ if (reg & SAA716x_I2C_TXBUSY) { -+ for (i = 0; i < 100; i++) { -+ /* TODO! check for hotplug devices */ -+ msleep(10); -+ reg = SAA716x_EPRD(I2C_DEV, I2C_STATUS); -+ -+ if (reg & SAA716x_I2C_TXBUSY) { -+ dprintk(SAA716x_ERROR, 1, "FIFO full or Blocked"); -+ -+ err = saa716x_i2c_hwinit(i2c, I2C_DEV); -+ if (err < 0) { -+ dprintk(SAA716x_ERROR, 1, "Error Reinit"); -+ err = -EIO; -+ goto exit; -+ } -+ } else { -+ break; -+ } -+ } -+ } -+ -+ /* Write to FIFO */ -+ SAA716x_EPWR(I2C_DEV, TX_FIFO, data); -+ -+ /* Check for data write */ -+ for (i = 0; i < 1000; i++) { -+ /* TODO! check for hotplug devices */ -+ reg = SAA716x_EPRD(I2C_DEV, I2C_STATUS); -+ if (reg & I2C_TRANSMIT_CLEAR) { -+ break; -+ } -+ } -+ i2c->stat_tx_done = reg; -+ -+ if (!(reg & I2C_TRANSMIT_CLEAR)) { -+ dprintk(SAA716x_ERROR, 1, "TXFIFO not empty after Timeout, tried %d loops!", i); -+ err = -EIO; -+ goto exit; -+ } -+ -+ return err; -+ -+exit: -+ dprintk(SAA716x_ERROR, 1, "I2C Send failed (Err=%d)", err); -+ return err; -+} -+ -+static int saa716x_i2c_recv(struct saa716x_i2c *i2c, u32 I2C_DEV, u32 *data) -+{ -+ struct saa716x_dev *saa716x = i2c->saa716x; -+ int i, err = 0; -+ u32 reg; -+ -+ /* Check FIFO status before RX */ -+ for (i = 0; i < 1000; i++) { -+ reg = SAA716x_EPRD(I2C_DEV, I2C_STATUS); -+ if (!(reg & SAA716x_I2C_RXBUSY)) { -+ break; -+ } -+ } -+ if (reg & SAA716x_I2C_RXBUSY) { -+ dprintk(SAA716x_INFO, 1, "FIFO empty"); -+ err = -EIO; -+ goto exit; -+ } -+ -+ /* Read from FIFO */ -+ *data = SAA716x_EPRD(I2C_DEV, RX_FIFO); -+ -+ return 0; -+exit: -+ dprintk(SAA716x_ERROR, 1, "Error Reading data, err=%d", err); -+ return err; -+} -+ -+static void saa716x_i2c_irq_start(struct saa716x_i2c *i2c, u32 I2C_DEV) -+{ -+ struct saa716x_dev *saa716x = i2c->saa716x; -+ -+ if (i2c->i2c_mode == SAA716x_I2C_MODE_POLLING) -+ return; -+ -+ i2c->i2c_op = 1; -+ SAA716x_EPWR(I2C_DEV, INT_CLR_STATUS, 0x1fff); -+} -+ -+static int saa716x_i2c_irq_wait(struct saa716x_i2c *i2c, u32 I2C_DEV) -+{ -+ struct saa716x_dev *saa716x = i2c->saa716x; -+ unsigned long timeout; -+ int err = 0; -+ -+ if (i2c->i2c_mode == SAA716x_I2C_MODE_POLLING) -+ return 0; -+ -+ timeout = HZ/100 + 1; /* 10ms */ -+ timeout = wait_event_interruptible_timeout(i2c->i2c_wq, i2c->i2c_op == 0, timeout); -+ if (timeout == -ERESTARTSYS || i2c->i2c_op) { -+ SAA716x_EPWR(I2C_DEV, INT_CLR_STATUS, 0x1fff); -+ if (timeout == -ERESTARTSYS) { -+ /* a signal arrived */ -+ err = -ERESTARTSYS; -+ } else { -+ dprintk(SAA716x_ERROR, 1, "timed out waiting for end of xfer!"); -+ err = -EIO; -+ } -+ } -+ return err; -+} -+ -+static int saa716x_i2c_write_msg(struct saa716x_i2c *i2c, u32 I2C_DEV, -+ u16 addr, u8 *buf, u16 len, u8 add_stop) -+{ -+ struct saa716x_dev *saa716x = i2c->saa716x; -+ u32 data; -+ int err; -+ int i; -+ int bytes; -+ -+ saa716x_i2c_irq_start(i2c, I2C_DEV); -+ -+ /* first write START with I2C address */ -+ data = I2C_START_BIT | (addr << 1); -+ dprintk(SAA716x_DEBUG, 1, "length=%d Addr:0x%02x", len, data); -+ err = saa716x_i2c_send(i2c, I2C_DEV, data); -+ if (err < 0) { -+ dprintk(SAA716x_ERROR, 1, "Address write failed"); -+ goto exit; -+ } -+ -+ bytes = i2c->block_size - 1; -+ -+ /* now write the data */ -+ while (len > 0) { -+ if (bytes == i2c->block_size) { -+ /* this is not the first round, so restart irq */ -+ saa716x_i2c_irq_start(i2c, I2C_DEV); -+ } -+ -+ if (bytes > len) -+ bytes = len; -+ -+ for (i = 0; i < bytes; i++) { -+ data = buf[i]; -+ dprintk(SAA716x_DEBUG, 0, " 0x%02x\n", i, data); -+ if (add_stop && i == (len - 1)) -+ data |= I2C_STOP_BIT; -+ err = saa716x_i2c_send(i2c, I2C_DEV, data); -+ if (err < 0) { -+ dprintk(SAA716x_ERROR, 1, "Data send failed"); -+ goto exit; -+ } -+ } -+ -+ err = saa716x_i2c_irq_wait(i2c, I2C_DEV); -+ if (err < 0) { -+ goto exit; -+ } -+ -+ len -= bytes; -+ buf += bytes; -+ bytes = i2c->block_size; -+ } -+ -+ return 0; -+ -+exit: -+ dprintk(SAA716x_ERROR, 1, "Error writing data, err=%d", err); -+ return err; -+} -+ -+static int saa716x_i2c_read_msg(struct saa716x_i2c *i2c, u32 I2C_DEV, -+ u16 addr, u8 *buf, u16 len, u8 add_stop) -+{ -+ struct saa716x_dev *saa716x = i2c->saa716x; -+ u32 data; -+ int err; -+ int i; -+ int bytes; -+ -+ saa716x_i2c_irq_start(i2c, I2C_DEV); -+ -+ /* first write START with I2C address */ -+ data = I2C_START_BIT | (addr << 1) | 1; -+ dprintk(SAA716x_DEBUG, 1, "length=%d Addr:0x%02x", len, data); -+ err = saa716x_i2c_send(i2c, I2C_DEV, data); -+ if (err < 0) { -+ dprintk(SAA716x_ERROR, 1, "Address write failed"); -+ goto exit; -+ } -+ -+ bytes = i2c->block_size - 1; -+ -+ /* now read the data */ -+ while (len > 0) { -+ if (bytes == i2c->block_size) { -+ /* this is not the first round, so restart irq */ -+ saa716x_i2c_irq_start(i2c, I2C_DEV); -+ } -+ -+ if (bytes > len) -+ bytes = len; -+ -+ for (i = 0; i < bytes; i++) { -+ data = 0x00; /* dummy write for reading */ -+ if (add_stop && i == (len - 1)) -+ data |= I2C_STOP_BIT; -+ err = saa716x_i2c_send(i2c, I2C_DEV, data); -+ if (err < 0) { -+ dprintk(SAA716x_ERROR, 1, "Data send failed"); -+ goto exit; -+ } -+ } -+ -+ err = saa716x_i2c_irq_wait(i2c, I2C_DEV); -+ if (err < 0) { -+ goto exit; -+ } -+ -+ for (i = 0; i < bytes; i++) { -+ err = saa716x_i2c_recv(i2c, I2C_DEV, &data); -+ if (err < 0) { -+ dprintk(SAA716x_ERROR, 1, "Data receive failed"); -+ goto exit; -+ } -+ dprintk(SAA716x_DEBUG, 0, " 0x%02x\n\n", i, data); -+ buf[i] = data; -+ } -+ -+ len -= bytes; -+ buf += bytes; -+ bytes = i2c->block_size; -+ } -+ -+ return 0; -+ -+exit: -+ dprintk(SAA716x_ERROR, 1, "Error reading data, err=%d", err); -+ return err; -+} -+ -+static int saa716x_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) -+{ -+ struct saa716x_i2c *i2c = i2c_get_adapdata(adapter); -+ struct saa716x_dev *saa716x = i2c->saa716x; -+ -+ u32 DEV = SAA716x_I2C_BUS(i2c->i2c_dev); -+ int i, j, err = 0; -+ int t; -+ -+ dprintk(SAA716x_DEBUG, 0, "\n"); -+ dprintk(SAA716x_DEBUG, 1, "Bus(%02x) I2C transfer", DEV); -+ mutex_lock(&i2c->i2c_lock); -+ -+ for (t = 0; t < 3; t++) { -+ for (i = 0; i < num; i++) { -+ if (msgs[i].flags & I2C_M_RD) -+ err = saa716x_i2c_read_msg(i2c, DEV, -+ msgs[i].addr, msgs[i].buf, msgs[i].len, -+ i == (num - 1)); -+ else -+ err = saa716x_i2c_write_msg(i2c, DEV, -+ msgs[i].addr, msgs[i].buf, msgs[i].len, -+ i == (num - 1)); -+ if (err < 0) { -+ err = -EIO; -+ goto retry; -+ } -+ } -+ break; -+retry: -+ dprintk(SAA716x_INFO, 1, "Error in Transfer, try %d", t); -+ for (i = 0; i < num; i++) { -+ dprintk(SAA716x_INFO, 1, "msg %d, addr = 0x%02x, len=%d, flags=0x%x", -+ i, msgs[i].addr, msgs[i].len, msgs[i].flags); -+ if (!(msgs[i].flags & I2C_M_RD)) { -+ for (j = 0; j < msgs[i].len; j++) { -+ dprintk(SAA716x_INFO, 1, " 0x%02x", -+ j, msgs[i].buf[j]); -+ } -+ } -+ } -+ err = saa716x_i2c_hwinit(i2c, DEV); -+ if (err < 0) { -+ dprintk(SAA716x_ERROR, 1, "Error Reinit"); -+ err = -EIO; -+ goto bail_out; -+ } -+ } -+ -+ mutex_unlock(&i2c->i2c_lock); -+ if (t < 3) -+ return num; -+ else -+ return -EIO; -+ -+bail_out: -+ dprintk(SAA716x_ERROR, 1, "ERROR: Bailing out <%d>", err); -+ mutex_unlock(&i2c->i2c_lock); -+ return err; -+} -+ -+static u32 saa716x_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -+} -+ -+static const struct i2c_algorithm saa716x_algo = { -+ .master_xfer = saa716x_i2c_xfer, -+ .functionality = saa716x_i2c_func, -+}; -+ -+struct saa716x_i2cvec { -+ u32 vector; -+ enum saa716x_edge edge; -+ irqreturn_t (*handler)(int irq, void *dev_id); -+}; -+ -+static const struct saa716x_i2cvec i2c_vec[] = { -+ { -+ .vector = I2CINT_0, -+ .edge = SAA716x_EDGE_RISING, -+ .handler = saa716x_i2c_irq -+ }, { -+ .vector = I2CINT_1, -+ .edge = SAA716x_EDGE_RISING, -+ .handler = saa716x_i2c_irq -+ } -+}; -+ -+int saa716x_i2c_init(struct saa716x_dev *saa716x) -+{ -+ struct pci_dev *pdev = saa716x->pdev; -+ struct saa716x_i2c *i2c = saa716x->i2c; -+ struct i2c_adapter *adapter = NULL; -+ -+ int i, err = 0; -+ -+ dprintk(SAA716x_DEBUG, 1, "Initializing SAA%02x I2C Core", -+ saa716x->pdev->device); -+ -+ for (i = 0; i < SAA716x_I2C_ADAPTERS; i++) { -+ -+ mutex_init(&i2c->i2c_lock); -+ -+ init_waitqueue_head(&i2c->i2c_wq); -+ i2c->i2c_op = 0; -+ -+ i2c->i2c_dev = i; -+ i2c->i2c_rate = saa716x->config->i2c_rate; -+ i2c->i2c_mode = saa716x->config->i2c_mode; -+ adapter = &i2c->i2c_adapter; -+ -+ if (i2c->i2c_mode == SAA716x_I2C_MODE_IRQ_BUFFERED) -+ i2c->block_size = 8; -+ else -+ i2c->block_size = 1; -+ -+ if (adapter != NULL) { -+ -+ i2c_set_adapdata(adapter, i2c); -+ -+ strcpy(adapter->name, SAA716x_I2C_ADAPTER(i)); -+ -+ adapter->owner = THIS_MODULE; -+ adapter->algo = &saa716x_algo; -+ adapter->algo_data = NULL; -+ adapter->timeout = 500; /* FIXME ! */ -+ adapter->retries = 3; /* FIXME ! */ -+ adapter->dev.parent = &pdev->dev; -+ -+ dprintk(SAA716x_DEBUG, 1, "Initializing adapter (%d) %s", -+ i, -+ adapter->name); -+ -+ err = i2c_add_adapter(adapter); -+ if (err < 0) { -+ dprintk(SAA716x_ERROR, 1, "Adapter (%d) %s init failed", i, adapter->name); -+ goto exit; -+ } -+ -+ i2c->saa716x = saa716x; -+ saa716x_i2c_hwinit(i2c, SAA716x_I2C_BUS(i)); -+ } -+ i2c++; -+ } -+ -+ if (saa716x->config->i2c_mode >= SAA716x_I2C_MODE_IRQ) { -+ SAA716x_EPWR(MSI, MSI_INT_ENA_SET_H, MSI_INT_I2CINT_0); -+ SAA716x_EPWR(MSI, MSI_INT_ENA_SET_H, MSI_INT_I2CINT_1); -+ } -+ -+ dprintk(SAA716x_DEBUG, 1, "SAA%02x I2C Core succesfully initialized", -+ saa716x->pdev->device); -+ -+ return 0; -+exit: -+ /* delete already added i2c adapters */ -+ while (i > 0) { -+ i2c--; -+ adapter = &i2c->i2c_adapter; -+ i2c_del_adapter(adapter); -+ i--; -+ } -+ return err; -+} -+EXPORT_SYMBOL_GPL(saa716x_i2c_init); -+ -+int saa716x_i2c_exit(struct saa716x_dev *saa716x) -+{ -+ struct saa716x_i2c *i2c = saa716x->i2c; -+ struct i2c_adapter *adapter = NULL; -+ int i; -+ -+ dprintk(SAA716x_DEBUG, 1, "Removing SAA%02x I2C Core", saa716x->pdev->device); -+ -+ for (i = 0; i < SAA716x_I2C_ADAPTERS; i++) { -+ -+ adapter = &i2c->i2c_adapter; -+#if 0 -+ saa716x_remove_irqvector(saa716x, i2c_vec[i].vector); -+#endif -+ saa716x_i2c_hwdeinit(i2c, SAA716x_I2C_BUS(i)); -+ dprintk(SAA716x_DEBUG, 1, "Removing adapter (%d) %s", i, adapter->name); -+ -+ i2c_del_adapter(adapter); -+ i2c++; -+ } -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_i2c_exit); -diff --git a/drivers/media/pci/saa716x/saa716x_i2c.h b/drivers/media/pci/saa716x/saa716x_i2c.h -new file mode 100644 -index 0000000..da767ac ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_i2c.h -@@ -0,0 +1,52 @@ -+#ifndef __SAA716x_I2C_H -+#define __SAA716x_I2C_H -+ -+#define SAA716x_I2C_ADAPTERS 2 -+ -+#define SAA716x_I2C_ADAPTER(__dev) (( \ -+ (__dev == 1) ? \ -+ "SAA716x I2C Core 1" : \ -+ "SAA716x I2C Core 0")) -+ -+#define SAA716x_I2C_BUS(__x) ((__x == 1) ? 0x0000c000 : 0x0000b000) -+ -+#define SAA716x_I2C_BUS_A 0x01 -+#define SAA716x_I2C_BUS_B 0x00 -+ -+struct saa716x_dev; -+ -+enum saa716x_i2c_rate { -+ SAA716x_I2C_RATE_400 = 1, -+ SAA716x_I2C_RATE_100, -+}; -+ -+enum saa716x_i2c_mode { -+ SAA716x_I2C_MODE_POLLING = 0, -+ SAA716x_I2C_MODE_IRQ, -+ SAA716x_I2C_MODE_IRQ_BUFFERED -+}; -+ -+struct saa716x_i2c { -+ struct i2c_adapter i2c_adapter; -+ struct mutex i2c_lock; -+ struct saa716x_dev *saa716x; -+ u8 i2c_dev; -+ -+ enum saa716x_i2c_rate i2c_rate; /* run time */ -+ enum saa716x_i2c_mode i2c_mode; -+ u32 block_size; /* block size for buffered -+ mode, 1 otherwise */ -+ u32 i2c_stat; -+ -+ u32 stat_tx_prior; -+ u32 stat_tx_done; -+ wait_queue_head_t i2c_wq; -+ int i2c_op; -+}; -+ -+extern int saa716x_i2c_init(struct saa716x_dev *saa716x); -+extern int saa716x_i2c_exit(struct saa716x_dev *saa716x); -+extern void saa716x_i2cint_disable(struct saa716x_dev *saa716x); -+extern int saa716x_i2c_irqevent(struct saa716x_dev *saa716x, u8 bus); -+ -+#endif /* __SAA716x_I2C_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_i2c_reg.h b/drivers/media/pci/saa716x/saa716x_i2c_reg.h -new file mode 100644 -index 0000000..8fa992c ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_i2c_reg.h -@@ -0,0 +1,145 @@ -+#ifndef __SAA716x_I2C_REG_H -+#define __SAA716x_I2C_REG_H -+ -+/* -------------- I2C Registers -------------- */ -+ -+#define RX_FIFO 0x000 -+#define I2C_RX_BYTE (0x000000ff << 0) -+ -+#define TX_FIFO 0x000 -+#define I2C_STOP_BIT (0x00000001 << 9) -+#define I2C_START_BIT (0x00000001 << 8) -+#define I2C_TX_BYTE (0x000000ff << 0) -+ -+#define I2C_STATUS 0x008 -+#define I2C_TRANSMIT (0x00000001 << 11) -+#define I2C_RECEIVE (0x00000001 << 10) -+#define I2C_TRANSMIT_S_PROG (0x00000001 << 9) -+#define I2C_TRANSMIT_S_CLEAR (0x00000001 << 8) -+#define I2C_TRANSMIT_PROG (0x00000001 << 7) -+#define I2C_TRANSMIT_CLEAR (0x00000001 << 6) -+#define I2C_RECEIVE_PROG (0x00000001 << 5) -+#define I2C_RECEIVE_CLEAR (0x00000001 << 4) -+#define I2C_SDA_LINE (0x00000001 << 3) -+#define I2C_SCL_LINE (0x00000001 << 2) -+#define I2C_START_STOP_FLAG (0x00000001 << 1) -+#define I2C_MODE_STATUS (0x00000001 << 0) -+ -+#define I2C_CONTROL 0x00c -+#define I2C_SCL_CONTROL (0x00000001 << 7) -+#define I2C_SDA_CONTROL (0x00000001 << 6) -+#define I2C_RECEIVE_PROTECT (0x00000001 << 5) -+#define I2C_RECEIVE_PRO_READ (0x00000001 << 4) -+#define I2C_TRANS_SELF_CLEAR (0x00000001 << 3) -+#define I2C_TRANS_S_SELF_CLEAR (0x00000001 << 2) -+#define I2C_SLAVE_ADDR_10BIT (0x00000001 << 1) -+#define I2C_RESET (0x00000001 << 0) -+ -+#define I2C_CLOCK_DIVISOR_HIGH 0x010 -+#define I2C_CLOCK_HIGH (0x0000ffff << 0) -+ -+#define I2C_CLOCK_DIVISOR_LOW 0x014 -+#define I2C_CLOCK_LOW (0x0000ffff << 0) -+ -+#define I2C_RX_LEVEL 0x01c -+#define I2C_RECEIVE_RANGE (0x0000007f << 0) -+ -+#define I2C_TX_LEVEL 0x020 -+#define I2C_TRANSMIT_RANGE (0x0000007f << 0) -+ -+#define I2C_SDA_HOLD 0x028 -+#define I2C_HOLD_TIME (0x0000007f << 0) -+ -+#define MODULE_CONF 0xfd4 -+#define INT_CLR_ENABLE 0xfd8 -+#define I2C_CLR_ENABLE_STFNF (0x00000001 << 12) -+#define I2C_CLR_ENABLE_MTFNF (0x00000001 << 11) -+#define I2C_CLR_ENABLE_RFDA (0x00000001 << 10) -+#define I2C_CLR_ENABLE_RFF (0x00000001 << 9) -+#define I2C_CLR_ENABLE_STDR (0x00000001 << 8) -+#define I2C_CLR_ENABLE_MTDR (0x00000001 << 7) -+#define I2C_CLR_ENABLE_IBE (0x00000001 << 6) -+#define I2C_CLR_ENABLE_MSMC (0x00000001 << 5) -+#define I2C_CLR_ENABLE_SRSD (0x00000001 << 4) -+#define I2C_CLR_ENABLE_STSD (0x00000001 << 3) -+#define I2C_CLR_ENABLE_MTNA (0x00000001 << 2) -+#define I2C_CLR_ENABLE_MAF (0x00000001 << 1) -+#define I2C_CLR_ENABLE_MTD (0x00000001 << 0) -+ -+#define INT_SET_ENABLE 0xfdc -+#define I2C_SET_ENABLE_STFNF (0x00000001 << 12) -+#define I2C_SET_ENABLE_MTFNF (0x00000001 << 11) -+#define I2C_SET_ENABLE_RFDA (0x00000001 << 10) -+#define I2C_SET_ENABLE_RFF (0x00000001 << 9) -+#define I2C_SET_ENABLE_STDR (0x00000001 << 8) -+#define I2C_SET_ENABLE_MTDR (0x00000001 << 7) -+#define I2C_SET_ENABLE_IBE (0x00000001 << 6) -+#define I2C_SET_ENABLE_MSMC (0x00000001 << 5) -+#define I2C_SET_ENABLE_SRSD (0x00000001 << 4) -+#define I2C_SET_ENABLE_STSD (0x00000001 << 3) -+#define I2C_SET_ENABLE_MTNA (0x00000001 << 2) -+#define I2C_SET_ENABLE_MAF (0x00000001 << 1) -+#define I2C_SET_ENABLE_MTD (0x00000001 << 0) -+ -+#define INT_STATUS 0xfe0 -+#define I2C_INTERRUPT_STFNF (0x00000001 << 12) -+#define I2C_INTERRUPT_MTFNF (0x00000001 << 11) -+#define I2C_INTERRUPT_RFDA (0x00000001 << 10) -+#define I2C_INTERRUPTE_RFF (0x00000001 << 9) -+#define I2C_SLAVE_INTERRUPT_STDR (0x00000001 << 8) -+#define I2C_MASTER_INTERRUPT_MTDR (0x00000001 << 7) -+#define I2C_ERROR_IBE (0x00000001 << 6) -+#define I2C_MODE_CHANGE_INTER_MSMC (0x00000001 << 5) -+#define I2C_SLAVE_RECEIVE_INTER_SRSD (0x00000001 << 4) -+#define I2C_SLAVE_TRANSMIT_INTER_STSD (0x00000001 << 3) -+#define I2C_ACK_INTER_MTNA (0x00000001 << 2) -+#define I2C_FAILURE_INTER_MAF (0x00000001 << 1) -+#define I2C_INTERRUPT_MTD (0x00000001 << 0) -+ -+#define INT_ENABLE 0xfe4 -+#define I2C_ENABLE_STFNF (0x00000001 << 12) -+#define I2C_ENABLE_MTFNF (0x00000001 << 11) -+#define I2C_ENABLE_RFDA (0x00000001 << 10) -+#define I2C_ENABLE_RFF (0x00000001 << 9) -+#define I2C_ENABLE_STDR (0x00000001 << 8) -+#define I2C_ENABLE_MTDR (0x00000001 << 7) -+#define I2C_ENABLE_IBE (0x00000001 << 6) -+#define I2C_ENABLE_MSMC (0x00000001 << 5) -+#define I2C_ENABLE_SRSD (0x00000001 << 4) -+#define I2C_ENABLE_STSD (0x00000001 << 3) -+#define I2C_ENABLE_MTNA (0x00000001 << 2) -+#define I2C_ENABLE_MAF (0x00000001 << 1) -+#define I2C_ENABLE_MTD (0x00000001 << 0) -+ -+#define INT_CLR_STATUS 0xfe8 -+#define I2C_CLR_STATUS_STFNF (0x00000001 << 12) -+#define I2C_CLR_STATUS_MTFNF (0x00000001 << 11) -+#define I2C_CLR_STATUS_RFDA (0x00000001 << 10) -+#define I2C_CLR_STATUS_RFF (0x00000001 << 9) -+#define I2C_CLR_STATUS_STDR (0x00000001 << 8) -+#define I2C_CLR_STATUS_MTDR (0x00000001 << 7) -+#define I2C_CLR_STATUS_IBE (0x00000001 << 6) -+#define I2C_CLR_STATUS_MSMC (0x00000001 << 5) -+#define I2C_CLR_STATUS_SRSD (0x00000001 << 4) -+#define I2C_CLR_STATUS_STSD (0x00000001 << 3) -+#define I2C_CLR_STATUS_MTNA (0x00000001 << 2) -+#define I2C_CLR_STATUS_MAF (0x00000001 << 1) -+#define I2C_CLR_STATIS_MTD (0x00000001 << 0) -+ -+#define INT_SET_STATUS 0xfec -+#define I2C_SET_STATUS_STFNF (0x00000001 << 12) -+#define I2C_SET_STATUS_MTFNF (0x00000001 << 11) -+#define I2C_SET_STATUS_RFDA (0x00000001 << 10) -+#define I2C_SET_STATUS_RFF (0x00000001 << 9) -+#define I2C_SET_STATUS_STDR (0x00000001 << 8) -+#define I2C_SET_STATUS_MTDR (0x00000001 << 7) -+#define I2C_SET_STATUS_IBE (0x00000001 << 6) -+#define I2C_SET_STATUS_MSMC (0x00000001 << 5) -+#define I2C_SET_STATUS_SRSD (0x00000001 << 4) -+#define I2C_SET_STATUS_STSD (0x00000001 << 3) -+#define I2C_SET_STATUS_MTNA (0x00000001 << 2) -+#define I2C_SET_STATUS_MAF (0x00000001 << 1) -+#define I2C_SET_STATIS_MTD (0x00000001 << 0) -+ -+ -+#endif /* __SAA716x_I2C_REG_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_mod.h b/drivers/media/pci/saa716x/saa716x_mod.h -new file mode 100644 -index 0000000..a059ca4b ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_mod.h -@@ -0,0 +1,50 @@ -+#ifndef __SAA716x_MOD_H -+#define __SAA716x_MOD_H -+ -+/* BAR = 17 bits */ -+/* -+ VI0 0x00000000 -+ VI1 0x00001000 -+ FGPI0 0x00002000 -+ FGPI1 0x00003000 -+ FGPI2 0x00004000 -+ FGPI3 0x00005000 -+ AI0 0x00006000 -+ AI1 0x00007000 -+ BAM 0x00008000 -+ MMU 0x00009000 -+ MSI 0x0000a000 -+ I2C_B 0x0000b000 -+ I2C_A 0x0000c000 -+ SPI 0x0000d000 -+ GPIO 0x0000e000 -+ PHI_0 0x0000f000 -+ CGU 0x00013000 -+ DCS 0x00014000 -+ GREG 0x00012000 -+ -+ PHI_1 0x00020000 -+*/ -+ -+#define VI0 0x00000000 -+#define VI1 0x00001000 -+#define FGPI0 0x00002000 -+#define FGPI1 0x00003000 -+#define FGPI2 0x00004000 -+#define FGPI3 0x00005000 -+#define AI0 0x00006000 -+#define AI1 0x00007000 -+#define BAM 0x00008000 -+#define MMU 0x00009000 -+#define MSI 0x0000a000 -+#define I2C_B 0x0000b000 -+#define I2C_A 0x0000c000 -+#define SPI 0x0000d000 -+#define GPIO 0x0000e000 -+#define PHI_0 0x0000f000 -+#define GREG 0x00012000 -+#define CGU 0x00013000 -+#define DCS 0x00014000 -+#define PHI_1 0x00020000 -+ -+#endif /* __SAA716x_MOD_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_msi.c b/drivers/media/pci/saa716x/saa716x_msi.c -new file mode 100644 -index 0000000..b0f05a2 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_msi.c -@@ -0,0 +1,479 @@ -+#include -+ -+#include -+#include -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_msi_reg.h" -+#include "saa716x_msi.h" -+#include "saa716x_spi.h" -+ -+#include "saa716x_priv.h" -+ -+#define SAA716x_MSI_VECTORS 50 -+ -+static const char *vector_name[] = { -+ "TAGACK_VI0_0", -+ "TAGACK_VI0_1", -+ "TAGACK_VI0_2", -+ "TAGACK_VI1_0", -+ "TAGACK_VI1_1", -+ "TAGACK_VI1_2", -+ "TAGACK_FGPI_0", -+ "TAGACK_FGPI_1", -+ "TAGACK_FGPI_2", -+ "TAGACK_FGPI_3", -+ "TAGACK_AI_0", -+ "TAGACK_AI_1", -+ "OVRFLW_VI0_0", -+ "OVRFLW_VI0_1", -+ "OVRFLW_VI0_2", -+ "OVRFLW_VI1_0", -+ "OVRFLW_VI1_1", -+ "OVRFLW_VI1_2", -+ "OVRFLW_FGPI_O", -+ "OVRFLW_FGPI_1", -+ "OVRFLW_FGPI_2", -+ "OVRFLW_FGPI_3", -+ "OVRFLW_AI_0", -+ "OVRFLW_AI_1", -+ "AVINT_VI0", -+ "AVINT_VI1", -+ "AVINT_FGPI_0", -+ "AVINT_FGPI_1", -+ "AVINT_FGPI_2", -+ "AVINT_FGPI_3", -+ "AVINT_AI_0", -+ "AVINT_AI_1", -+ "UNMAPD_TC_INT", -+ "EXTINT_0", -+ "EXTINT_1", -+ "EXTINT_2", -+ "EXTINT_3", -+ "EXTINT_4", -+ "EXTINT_5", -+ "EXTINT_6", -+ "EXTINT_7", -+ "EXTINT_8", -+ "EXTINT_9", -+ "EXTINT_10", -+ "EXTINT_11", -+ "EXTINT_12", -+ "EXTINT_13", -+ "EXTINT_14", -+ "EXTINT_15", -+ "I2CINT_0", -+ "I2CINT_1" -+}; -+ -+static u32 MSI_CONFIG_REG[51] = { -+ MSI_CONFIG0, -+ MSI_CONFIG1, -+ MSI_CONFIG2, -+ MSI_CONFIG3, -+ MSI_CONFIG4, -+ MSI_CONFIG5, -+ MSI_CONFIG6, -+ MSI_CONFIG7, -+ MSI_CONFIG8, -+ MSI_CONFIG9, -+ MSI_CONFIG10, -+ MSI_CONFIG11, -+ MSI_CONFIG12, -+ MSI_CONFIG13, -+ MSI_CONFIG14, -+ MSI_CONFIG15, -+ MSI_CONFIG16, -+ MSI_CONFIG17, -+ MSI_CONFIG18, -+ MSI_CONFIG19, -+ MSI_CONFIG20, -+ MSI_CONFIG21, -+ MSI_CONFIG22, -+ MSI_CONFIG23, -+ MSI_CONFIG24, -+ MSI_CONFIG25, -+ MSI_CONFIG26, -+ MSI_CONFIG27, -+ MSI_CONFIG28, -+ MSI_CONFIG29, -+ MSI_CONFIG30, -+ MSI_CONFIG31, -+ MSI_CONFIG32, -+ MSI_CONFIG33, -+ MSI_CONFIG34, -+ MSI_CONFIG35, -+ MSI_CONFIG36, -+ MSI_CONFIG37, -+ MSI_CONFIG38, -+ MSI_CONFIG39, -+ MSI_CONFIG40, -+ MSI_CONFIG41, -+ MSI_CONFIG42, -+ MSI_CONFIG43, -+ MSI_CONFIG44, -+ MSI_CONFIG45, -+ MSI_CONFIG46, -+ MSI_CONFIG47, -+ MSI_CONFIG48, -+ MSI_CONFIG49, -+ MSI_CONFIG50 -+}; -+ -+int saa716x_msi_event(struct saa716x_dev *saa716x, u32 stat_l, u32 stat_h) -+{ -+ dprintk(SAA716x_DEBUG, 0, "%s: MSI event ", __func__); -+ -+ if (stat_l & MSI_INT_TAGACK_VI0_0) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[0]); -+ -+ if (stat_l & MSI_INT_TAGACK_VI0_1) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[1]); -+ -+ if (stat_l & MSI_INT_TAGACK_VI0_2) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[2]); -+ -+ if (stat_l & MSI_INT_TAGACK_VI1_0) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[3]); -+ -+ if (stat_l & MSI_INT_TAGACK_VI1_1) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[4]); -+ -+ if (stat_l & MSI_INT_TAGACK_VI1_2) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[5]); -+ -+ if (stat_l & MSI_INT_TAGACK_FGPI_0) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[6]); -+ -+ if (stat_l & MSI_INT_TAGACK_FGPI_1) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[7]); -+ -+ if (stat_l & MSI_INT_TAGACK_FGPI_2) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[8]); -+ -+ if (stat_l & MSI_INT_TAGACK_FGPI_3) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[9]); -+ -+ if (stat_l & MSI_INT_TAGACK_AI_0) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[10]); -+ -+ if (stat_l & MSI_INT_TAGACK_AI_1) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[11]); -+ -+ if (stat_l & MSI_INT_OVRFLW_VI0_0) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[12]); -+ -+ if (stat_l & MSI_INT_OVRFLW_VI0_1) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[13]); -+ -+ if (stat_l & MSI_INT_OVRFLW_VI0_2) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[14]); -+ -+ if (stat_l & MSI_INT_OVRFLW_VI1_0) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[15]); -+ -+ if (stat_l & MSI_INT_OVRFLW_VI1_1) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[16]); -+ -+ if (stat_l & MSI_INT_OVRFLW_VI1_2) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[17]); -+ -+ if (stat_l & MSI_INT_OVRFLW_FGPI_0) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[18]); -+ -+ if (stat_l & MSI_INT_OVRFLW_FGPI_1) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[19]); -+ -+ if (stat_l & MSI_INT_OVRFLW_FGPI_2) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[20]); -+ -+ if (stat_l & MSI_INT_OVRFLW_FGPI_3) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[21]); -+ -+ if (stat_l & MSI_INT_OVRFLW_AI_0) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[22]); -+ -+ if (stat_l & MSI_INT_OVRFLW_AI_1) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[23]); -+ -+ if (stat_l & MSI_INT_AVINT_VI0) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[24]); -+ -+ if (stat_l & MSI_INT_AVINT_VI1) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[25]); -+ -+ if (stat_l & MSI_INT_AVINT_FGPI_0) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[26]); -+ -+ if (stat_l & MSI_INT_AVINT_FGPI_1) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[27]); -+ -+ if (stat_l & MSI_INT_AVINT_FGPI_2) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[28]); -+ -+ if (stat_l & MSI_INT_AVINT_FGPI_3) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[29]); -+ -+ if (stat_l & MSI_INT_AVINT_AI_0) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[30]); -+ -+ if (stat_l & MSI_INT_AVINT_AI_1) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[31]); -+ -+ if (stat_h & MSI_INT_UNMAPD_TC_INT) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[32]); -+ -+ if (stat_h & MSI_INT_EXTINT_0) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[33]); -+ -+ if (stat_h & MSI_INT_EXTINT_1) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[34]); -+ -+ if (stat_h & MSI_INT_EXTINT_2) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[35]); -+ -+ if (stat_h & MSI_INT_EXTINT_3) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[36]); -+ -+ if (stat_h & MSI_INT_EXTINT_4) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[37]); -+ -+ if (stat_h & MSI_INT_EXTINT_5) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[38]); -+ -+ if (stat_h & MSI_INT_EXTINT_6) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[39]); -+ -+ if (stat_h & MSI_INT_EXTINT_7) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[40]); -+ -+ if (stat_h & MSI_INT_EXTINT_8) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[41]); -+ -+ if (stat_h & MSI_INT_EXTINT_9) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[42]); -+ -+ if (stat_h & MSI_INT_EXTINT_10) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[43]); -+ -+ if (stat_h & MSI_INT_EXTINT_11) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[44]); -+ -+ if (stat_h & MSI_INT_EXTINT_12) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[45]); -+ -+ if (stat_h & MSI_INT_EXTINT_13) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[46]); -+ -+ if (stat_h & MSI_INT_EXTINT_14) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[47]); -+ -+ if (stat_h & MSI_INT_EXTINT_15) -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[48]); -+ -+ if (stat_h & MSI_INT_I2CINT_0) { -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[49]); -+ saa716x_i2c_irqevent(saa716x, 0); -+ } -+ -+ if (stat_h & MSI_INT_I2CINT_1) { -+ dprintk(SAA716x_DEBUG, 0, "<%s> ", vector_name[50]); -+ saa716x_i2c_irqevent(saa716x, 1); -+ } -+ -+ dprintk(SAA716x_DEBUG, 0, "\n"); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_msi_event); -+ -+int saa716x_msi_init(struct saa716x_dev *saa716x) -+{ -+ u32 ena_l, ena_h, sta_l, sta_h, mid; -+ int i; -+ -+ dprintk(SAA716x_DEBUG, 1, "Initializing MSI .."); -+ saa716x->handlers = 0; -+ -+ /* get module id & version */ -+ mid = SAA716x_EPRD(MSI, MSI_MODULE_ID); -+ if (mid != 0x30100) -+ dprintk(SAA716x_ERROR, 1, "MSI Id<%04x> is not supported", mid); -+ -+ /* let HW take care of MSI race */ -+ SAA716x_EPWR(MSI, MSI_DELAY_TIMER, 0x0); -+ -+ /* INTA Polarity: Active High */ -+ SAA716x_EPWR(MSI, MSI_INTA_POLARITY, MSI_INTA_POLARITY_HIGH); -+ -+ /* -+ * IRQ Edge Rising: 25:24 = 0x01 -+ * Traffic Class: 18:16 = 0x00 -+ * MSI ID: 4:0 = 0x00 -+ */ -+ for (i = 0; i < SAA716x_MSI_VECTORS; i++) -+ SAA716x_EPWR(MSI, MSI_CONFIG_REG[i], MSI_INT_POL_EDGE_RISE); -+ -+ /* get Status */ -+ ena_l = SAA716x_EPRD(MSI, MSI_INT_ENA_L); -+ ena_h = SAA716x_EPRD(MSI, MSI_INT_ENA_H); -+ sta_l = SAA716x_EPRD(MSI, MSI_INT_STATUS_L); -+ sta_h = SAA716x_EPRD(MSI, MSI_INT_STATUS_H); -+ -+ /* disable and clear enabled and asserted IRQ's */ -+ if (sta_l) -+ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_L, sta_l); -+ -+ if (sta_h) -+ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_H, sta_h); -+ -+ if (ena_l) -+ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_L, ena_l); -+ -+ if (ena_h) -+ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_H, ena_h); -+ -+ msleep(5); -+ -+ /* Check IRQ's really disabled */ -+ ena_l = SAA716x_EPRD(MSI, MSI_INT_ENA_L); -+ ena_h = SAA716x_EPRD(MSI, MSI_INT_ENA_H); -+ sta_l = SAA716x_EPRD(MSI, MSI_INT_STATUS_L); -+ sta_h = SAA716x_EPRD(MSI, MSI_INT_STATUS_H); -+ -+ if ((ena_l == 0) && (ena_h == 0) && (sta_l == 0) && (sta_h == 0)) { -+ dprintk(SAA716x_DEBUG, 1, "Interrupts ena_l <%02x> ena_h <%02x> sta_l <%02x> sta_h <%02x>", -+ ena_l, ena_h, sta_l, sta_h); -+ -+ return 0; -+ } else { -+ dprintk(SAA716x_DEBUG, 1, "I/O error"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_msi_init); -+ -+void saa716x_msiint_disable(struct saa716x_dev *saa716x) -+{ -+ dprintk(SAA716x_DEBUG, 1, "Disabling Interrupts ..."); -+ -+ SAA716x_EPWR(MSI, MSI_INT_ENA_L, 0x0); -+ SAA716x_EPWR(MSI, MSI_INT_ENA_H, 0x0); -+ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_L, 0xffffffff); -+ SAA716x_EPWR(MSI, MSI_INT_STATUS_CLR_L, 0x0000ffff); -+} -+EXPORT_SYMBOL_GPL(saa716x_msiint_disable); -+ -+ -+/* Map the given vector Id to the hardware bitmask. */ -+static void saa716x_map_vector(struct saa716x_dev *saa716x, int vector, u32 *mask_l, u32 *mask_h) -+{ -+ u32 tmp = 1; -+ -+ if (vector < 32) { -+ /* Bits 0 - 31 */ -+ tmp <<= vector; -+ *mask_l = tmp; -+ *mask_h = 0; -+ } else { -+ /* Bits 32 - 48 */ -+ tmp <<= vector - 32; -+ *mask_l = 0; -+ *mask_h = tmp; -+ } -+} -+ -+int saa716x_add_irqvector(struct saa716x_dev *saa716x, -+ int vector, -+ enum saa716x_edge edge, -+ irqreturn_t (*handler)(int irq, void *dev_id), -+ char *desc) -+{ -+ struct saa716x_msix_entry *msix_handler = NULL; -+ -+ u32 config, mask_l, mask_h, ena_l, ena_h; -+ -+ BUG_ON(saa716x == NULL); -+ BUG_ON(vector > SAA716x_MSI_VECTORS); -+ dprintk(SAA716x_DEBUG, 1, "Adding Vector %d <%s>", vector, vector_name[vector]); -+ -+ if ((vector > 32) && (vector < 49)) { -+ config = SAA716x_EPRD(MSI, MSI_CONFIG_REG[vector]); -+ config &= 0xfcffffff; /* clear polarity */ -+ -+ switch (edge) { -+ default: -+ case SAA716x_EDGE_RISING: -+ SAA716x_EPWR(MSI, MSI_CONFIG_REG[vector], config | 0x01000000); -+ break; -+ -+ case SAA716x_EDGE_FALLING: -+ SAA716x_EPWR(MSI, MSI_CONFIG_REG[vector], config | 0x02000000); -+ break; -+ -+ case SAA716x_EDGE_ANY: -+ SAA716x_EPWR(MSI, MSI_CONFIG_REG[vector], config | 0x03000000); -+ break; -+ } -+ } -+ -+ saa716x_map_vector(saa716x, vector, &mask_l, &mask_h); -+ -+ /* add callback */ -+ msix_handler = &saa716x->saa716x_msix_handler[saa716x->handlers]; -+ strcpy(msix_handler->desc, desc); -+ msix_handler->vector = vector; -+ msix_handler->handler = handler; -+ saa716x->handlers++; -+ -+ SAA716x_EPWR(MSI, MSI_INT_ENA_SET_L, mask_l); -+ SAA716x_EPWR(MSI, MSI_INT_ENA_SET_H, mask_h); -+ -+ ena_l = SAA716x_EPRD(MSI, MSI_INT_ENA_L); -+ ena_h = SAA716x_EPRD(MSI, MSI_INT_ENA_H); -+ dprintk(SAA716x_DEBUG, 1, "Interrupts ena_l <%02x> ena_h <%02x>", ena_l, ena_h); -+ -+ return 0; -+} -+ -+int saa716x_remove_irqvector(struct saa716x_dev *saa716x, int vector) -+{ -+ struct saa716x_msix_entry *msix_handler; -+ int i; -+ u32 mask_l, mask_h; -+ -+ msix_handler = &saa716x->saa716x_msix_handler[saa716x->handlers]; -+ BUG_ON(msix_handler == NULL); -+ dprintk(SAA716x_DEBUG, 1, "Removing Vector %d <%s>", vector, vector_name[vector]); -+ -+ /* loop through the registered handlers */ -+ for (i = 0; i < saa716x->handlers; i++) { -+ -+ /* we found our vector */ -+ if (msix_handler->vector == vector) { -+ BUG_ON(msix_handler->handler == NULL); /* no handler yet */ -+ dprintk(SAA716x_DEBUG, 1, "Vector %d <%s> removed", -+ msix_handler->vector, -+ msix_handler->desc); -+ -+ /* check whether it is already released */ -+ if (msix_handler->handler) { -+ msix_handler->vector = 0; -+ msix_handler->handler = NULL; -+ saa716x->handlers--; -+ } -+ } -+ } -+ -+ saa716x_map_vector(saa716x, vector, &mask_l, &mask_h); -+ -+ /* disable vector */ -+ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_L, mask_l); -+ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_H, mask_h); -+ -+ return 0; -+} -diff --git a/drivers/media/pci/saa716x/saa716x_msi.h b/drivers/media/pci/saa716x/saa716x_msi.h -new file mode 100644 -index 0000000..8eb72d76 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_msi.h -@@ -0,0 +1,87 @@ -+#ifndef __SAA716x_MSI_H -+#define __SAA716x_MSI_H -+ -+#define TAGACK_VI0_0 0x000 -+#define TAGACK_VI0_1 0x001 -+#define TAGACK_VI0_2 0x002 -+#define TAGACK_VI1_0 0x003 -+#define TAGACK_VI1_1 0x004 -+#define TAGACK_VI1_2 0x005 -+#define TAGACK_FGPI_0 0x006 -+#define TAGACK_FGPI_1 0x007 -+#define TAGACK_FGPI_2 0x008 -+#define TAGACK_FGPI_3 0x009 -+#define TAGACK_AI_0 0x00a -+#define TAGACK_AI_1 0x00b -+#define OVRFLW_VI0_0 0x00c -+#define OVRFLW_VI0_1 0x00d -+#define OVRFLW_VI0_2 0x00e -+#define OVRFLW_VI1_0 0x00f -+#define OVRFLW_VI1_1 0x010 -+#define OVRFLW_VI1_2 0x011 -+#define OVRFLW_FGPI_O 0x012 -+#define OVRFLW_FGPI_1 0x013 -+#define OVRFLW_FGPI_2 0x014 -+#define OVRFLW_FGPI_3 0x015 -+#define OVRFLW_AI_0 0x016 -+#define OVRFLW_AI_1 0x017 -+#define AVINT_VI0 0x018 -+#define AVINT_VI1 0x019 -+#define AVINT_FGPI_0 0x01a -+#define AVINT_FGPI_1 0x01b -+#define AVINT_FGPI_2 0x01c -+#define AVINT_FGPI_3 0x01d -+#define AVINT_AI_0 0x01e -+#define AVINT_AI_1 0x01f -+#define UNMAPD_TC_INT 0x020 -+#define EXTINT_0 0x021 -+#define EXTINT_1 0x022 -+#define EXTINT_2 0x023 -+#define EXTINT_3 0x024 -+#define EXTINT_4 0x025 -+#define EXTINT_5 0x026 -+#define EXTINT_6 0x027 -+#define EXTINT_7 0x028 -+#define EXTINT_8 0x029 -+#define EXTINT_9 0x02a -+#define EXTINT_10 0x02b -+#define EXTINT_11 0x02c -+#define EXTINT_12 0x02d -+#define EXTINT_13 0x02e -+#define EXTINT_14 0x02f -+#define EXTINT_15 0x030 -+#define I2CINT_0 0x031 -+#define I2CINT_1 0x032 -+ -+#define SAA716x_TC0 0x000 -+#define SAA716x_TC1 0x001 -+#define SAA716x_TC2 0x002 -+#define SAA716x_TC3 0x003 -+#define SAA716x_TC4 0x004 -+#define SAA716x_TC5 0x005 -+#define SAA716x_TC6 0x006 -+#define SAA716x_TC7 0x007 -+ -+ -+enum saa716x_edge { -+ SAA716x_EDGE_RISING = 1, -+ SAA716x_EDGE_FALLING = 2, -+ SAA716x_EDGE_ANY = 3 -+}; -+ -+struct saa716x_dev; -+ -+extern int saa716x_msi_event(struct saa716x_dev *saa716x, u32 stat_l, u32 stat_h); -+ -+extern int saa716x_msi_init(struct saa716x_dev *saa716x); -+extern void saa716x_msiint_disable(struct saa716x_dev *saa716x); -+ -+extern int saa716x_add_irqvector(struct saa716x_dev *saa716x, -+ int vector, -+ enum saa716x_edge edge, -+ irqreturn_t (*handler)(int irq, void *dev_id), -+ char *desc); -+ -+extern int saa716x_remove_irqvector(struct saa716x_dev *saa716x, int vector); -+ -+#endif /* __SAA716x_MSI_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_msi_reg.h b/drivers/media/pci/saa716x/saa716x_msi_reg.h -new file mode 100644 -index 0000000..d9a12c7 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_msi_reg.h -@@ -0,0 +1,143 @@ -+#ifndef __SAA716x_MSI_REG_H -+#define __SAA716x_MSI_REG_H -+ -+/* -------------- MSI Registers -------------- */ -+ -+#define MSI_DELAY_TIMER 0x000 -+#define MSI_DELAY_1CLK (0x00000001 << 0) -+#define MSI_DELAY_2CLK (0x00000002 << 0) -+ -+#define MSI_INTA_POLARITY 0x004 -+#define MSI_INTA_POLARITY_HIGH (0x00000001 << 0) -+ -+#define MSI_CONFIG0 0x008 -+#define MSI_CONFIG1 0x00c -+#define MSI_CONFIG2 0x010 -+#define MSI_CONFIG3 0x014 -+#define MSI_CONFIG4 0x018 -+#define MSI_CONFIG5 0x01c -+#define MSI_CONFIG6 0x020 -+#define MSI_CONFIG7 0x024 -+#define MSI_CONFIG8 0x028 -+#define MSI_CONFIG9 0x02c -+#define MSI_CONFIG10 0x030 -+#define MSI_CONFIG11 0x034 -+#define MSI_CONFIG12 0x038 -+#define MSI_CONFIG13 0x03c -+#define MSI_CONFIG14 0x040 -+#define MSI_CONFIG15 0x044 -+#define MSI_CONFIG16 0x048 -+#define MSI_CONFIG17 0x04c -+#define MSI_CONFIG18 0x050 -+#define MSI_CONFIG19 0x054 -+#define MSI_CONFIG20 0x058 -+#define MSI_CONFIG21 0x05c -+#define MSI_CONFIG22 0x060 -+#define MSI_CONFIG23 0x064 -+#define MSI_CONFIG24 0x068 -+#define MSI_CONFIG25 0x06c -+#define MSI_CONFIG26 0x070 -+#define MSI_CONFIG27 0x074 -+#define MSI_CONFIG28 0x078 -+#define MSI_CONFIG29 0x07c -+#define MSI_CONFIG30 0x080 -+#define MSI_CONFIG31 0x084 -+#define MSI_CONFIG32 0x088 -+#define MSI_CONFIG33 0x08c -+#define MSI_CONFIG34 0x090 -+#define MSI_CONFIG35 0x094 -+#define MSI_CONFIG36 0x098 -+#define MSI_CONFIG37 0x09c -+#define MSI_CONFIG38 0x0a0 -+#define MSI_CONFIG39 0x0a4 -+#define MSI_CONFIG40 0x0a8 -+#define MSI_CONFIG41 0x0ac -+#define MSI_CONFIG42 0x0b0 -+#define MSI_CONFIG43 0x0b4 -+#define MSI_CONFIG44 0x0b8 -+#define MSI_CONFIG45 0x0bc -+#define MSI_CONFIG46 0x0c0 -+#define MSI_CONFIG47 0x0c4 -+#define MSI_CONFIG48 0x0c8 -+#define MSI_CONFIG49 0x0cc -+#define MSI_CONFIG50 0x0d0 -+ -+#define MSI_INT_POL_EDGE_RISE (0x00000001 << 24) -+#define MSI_INT_POL_EDGE_FALL (0x00000002 << 24) -+#define MSI_INT_POL_EDGE_ANY (0x00000003 << 24) -+#define MSI_TC (0x00000007 << 16) -+#define MSI_ID (0x0000000f << 0) -+ -+#define MSI_INT_STATUS_L 0xfc0 -+#define MSI_INT_TAGACK_VI0_0 (0x00000001 << 0) -+#define MSI_INT_TAGACK_VI0_1 (0x00000001 << 1) -+#define MSI_INT_TAGACK_VI0_2 (0x00000001 << 2) -+#define MSI_INT_TAGACK_VI1_0 (0x00000001 << 3) -+#define MSI_INT_TAGACK_VI1_1 (0x00000001 << 4) -+#define MSI_INT_TAGACK_VI1_2 (0x00000001 << 5) -+#define MSI_INT_TAGACK_FGPI_0 (0x00000001 << 6) -+#define MSI_INT_TAGACK_FGPI_1 (0x00000001 << 7) -+#define MSI_INT_TAGACK_FGPI_2 (0x00000001 << 8) -+#define MSI_INT_TAGACK_FGPI_3 (0x00000001 << 9) -+#define MSI_INT_TAGACK_AI_0 (0x00000001 << 10) -+#define MSI_INT_TAGACK_AI_1 (0x00000001 << 11) -+#define MSI_INT_OVRFLW_VI0_0 (0x00000001 << 12) -+#define MSI_INT_OVRFLW_VI0_1 (0x00000001 << 13) -+#define MSI_INT_OVRFLW_VI0_2 (0x00000001 << 14) -+#define MSI_INT_OVRFLW_VI1_0 (0x00000001 << 15) -+#define MSI_INT_OVRFLW_VI1_1 (0x00000001 << 16) -+#define MSI_INT_OVRFLW_VI1_2 (0x00000001 << 17) -+#define MSI_INT_OVRFLW_FGPI_0 (0x00000001 << 18) -+#define MSI_INT_OVRFLW_FGPI_1 (0x00000001 << 19) -+#define MSI_INT_OVRFLW_FGPI_2 (0x00000001 << 20) -+#define MSI_INT_OVRFLW_FGPI_3 (0x00000001 << 21) -+#define MSI_INT_OVRFLW_AI_0 (0x00000001 << 22) -+#define MSI_INT_OVRFLW_AI_1 (0x00000001 << 23) -+#define MSI_INT_AVINT_VI0 (0x00000001 << 24) -+#define MSI_INT_AVINT_VI1 (0x00000001 << 25) -+#define MSI_INT_AVINT_FGPI_0 (0x00000001 << 26) -+#define MSI_INT_AVINT_FGPI_1 (0x00000001 << 27) -+#define MSI_INT_AVINT_FGPI_2 (0x00000001 << 28) -+#define MSI_INT_AVINT_FGPI_3 (0x00000001 << 29) -+#define MSI_INT_AVINT_AI_0 (0x00000001 << 30) -+#define MSI_INT_AVINT_AI_1 (0x00000001 << 31) -+ -+#define MSI_INT_STATUS_H 0xfc4 -+#define MSI_INT_UNMAPD_TC_INT (0x00000001 << 0) -+#define MSI_INT_EXTINT_0 (0x00000001 << 1) -+#define MSI_INT_EXTINT_1 (0x00000001 << 2) -+#define MSI_INT_EXTINT_2 (0x00000001 << 3) -+#define MSI_INT_EXTINT_3 (0x00000001 << 4) -+#define MSI_INT_EXTINT_4 (0x00000001 << 5) -+#define MSI_INT_EXTINT_5 (0x00000001 << 6) -+#define MSI_INT_EXTINT_6 (0x00000001 << 7) -+#define MSI_INT_EXTINT_7 (0x00000001 << 8) -+#define MSI_INT_EXTINT_8 (0x00000001 << 9) -+#define MSI_INT_EXTINT_9 (0x00000001 << 10) -+#define MSI_INT_EXTINT_10 (0x00000001 << 11) -+#define MSI_INT_EXTINT_11 (0x00000001 << 12) -+#define MSI_INT_EXTINT_12 (0x00000001 << 13) -+#define MSI_INT_EXTINT_13 (0x00000001 << 14) -+#define MSI_INT_EXTINT_14 (0x00000001 << 15) -+#define MSI_INT_EXTINT_15 (0x00000001 << 16) -+#define MSI_INT_I2CINT_0 (0x00000001 << 17) -+#define MSI_INT_I2CINT_1 (0x00000001 << 18) -+ -+#define MSI_INT_STATUS_CLR_L 0xfc8 -+#define MSI_INT_STATUS_CLR_H 0xfcc -+#define MSI_INT_STATUS_SET_L 0xfd0 -+#define MSI_INT_STATUS_SET_H 0xfd4 -+#define MSI_INT_ENA_L 0xfd8 -+#define MSI_INT_ENA_H 0xfdc -+#define MSI_INT_ENA_CLR_L 0xfe0 -+#define MSI_INT_ENA_CLR_H 0xfe4 -+#define MSI_INT_ENA_SET_L 0xfe8 -+#define MSI_INT_ENA_SET_H 0xfec -+ -+#define MSI_SW_RST 0xff0 -+#define MSI_SW_RESET (0x0001 << 0) -+ -+#define MSI_MODULE_ID 0xffc -+ -+ -+#endif /* __SAA716x_MSI_REG_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_pci.c b/drivers/media/pci/saa716x/saa716x_pci.c -new file mode 100644 -index 0000000..f97e4d3 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_pci.c -@@ -0,0 +1,278 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "saa716x_spi.h" -+#include "saa716x_msi.h" -+#include "saa716x_priv.h" -+ -+#define DRIVER_NAME "SAA716x Core" -+ -+static inline irqreturn_t saa716x_msi_handler(int irq, void *dev_id) -+{ -+ return IRQ_HANDLED; -+} -+ -+static int saa716x_enable_msi(struct saa716x_dev *saa716x) -+{ -+ struct pci_dev *pdev = saa716x->pdev; -+ int err; -+ -+ err = pci_enable_msi(pdev); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "MSI enable failed <%d>", err); -+ return err; -+ } -+ -+ return err; -+} -+ -+static int saa716x_enable_msix(struct saa716x_dev *saa716x) -+{ -+ struct pci_dev *pdev = saa716x->pdev; -+ int i, ret = 0; -+ -+ for (i = 0; i < SAA716x_MSI_MAX_VECTORS; i++) -+ saa716x->msix_entries[i].entry = i; -+ -+ ret = pci_enable_msix(pdev, saa716x->msix_entries, SAA716x_MSI_MAX_VECTORS); -+ if (ret < 0) -+ dprintk(SAA716x_ERROR, 1, "MSI-X request failed <%d>", ret); -+ if (ret > 0) -+ dprintk(SAA716x_ERROR, 1, "Request exceeds available IRQ's <%d>", ret); -+ -+ return ret; -+} -+ -+static int saa716x_request_irq(struct saa716x_dev *saa716x) -+{ -+ struct pci_dev *pdev = saa716x->pdev; -+ struct saa716x_config *config = saa716x->config; -+ int i, ret = 0; -+ -+ if (saa716x->int_type == MODE_MSI) { -+ dprintk(SAA716x_DEBUG, 1, "Using MSI mode"); -+ ret = saa716x_enable_msi(saa716x); -+ } else if (saa716x->int_type == MODE_MSI_X) { -+ dprintk(SAA716x_DEBUG, 1, "Using MSI-X mode"); -+ ret = saa716x_enable_msix(saa716x); -+ } -+ -+ if (ret) { -+ dprintk(SAA716x_ERROR, 1, "INT-A Mode"); -+ saa716x->int_type = MODE_INTA; -+ } -+ -+ if (saa716x->int_type == MODE_MSI) { -+ ret = request_irq(pdev->irq, -+ config->irq_handler, -+ 0, -+ DRIVER_NAME, -+ saa716x); -+ -+ if (ret) { -+ pci_disable_msi(pdev); -+ dprintk(SAA716x_ERROR, 1, "MSI registration failed"); -+ } -+ } -+ -+ if (saa716x->int_type == MODE_MSI_X) { -+ for (i = 0; i < SAA716x_MSI_MAX_VECTORS; i++) { -+ ret = request_irq(saa716x->msix_entries[i].vector, -+ saa716x->saa716x_msix_handler[i].handler, -+ IRQF_SHARED, -+ saa716x->saa716x_msix_handler[i].desc, -+ saa716x); -+ -+ dprintk(SAA716x_ERROR, 1, "%s @ 0x%p", saa716x->saa716x_msix_handler[i].desc, saa716x->saa716x_msix_handler[i].handler); -+ if (ret) { -+ dprintk(SAA716x_ERROR, 1, "%s MSI-X-%d registration failed <%d>", saa716x->saa716x_msix_handler[i].desc, i, ret); -+ break; -+ } -+ } -+ -+ /* free already allocated vectors in error case */ -+ while (ret && i > 0) { -+ --i; -+ free_irq(saa716x->msix_entries[i].vector, saa716x); -+ } -+ } -+ -+ if (saa716x->int_type == MODE_INTA) { -+ ret = request_irq(pdev->irq, -+ config->irq_handler, -+ IRQF_SHARED, -+ DRIVER_NAME, -+ saa716x); -+ if (ret < 0) -+ dprintk(SAA716x_ERROR, 1, "SAA716x IRQ registration failed <%d>", ret); -+ } -+ -+ return ret; -+} -+ -+static void saa716x_free_irq(struct saa716x_dev *saa716x) -+{ -+ struct pci_dev *pdev = saa716x->pdev; -+ int i, vector; -+ -+ if (saa716x->int_type == MODE_MSI_X) { -+ -+ for (i = 0; i < SAA716x_MSI_MAX_VECTORS; i++) { -+ vector = saa716x->msix_entries[i].vector; -+ free_irq(vector, saa716x); -+ } -+ -+ pci_disable_msix(pdev); -+ -+ } else { -+ free_irq(pdev->irq, saa716x); -+ if (saa716x->int_type == MODE_MSI) -+ pci_disable_msi(pdev); -+ } -+} -+ -+int saa716x_pci_init(struct saa716x_dev *saa716x) -+{ -+ struct pci_dev *pdev = saa716x->pdev; -+ int err = 0, ret = -ENODEV, i, use_dac, pm_cap; -+ u32 msi_cap; -+ u8 revision; -+ -+ dprintk(SAA716x_ERROR, 1, "found a %s PCIe card", saa716x->config->model_name); -+ -+ err = pci_enable_device(pdev); -+ if (err != 0) { -+ ret = -ENODEV; -+ dprintk(SAA716x_ERROR, 1, "ERROR: PCI enable failed (%i)", err); -+ goto fail0; -+ } -+ -+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { -+ use_dac = 1; -+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); -+ if (err) { -+ dprintk(SAA716x_ERROR, 1, "Unable to obtain 64bit DMA"); -+ goto fail1; -+ } -+ } else if ((err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) { -+ dprintk(SAA716x_ERROR, 1, "Unable to obtain 32bit DMA"); -+ goto fail1; -+ } -+ -+ pci_set_master(pdev); -+ -+ pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); -+ if (pm_cap == 0) { -+ dprintk(SAA716x_ERROR, 1, "Cannot find Power Management Capability"); -+ err = -EIO; -+ goto fail1; -+ } -+ -+ if (!request_mem_region(pci_resource_start(pdev, 0), -+ pci_resource_len(pdev, 0), -+ DRIVER_NAME)) { -+ -+ dprintk(SAA716x_ERROR, 1, "BAR0 Request failed"); -+ ret = -ENODEV; -+ goto fail1; -+ } -+ saa716x->mmio = ioremap(pci_resource_start(pdev, 0), -+ pci_resource_len(pdev, 0)); -+ -+ if (!saa716x->mmio) { -+ dprintk(SAA716x_ERROR, 1, "Mem 0 remap failed"); -+ ret = -ENODEV; -+ goto fail2; -+ } -+ -+ for (i = 0; i < SAA716x_MSI_MAX_VECTORS; i++) -+ saa716x->msix_entries[i].entry = i; -+ -+ err = saa716x_request_irq(saa716x); -+ if (err < 0) { -+ dprintk(SAA716x_ERROR, 1, "SAA716x IRQ registration failed, err=%d", err); -+ ret = -ENODEV; -+ goto fail3; -+ } -+ -+ pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); -+ pci_read_config_dword(pdev, 0x40, &msi_cap); -+ -+ saa716x->revision = revision; -+ -+ dprintk(SAA716x_ERROR, 0, " SAA%02x Rev %d [%04x:%04x], ", -+ saa716x->pdev->device, -+ revision, -+ saa716x->pdev->subsystem_vendor, -+ saa716x->pdev->subsystem_device); -+ -+ dprintk(SAA716x_ERROR, 0, -+ "irq: %d,\n mmio: 0x%p\n", -+ saa716x->pdev->irq, -+ saa716x->mmio); -+ -+ dprintk(SAA716x_ERROR, 0, " SAA%02x %sBit, MSI %s, MSI-X=%d msgs", -+ saa716x->pdev->device, -+ (((msi_cap >> 23) & 0x01) == 1 ? "64":"32"), -+ (((msi_cap >> 16) & 0x01) == 1 ? "Enabled" : "Disabled"), -+ (1 << ((msi_cap >> 17) & 0x07))); -+ -+ dprintk(SAA716x_ERROR, 0, "\n"); -+ -+ pci_set_drvdata(pdev, saa716x); -+ -+ return 0; -+ -+fail3: -+ dprintk(SAA716x_ERROR, 1, "Err: IO Unmap"); -+ if (saa716x->mmio) -+ iounmap(saa716x->mmio); -+fail2: -+ dprintk(SAA716x_ERROR, 1, "Err: Release regions"); -+ release_mem_region(pci_resource_start(pdev, 0), -+ pci_resource_len(pdev, 0)); -+ -+fail1: -+ dprintk(SAA716x_ERROR, 1, "Err: Disabling device"); -+ pci_disable_device(pdev); -+ -+fail0: -+ pci_set_drvdata(pdev, NULL); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(saa716x_pci_init); -+ -+void saa716x_pci_exit(struct saa716x_dev *saa716x) -+{ -+ struct pci_dev *pdev = saa716x->pdev; -+ -+ saa716x_free_irq(saa716x); -+ -+ dprintk(SAA716x_NOTICE, 1, "SAA%02x mem0: 0x%p", -+ saa716x->pdev->device, -+ saa716x->mmio); -+ -+ if (saa716x->mmio) { -+ iounmap(saa716x->mmio); -+ release_mem_region(pci_resource_start(pdev, 0), -+ pci_resource_len(pdev, 0)); -+ } -+ -+ pci_disable_device(pdev); -+ pci_set_drvdata(pdev, NULL); -+} -+EXPORT_SYMBOL_GPL(saa716x_pci_exit); -+ -+MODULE_DESCRIPTION("SAA716x bridge driver"); -+MODULE_AUTHOR("Manu Abraham"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/pci/saa716x/saa716x_phi.c b/drivers/media/pci/saa716x/saa716x_phi.c -new file mode 100644 -index 0000000..7df9a98 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_phi.c -@@ -0,0 +1,152 @@ -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_phi_reg.h" -+ -+#include "saa716x_spi.h" -+#include "saa716x_phi.h" -+#include "saa716x_priv.h" -+ -+u32 PHI_0_REGS[] = { -+ PHI_0_MODE, -+ PHI_0_0_CONFIG, -+ PHI_0_1_CONFIG, -+ PHI_0_2_CONFIG, -+ PHI_0_3_CONFIG -+}; -+ -+u32 PHI_1_REGS[] = { -+ PHI_1_MODE, -+ PHI_1_0_CONFIG, -+ PHI_1_1_CONFIG, -+ PHI_1_2_CONFIG, -+ PHI_1_3_CONFIG, -+ PHI_1_4_CONFIG, -+ PHI_1_5_CONFIG, -+ PHI_1_6_CONFIG, -+ PHI_1_7_CONFIG -+}; -+ -+#define PHI_BASE(__port) (( \ -+ (__port == PHI_1) ? \ -+ PHI_1_BASE : \ -+ PHI_0_BASE \ -+)) -+ -+#define PHI_APERTURE(_port) (( \ -+ (__port == PHI_1) ? \ -+ PHI_1_APERTURE: \ -+ PHI_0_APERTURE \ -+)) -+ -+#define PHI_REG(__port, __reg) (( \ -+ (__port == PHI_1) ? \ -+ PHI_1_REGS[__reg] : \ -+ PHI_0_REGS[__reg] \ -+)) -+ -+#define PHI_SLAVE(__port, __slave) (( \ -+ PHI_BASE(__port) + (__slave * (PHI_APERTURE(__port))) \ -+)) -+ -+/* // Read SAA716x registers -+ * SAA716x_EPRD(PHI_0, PHI_REG(__port, __reg)) -+ * SAA716x_EPWR(PHI_1, PHI_REG(__port, __reg), __data) -+ * -+ * // Read slave registers -+ * SAA716x_EPRD(PHI_0, PHI_SLAVE(__port, __slave, __offset)) -+ * SAA716x_EPWR(PHI_1, PHI_SLAVE(__port, __slave, _offset), __data) -+ */ -+ -+int saa716x_init_phi(struct saa716x_dev *saa716x, u32 port, u8 slave) -+{ -+ int i; -+ -+ /* Reset */ -+ SAA716x_EPWR(PHI_0, PHI_SW_RST, 0x1); -+ -+ for (i = 0; i < 20; i++) { -+ msleep(1); -+ if (!(SAA716x_EPRD(PHI_0, PHI_SW_RST))) -+ break; -+ } -+ -+ return 0; -+} -+ -+int saa716x_phi_init(struct saa716x_dev *saa716x) -+{ -+ uint32_t value; -+ -+ /* init PHI 0 to FIFO mode */ -+ value = 0; -+ value |= PHI_FIFO_MODE; -+ SAA716x_EPWR(PHI_0, PHI_0_MODE, value); -+ -+ value = 0; -+ value |= 0x02; /* chip select 1 */ -+ value |= 0x00 << 8; /* ready mask */ -+ value |= 0x03 << 12; /* strobe time */ -+ value |= 0x06 << 20; /* cycle time */ -+ SAA716x_EPWR(PHI_0, PHI_0_0_CONFIG, value); -+ -+ /* init PHI 1 to SRAM mode, auto increment on */ -+ value = 0; -+ value |= PHI_AUTO_INCREMENT; -+ SAA716x_EPWR(PHI_0, PHI_1_MODE, value); -+ -+ value = 0; -+ value |= 0x01; /* chip select 0 */ -+ value |= 0x00 << 8; /* ready mask */ -+ value |= 0x03 << 12; /* strobe time */ -+ value |= 0x05 << 20; /* cycle time */ -+ SAA716x_EPWR(PHI_0, PHI_1_0_CONFIG, value); -+ -+ value = 0; -+ value |= PHI_ALE_POL; /* ALE is active high */ -+ SAA716x_EPWR(PHI_0, PHI_POLARITY, value); -+ -+ SAA716x_EPWR(PHI_0, PHI_TIMEOUT, 0x2a); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_phi_init); -+ -+int saa716x_phi_write(struct saa716x_dev *saa716x, u32 address, const u8 * data, int length) -+{ -+ int i; -+ -+ for (i = 0; i < length; i += 4) { -+ SAA716x_EPWR(PHI_1, address, *((u32 *) &data[i])); -+ address += 4; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_phi_write); -+ -+int saa716x_phi_read(struct saa716x_dev *saa716x, u32 address, u8 * data, int length) -+{ -+ int i; -+ -+ for (i = 0; i < length; i += 4) { -+ *((u32 *) &data[i]) = SAA716x_EPRD(PHI_1, address); -+ address += 4; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_phi_read); -+ -+int saa716x_phi_write_fifo(struct saa716x_dev *saa716x, const u8 * data, int length) -+{ -+ int i; -+ -+ for (i = 0; i < length; i += 4) { -+ SAA716x_EPWR(PHI_0, PHI_0_0_RW_0, *((u32 *) &data[i])); -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_phi_write_fifo); -diff --git a/drivers/media/pci/saa716x/saa716x_phi.h b/drivers/media/pci/saa716x/saa716x_phi.h -new file mode 100644 -index 0000000..ff5cda2 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_phi.h -@@ -0,0 +1,39 @@ -+#ifndef __SAA716x_PHI_H -+#define __SAA716x_PHI_H -+ -+/* PHI SLAVE */ -+#define PHI_SLAVE_0 0 -+#define PHI_SLAVE_1 1 -+#define PHI_SLAVE_2 2 -+#define PHI_SLAVE_3 3 -+#define PHI_SLAVE_4 4 -+#define PHI_SLAVE_5 5 -+#define PHI_SLAVE_6 6 -+#define PHI_SLAVE_7 7 -+ -+/* PHI_REG */ -+#define PHI_MODE 0 -+#define PHI_CONFIG_0 1 -+#define PHI_CONFIG_1 2 -+#define PHI_CONFIG_2 3 -+#define PHI_CONFIG_3 4 -+#define PHI_CONFIG_4 5 -+#define PHI_CONFIG_5 6 -+#define PHI_CONFIG_6 7 -+#define PHI_CONFIG_7 8 -+ -+#define PHI_0_BASE 0x1000 -+#define PHI_0_APERTURE 0x0800 -+ -+#define PHI_1_BASE 0x0000 -+#define PHI_1_APERTURE 0xfffc -+ -+struct saa716x_dev; -+ -+extern int saa716x_init_phi(struct saa716x_dev *saa716x, u32 port, u8 slave); -+extern int saa716x_phi_init(struct saa716x_dev *saa716x); -+extern int saa716x_phi_write(struct saa716x_dev *saa716x, u32 address, const u8 *data, int length); -+extern int saa716x_phi_read(struct saa716x_dev *saa716x, u32 address, u8 *data, int length); -+extern int saa716x_phi_write_fifo(struct saa716x_dev *saa716x, const u8 * data, int length); -+ -+#endif /* __SAA716x_PHI_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_phi_reg.h b/drivers/media/pci/saa716x/saa716x_phi_reg.h -new file mode 100644 -index 0000000..cb9e148 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_phi_reg.h -@@ -0,0 +1,94 @@ -+#ifndef __SAA716x_PHI_REG_H -+#define __SAA716x_PHI_REG_H -+ -+/* -------------- PHI_0 Registers -------------- */ -+ -+#define PHI_0_MODE 0x0000 -+#define PHI_0_0_CONFIG 0x0008 -+#define PHI_0_1_CONFIG 0x000c -+#define PHI_0_2_CONFIG 0x0010 -+#define PHI_0_3_CONFIG 0x0014 -+ -+#define PHI_POLARITY 0x0038 -+#define PHI_TIMEOUT 0x003c -+#define PHI_SW_RST 0x0ff0 -+ -+#define PHI_0_0_RW_0 0x1000 -+#define PHI_0_0_RW_511 0x17fc -+ -+#define PHI_0_1_RW_0 0x1800 -+#define PHI_0_1_RW_511 0x1ffc -+ -+#define PHI_0_2_RW_0 0x2000 -+#define PHI_0_2_RW_511 0x27fc -+ -+#define PHI_0_3_RW_0 0x2800 -+#define PHI_0_3_RW_511 0x2ffc -+ -+#define PHI_CSN_DEASSERT (0x00000001 << 2) -+#define PHI_AUTO_INCREMENT (0x00000001 << 1) -+#define PHI_FIFO_MODE (0x00000001 << 0) -+ -+#define PHI_DELAY_RD_WR (0x0000001f << 27) -+#define PHI_EXTEND_RDY3 (0x00000003 << 25) -+#define PHI_EXTEND_RDY2 (0x00000003 << 23) -+#define PHI_EXTEND_RDY1 (0x00000003 << 21) -+#define PHI_EXTEND_RDY0 (0x00000003 << 19) -+#define PHI_RDY3_OD (0x00000001 << 18) -+#define PHI_RDY2_OD (0x00000001 << 17) -+#define PHI_RDY1_OD (0x00000001 << 16) -+#define PHI_RDY0_OD (0x00000001 << 15) -+#define PHI_ALE_POL (0x00000001 << 14) -+#define PHI_WRN_POL (0x00000001 << 13) -+#define PHI_RDN_POL (0x00000001 << 12) -+#define PHI_RDY3_POL (0x00000001 << 11) -+#define PHI_RDY2_POL (0x00000001 << 10) -+#define PHI_RDY1_POL (0x00000001 << 9) -+#define PHI_RDY0_POL (0x00000001 << 8) -+#define PHI_CSN7_POL (0x00000001 << 7) -+#define PHI_CSN6_POL (0x00000001 << 6) -+#define PHI_CSN5_POL (0x00000001 << 5) -+#define PHI_CSN4_POL (0x00000001 << 4) -+#define PHI_CSN3_POL (0x00000001 << 3) -+#define PHI_CSN2_POL (0x00000001 << 2) -+#define PHI_CSN1_POL (0x00000001 << 1) -+#define PHI_CSN0_POL (0x00000001 << 0) -+ -+/* -------------- PHI_1 Registers -------------- */ -+ -+#define PHI_1_MODE 0x00004 -+#define PHI_1_0_CONFIG 0x00018 -+#define PHI_1_1_CONFIG 0x0001c -+#define PHI_1_2_CONFIG 0x00020 -+#define PHI_1_3_CONFIG 0x00024 -+#define PHI_1_4_CONFIG 0x00028 -+#define PHI_1_5_CONFIG 0x0002c -+#define PHI_1_6_CONFIG 0x00030 -+#define PHI_1_7_CONFIG 0x00034 -+ -+#define PHI_1_0_RW_0 0x00000 -+#define PHI_1_0_RW_16383 0x0fffc -+ -+#define PHI_1_1_RW_0 0x1000 -+#define PHI_1_1_RW_16383 0x1ffc -+ -+#define PHI_1_2_RW_0 0x2000 -+#define PHI_1_2_RW_16383 0x2ffc -+ -+#define PHI_1_3_RW_0 0x3000 -+#define PHI_1_3_RW_16383 0x3ffc -+ -+#define PHI_1_4_RW_0 0x4000 -+#define PHI_1_4_RW_16383 0x4ffc -+ -+#define PHI_1_5_RW_0 0x5000 -+#define PHI_1_5_RW_16383 0x5ffc -+ -+#define PHI_1_6_RW_0 0x6000 -+#define PHI_1_6_RW_16383 0x6ffc -+ -+#define PHI_1_7_RW_0 0x7000 -+#define PHI_1_7_RW_16383 0x7ffc -+ -+ -+#endif /* __SAA716x_PHI_REG_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_priv.h b/drivers/media/pci/saa716x/saa716x_priv.h -new file mode 100644 -index 0000000..5ae8000 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_priv.h -@@ -0,0 +1,205 @@ -+#ifndef __SAA716x_PRIV_H -+#define __SAA716x_PRIV_H -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include "saa716x_i2c.h" -+#include "saa716x_boot.h" -+#include "saa716x_cgu.h" -+#include "saa716x_dma.h" -+#include "saa716x_fgpi.h" -+#include "saa716x_spi.h" -+#include "saa716x_vip.h" -+ -+#include "dvbdev.h" -+#include "dvb_demux.h" -+#include "dmxdev.h" -+#include "dvb_frontend.h" -+#include "dvb_net.h" -+ -+#define SAA716x_ERROR 0 -+#define SAA716x_NOTICE 1 -+#define SAA716x_INFO 2 -+#define SAA716x_DEBUG 3 -+ -+#define SAA716x_DEV (saa716x)->num -+#define SAA716x_VERBOSE (saa716x)->verbose -+#define SAA716x_MAX_ADAPTERS 4 -+ -+#define dprintk(__x, __y, __fmt, __arg...) do { \ -+ if (__y) { \ -+ if ((SAA716x_VERBOSE > SAA716x_ERROR) && (SAA716x_VERBOSE > __x)) \ -+ printk(KERN_ERR "%s (%d): " __fmt "\n" , __func__ , SAA716x_DEV , ##__arg); \ -+ else if ((SAA716x_VERBOSE > SAA716x_NOTICE) && (SAA716x_VERBOSE > __x)) \ -+ printk(KERN_NOTICE "%s (%d): " __fmt "\n" , __func__ , SAA716x_DEV , ##__arg); \ -+ else if ((SAA716x_VERBOSE > SAA716x_INFO) && (SAA716x_VERBOSE > __x)) \ -+ printk(KERN_INFO "%s (%d): " __fmt "\n" , __func__ , SAA716x_DEV , ##__arg); \ -+ else if ((SAA716x_VERBOSE > SAA716x_DEBUG) && (SAA716x_VERBOSE > __x)) \ -+ printk(KERN_DEBUG "%s (%d): " __fmt "\n" , __func__ , SAA716x_DEV , ##__arg); \ -+ } else { \ -+ if (SAA716x_VERBOSE > __x) \ -+ printk(__fmt , ##__arg); \ -+ } \ -+} while(0) -+ -+ -+#define NXP_SEMICONDUCTOR 0x1131 -+#define SAA7160 0x7160 -+#define SAA7161 0x7161 -+#define SAA7162 0x7162 -+ -+#define NXP_REFERENCE_BOARD 0x1131 -+ -+#define MAKE_ENTRY(__subven, __subdev, __chip, __configptr) { \ -+ .vendor = NXP_SEMICONDUCTOR, \ -+ .device = (__chip), \ -+ .subvendor = (__subven), \ -+ .subdevice = (__subdev), \ -+ .driver_data = (unsigned long) (__configptr) \ -+} -+ -+#define SAA716x_EPWR(__offst, __addr, __data) writel((__data), (saa716x->mmio + (__offst + __addr))) -+#define SAA716x_EPRD(__offst, __addr) readl((saa716x->mmio + (__offst + __addr))) -+ -+#define SAA716x_RCWR(__offst, __addr, __data) writel((__data), (saa716x->mmio + (__offst + __addr))) -+#define SAA716x_RCRD(__offst, __addr) readl((saa716x->mmio + (__offst + __addr))) -+ -+ -+#define SAA716x_MSI_MAX_VECTORS 16 -+ -+struct saa716x_msix_entry { -+ int vector; -+ u8 desc[32]; -+ irqreturn_t (*handler)(int irq, void *dev_id); -+}; -+ -+struct saa716x_dev; -+struct saa716x_adapter; -+struct saa716x_spi_config; -+ -+struct saa716x_adap_config { -+ u32 ts_port; -+ void (*worker)(unsigned long); -+}; -+ -+struct saa716x_config { -+ char *model_name; -+ char *dev_type; -+ -+ enum saa716x_boot_mode boot_mode; -+ -+ int adapters; -+ int frontends; -+ -+ int (*frontend_attach)(struct saa716x_adapter *adapter, int count); -+ irqreturn_t (*irq_handler)(int irq, void *dev_id); -+ -+ struct saa716x_adap_config adap_config[SAA716x_MAX_ADAPTERS]; -+ enum saa716x_i2c_rate i2c_rate; -+ enum saa716x_i2c_mode i2c_mode; -+}; -+ -+struct saa716x_adapter { -+ struct dvb_adapter dvb_adapter; -+ struct dvb_frontend *fe; -+ struct dvb_demux demux; -+ struct dmxdev dmxdev; -+ struct dmx_frontend fe_hw; -+ struct dmx_frontend fe_mem; -+ struct dvb_net dvb_net; -+ -+ struct saa716x_dev *saa716x; -+ -+ u8 feeds; -+ u8 count; -+ -+ struct i2c_client *i2c_client_demod; -+ struct i2c_client *i2c_client_tuner; -+ -+ struct tbsci_i2c_state *tbsci; -+ void*adap_priv; -+}; -+ -+struct saa716x_dev { -+ struct saa716x_config *config; -+ struct pci_dev *pdev; -+ struct module *module; -+ -+ int num_adapters; /* adapter count (adapters on this saa716x card) */ -+ int num; /* device count (saa716x based cards) */ -+ int verbose; -+ -+ u8 revision; -+ -+ /* PCI */ -+ void __iomem *mmio; -+ -+#define MODE_INTA 0 -+#define MODE_MSI 1 -+#define MODE_MSI_X 2 -+ u8 int_type; -+ -+ struct msix_entry msix_entries[SAA716x_MSI_MAX_VECTORS]; -+ struct saa716x_msix_entry saa716x_msix_handler[56]; -+ u8 handlers; /* no. of active handlers */ -+ -+ /* I2C */ -+ struct saa716x_i2c i2c[2]; -+ u32 i2c_rate; /* init time */ -+ u32 I2C_DEV[2]; -+ -+ struct saa716x_spi_state *saa716x_spi; -+ struct saa716x_spi_config spi_config; -+ -+ struct saa716x_adapter saa716x_adap[SAA716x_MAX_ADAPTERS]; -+ struct mutex adap_lock; -+ struct saa716x_cgu cgu; -+ -+ spinlock_t gpio_lock; -+ /* DMA */ -+ -+ struct saa716x_fgpi_stream_port fgpi[4]; -+ struct saa716x_vip_stream_port vip[2]; -+ -+ u32 id_offst; -+ u32 id_len; -+ void *priv; -+ -+ /* remote control */ -+ void *ir_priv; -+}; -+ -+/* PCI */ -+extern int saa716x_pci_init(struct saa716x_dev *saa716x); -+extern void saa716x_pci_exit(struct saa716x_dev *saa716x); -+ -+/* MSI */ -+extern int saa716x_msi_init(struct saa716x_dev *saa716x); -+extern void saa716x_msi_exit(struct saa716x_dev *saa716x); -+extern void saa716x_msiint_disable(struct saa716x_dev *saa716x); -+ -+/* DMA */ -+extern int saa716x_dma_init(struct saa716x_dev *saa716x); -+extern void saa716x_dma_exit(struct saa716x_dev *saa716x); -+ -+/* AUDIO */ -+extern int saa716x_audio_init(struct saa716x_dev *saa716x); -+extern void saa716x_audio_exit(struct saa716x_dev *saa716x); -+ -+/* Boot */ -+extern int saa716x_core_boot(struct saa716x_dev *saa716x); -+extern int saa716x_jetpack_init(struct saa716x_dev *saa716x); -+ -+/* Remote control */ -+extern int saa716x_ir_init(struct saa716x_dev *saa716x); -+extern void saa716x_ir_exit(struct saa716x_dev *saa716x); -+extern void saa716x_ir_handler(struct saa716x_dev *saa716x, u32 ir_cmd); -+ -+#endif /* __SAA716x_PRIV_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_rom.c b/drivers/media/pci/saa716x/saa716x_rom.c -new file mode 100644 -index 0000000..63fd061 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_rom.c -@@ -0,0 +1,1087 @@ -+#include -+#include -+ -+#include "saa716x_rom.h" -+#include "saa716x_adap.h" -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+ -+int i; -+ -+static int eeprom_read_bytes(struct saa716x_dev *saa716x, u16 reg, u16 len, u8 *val) -+{ -+ struct saa716x_i2c *i2c = saa716x->i2c; -+ struct i2c_adapter *adapter = &i2c[SAA716x_I2C_BUS_B].i2c_adapter; -+ -+ u8 b0[] = { MSB(reg), LSB(reg) }; -+ int ret; -+ -+ struct i2c_msg msg[] = { -+ { .addr = 0x50, .flags = 0, .buf = b0, .len = sizeof (b0) }, -+ { .addr = 0x50, .flags = I2C_M_RD, .buf = val, .len = len } -+ }; -+ -+ ret = i2c_transfer(adapter, msg, 2); -+ if (ret != 2) { -+ dprintk(SAA716x_ERROR, 1, "read error ", reg, ret); -+ return -EREMOTEIO; -+ } -+ -+ return ret; -+} -+ -+int saa716x_read_rombytes(struct saa716x_dev *saa716x, u16 reg, u16 len, u8 *val) -+{ -+ struct saa716x_i2c *i2c = saa716x->i2c; -+ struct i2c_adapter *adapter = &i2c[SAA716x_I2C_BUS_B].i2c_adapter; -+ struct i2c_msg msg[2]; -+ -+ u8 b0[2]; -+ int ret, count; -+ -+ count = len / DUMP_BYTES; -+ if (len % DUMP_BYTES) -+ count++; -+ -+ count *= 2; -+ -+ for (i = 0; i < count; i += 2) { -+ dprintk(SAA716x_DEBUG, 1, "Length=%d, Count=%d, Reg=0x%02x", -+ len, -+ count, -+ reg); -+ -+ b0[0] = MSB(reg); -+ b0[1] = LSB(reg); -+ -+ /* Write */ -+ msg[0].addr = 0x50; -+ msg[0].flags = 0; -+ msg[0].buf = b0; -+ msg[0].len = 2; -+ -+ /* Read */ -+ msg[1].addr = 0x50; -+ msg[1].flags = I2C_M_RD; -+ msg[1].buf = val; -+ -+ if (i == (count - 2)) { -+ /* last message */ -+ if (len % DUMP_BYTES) { -+ msg[1].len = len % DUMP_BYTES; -+ dprintk(SAA716x_DEBUG, 1, "Last Message length=%d", len % DUMP_BYTES); -+ } else { -+ msg[1].len = DUMP_BYTES; -+ } -+ } else { -+ msg[1].len = DUMP_BYTES; -+ } -+ -+ ret = i2c_transfer(adapter, msg, 2); -+ if (ret != 2) { -+ dprintk(SAA716x_ERROR, 1, "read error ", reg, ret); -+ return -EREMOTEIO; -+ } -+ -+ reg += DUMP_BYTES; -+ val += DUMP_BYTES; -+ } -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(saa716x_read_rombytes); -+ -+static int saa716x_get_offset(struct saa716x_dev *saa716x, u8 *buf, u32 *offset) -+{ -+ int i; -+ -+ *offset = 0; -+ for (i = 0; i < 256; i++) { -+ if (!(strncmp("START", buf + i, 5))) -+ break; -+ } -+ dprintk(SAA716x_INFO, 1, "Offset @ %d", i); -+ *offset = i; -+ -+ return 0; -+} -+ -+static int saa716x_eeprom_header(struct saa716x_dev *saa716x, -+ struct saa716x_romhdr *rom_header, -+ u8 *buf, -+ u32 *offset) -+{ -+ memcpy(rom_header, &buf[*offset], sizeof (struct saa716x_romhdr)); -+ if (rom_header->header_size != sizeof (struct saa716x_romhdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%zd bytes, Expected=%d", -+ sizeof (struct saa716x_romhdr), -+ rom_header->header_size); -+ -+ return -1; -+ } -+ *offset += sizeof (struct saa716x_romhdr); -+ -+ dprintk(SAA716x_NOTICE, 0, "SAA%02x ROM: Data=%d bytes\n", -+ saa716x->pdev->device, -+ rom_header->data_size); -+ -+ dprintk(SAA716x_NOTICE, 0, "SAA%02x ROM: Version=%d\n", -+ saa716x->pdev->device, -+ rom_header->version); -+ -+ dprintk(SAA716x_NOTICE, 0, "SAA%02x ROM: Devices=%d\n", -+ saa716x->pdev->device, -+ rom_header->devices); -+ -+ dprintk(SAA716x_NOTICE, 0, "SAA%02x ROM: Compressed=%d\n\n", -+ saa716x->pdev->device, -+ rom_header->compression); -+ -+ return 0; -+} -+ -+int saa716x_dump_eeprom(struct saa716x_dev *saa716x) -+{ -+ struct saa716x_romhdr rom_header; -+ u8 buf[DUMP_BYTES]; -+ int i, err = 0; -+ u32 offset = 0; -+ -+ err = eeprom_read_bytes(saa716x, DUMP_OFFST, DUMP_BYTES, buf); -+ if (err < 0) { -+ dprintk(SAA716x_ERROR, 1, "EEPROM Read error"); -+ return err; -+ } -+ -+ dprintk(SAA716x_NOTICE, 0, " Card: %s\n", -+ saa716x->config->model_name); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " ---------------- SAA%02x ROM @ Offset 0x%02x ----------------", -+ saa716x->pdev->device, -+ DUMP_OFFST); -+ -+ for (i = 0; i < DUMP_BYTES; i++) { -+ if ((i % 16) == 0) { -+ dprintk(SAA716x_NOTICE, 0, "\n "); -+ dprintk(SAA716x_NOTICE, 0, "%04x: ", i); -+ } -+ -+ if ((i % 8) == 0) -+ dprintk(SAA716x_NOTICE, 0, " "); -+ if ((i % 4) == 0) -+ dprintk(SAA716x_NOTICE, 0, " "); -+ dprintk(SAA716x_NOTICE, 0, "%02x ", buf[i]); -+ } -+ dprintk(SAA716x_NOTICE, 0, "\n"); -+ dprintk(SAA716x_NOTICE, 0, -+ " ---------------- SAA%02x ROM Dump end ---------------------\n\n", -+ saa716x->pdev->device); -+ -+ err = saa716x_get_offset(saa716x, buf, &offset); -+ if (err != 0) { -+ dprintk(SAA716x_ERROR, 1, "ERROR: Descriptor not found <%d>", err); -+ return err; -+ } -+ offset += 5; -+ saa716x->id_offst = offset; -+ /* Get header */ -+ err = saa716x_eeprom_header(saa716x, &rom_header, buf, &offset); -+ if (err != 0) { -+ dprintk(SAA716x_ERROR, 1, "ERROR: Header Read failed <%d>", err); -+ return -1; -+ } -+ saa716x->id_len = rom_header.data_size; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_dump_eeprom); -+ -+static void saa716x_descriptor_dbg(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset, -+ u8 size, -+ u8 ext_size) -+{ -+ int i; -+ -+ dprintk(SAA716x_INFO, 0, " "); -+ for (i = 0; i < 49; i++) -+ dprintk(SAA716x_INFO, 0, "-"); -+ -+ for (i = 0; i < size + ext_size; i++) { -+ if ((i % 16) == 0) -+ dprintk(SAA716x_INFO, 0, "\n "); -+ if ((i % 8) == 0) -+ dprintk(SAA716x_INFO, 0, " "); -+ if ((i % 4) == 0) -+ dprintk(SAA716x_INFO, 0, " "); -+ -+ dprintk(SAA716x_INFO, 0, "%02x ", buf[*offset + i]); -+ } -+ -+ dprintk(SAA716x_INFO, 0, "\n "); -+ for (i = 0; i < 49; i++) -+ dprintk(SAA716x_INFO, 0, "-"); -+ dprintk(SAA716x_INFO, 0, "\n"); -+ -+} -+ -+static int saa716x_decoder_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_decoder_hdr header; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_decoder_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_decoder_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_decoder_hdr)); -+ -+ return -1; -+ } -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext Data=%d bytes\n\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data; -+ return 0; -+} -+ -+static int saa716x_gpio_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_gpio_hdr header; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_gpio_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_gpio_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_gpio_hdr)); -+ -+ return -1; -+ } -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Pins=%d\n", -+ saa716x->pdev->device, -+ header.pins); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d\n\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data; -+ -+ return 0; -+} -+ -+static int saa716x_video_decoder_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_video_decoder_hdr header; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_video_decoder_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_video_decoder_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_video_decoder_hdr)); -+ -+ return -1; -+ } -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: PORT 0=0x%02x\n", -+ saa716x->pdev->device, -+ header.video_port0); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: PORT 1=0x%02x\n", -+ saa716x->pdev->device, -+ header.video_port1); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: PORT 2=0x%02x\n", -+ saa716x->pdev->device, -+ header.video_port2); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: VBI PORT ID=0x%02x\n", -+ saa716x->pdev->device, -+ header.vbi_port_id); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Video PORT Type=0x%02x\n", -+ saa716x->pdev->device, -+ header.video_port_type); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: VBI PORT Type=0x%02x\n", -+ saa716x->pdev->device, -+ header.vbi_port_type); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Encoder PORT Type=0x%02x\n", -+ saa716x->pdev->device, -+ header.encoder_port_type); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Video Output=0x%02x\n", -+ saa716x->pdev->device, -+ header.video_output); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: VBI Output=0x%02x\n", -+ saa716x->pdev->device, -+ header.vbi_output); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Encoder Output=0x%02x\n", -+ saa716x->pdev->device, -+ header.encoder_output); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d bytes\n\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data; -+ return 0; -+} -+ -+static int saa716x_audio_decoder_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_audio_decoder_hdr header; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_audio_decoder_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_audio_decoder_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_audio_decoder_hdr)); -+ -+ return -1; -+ } -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d bytes\n\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data; -+ return 0; -+} -+ -+static int saa716x_event_source_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_evsrc_hdr header; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_evsrc_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_evsrc_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_evsrc_hdr)); -+ -+ return -1; -+ } -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d bytes\n\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data; -+ return 0; -+} -+ -+static int saa716x_crossbar_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_xbar_hdr header; -+ struct saa716x_xbar_pair_info pair_info; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_xbar_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_xbar_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_xbar_hdr)); -+ -+ return -1; -+ } -+ -+ memcpy(&pair_info, &buf[*offset], sizeof (struct saa716x_xbar_pair_info)); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Pairs=%d\n", -+ saa716x->pdev->device, -+ header.pair_inputs); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d bytes\n\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data + (sizeof (struct saa716x_xbar_pair_info) * header.pair_inputs); -+ return 0; -+} -+ -+static int saa716x_tuner_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_tuner_hdr header; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_tuner_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_tuner_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_tuner_hdr)); -+ -+ return -1; -+ } -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d bytes\n\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data; -+ return 0; -+} -+ -+static int saa716x_pll_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_pll_hdr header; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_pll_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_pll_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_pll_hdr)); -+ -+ return -1; -+ } -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d bytes\n\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data; -+ return 0; -+} -+ -+static int saa716x_channel_decoder_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_channel_decoder_hdr header; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_channel_decoder_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_channel_decoder_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_channel_decoder_hdr)); -+ -+ return -1; -+ } -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d bytes\n\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data; -+ return 0; -+} -+ -+static int saa716x_encoder_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_encoder_hdr header; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_encoder_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_encoder_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_encoder_hdr)); -+ -+ return -1; -+ } -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d bytes\n\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data; -+ return 0; -+} -+ -+static int saa716x_ir_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_ir_hdr header; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_ir_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_ir_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_ir_hdr)); -+ -+ return -1; -+ } -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d bytes\n\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data; -+ return 0; -+} -+ -+static int saa716x_eeprom_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_eeprom_hdr header; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_eeprom_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_eeprom_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_eeprom_hdr)); -+ -+ return -1; -+ } -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d bytes\n\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data; -+ return 0; -+} -+ -+static int saa716x_filter_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_filter_hdr header; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_filter_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_filter_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_filter_hdr)); -+ -+ return -1; -+ } -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d bytes\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data; -+ return 0; -+} -+ -+static int saa716x_streamdev_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ struct saa716x_streamdev_hdr header; -+ -+ memcpy(&header, &buf[*offset], sizeof (struct saa716x_streamdev_hdr)); -+ saa716x_descriptor_dbg(saa716x, buf, offset, header.size, header.ext_data); -+ if (header.size != sizeof (struct saa716x_streamdev_hdr)) { -+ dprintk(SAA716x_ERROR, 1, -+ "ERROR: Header size mismatch! Read size=%d bytes, Expected=%zd", -+ header.size, -+ sizeof (struct saa716x_streamdev_hdr)); -+ -+ return -1; -+ } -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ header.size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d bytes\n", -+ saa716x->pdev->device, -+ header.ext_data); -+ -+ *offset += header.size + header.ext_data; -+ return 0; -+} -+ -+static int saa716x_unknown_device_info(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset) -+{ -+ u8 size; -+ u8 ext_size = 0; -+ -+ size = buf[*offset]; -+ if (size > 1) -+ ext_size = buf[*offset + size -1]; -+ -+ saa716x_descriptor_dbg(saa716x, buf, offset, size, ext_size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ size); -+ -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Ext data=%d bytes\n\n", -+ saa716x->pdev->device, -+ ext_size); -+ -+ *offset += size + ext_size; -+ return 0; -+} -+ -+ -+static void saa716x_device_dbg(struct saa716x_dev *saa716x, -+ u8 *buf, -+ u32 *offset, -+ u8 size, -+ u8 ext_size, -+ u8 addr_size) -+{ -+ int i; -+ -+ dprintk(SAA716x_INFO, 0, " "); -+ for (i = 0; i < 53; i++) -+ dprintk(SAA716x_INFO, 0, "-"); -+ -+ for (i = 0; i < size + ext_size + addr_size; i++) { -+ if ((i % 16) == 0) -+ dprintk(SAA716x_INFO, 0, "\n "); -+ if ((i % 8) == 0) -+ dprintk(SAA716x_INFO, 0, " "); -+ if ((i % 4) == 0) -+ dprintk(SAA716x_INFO, 0, " "); -+ -+ dprintk(SAA716x_INFO, 0, "%02x ", buf[*offset + i]); -+ } -+ -+ dprintk(SAA716x_INFO, 0, "\n "); -+ for (i = 0; i < 53; i++) -+ dprintk(SAA716x_INFO, 0, "-"); -+ dprintk(SAA716x_INFO, 0, "\n"); -+ -+} -+ -+ -+static int saa716x_device_info(struct saa716x_dev *saa716x, -+ struct saa716x_devinfo *device, -+ u8 *buf, -+ u32 *offset) -+{ -+ u8 address = 0; -+ -+ memcpy(device, &buf[*offset], sizeof (struct saa716x_devinfo)); -+ if (device->struct_size != sizeof (struct saa716x_devinfo)) { -+ dprintk(SAA716x_ERROR, 1, "ERROR: Device size mismatch! Read=%d bytes, expected=%zd bytes", -+ device->struct_size, -+ sizeof (struct saa716x_devinfo)); -+ -+ return -1; -+ } -+ -+ saa716x_device_dbg(saa716x, -+ buf, -+ offset, -+ device->struct_size, -+ device->extd_data_size, -+ device->addr_size); -+ -+ *offset += device->struct_size; -+ -+ if (device->addr_size) { -+ address = buf[*offset]; -+ address >>= 1; -+ *offset += device->addr_size; -+ } -+ -+ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Device @ 0x%02x\n", -+ saa716x->pdev->device, -+ address); -+ -+ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Size=%d bytes\n", -+ saa716x->pdev->device, -+ device->struct_size); -+ -+ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Device ID=0x%02x\n", -+ saa716x->pdev->device, -+ device->device_id); -+ -+ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Master ID=0x%02x\n", -+ saa716x->pdev->device, -+ device->master_devid); -+ -+ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Bus ID=0x%02x\n", -+ saa716x->pdev->device, -+ device->master_busid); -+ -+ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Device type=0x%02x\n", -+ saa716x->pdev->device, -+ device->device_type); -+ -+ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Implementation ID=0x%02x\n", -+ saa716x->pdev->device, -+ device->implem_id); -+ -+ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Path ID=0x%02x\n", -+ saa716x->pdev->device, -+ device->path_id); -+ -+ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: GPIO ID=0x%02x\n", -+ saa716x->pdev->device, -+ device->gpio_id); -+ -+ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Address=%d bytes\n", -+ saa716x->pdev->device, -+ device->addr_size); -+ -+ dprintk(SAA716x_NOTICE, 0, " SAA%02x ROM: Extended data=%d bytes\n\n", -+ saa716x->pdev->device, -+ device->extd_data_size); -+ -+ if (device->extd_data_size) { -+ u32 mask; -+ -+ mask = 0x00000001; -+ while (mask) { -+ if (device->device_type & mask) { -+ switch (mask) { -+ case DECODER_DEVICE: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found decoder device\n", -+ saa716x->pdev->device); -+ -+ saa716x_decoder_info(saa716x, buf, offset); -+ break; -+ -+ case GPIO_SOURCE: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found GPIO device\n", -+ saa716x->pdev->device); -+ -+ saa716x_gpio_info(saa716x, buf, offset); -+ break; -+ -+ case VIDEO_DECODER: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found Video Decoder device\n", -+ saa716x->pdev->device); -+ -+ saa716x_video_decoder_info(saa716x, buf, offset); -+ break; -+ -+ case AUDIO_DECODER: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found Audio Decoder device\n", -+ saa716x->pdev->device); -+ -+ saa716x_audio_decoder_info(saa716x, buf, offset); -+ break; -+ -+ case EVENT_SOURCE: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found Event source\n", -+ saa716x->pdev->device); -+ -+ saa716x_event_source_info(saa716x, buf, offset); -+ break; -+ -+ case CROSSBAR: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found Crossbar device\n", -+ saa716x->pdev->device); -+ -+ saa716x_crossbar_info(saa716x, buf, offset); -+ break; -+ -+ case TUNER_DEVICE: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found Tuner device\n", -+ saa716x->pdev->device); -+ -+ saa716x_tuner_info(saa716x, buf, offset); -+ break; -+ -+ case PLL_DEVICE: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found PLL device\n", -+ saa716x->pdev->device); -+ -+ saa716x_pll_info(saa716x, buf, offset); -+ break; -+ -+ case CHANNEL_DECODER: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found Channel Demodulator device\n", -+ saa716x->pdev->device); -+ -+ saa716x_channel_decoder_info(saa716x, buf, offset); -+ break; -+ -+ case RDS_DECODER: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found RDS Decoder device\n", -+ saa716x->pdev->device); -+ -+ saa716x_unknown_device_info(saa716x, buf, offset); -+ break; -+ -+ case ENCODER_DEVICE: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found Encoder device\n", -+ saa716x->pdev->device); -+ -+ saa716x_encoder_info(saa716x, buf, offset); -+ break; -+ -+ case IR_DEVICE: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found IR device\n", -+ saa716x->pdev->device); -+ -+ saa716x_ir_info(saa716x, buf, offset); -+ break; -+ -+ case EEPROM_DEVICE: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found EEPROM device\n", -+ saa716x->pdev->device); -+ -+ saa716x_eeprom_info(saa716x, buf, offset); -+ break; -+ -+ case NOISE_FILTER: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found Noise filter device\n", -+ saa716x->pdev->device); -+ -+ saa716x_filter_info(saa716x, buf, offset); -+ break; -+ -+ case LNx_DEVICE: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found LNx device\n", -+ saa716x->pdev->device); -+ -+ saa716x_unknown_device_info(saa716x, buf, offset); -+ break; -+ -+ case STREAM_DEVICE: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found streaming device\n", -+ saa716x->pdev->device); -+ -+ saa716x_streamdev_info(saa716x, buf, offset); -+ break; -+ -+ case CONFIGSPACE_DEVICE: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found Configspace device\n", -+ saa716x->pdev->device); -+ -+ saa716x_unknown_device_info(saa716x, buf, offset); -+ break; -+ -+ default: -+ dprintk(SAA716x_NOTICE, 0, -+ " SAA%02x ROM: Found unknown device\n", -+ saa716x->pdev->device); -+ -+ saa716x_unknown_device_info(saa716x, buf, offset); -+ break; -+ } -+ } -+ mask <<= 1; -+ } -+ } -+ -+ dprintk(SAA716x_NOTICE, 0, "\n"); -+ -+ return 0; -+} -+ -+int saa716x_eeprom_data(struct saa716x_dev *saa716x) -+{ -+ struct saa716x_romhdr rom_header; -+ struct saa716x_devinfo *device; -+ -+ u8 *buf; -+ int i, ret = 0; -+ u32 offset = 0; -+ -+ buf = kmalloc(1024, GFP_KERNEL); -+ if (buf == NULL) { -+ dev_err(&saa716x->pdev->dev, -+ "%s: out of memory (buf)\n", __func__); -+ goto err; -+ } -+ -+ /* dump */ -+ ret = saa716x_read_rombytes(saa716x, -+ saa716x->id_offst, saa716x->id_len + 8, buf); -+ if (ret < 0) { -+ dev_err(&saa716x->pdev->dev, -+ "%s: EEPROM read error <%d>", __func__, ret); -+ goto err0; -+ } -+ -+ /* Get header */ -+ ret = saa716x_eeprom_header(saa716x, &rom_header, buf, &offset); -+ if (ret != 0) { -+ dev_err(&saa716x->pdev->dev, -+ "%s: header read failed <%d>", __func__, ret); -+ goto err0; -+ } -+ -+ /* allocate for device info */ -+ device = kzalloc(sizeof (struct saa716x_devinfo) * rom_header.devices, -+ GFP_KERNEL); -+ if (device == NULL) { -+ dev_err(&saa716x->pdev->dev, -+ "%s: out of memory (device)", __func__); -+ goto err0; -+ } -+ -+ for (i = 0; i < rom_header.devices; i++) { -+ dev_dbg(&saa716x->pdev->dev, -+ "%s: SAA%02x ROM: ===== Device %d =====\n", -+ __func__, saa716x->pdev->device, i); -+ -+ ret = saa716x_device_info(saa716x, &device[i], buf, &offset); -+ if (ret != 0) { -+ dev_err(&saa716x->pdev->dev, -+ "%s: device info read failed <%d>", __func__, ret); -+ goto err1; -+ } -+ } -+ -+ kfree(buf); -+ kfree(device); -+ return 0; -+ -+err1: -+ kfree(device); -+err0: -+ kfree(buf); -+err: -+ return ret; -+} -+EXPORT_SYMBOL_GPL(saa716x_eeprom_data); -diff --git a/drivers/media/pci/saa716x/saa716x_rom.h b/drivers/media/pci/saa716x/saa716x_rom.h -new file mode 100644 -index 0000000..bae4e11 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_rom.h -@@ -0,0 +1,254 @@ -+#ifndef __SAA716x_ROM_H -+#define __SAA716x_ROM_H -+ -+ -+#define MSB(__x) ((__x >> 8) & 0xff) -+#define LSB(__x) (__x & 0xff) -+ -+#define DUMP_BYTES 0xf0 -+#define DUMP_OFFST 0x000 -+ -+struct saa716x_dev; -+ -+struct saa716x_romhdr { -+ u16 header_size; -+ u8 compression; -+ u8 version; -+ u16 data_size; -+ u8 devices; -+ u8 checksum; -+} __attribute__((packed)); -+ -+struct saa716x_devinfo { -+ u8 struct_size; -+ u8 device_id; -+ u8 master_devid; -+ u8 master_busid; -+ u32 device_type; -+ u16 implem_id; -+ u8 path_id; -+ u8 gpio_id; -+ u16 addr_size; -+ u16 extd_data_size; -+} __attribute__((packed)); -+ -+enum saa716x_device_types { -+ DECODER_DEVICE = 0x00000001, -+ GPIO_SOURCE = 0x00000002, -+ VIDEO_DECODER = 0x00000004, -+ AUDIO_DECODER = 0x00000008, -+ EVENT_SOURCE = 0x00000010, -+ CROSSBAR = 0x00000020, -+ TUNER_DEVICE = 0x00000040, -+ PLL_DEVICE = 0x00000080, -+ CHANNEL_DECODER = 0x00000100, -+ RDS_DECODER = 0x00000200, -+ ENCODER_DEVICE = 0x00000400, -+ IR_DEVICE = 0x00000800, -+ EEPROM_DEVICE = 0x00001000, -+ NOISE_FILTER = 0x00002000, -+ LNx_DEVICE = 0x00004000, -+ STREAM_DEVICE = 0x00010000, -+ CONFIGSPACE_DEVICE = 0x80000000 -+}; -+ -+struct saa716x_decoder_hdr { -+ u8 size; -+ u8 ext_data; -+}; -+ -+struct saa716x_decoder_info { -+ struct saa716x_decoder_hdr decoder_hdr; -+ u8 *ext_data; -+}; -+ -+struct saa716x_gpio_hdr { -+ u8 size; -+ u8 pins; -+ u8 rsvd; -+ u8 ext_data; -+}; -+ -+struct saa716x_gpio_info { -+ struct saa716x_gpio_hdr gpio_hdr; -+ u8 *ext_data; -+}; -+ -+struct saa716x_video_decoder_hdr { -+ u8 size; -+ u8 video_port0; -+ u8 video_port1; -+ u8 video_port2; -+ u8 vbi_port_id; -+ u8 video_port_type; -+ u8 vbi_port_type; -+ u8 encoder_port_type; -+ u8 video_output; -+ u8 vbi_output; -+ u8 encoder_output; -+ u8 ext_data; -+}; -+ -+struct saa716x_video_decoder_info { -+ struct saa716x_video_decoder_hdr decoder_hdr; -+ u8 *ext_data; -+}; -+ -+struct saa716x_audio_decoder_hdr { -+ u8 size; -+ u8 port; -+ u8 output; -+ u8 ext_data; -+}; -+ -+struct saa716x_audio_decoder_info { -+ struct saa716x_audio_decoder_hdr decoder_hdr; -+ u8 *ext_data; -+}; -+ -+struct saa716x_evsrc_hdr { -+ u8 size; -+ u8 master_devid; -+ u16 condition_id; -+ u8 rsvd; -+ u8 ext_data; -+}; -+ -+struct saa716x_evsrc_info { -+ struct saa716x_evsrc_hdr evsrc_hdr; -+ u8 *ext_data; -+}; -+ -+enum saa716x_input_pair_type { -+ TUNER_SIF = 0x00, -+ TUNER_LINE = 0x01, -+ TUNER_SPDIF = 0x02, -+ TUNER_NONE = 0x03, -+ CVBS_LINE = 0x04, -+ CVBS_SPDIF = 0x05, -+ CVBS_NONE = 0x06, -+ YC_LINE = 0x07, -+ YC_SPDIF = 0x08, -+ YC_NONE = 0x09, -+ YPbPr_LINE = 0x0a, -+ YPbPr_SPDIF = 0x0b, -+ YPbPr_NONE = 0x0c, -+ NO_LINE = 0x0d, -+ NO_SPDIF = 0x0e, -+ RGB_LINE = 0x0f, -+ RGB_SPDIF = 0x10, -+ RGB_NONE = 0x11 -+}; -+ -+struct saa716x_xbar_pair_info { -+ u8 pair_input_type; -+ u8 video_input_id; -+ u8 audio_input_id; -+}; -+ -+struct saa716x_xbar_hdr { -+ u8 size; -+ u8 pair_inputs; -+ u8 pair_route_default; -+ u8 ext_data; -+}; -+ -+struct saa716x_xbar_info { -+ struct saa716x_xbar_hdr xbar_hdr; -+ struct saa716x_xbar_pair_info *pair_info; -+ u8 *ext_data; -+}; -+ -+struct saa716x_tuner_hdr { -+ u8 size; -+ u8 ext_data; -+}; -+ -+struct saa716x_tuner_info { -+ struct saa716x_tuner_hdr tuner_hdr; -+ u8 *ext_data; -+}; -+ -+struct saa716x_pll_hdr { -+ u8 size; -+ u8 ext_data; -+}; -+ -+struct saa716x_pll_info { -+ struct saa716x_pll_hdr pll_hdr; -+ u8 *ext_data; -+}; -+ -+struct saa716x_channel_decoder_hdr { -+ u8 size; -+ u8 port; -+ u8 ext_data; -+}; -+ -+struct saa716x_channel_decoder_info { -+ struct saa716x_channel_decoder_hdr channel_dec_hdr; -+ u8 *ext_data; -+}; -+ -+struct saa716x_encoder_hdr { -+ u8 size; -+ u8 stream_port0; -+ u8 stream_port1; -+ u8 ext_data; -+}; -+ -+struct saa716x_encoder_info { -+ struct saa716x_encoder_hdr encoder_hdr; -+ u8 *ext_data; -+}; -+ -+struct saa716x_ir_hdr { -+ u8 size; -+ u8 ir_caps; -+ u8 ext_data; -+}; -+ -+struct saa716x_ir_info { -+ struct saa716x_ir_hdr ir_hdr; -+ u8 *ext_data; -+}; -+ -+struct saa716x_eeprom_hdr { -+ u8 size; -+ u8 rel_device; -+ u8 ext_data; -+}; -+ -+struct saa716x_eeprom_info { -+ struct saa716x_eeprom_hdr eeprom_hdr; -+ u8 *ext_data; -+}; -+ -+struct saa716x_filter_hdr { -+ u8 size; -+ u8 video_decoder; -+ u8 audio_decoder; -+ u8 event_source; -+ u8 ext_data; -+}; -+ -+struct saa716x_filter_info { -+ struct saa716x_filter_hdr filter_hdr; -+ u8 *ext_data; -+}; -+ -+struct saa716x_streamdev_hdr { -+ u8 size; -+ u8 ext_data; -+}; -+ -+struct saa716x_streamdev_info { -+ struct saa716x_streamdev_hdr streamdev_hdr; -+ u8 *ext_data; -+}; -+ -+extern int saa716x_read_rombytes(struct saa716x_dev *saa716x, u16 reg, u16 len, u8 *val); -+extern int saa716x_dump_eeprom(struct saa716x_dev *saa716x); -+extern int saa716x_eeprom_data(struct saa716x_dev *saa716x); -+ -+#endif /* __SAA716x_ROM_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_spi.c b/drivers/media/pci/saa716x/saa716x_spi.c -new file mode 100644 -index 0000000..8859454 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_spi.c -@@ -0,0 +1,313 @@ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_spi_reg.h" -+#include "saa716x_spi.h" -+#include "saa716x_priv.h" -+ -+#if 0 // not needed atm -+int saa716x_spi_irqevent(struct saa716x_dev *saa716x) -+{ -+ u32 stat, mask; -+ -+ BUG_ON(saa716x == NULL); -+ -+ stat = SAA716x_EPRD(SPI, SPI_STATUS); -+ mask = SAA716x_EPRD(SPI, SPI_CONTROL_REG) & SPI_SERIAL_INTER_ENABLE; -+ if ((!stat && !mask)) -+ return -1; -+ -+ dprintk(SAA716x_DEBUG, 0, "SPI event: Stat=<%02x>", stat); -+ -+ if (stat & SPI_TRANSFER_FLAG) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ if (stat & SPI_WRITE_COLLISSION) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ if (stat & SPI_READ_OVERRUN) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ if (stat & SPI_MODE_FAULT) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ if (stat & SPI_SLAVE_ABORT) -+ dprintk(SAA716x_DEBUG, 0, " "); -+ -+ return 0; -+} -+#endif -+ -+void saa716x_spi_write(struct saa716x_dev *saa716x, const u8 *data, int length) -+{ -+ int i; -+ u32 value; -+ int rounds; -+ -+ for (i = 0; i < length; i++) { -+ SAA716x_EPWR(SPI, SPI_DATA, data[i]); -+ rounds = 0; -+ value = SAA716x_EPRD(SPI, SPI_STATUS); -+ -+ while ((value & SPI_TRANSFER_FLAG) == 0 && rounds < 5000) { -+ value = SAA716x_EPRD(SPI, SPI_STATUS); -+ rounds++; -+ } -+ } -+} -+EXPORT_SYMBOL_GPL(saa716x_spi_write); -+ -+#if 0 // not needed atm -+static int saa716x_spi_status(struct saa716x_dev *saa716x, u32 *status) -+{ -+ u32 stat; -+ -+ stat = SAA716x_EPRD(SPI, SPI_STATUS); -+ -+ if (stat & SPI_TRANSFER_FLAG) -+ dprintk(SAA716x_DEBUG, 1, "Transfer complete <%02x>", stat); -+ -+ if (stat & SPI_WRITE_COLLISSION) -+ dprintk(SAA716x_DEBUG, 1, "Write collission <%02x>", stat); -+ -+ if (stat & SPI_READ_OVERRUN) -+ dprintk(SAA716x_DEBUG, 1, "Read Overrun <%02x>", stat); -+ -+ if (stat & SPI_MODE_FAULT) -+ dprintk(SAA716x_DEBUG, 1, "MODE fault <%02x>", stat); -+ -+ if (stat & SPI_SLAVE_ABORT) -+ dprintk(SAA716x_DEBUG, 1, "SLAVE abort <%02x>", stat); -+ -+ *status = stat; -+ -+ return 0; -+} -+ -+#define SPI_CYCLE_TIMEOUT 100 -+ -+static int saa716x_spi_xfer(struct saa716x_dev *saa716x, u32 *data) -+{ -+ u32 i, status = 0; -+ -+ /* write data and wait for completion */ -+ SAA716x_EPWR(SPI, SPI_DATA, data[i]); -+ for (i = 0; i < SPI_CYCLE_TIMEOUT; i++) { -+ msleep(10); -+ saa716x_spi_status(saa716x, &status); -+#if 0 -+ if (status & SPI_TRANSFER_FLAG) { -+ data = SAA716x_EPRD(SPI, SPI_DATA); -+ return 0; -+ } -+#endif -+ if (status & (SPI_WRITE_COLLISSION | -+ SPI_READ_OVERRUN | -+ SPI_MODE_FAULT | -+ SPI_SLAVE_ABORT)) -+ -+ return -EIO; -+ } -+ -+ return -EIO; -+} -+ -+#if 0 -+static int saa716x_spi_wr(struct saa716x_dev *saa716x, const u8 *data, int length) -+{ -+ struct saa716x_spi_config *config = saa716x->spi_config; -+ u32 gpio_mask; -+ int ret = 0; -+ -+ // protect against multiple access -+ spin_lock(&saa716x->gpio_lock); -+ -+ // configure the module -+ saa716x_spi_config(saa716x); -+ -+ // check input -+ -+ // change polarity of GPIO if active high -+ if (config->active_hi) { -+ select = 1; -+ release = 0; -+ } -+ -+ // configure GPIO, first set output register to low selected level -+ saa716x_gpio_write(saa716x, gpio, select); -+ -+ // set mode register to register controlled (0) -+ gpio_mask = (1 << gpio); -+ saa716x_set_gpio_mode(saa716x, gpio_mask, 0); -+ -+ // configure bit as output (0) -+ saa716x_gpio_ctl(saa716x, gpio_mask, 0); -+ -+ // wait at least 500ns before sending a byte -+ msleep(1); -+ -+ // send command -+ for (i = 0; i < dwCommandSize; i++) { -+ ucData = 0; -+// dwStatus = TransferData(pucCommand[i], &ucData); -+ ret = saa716x_spi_xfer(saa716x); -+ //tmDBGPRINTEx(4,("Info: Command 0x%x ", pucCommand[i] )); -+ -+ /* If command length > 1, disable CS at the end of each command. -+ * But after the last command byte CS must be left active! -+ */ -+ if ((dwCommandSize > 1) && (i < dwCommandSize - 1)) { -+ -+ saa716x_gpio_write(saa716x, gpio, release); -+ msleep(1); /* 500 nS minimum */ -+ saa716x_gpio_write(saa716x, gpio, select); -+ } -+ -+ if (ret != 0) { -+ dprintk(SAA716x_ERROR, 1, "ERROR: Command transfer failed"); -+ msleep(1); /* 500 nS minimum */ -+ saa716x_gpio_write(saa716x, gpio, release); /* release GPIO */ -+ spin_unlock(&saa716x->spi_lock); -+ return ret; -+ } -+ -+ if (config->LSB_first) -+ dwTransferByte++; -+ else -+ dwTransferByte--; -+ } -+ -+// assume that the byte order is the same as the bit order -+ -+// send read address -+ -+// send data -+ -+// wait at least 500ns before releasing slave -+ -+// release GPIO pin -+ -+ // release spinlock -+ spin_unlock(&saa716x->gpio_lock); -+} -+#endif -+ -+#define MODEBITS (SPI_CPOL | SPI_CPHA) -+ -+static int saa716x_spi_setup(struct spi_device *spi) -+{ -+ struct spi_master *master = spi->master; -+ struct saa716x_spi_state *saa716x_spi = spi_master_get_devdata(master); -+ struct saa716x_dev *saa716x = saa716x_spi->saa716x; -+ struct saa716x_spi_config *config = &saa716x->spi_config; -+ -+ u8 control = 0; -+ -+ if (spi->mode & ~MODEBITS) { -+ dprintk(SAA716x_ERROR, 1, "ERROR: Unsupported MODE bits <%x>", -+ spi->mode & ~MODEBITS); -+ -+ return -EINVAL; -+ } -+ -+ SAA716x_EPWR(SPI, SPI_CLOCK_COUNTER, config->clk_count); -+ -+ control |= SPI_MODE_SELECT; /* SPI Master */ -+ -+ if (config->LSB_first) -+ control |= SPI_LSB_FIRST_ENABLE; -+ -+ if (config->clk_pol) -+ control |= SPI_CLOCK_POLARITY; -+ -+ if (config->clk_pha) -+ control |= SPI_CLOCK_PHASE; -+ -+ SAA716x_EPWR(SPI, SPI_CONTROL_REG, control); -+ -+ return 0; -+} -+ -+static void saa716x_spi_cleanup(struct spi_device *spi) -+{ -+ -+} -+ -+static int saa716x_spi_transfer(struct spi_device *spi, struct spi_message *msg) -+{ -+ struct spi_master *master = spi->master; -+ struct saa716x_spi_state *saa716x_spi = spi_master_get_devdata(master); -+ struct saa716x_dev *saa716x = saa716x_spi->saa716x; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&saa716x->gpio_lock, flags); -+#if 0 -+ if (saa716x_spi->run == QUEUE_STOPPED) { -+ spin_unlock_irqrestore(&saa716x_spi->lock, flags); -+ return -ESHUTDOWN; -+ } -+ -+ msg->actual_length = 0; -+ msg->status = -EINPROGRESS; -+ msg->state = START_STATE; -+ -+ list_add_tail(&msg->queue, &saa716x_spi->queue); -+ -+ if (saa716x_spi->run == QUEUE_RUNNING && !saa716x_spi->busy) -+ queue_work(saa716x_spi->workqueue, &saa716x_spi->pump_messages); -+#endif -+ spin_unlock_irqrestore(&saa716x->gpio_lock, flags); -+ -+ return 0; -+} -+ -+int saa716x_spi_init(struct saa716x_dev *saa716x) -+{ -+ struct pci_dev *pdev = saa716x->pdev; -+ struct spi_master *master; -+ struct saa716x_spi_state *saa716x_spi; -+ int ret; -+ -+ dprintk(SAA716x_DEBUG, 1, "Initializing SAA%02x I2C Core", -+ saa716x->pdev->device); -+ -+ master = spi_alloc_master(&pdev->dev, sizeof (struct saa716x_spi_state)); -+ if (master == NULL) { -+ dprintk(SAA716x_ERROR, 1, "ERROR: Cannot allocate SPI Master!"); -+ return -ENOMEM; -+ } -+ -+ saa716x_spi = spi_master_get_devdata(master); -+ saa716x_spi->master = master; -+ saa716x_spi->saa716x = saa716x; -+ saa716x->saa716x_spi = saa716x_spi; -+ -+ master->bus_num = pdev->bus->number; -+ master->num_chipselect = 1; /* TODO! use config */ -+ master->cleanup = saa716x_spi_cleanup; -+ master->setup = saa716x_spi_setup; -+ master->transfer = saa716x_spi_transfer; -+ -+ ret = spi_register_master(master); -+ if (ret != 0) { -+ dprintk(SAA716x_ERROR, 1, "ERROR: registering SPI Master!"); -+ goto err; -+ } -+err: -+ spi_master_put(master); -+ return ret; -+} -+EXPORT_SYMBOL(saa716x_spi_init); -+ -+void saa716x_spi_exit(struct saa716x_dev *saa716x) -+{ -+ struct saa716x_spi_state *saa716x_spi = saa716x->saa716x_spi; -+ -+ spi_unregister_master(saa716x_spi->master); -+ dprintk(SAA716x_DEBUG, 1, "SAA%02x SPI succesfully removed", saa716x->pdev->device); -+} -+EXPORT_SYMBOL(saa716x_spi_exit); -+#endif -+ -diff --git a/drivers/media/pci/saa716x/saa716x_spi.h b/drivers/media/pci/saa716x/saa716x_spi.h -new file mode 100644 -index 0000000..0060c22 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_spi.h -@@ -0,0 +1,23 @@ -+#ifndef __SAA716x_SPI_H -+#define __SAA716x_SPI_H -+ -+struct saa716x_dev; -+ -+struct saa716x_spi_config { -+ u8 clk_count; -+ u8 clk_pol:1; -+ u8 clk_pha:1; -+ u8 LSB_first:1; -+}; -+ -+struct saa716x_spi_state { -+ struct spi_master *master; -+ struct saa716x_dev *saa716x; -+}; -+ -+extern void saa716x_spi_write(struct saa716x_dev *saa716x, const u8 *data, int length); -+ -+extern int saa716x_spi_init(struct saa716x_dev *saa716x); -+extern void saa716x_spi_exit(struct saa716x_dev *saa716x); -+ -+#endif /* __SAA716x_SPI_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_spi_reg.h b/drivers/media/pci/saa716x/saa716x_spi_reg.h -new file mode 100644 -index 0000000..c51abce ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_spi_reg.h -@@ -0,0 +1,27 @@ -+#ifndef __SAA716x_SPI_REG_H -+#define __SAA716x_SPI_REG_H -+ -+/* -------------- SPI Registers -------------- */ -+ -+#define SPI_CONTROL_REG 0x000 -+#define SPI_SERIAL_INTER_ENABLE (0x00000001 << 7) -+#define SPI_LSB_FIRST_ENABLE (0x00000001 << 6) -+#define SPI_MODE_SELECT (0x00000001 << 5) -+#define SPI_CLOCK_POLARITY (0x00000001 << 4) -+#define SPI_CLOCK_PHASE (0x00000001 << 3) -+ -+#define SPI_STATUS 0x004 -+#define SPI_TRANSFER_FLAG (0x00000001 << 7) -+#define SPI_WRITE_COLLISSION (0x00000001 << 6) -+#define SPI_READ_OVERRUN (0x00000001 << 5) -+#define SPI_MODE_FAULT (0x00000001 << 4) -+#define SPI_SLAVE_ABORT (0x00000001 << 3) -+ -+#define SPI_DATA 0x008 -+#define SPI_BIDI_DATA (0x000000ff << 0) -+ -+#define SPI_CLOCK_COUNTER 0x00c -+#define SPI_CLOCK (0x00000001 << 0) -+ -+ -+#endif /* __SAA716x_SPI_REG_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_vip.c b/drivers/media/pci/saa716x/saa716x_vip.c -new file mode 100644 -index 0000000..641a104 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_vip.c -@@ -0,0 +1,401 @@ -+#include -+ -+#include "saa716x_mod.h" -+ -+#include "saa716x_vip_reg.h" -+#include "saa716x_dma_reg.h" -+#include "saa716x_msi_reg.h" -+ -+#include "saa716x_priv.h" -+ -+ -+static const u32 vi_ch[] = { -+ VI0, -+ VI1 -+}; -+ -+static const u32 msi_int_tagack[] = { -+ MSI_INT_TAGACK_VI0_0, -+ MSI_INT_TAGACK_VI0_1, -+ MSI_INT_TAGACK_VI0_2, -+ MSI_INT_TAGACK_VI1_0, -+ MSI_INT_TAGACK_VI1_1, -+ MSI_INT_TAGACK_VI1_2 -+}; -+ -+static const u32 msi_int_avint[] = { -+ MSI_INT_AVINT_VI0, -+ MSI_INT_AVINT_VI1 -+}; -+ -+void saa716x_vipint_disable(struct saa716x_dev *saa716x) -+{ -+ SAA716x_EPWR(VI0, INT_ENABLE, 0); /* disable VI 0 IRQ */ -+ SAA716x_EPWR(VI1, INT_ENABLE, 0); /* disable VI 1 IRQ */ -+ SAA716x_EPWR(VI0, INT_CLR_STATUS, 0x3ff); /* clear IRQ */ -+ SAA716x_EPWR(VI1, INT_CLR_STATUS, 0x3ff); /* clear IRQ */ -+} -+EXPORT_SYMBOL_GPL(saa716x_vipint_disable); -+ -+void saa716x_vip_disable(struct saa716x_dev *saa716x) -+{ -+ SAA716x_EPWR(VI0, VIP_POWER_DOWN, VI_PWR_DWN); -+ SAA716x_EPWR(VI1, VIP_POWER_DOWN, VI_PWR_DWN); -+} -+EXPORT_SYMBOL_GPL(saa716x_vip_disable); -+ -+int saa716x_vip_get_write_index(struct saa716x_dev *saa716x, int port) -+{ -+ u32 buf_mode, val; -+ -+ buf_mode = BAM_DMA_BUF_MODE(saa716x->vip[port].dma_channel[0]); -+ -+ val = SAA716x_EPRD(BAM, buf_mode); -+ return (val >> 3) & 0x7; -+} -+EXPORT_SYMBOL_GPL(saa716x_vip_get_write_index); -+ -+static int saa716x_vip_init_ptables(struct saa716x_dmabuf *dmabuf, int channel, -+ struct vip_stream_params *stream_params) -+{ -+ struct saa716x_dev *saa716x = dmabuf->saa716x; -+ u32 config, i; -+ -+ for (i = 0; i < VIP_BUFFERS; i++) -+ BUG_ON((dmabuf[i].mem_ptab_phys == 0)); -+ -+ config = MMU_DMA_CONFIG(channel); /* DMACONFIGx */ -+ -+ SAA716x_EPWR(MMU, config, (VIP_BUFFERS - 1)); -+ -+ if ((stream_params->stream_flags & VIP_INTERLACED) && -+ (stream_params->stream_flags & VIP_ODD_FIELD) && -+ (stream_params->stream_flags & VIP_EVEN_FIELD)) { -+ /* In interlaced mode the same buffer is written twice, once -+ the odd field and once the even field */ -+ SAA716x_EPWR(MMU, MMU_PTA0_LSB(channel), PTA_LSB(dmabuf[0].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA0_MSB(channel), PTA_MSB(dmabuf[0].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA1_LSB(channel), PTA_LSB(dmabuf[0].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA1_MSB(channel), PTA_MSB(dmabuf[0].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA2_LSB(channel), PTA_LSB(dmabuf[1].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA2_MSB(channel), PTA_MSB(dmabuf[1].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA3_LSB(channel), PTA_LSB(dmabuf[1].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA3_MSB(channel), PTA_MSB(dmabuf[1].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA4_LSB(channel), PTA_LSB(dmabuf[2].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA4_MSB(channel), PTA_MSB(dmabuf[2].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA5_LSB(channel), PTA_LSB(dmabuf[2].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA5_MSB(channel), PTA_MSB(dmabuf[2].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA6_LSB(channel), PTA_LSB(dmabuf[3].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA6_MSB(channel), PTA_MSB(dmabuf[3].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA7_LSB(channel), PTA_LSB(dmabuf[3].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA7_MSB(channel), PTA_MSB(dmabuf[3].mem_ptab_phys)); /* High */ -+ } else { -+ SAA716x_EPWR(MMU, MMU_PTA0_LSB(channel), PTA_LSB(dmabuf[0].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA0_MSB(channel), PTA_MSB(dmabuf[0].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA1_LSB(channel), PTA_LSB(dmabuf[1].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA1_MSB(channel), PTA_MSB(dmabuf[1].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA2_LSB(channel), PTA_LSB(dmabuf[2].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA2_MSB(channel), PTA_MSB(dmabuf[2].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA3_LSB(channel), PTA_LSB(dmabuf[3].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA3_MSB(channel), PTA_MSB(dmabuf[3].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA4_LSB(channel), PTA_LSB(dmabuf[4].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA4_MSB(channel), PTA_MSB(dmabuf[4].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA5_LSB(channel), PTA_LSB(dmabuf[5].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA5_MSB(channel), PTA_MSB(dmabuf[5].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA6_LSB(channel), PTA_LSB(dmabuf[6].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA6_MSB(channel), PTA_MSB(dmabuf[6].mem_ptab_phys)); /* High */ -+ SAA716x_EPWR(MMU, MMU_PTA7_LSB(channel), PTA_LSB(dmabuf[7].mem_ptab_phys)); /* Low */ -+ SAA716x_EPWR(MMU, MMU_PTA7_MSB(channel), PTA_MSB(dmabuf[7].mem_ptab_phys)); /* High */ -+ } -+ return 0; -+} -+ -+static int saa716x_vip_setparams(struct saa716x_dev *saa716x, int port, -+ struct vip_stream_params *stream_params) -+{ -+ u32 vi_port, buf_mode, mid, val, i; -+ u8 dma_channel; -+ u32 num_pages; -+ u32 start_x, start_line, end_line, num_lines; -+ u32 base_address, base_offset, pitch; -+ u32 vin_format; -+ -+ vi_port = vi_ch[port]; -+ buf_mode = BAM_DMA_BUF_MODE(saa716x->vip[port].dma_channel[0]); -+ dma_channel = saa716x->vip[port].dma_channel[0]; -+ -+ /* number of pages needed for a buffer */ -+ num_pages = (stream_params->bits / 8 * stream_params->samples -+ * stream_params->lines) / SAA716x_PAGE_SIZE; -+ /* check if these will fit into one page table */ -+ if (num_pages > (SAA716x_PAGE_SIZE / 8)) -+ saa716x->vip[port].dual_channel = 1; -+ else -+ saa716x->vip[port].dual_channel = 0; -+ -+ /* Reset DMA channel */ -+ SAA716x_EPWR(BAM, buf_mode, 0x00000040); -+ saa716x_vip_init_ptables(saa716x->vip[port].dma_buf[0], -+ saa716x->vip[port].dma_channel[0], -+ stream_params); -+ if (saa716x->vip[port].dual_channel) -+ saa716x_vip_init_ptables(saa716x->vip[port].dma_buf[1], -+ saa716x->vip[port].dma_channel[1], -+ stream_params); -+ -+ /* get module ID */ -+ mid = SAA716x_EPRD(vi_port, VI_MODULE_ID); -+ if (mid != 0x11A5100) { -+ dprintk(SAA716x_ERROR, 1, "VIP Id<%04x> is not supported", mid); -+ return -1; -+ } -+ -+ start_x = stream_params->offset_x; -+ start_line = stream_params->offset_y + 1; -+ end_line = 0; -+ num_lines = stream_params->lines; -+ pitch = stream_params->pitch; -+ base_address = saa716x->vip[port].dma_channel[0] << 21; -+ base_offset = 0; -+ vin_format = 0x00004000; -+ -+ if ((stream_params->stream_flags & VIP_INTERLACED) && -+ (stream_params->stream_flags & VIP_ODD_FIELD) && -+ (stream_params->stream_flags & VIP_EVEN_FIELD)) { -+ num_lines /= 2; -+ pitch *= 2; -+ base_offset = stream_params->pitch; -+ } -+ if (stream_params->stream_flags & VIP_HD) { -+ if (stream_params->stream_flags & VIP_INTERLACED) { -+ vin_format |= 0x01000000; -+ } else { -+ /* suppress the windower break message */ -+ vin_format |= 0x01000200; -+ } -+ } -+ if (stream_params->stream_flags & VIP_NO_SCALER) { -+ vin_format |= 0x00000400; -+ } -+ -+ end_line = stream_params->offset_y + num_lines; -+ -+ /* set device to normal operation */ -+ SAA716x_EPWR(vi_port, VIP_POWER_DOWN, 0); -+ /* disable ANC bit detection */ -+ SAA716x_EPWR(vi_port, ANC_DID_FIELD0, 0); -+ SAA716x_EPWR(vi_port, ANC_DID_FIELD1, 0); -+ /* set line threshold to 0 (interrupt is disabled anyway)*/ -+ SAA716x_EPWR(vi_port, VI_LINE_THRESH, 0); -+ -+ vin_format |= 2; -+ SAA716x_EPWR(vi_port, VIN_FORMAT, vin_format); -+ -+ /* disable dithering */ -+ SAA716x_EPWR(vi_port, PRE_DIT_CTRL, 0); -+ SAA716x_EPWR(vi_port, POST_DIT_CTRL, 0); -+ /* set alpha value */ -+ SAA716x_EPWR(vi_port, CSM_CKEY, 0); -+ -+ SAA716x_EPWR(vi_port, WIN_XYSTART, (start_x << 16) + start_line); -+ SAA716x_EPWR(vi_port, WIN_XYEND, -+ ((start_x + stream_params->samples - 1) << 16) + end_line); -+ -+ /* enable cropping to assure that VIP does not exceed buffer boundaries */ -+ SAA716x_EPWR(vi_port, PSU_WINDOW, -+ (stream_params->samples << 16) + num_lines); -+ /* set packet YUY2 output format */ -+ SAA716x_EPWR(vi_port, PSU_FORMAT, 0x800000A1); -+ -+ SAA716x_EPWR(vi_port, PSU_BASE1, base_address); -+ SAA716x_EPWR(vi_port, PSU_PITCH1, pitch); -+ SAA716x_EPWR(vi_port, PSU_PITCH2, 0); -+ SAA716x_EPWR(vi_port, PSU_BASE2, 0); -+ SAA716x_EPWR(vi_port, PSU_BASE3, 0); -+ SAA716x_EPWR(vi_port, PSU_BASE4, base_address + base_offset); -+ SAA716x_EPWR(vi_port, PSU_BASE5, 0); -+ SAA716x_EPWR(vi_port, PSU_BASE6, 0); -+ -+ /* monitor BAM reset */ -+ i = 0; -+ val = SAA716x_EPRD(BAM, buf_mode); -+ while (val && (i < 100)) { -+ msleep(30); -+ val = SAA716x_EPRD(BAM, buf_mode); -+ i++; -+ } -+ if (val) { -+ dprintk(SAA716x_ERROR, 1, "Error: BAM VIP Reset failed!"); -+ return -EIO; -+ } -+ -+ /* set buffer count */ -+ SAA716x_EPWR(BAM, buf_mode, VIP_BUFFERS - 1); -+ /* initialize all available address offsets to 0 */ -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_0(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_1(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_2(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_3(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_4(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_5(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_6(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_7(dma_channel), 0x0); -+ -+ if (saa716x->vip[port].dual_channel) { -+ buf_mode = BAM_DMA_BUF_MODE(saa716x->vip[port].dma_channel[1]); -+ dma_channel = saa716x->vip[port].dma_channel[1]; -+ -+ /* set buffer count */ -+ SAA716x_EPWR(BAM, buf_mode, VIP_BUFFERS - 1); -+ /* initialize all available address offsets to 0 */ -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_0(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_1(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_2(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_3(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_4(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_5(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_6(dma_channel), 0x0); -+ SAA716x_EPWR(BAM, BAM_ADDR_OFFSET_7(dma_channel), 0x0); -+ } -+ -+ return 0; -+} -+ -+int saa716x_vip_start(struct saa716x_dev *saa716x, int port, int one_shot, -+ struct vip_stream_params *stream_params) -+{ -+ u32 vi_port; -+ u32 config1; -+ u32 config2; -+ u32 val; -+ u32 i; -+ -+ vi_port = vi_ch[port]; -+ config1 = MMU_DMA_CONFIG(saa716x->vip[port].dma_channel[0]); -+ config2 = MMU_DMA_CONFIG(saa716x->vip[port].dma_channel[1]); -+ -+ if (saa716x_vip_setparams(saa716x, port, stream_params) != 0) { -+ return -EIO; -+ } -+ -+ val = SAA716x_EPRD(MMU, config1); -+ SAA716x_EPWR(MMU, config1, val & ~0x40); -+ SAA716x_EPWR(MMU, config1, val | 0x40); -+ if (saa716x->vip[port].dual_channel) { -+ val = SAA716x_EPRD(MMU, config2); -+ SAA716x_EPWR(MMU, config2, val & ~0x40); -+ SAA716x_EPWR(MMU, config2, val | 0x40); -+ } -+ -+ SAA716x_EPWR(vi_port, INT_ENABLE, 0x33F); -+ -+ i = 0; -+ while (i < 500) { -+ val = SAA716x_EPRD(MMU, config1); -+ if (saa716x->vip[port].dual_channel) -+ val &= SAA716x_EPRD(MMU, config2); -+ if (val & 0x80) -+ break; -+ msleep(10); -+ i++; -+ } -+ -+ if (!(val & 0x80)) { -+ dprintk(SAA716x_ERROR, 1, "Error: PTE pre-fetch failed!"); -+ return -EIO; -+ } -+ -+ /* enable video capture path */ -+ val = SAA716x_EPRD(vi_port, VI_MODE); -+ val &= ~(VID_CFEN | VID_FSEQ | VID_OSM); -+ -+ if ((stream_params->stream_flags & VIP_INTERLACED) && -+ (stream_params->stream_flags & VIP_ODD_FIELD) && -+ (stream_params->stream_flags & VIP_EVEN_FIELD)) { -+ val |= VID_CFEN_BOTH; /* capture both fields */ -+ val |= VID_FSEQ; /* start capture with odd field */ -+ } else { -+ val |= VID_CFEN_BOTH; /* capture both fields */ -+ } -+ -+ if (one_shot) -+ val |= VID_OSM; /* stop capture after receiving one frame */ -+ -+ saa716x_set_clk_external(saa716x, saa716x->vip[port].dma_channel[0]); -+ -+ SAA716x_EPWR(vi_port, VI_MODE, val); -+ -+ SAA716x_EPWR(MSI, MSI_INT_ENA_SET_L, msi_int_tagack[port]); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_vip_start); -+ -+int saa716x_vip_stop(struct saa716x_dev *saa716x, int port) -+{ -+ u32 val; -+ -+ SAA716x_EPWR(MSI, MSI_INT_ENA_CLR_L, msi_int_tagack[port]); -+ -+ /* disable capture */ -+ val = SAA716x_EPRD(vi_ch[port], VI_MODE); -+ val &= ~VID_CFEN; -+ SAA716x_EPWR(vi_ch[port], VI_MODE, val); -+ -+ saa716x_set_clk_internal(saa716x, saa716x->vip[port].dma_channel[0]); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_vip_stop); -+ -+int saa716x_vip_init(struct saa716x_dev *saa716x, int port, -+ void (*worker)(unsigned long)) -+{ -+ int n; -+ int i; -+ int ret; -+ -+ /* reset VI */ -+ SAA716x_EPWR(vi_ch[port], VI_MODE, SOFT_RESET); -+ -+ for (n = 0; n < 2; n++) -+ { -+ saa716x->vip[port].dma_channel[n] = port * 3 + n; -+ for (i = 0; i < VIP_BUFFERS; i++) -+ { -+ ret = saa716x_dmabuf_alloc( -+ saa716x, -+ &saa716x->vip[port].dma_buf[n][i], -+ 512 * SAA716x_PAGE_SIZE); -+ if (ret < 0) { -+ return ret; -+ } -+ } -+ } -+ saa716x->vip[port].saa716x = saa716x; -+ tasklet_init(&saa716x->vip[port].tasklet, worker, -+ (unsigned long)&saa716x->vip[port]); -+ saa716x->vip[port].read_index = 0; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_vip_init); -+ -+int saa716x_vip_exit(struct saa716x_dev *saa716x, int port) -+{ -+ int n; -+ int i; -+ -+ tasklet_kill(&saa716x->vip[port].tasklet); -+ for (n = 0; n < 2; n++) -+ { -+ for (i = 0; i < VIP_BUFFERS; i++) -+ { -+ saa716x_dmabuf_free( -+ saa716x, &saa716x->vip[port].dma_buf[n][i]); -+ } -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(saa716x_vip_exit); -diff --git a/drivers/media/pci/saa716x/saa716x_vip.h b/drivers/media/pci/saa716x/saa716x_vip.h -new file mode 100644 -index 0000000..b81da96 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_vip.h -@@ -0,0 +1,58 @@ -+#ifndef __SAA716x_VIP_H -+#define __SAA716x_VIP_H -+ -+#include "saa716x_dma.h" -+ -+#define VIP_BUFFERS 8 -+ -+/* -+ * Stream port flags -+ */ -+enum vip_stream_flags { -+ VIP_ODD_FIELD = 0x0001, -+ VIP_EVEN_FIELD = 0x0002, -+ VIP_INTERLACED = 0x0004, -+ VIP_HD = 0x0010, -+ VIP_NO_SCALER = 0x0100 -+}; -+ -+/* -+ * Stream port parameters -+ * bits: Bits per sample -+ * samples: samples perline -+ * lines: number of lines -+ * pitch: stream pitch in bytes -+ * offset_x: offset to first valid pixel -+ * offset_y: offset to first valid line -+ */ -+struct vip_stream_params { -+ u32 bits; -+ u32 samples; -+ u32 lines; -+ s32 pitch; -+ u32 offset_x; -+ u32 offset_y; -+ enum vip_stream_flags stream_flags; -+}; -+ -+struct saa716x_vip_stream_port { -+ u8 dual_channel; -+ u8 read_index; -+ u8 dma_channel[2]; -+ struct saa716x_dmabuf dma_buf[2][VIP_BUFFERS]; -+ struct saa716x_dev *saa716x; -+ struct tasklet_struct tasklet; -+}; -+ -+extern void saa716x_vipint_disable(struct saa716x_dev *saa716x); -+extern void saa716x_vip_disable(struct saa716x_dev *saa716x); -+extern int saa716x_vip_get_write_index(struct saa716x_dev *saa716x, int port); -+extern int saa716x_vip_start(struct saa716x_dev *saa716x, int port, -+ int one_shot, -+ struct vip_stream_params *stream_params); -+extern int saa716x_vip_stop(struct saa716x_dev *saa716x, int port); -+extern int saa716x_vip_init(struct saa716x_dev *saa716x, int port, -+ void (*worker)(unsigned long)); -+extern int saa716x_vip_exit(struct saa716x_dev *saa716x, int port); -+ -+#endif /* __SAA716x_VIP_H */ -diff --git a/drivers/media/pci/saa716x/saa716x_vip_reg.h b/drivers/media/pci/saa716x/saa716x_vip_reg.h -new file mode 100644 -index 0000000..b064c35 ---- /dev/null -+++ b/drivers/media/pci/saa716x/saa716x_vip_reg.h -@@ -0,0 +1,141 @@ -+#ifndef __SAA716x_VIP_REG_H -+#define __SAA716x_VIP_REG_H -+ -+/* -------------- VIP Registers -------------- */ -+ -+#define VI_MODE 0x000 -+#define VID_CFEN (0x00000003 << 30) -+#define VID_CFEN_ODD (0x00000001 << 30) -+#define VID_CFEN_EVEN (0x00000002 << 30) -+#define VID_CFEN_BOTH (0x00000003 << 30) -+#define VID_OSM (0x00000001 << 29) -+#define VID_FSEQ (0x00000001 << 28) -+#define AUX_CFEN (0x00000003 << 26) -+#define AUX_OSM (0x00000001 << 25) -+#define AUX_FSEQ (0x00000001 << 24) -+#define AUX_ANC_DATA (0x00000003 << 22) -+#define AUX_ANC_RAW (0x00000001 << 21) -+#define RST_ON_ERR (0x00000001 << 17) -+#define SOFT_RESET (0x00000001 << 16) -+#define IFF_CLAMP (0x00000001 << 14) -+#define IFF_MODE (0x00000003 << 12) -+#define DFF_CLAMP (0x00000001 << 10) -+#define DFF_MODE (0x00000003 << 8) -+#define HSP_CLAMP (0x00000001 << 3) -+#define HSP_RGB (0x00000001 << 2) -+#define HSP_MODE (0x00000003 << 0) -+ -+#define ANC_DID_FIELD0 0x020 -+#define VI_ID_MASK_0 (0x000000ff << 8) -+#define VI_DATA_ID_0 (0x000000ff << 0) -+ -+#define ANC_DID_FIELD1 0x024 -+#define VI_ID_MASK_1 (0x000000ff << 8) -+#define VI_DATA_ID_1 (0x000000ff << 0) -+ -+#define VI_LINE_THRESH 0x040 -+#define VI_LCTHR (0x000007ff << 0) -+ -+#define VIN_FORMAT 0x100 -+#define VI_VSRA (0x00000003 << 30) -+#define VI_SYNCHD (0x00000001 << 25) -+#define VI_DUAL_STREAM (0x00000001 << 24) -+#define VI_NHDAUX (0x00000001 << 20) -+#define VI_NPAR (0x00000001 << 19) -+#define VI_VSEL (0x00000003 << 14) -+#define VI_TWOS (0x00000001 << 13) -+#define VI_TPG (0x00000001 << 12) -+#define VI_FREF (0x00000001 << 10) -+#define VI_FTGL (0x00000001 << 9) -+#define VI_SF (0x00000001 << 3) -+#define VI_FZERO (0x00000001 << 2) -+#define VI_REVS (0x00000001 << 1) -+#define VI_REHS (0x00000001 << 0) -+ -+#define VIN_TESTPGEN 0x104 -+ -+#define WIN_XYSTART 0x140 -+#define WIN_XYEND 0x144 -+ -+#define PRE_DIT_CTRL 0x160 -+#define POST_DIT_CTRL 0x164 -+ -+#define AUX_XYSTART 0x180 -+#define AUX_XYEND 0x184 -+ -+#define CSM_CKEY 0x284 -+ -+#define PSU_FORMAT 0x300 -+#define PSU_WINDOW 0x304 -+#define PSU_BASE1 0x340 -+#define PSU_PITCH1 0x344 -+#define PSU_BASE2 0x348 -+#define PSU_PITCH2 0x34c -+#define PSU_BASE3 0x350 -+#define PSU_BASE4 0x354 -+#define PSU_BASE5 0x358 -+#define PSU_BASE6 0x35c -+ -+#define AUX_FORMAT 0x380 -+#define AUX_BASE 0x390 -+#define AUX_PITCH 0x394 -+ -+#define INT_STATUS 0xfe0 -+#define VI_STAT_FID_AUX (0x00000001 << 31) -+#define VI_STAT_FID_VID (0x00000001 << 30) -+#define VI_STAT_FID_VPI (0x00000001 << 29) -+#define VI_STAT_LINE_COUNT (0x00000fff << 16) -+#define VI_STAT_AUX_OVRFLW (0x00000001 << 9) -+#define VI_STAT_VID_OVRFLW (0x00000001 << 8) -+#define VI_STAT_WIN_SEQBRK (0x00000001 << 7) -+#define VI_STAT_FID_SEQBRK (0x00000001 << 6) -+#define VI_STAT_LINE_THRESH (0x00000001 << 5) -+#define VI_STAT_AUX_WRAP (0x00000001 << 4) -+#define VI_STAT_AUX_START_IN (0x00000001 << 3) -+#define VI_STAT_AUX_END_OUT (0x00000001 << 2) -+#define VI_STAT_VID_START_IN (0x00000001 << 1) -+#define VI_STAT_VID_END_OUT (0x00000001 << 0) -+ -+#define INT_ENABLE 0xfe4 -+#define VI_ENABLE_AUX_OVRFLW (0x00000001 << 9) -+#define VI_ENABLE_VID_OVRFLW (0x00000001 << 8) -+#define VI_ENABLE_WIN_SEQBRK (0x00000001 << 7) -+#define VI_ENABLE_FID_SEQBRK (0x00000001 << 6) -+#define VI_ENABLE_LINE_THRESH (0x00000001 << 5) -+#define VI_ENABLE_AUX_WRAP (0x00000001 << 4) -+#define VI_ENABLE_AUX_START_IN (0x00000001 << 3) -+#define VI_ENABLE_AUX_END_OUT (0x00000001 << 2) -+#define VI_ENABLE_VID_START_IN (0x00000001 << 1) -+#define VI_ENABLE_VID_END_OUT (0x00000001 << 0) -+ -+#define INT_CLR_STATUS 0xfe8 -+#define VI_CLR_STATUS_AUX_OVRFLW (0x00000001 << 9) -+#define VI_CLR_STATUS_VID_OVRFLW (0x00000001 << 8) -+#define VI_CLR_STATUS_WIN_SEQBRK (0x00000001 << 7) -+#define VI_CLR_STATUS_FID_SEQBRK (0x00000001 << 6) -+#define VI_CLR_STATUS_LINE_THRESH (0x00000001 << 5) -+#define VI_CLR_STATUS_AUX_WRAP (0x00000001 << 4) -+#define VI_CLR_STATUS_AUX_START_IN (0x00000001 << 3) -+#define VI_CLR_STATUS_AUX_END_OUT (0x00000001 << 2) -+#define VI_CLR_STATUS_VID_START_IN (0x00000001 << 1) -+#define VI_CLR_STATUS_VID_END_OUT (0x00000001 << 0) -+ -+#define INT_SET_STATUS 0xfec -+#define VI_SET_STATUS_AUX_OVRFLW (0x00000001 << 9) -+#define VI_SET_STATUS_VID_OVRFLW (0x00000001 << 8) -+#define VI_SET_STATUS_WIN_SEQBRK (0x00000001 << 7) -+#define VI_SET_STATUS_FID_SEQBRK (0x00000001 << 6) -+#define VI_SET_STATUS_LINE_THRESH (0x00000001 << 5) -+#define VI_SET_STATUS_AUX_WRAP (0x00000001 << 4) -+#define VI_SET_STATUS_AUX_START_IN (0x00000001 << 3) -+#define VI_SET_STATUS_AUX_END_OUT (0x00000001 << 2) -+#define VI_SET_STATUS_VID_START_IN (0x00000001 << 1) -+#define VI_SET_STATUS_VID_END_OUT (0x00000001 << 0) -+ -+#define VIP_POWER_DOWN 0xff4 -+#define VI_PWR_DWN (0x00000001 << 31) -+ -+#define VI_MODULE_ID 0xffc -+ -+ -+#endif /* __SAA716x_VIP_REG_H */ -diff --git a/drivers/media/pci/saa716x/tbs-ci.c b/drivers/media/pci/saa716x/tbs-ci.c -new file mode 100644 -index 0000000..c85dbbd ---- /dev/null -+++ b/drivers/media/pci/saa716x/tbs-ci.c -@@ -0,0 +1,556 @@ -+/* -+ TurboSight TBS CI driver -+ Copyright (C) 2011 Konstantin Dimitrov -+ -+ Copyright (C) 2011 TurboSight.com -+*/ -+ -+#include "tbs-ci.h" -+ -+#define TBSCI_I2C_ADDR 0x1a -+ -+struct tbsci_state { -+ struct dvb_ca_en50221 ca; -+ struct mutex ca_mutex; -+ struct i2c_adapter *i2c_adap; -+ int nr, mode; -+ void *priv; /* struct saa716x_adapter *priv; */ -+ int status; -+}; -+ -+int tbsci_i2c_read(struct tbsci_state *state) -+{ -+ int ret; -+ u8 buf = 0; -+ -+ struct i2c_msg msg = { .addr = TBSCI_I2C_ADDR, .flags = I2C_M_RD, -+ .buf = &buf, .len = 1 }; -+ -+ if (((state->mode == 2) || (state->mode == 4) || -+ (state->mode == 6) || (state->mode == 8) || (state->mode == 9)) -+ && (state->nr == 1)) -+ msg.addr += 1; -+ -+ if (state->mode == 10) -+ msg.addr += 2; -+ -+ ret = i2c_transfer(state->i2c_adap, &msg, 1); -+ -+ if (ret != 1) { -+ printk("tbsci: read error=%d\n", ret); -+ return -EREMOTEIO; -+ } -+ -+ return buf; -+}; -+ -+int tbsci_i2c_write(struct tbsci_state *state, -+ u8 addr, u8* data, int len) -+{ -+ int ret; -+ unsigned char buf[len + 1]; -+ -+ struct i2c_msg msg = { .addr = TBSCI_I2C_ADDR, .flags = 0, -+ .buf = &buf[0], .len = len + 1 }; -+ -+ if (((state->mode == 2) || (state->mode == 4) || -+ (state->mode == 6) || (state->mode == 8) || (state->mode == 9)) -+ && (state->nr == 1)) -+ msg.addr += 1; -+ -+ if (state->mode == 10) -+ msg.addr += 2; -+ -+ memcpy(&buf[1], data, len); -+ buf[0] = addr; -+ -+ ret = i2c_transfer(state->i2c_adap, &msg, 1); -+ -+ if (ret != 1) { -+ printk("tbsci: error=%d\n", ret); -+ return -EREMOTEIO; -+ } -+ -+ return 0; -+}; -+ -+int tbsci_read_cam_control(struct dvb_ca_en50221 *ca, -+ int slot, u8 address) -+{ -+ struct tbsci_state *state = ca->data; -+ int ret; -+ unsigned char data; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ data = (address & 3); -+ ret = tbsci_i2c_write(state, 0x80, &data, 1); -+ data = tbsci_i2c_read(state); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return data; -+} -+ -+int tbsci_write_cam_control(struct dvb_ca_en50221 *ca, int slot, -+ u8 address, u8 value) -+{ -+ struct tbsci_state *state = ca->data; -+ int ret; -+ unsigned char data[2]; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ data[0] = (address & 3); -+ data[1] = value; -+ ret = tbsci_i2c_write(state, 0x80, data, 2); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+int tbsci_read_attribute_mem(struct dvb_ca_en50221 *ca, -+ int slot, int address) -+{ -+ struct tbsci_state *state = ca->data; -+ int ret; -+ unsigned char data; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ data = (address & 0xff); -+ ret = tbsci_i2c_write(state, -+ ((address >> 8) & 0x7f), &data, 1); -+ data = tbsci_i2c_read(state); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return data; -+} -+ -+int tbsci_write_attribute_mem(struct dvb_ca_en50221 *ca, -+ int slot, int address, u8 value) -+{ -+ struct tbsci_state *state = ca->data; -+ int ret; -+ unsigned char data[2]; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ data[0] = (address & 0xff); -+ data[1] = value; -+ ret = tbsci_i2c_write(state, -+ ((address >> 8) & 0x7f), data, 2); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int tbsci_set_video_port(struct dvb_ca_en50221 *ca, -+ int slot, int enable) -+{ -+ struct tbsci_state *state = ca->data; -+ struct saa716x_adapter *adap = state->priv; -+ struct saa716x_dev *saa716x = adap->saa716x; -+ unsigned char data; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ switch (state->mode) { -+ case 0: -+ case 1: -+ saa716x_gpio_set_output(saa716x, -+ state->nr ? 16 : 17); -+ msleep(1); -+ saa716x_gpio_write(saa716x, -+ state->nr ? 16 : 17, (enable & 1)); -+ msleep(100); -+ break; -+ case 2: -+ saa716x_gpio_set_output(saa716x, -+ state->nr ? 6 : 16); -+ msleep(1); -+ saa716x_gpio_write(saa716x, -+ state->nr ? 6 : 16, (enable & 1)); -+ msleep(100); -+ break; -+ case 3: -+ case 4: -+ case 5: -+ case 6: -+ case 7: -+ case 8: -+ case 9: -+ data = enable & 1; -+ tbsci_i2c_write(state, 0xc0, &data, 1); -+ break; -+ } -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ printk("tbsci: Adapter %d CI slot %sabled\n", -+ adap->fe->dvb->num, -+ enable ? "en" : "dis"); -+ -+ return 0; -+} -+ -+int tbsci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) -+{ -+ return tbsci_set_video_port(ca, slot, /* enable */ 0); -+} -+ -+int tbsci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) -+{ -+ return tbsci_set_video_port(ca, slot, /* enable */ 1); -+} -+ -+int tbsci_slot_reset(struct dvb_ca_en50221 *ca, int slot) -+{ -+ struct tbsci_state *state = ca->data; -+ int ret; -+ unsigned char data; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock (&state->ca_mutex); -+ -+ data = 1; -+ ret = tbsci_i2c_write(state, 0xc1, &data, 1); -+ msleep (5); -+ -+ data = 0; -+ ret = tbsci_i2c_write(state, 0xc1, &data, 1); -+ msleep (1400); -+ -+ mutex_unlock (&state->ca_mutex); -+ -+ if (ret != 0) -+ return ret; -+ -+ return 0; -+} -+ -+int tbsci_poll_slot_status(struct dvb_ca_en50221 *ca, -+ int slot, int open) -+{ -+ struct tbsci_state *state = ca->data; -+ struct saa716x_adapter *adap = state->priv; -+ struct saa716x_dev *saa716x = adap->saa716x; -+ unsigned char data, value; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ switch (state->mode) { -+ case 0: -+ data = 0; -+ tbsci_i2c_write(state, 0xc0, &data, 1); -+ data = tbsci_i2c_read(state); -+ break; -+ case 1: -+ case 2: -+ data = 0; -+ tbsci_i2c_write(state, 0xc2, &data, 1); -+ data = tbsci_i2c_read(state); -+ break; -+ case 3: -+ data = saa716x_gpio_read(saa716x, 3); -+ if (data != saa716x_gpio_read(saa716x, 5)) -+ data = 0; -+ else -+ data ^= 1; -+ break; -+ case 4: -+ data = saa716x_gpio_read(saa716x, state->nr ? 3 : 14); -+ if (data != saa716x_gpio_read(saa716x, state->nr ? 6 : 2)) -+ data = 0; -+ else -+ data ^= 1; -+ break; -+ case 5: -+ data = saa716x_gpio_read(saa716x, 6); -+ if (data != saa716x_gpio_read(saa716x, 14)) -+ data = 0; -+ else -+ data ^= 1; -+ break; -+ case 6: -+ data = saa716x_gpio_read(saa716x, state->nr ? 17 : 5); -+ if (data != saa716x_gpio_read(saa716x, state->nr ? 16 : 6)) -+ data = 0; -+ else -+ data ^= 1; -+ break; -+ case 7: -+ data = saa716x_gpio_read(saa716x, 3); -+ if (data != saa716x_gpio_read(saa716x, 5)) { -+ data = 0; -+ } else { -+ data ^= 1; -+ } -+ -+ if (state->status != data){ -+ value = !data; -+ tbsci_i2c_write(state, 0xc3, &value, 1); -+ saa716x_gpio_write(saa716x, 6, value); -+ msleep(300); -+ state->status = data; -+ } -+ -+ break; -+ case 8: -+ case 9: -+ data = saa716x_gpio_read(saa716x, state->nr ? 6 : 2); -+ if (data != saa716x_gpio_read(saa716x, state->nr ? 3 : 14)) { -+ data = 0; -+ } else { -+ data ^= 1; -+ } -+ -+ if (state->status != data) -+ { -+ value = !data; -+ saa716x_gpio_write(saa716x, state->nr ? 17 : 20, value); -+ msleep(300); -+ state->status = data; -+ } -+ break; -+ } -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (data & 1) { -+ return (DVB_CA_EN50221_POLL_CAM_PRESENT | -+ DVB_CA_EN50221_POLL_CAM_READY); -+ } else { -+ return 0; -+ } -+} -+ -+int tbsci_init(struct saa716x_adapter *adap, int tbsci_nr, int tbsci_mode) -+{ -+ struct tbsci_state *state; -+ int ret; -+ unsigned char data; -+ -+ /* allocate memory for the internal state */ -+ state = kzalloc(sizeof(struct tbsci_state), GFP_KERNEL); -+ if (state == NULL) { -+ ret = -ENOMEM; -+ goto error1; -+ } -+ -+ adap->adap_priv = state; -+ -+ state->nr = tbsci_nr; -+ state->mode = tbsci_mode; -+ state->status = 0; -+ -+ mutex_init(&state->ca_mutex); -+ -+ state->i2c_adap = &adap->tbsci->adap; -+ state->ca.owner = THIS_MODULE; -+ state->ca.read_attribute_mem = tbsci_read_attribute_mem; -+ state->ca.write_attribute_mem = tbsci_write_attribute_mem; -+ state->ca.read_cam_control = tbsci_read_cam_control; -+ state->ca.write_cam_control = tbsci_write_cam_control; -+ state->ca.slot_reset = tbsci_slot_reset; -+ state->ca.slot_shutdown = tbsci_slot_shutdown; -+ state->ca.slot_ts_enable = tbsci_slot_ts_enable; -+ state->ca.poll_slot_status = tbsci_poll_slot_status; -+ state->ca.data = state; -+ state->priv = adap; -+ -+ if ((state->mode != 0) && (state->mode != 10)) { -+ data = 1; -+ tbsci_i2c_write(state, 0xc2, &data, 1); -+ data = tbsci_i2c_read(state); -+ switch (data) { -+ case 0x55: -+ printk("tbsci: Initializing TBS 6928 v11 CI slot\n"); -+ break; -+ case 0x56: -+ case 0x58: -+ printk("tbsci: Initializing TBS 6991 v11 CI %d slot\n", -+ tbsci_nr); -+ break; -+ case 0x60: -+ if (state->mode != 5) { -+ printk("tbsci: Initializing TBS 6928 v12 CI slot\n"); -+ state->mode = 3; -+ -+ data = 0; -+ tbsci_i2c_write(state, 0xd0, &data, 1); -+ -+ tbsci_i2c_write(state, 0xcc, &data, 1); -+ tbsci_i2c_write(state, 0xcd, &data, 1); -+ -+ data = 2; -+ tbsci_i2c_write(state, 0xce, &data, 1); -+ } else { -+ printk("tbsci: Initializing TBS 6618 CI slot\n"); -+ } -+ break; -+ case 0x62: -+ printk("tbsci: Initializing TBS 6928SE CI slot\n"); -+ state->mode = 7; -+ break; -+ case 0x66: -+ case 0x68: -+ if (state->mode == 8){ -+ printk("tbsci: Initializing TBS 6991SE CI %d slot\n", -+ tbsci_nr); -+ //Fix Data Rate -+ data = 0; -+ tbsci_i2c_write(state, 0xd0, &data, 1); -+ -+ data = 1; -+ tbsci_i2c_write(state, 0xcd, &data, 1); -+ data = 8; -+ tbsci_i2c_write(state, 0xce, &data, 1); -+ -+ data = 0; -+ tbsci_i2c_write(state, 0xcf, &data, 1); -+ -+ }else -+ if (state->mode == 9) { -+ printk("tbsci: Initializing TBS 6290 CI %d slot\n", -+ tbsci_nr); -+ } else { -+ if (state->mode != 6) { -+ printk("tbsci: Initializing TBS 6991 v13 CI %d slot\n", -+ tbsci_nr); -+ state->mode = 4; -+ -+ data = 0; -+ tbsci_i2c_write(state, 0xd0, &data, 1); -+ data = 1; -+ tbsci_i2c_write(state, 0xcc, &data, 1); -+ data = 0; -+ tbsci_i2c_write(state, 0xcd, &data, 1); -+ -+ data = 2; -+ tbsci_i2c_write(state, 0xce, &data, 1); -+ } else { -+ printk("tbsci: Initializing TBS 6680 CI %d slot\n", -+ tbsci_nr); -+ }} -+ break; -+ default: -+ ret = -EREMOTEIO; -+ goto error2; -+ } -+ } -+ -+ if (state->mode == 10) { -+ data = 0xc0; -+ tbsci_i2c_write(state, 0x40, &data, 1); -+ data = tbsci_i2c_read(state); -+ -+ data = 0x01; -+ tbsci_i2c_write(state, 0xc0, &data, 1); -+ -+ data = 0xc0; -+ tbsci_i2c_write(state, 0x40, &data, 1); -+ data = tbsci_i2c_read(state); -+ -+ data = 0xc1; -+ tbsci_i2c_write(state, 0x40, &data, 1); -+ data = tbsci_i2c_read(state); -+ -+ data = 0x01; -+ tbsci_i2c_write(state, 0xc1, &data, 1); -+ -+ data = 0xc1; -+ tbsci_i2c_write(state, 0x40, &data, 1); -+ data = tbsci_i2c_read(state); -+ -+ data = 0xc2; -+ tbsci_i2c_write(state, 0x40, &data, 1); -+ data = tbsci_i2c_read(state); -+ -+ data = 0x01; -+ tbsci_i2c_write(state, 0xc2, &data, 1); -+ -+ data = 0xc2; -+ tbsci_i2c_write(state, 0x40, &data, 1); -+ data = tbsci_i2c_read(state); -+ -+ data = 0xc3; -+ tbsci_i2c_write(state, 0x40, &data, 1); -+ data = tbsci_i2c_read(state); -+ -+ data = 0x01; -+ tbsci_i2c_write(state, 0xc3, &data, 1); -+ -+ data = 0xc3; -+ tbsci_i2c_write(state, 0x40, &data, 1); -+ data = tbsci_i2c_read(state); -+ -+ return 0; -+ } -+ -+ ret = dvb_ca_en50221_init(&adap->dvb_adapter, &state->ca, -+ /* flags */ 0, /* n_slots */ 1); -+ if (ret != 0) goto error2; -+ -+ printk("tbsci: Adapter %d CI slot initialized\n", adap->dvb_adapter.num); -+ -+ return 0; -+ -+error2: -+ //memset (&state->ca, 0, sizeof (state->ca)); -+ kfree(state); -+error1: -+ printk("tbsci: Adapter %d CI slot initialization failed\n", adap->dvb_adapter.num); -+ return ret; -+} -+ -+void tbsci_release(struct saa716x_adapter *adap) -+{ -+ struct tbsci_state *state; -+ -+ if (NULL == adap) return; -+ -+ state = (struct tbsci_state *)adap->adap_priv; -+ if (NULL == state) return; -+ -+ if (NULL == state->ca.data) return; -+ -+ dvb_ca_en50221_release(&state->ca); -+ //memset(&state->ca, 0, sizeof(state->ca)); -+ kfree(state); -+} -diff --git a/drivers/media/pci/saa716x/tbs-ci.h b/drivers/media/pci/saa716x/tbs-ci.h -new file mode 100644 -index 0000000..b81ecf1 ---- /dev/null -+++ b/drivers/media/pci/saa716x/tbs-ci.h -@@ -0,0 +1,37 @@ -+/* -+ TurboSight TBS CI driver -+ Copyright (C) 2011 Konstantin Dimitrov -+ -+ Copyright (C) 2011 TurboSight.com -+*/ -+ -+#ifndef TBS_CI_H -+#define TBS_CI_H -+ -+#include "saa716x_priv.h" -+#include "saa716x_gpio.h" -+#include "tbsci-i2c.h" -+ -+#include "dvb_ca_en50221.h" -+ -+extern int tbsci_read_attribute_mem(struct dvb_ca_en50221 *en50221, -+ int slot, int addr); -+extern int tbsci_write_attribute_mem(struct dvb_ca_en50221 *en50221, -+ int slot, int addr, u8 data); -+extern int tbsci_read_cam_control(struct dvb_ca_en50221 *en50221, -+ int slot, u8 addr); -+extern int tbsci_write_cam_control(struct dvb_ca_en50221 *en50221, -+ int slot, u8 addr, u8 data); -+extern int tbsci_slot_reset(struct dvb_ca_en50221 *en50221, -+ int slot); -+extern int tbsci_slot_shutdown(struct dvb_ca_en50221 *en50221, -+ int slot); -+extern int tbsci_slot_ts_enable(struct dvb_ca_en50221 *en50221, -+ int slot); -+extern int tbsci_poll_slot_status(struct dvb_ca_en50221 *en50221, -+ int slot, int open); -+extern int tbsci_init(struct saa716x_adapter *adap, int tbsci_nr, -+ int tbsci_mode); -+extern void tbsci_release(struct saa716x_adapter *adap); -+ -+#endif -diff --git a/drivers/media/pci/saa716x/tbsci-i2c.c b/drivers/media/pci/saa716x/tbsci-i2c.c -new file mode 100644 -index 0000000..f71f816 ---- /dev/null -+++ b/drivers/media/pci/saa716x/tbsci-i2c.c -@@ -0,0 +1,144 @@ -+/* -+ TurboSight TBS CI I2C over GPIO driver -+ Copyright (C) 2011 Konstantin Dimitrov -+ -+ Copyright (C) 2011 TurboSight.com -+*/ -+ -+#include "saa716x_priv.h" -+#include "saa716x_gpio.h" -+#include "tbsci-i2c.h" -+ -+static void tbsci_setscl(void *data, int state) -+{ -+ struct saa716x_adapter *adap = data; -+ struct saa716x_dev *saa716x = adap->saa716x; -+ struct tbsci_i2c_state *tbsci_i2c = adap->tbsci; -+ -+ saa716x_gpio_write(saa716x, tbsci_i2c->wscl, state); -+} -+ -+static void tbsci_setsda(void *data, int state) -+{ -+ struct saa716x_adapter *adap = data; -+ struct saa716x_dev *saa716x = adap->saa716x; -+ struct tbsci_i2c_state *tbsci_i2c = adap->tbsci; -+ -+ saa716x_gpio_write(saa716x, tbsci_i2c->wsda, state); -+} -+ -+static int tbsci_getscl(void *data) -+{ -+ struct saa716x_adapter *adap = data; -+ struct saa716x_dev *saa716x = adap->saa716x; -+ struct tbsci_i2c_state *tbsci_i2c = adap->tbsci; -+ u32 state; -+ -+ state = saa716x_gpio_read(saa716x, tbsci_i2c->wscl); -+ -+ return state ? 1 : 0; -+} -+ -+static int tbsci_getsda(void *data) -+{ -+ struct saa716x_adapter *adap = data; -+ struct saa716x_dev *saa716x = adap->saa716x; -+ struct tbsci_i2c_state *tbsci_i2c = adap->tbsci; -+ u32 state; -+ -+ state = saa716x_gpio_read(saa716x, tbsci_i2c->rsda); -+ -+ return state ? 1 : 0; -+} -+ -+static const struct i2c_algo_bit_data tbsci_i2c_algo_template = { -+ .setsda = tbsci_setsda, -+ .setscl = tbsci_setscl, -+ .getsda = tbsci_getsda, -+ .getscl = tbsci_getscl, -+ .udelay = 5, -+ .timeout = 200, -+}; -+ -+int tbsci_i2c_probe(struct saa716x_adapter *adap, int tbsci_i2c_nr) -+{ -+ struct saa716x_dev *saa716x = adap->saa716x; -+ struct saa716x_i2c *i2c0 = &saa716x->i2c[0]; -+ struct saa716x_i2c *i2c1 = &saa716x->i2c[1]; -+ struct tbsci_i2c_state *tbsci_i2c; -+ int ret; -+ -+ tbsci_i2c = kzalloc(sizeof(*tbsci_i2c), GFP_KERNEL); -+ if (tbsci_i2c == NULL) { -+ return -ENOMEM; -+ } -+ adap->tbsci = tbsci_i2c; -+ tbsci_i2c->nr = tbsci_i2c_nr; -+ -+ if (tbsci_i2c_nr == 3) { -+ tbsci_i2c->adap = i2c1->i2c_adapter; -+ return 0; -+ } -+ -+ if (tbsci_i2c_nr == 4) { -+ tbsci_i2c->adap = i2c0->i2c_adapter; -+ return 0; -+ } -+ -+ memcpy(&tbsci_i2c->algo, &tbsci_i2c_algo_template, -+ sizeof(tbsci_i2c->algo)); -+ -+ tbsci_i2c->adap.dev.parent = &saa716x->pdev->dev; -+ strlcpy(tbsci_i2c->adap.name, -+ tbsci_i2c_nr ? "TBSCI I2C Adapter 0" : "TBSCI I2C Adapter 1", -+ sizeof(tbsci_i2c->adap.name)); -+ tbsci_i2c->adap.owner = THIS_MODULE; -+ //tbsci_i2c->adap.id = I2C_HW_B_SAA716x; -+ tbsci_i2c->algo.data = adap; -+ i2c_set_adapdata(&tbsci_i2c->adap, saa716x); -+ tbsci_i2c->adap.algo_data = &tbsci_i2c->algo; -+ -+ if (tbsci_i2c->nr == 2) { -+ tbsci_i2c->wscl = 16; -+ tbsci_i2c->wsda = 3; -+ tbsci_i2c->rsda = 5; -+ } else { -+ tbsci_i2c->wscl = tbsci_i2c->nr ? 3 : 26; -+ tbsci_i2c->wsda = tbsci_i2c->nr ? 5 : 15; -+ tbsci_i2c->rsda = tbsci_i2c->nr ? 2 : 20; -+ } -+ -+ saa716x_gpio_set_output(saa716x, tbsci_i2c->wscl); -+ msleep(1); -+ saa716x_gpio_set_output(saa716x, tbsci_i2c->wsda); -+ msleep(1); -+ saa716x_gpio_set_input(saa716x, tbsci_i2c->rsda); -+ msleep(1); -+ -+ tbsci_setscl(adap, 1); -+ tbsci_setsda(adap, 1); -+ -+ ret = i2c_bit_add_bus(&tbsci_i2c->adap); -+ if (ret != 0) { -+ printk("tbsci_i2c: %s probe failed\n", -+ tbsci_i2c_nr ? "TBSCI I2C Adapter 0" : "TBSCI I2C Adapter 1"); -+ -+ kfree(adap->tbsci); -+ adap->tbsci = NULL; -+ } -+ -+ return ret; -+} -+ -+void tbsci_i2c_remove(struct saa716x_adapter *adap) -+{ -+ struct tbsci_i2c_state *tbsci_i2c = adap->tbsci; -+ -+ if (tbsci_i2c == NULL) -+ return; -+ -+ if ((tbsci_i2c->nr != 3) && (tbsci_i2c->nr != 4)) -+ i2c_del_adapter(&tbsci_i2c->adap); -+ -+ kfree(tbsci_i2c); -+} -diff --git a/drivers/media/pci/saa716x/tbsci-i2c.h b/drivers/media/pci/saa716x/tbsci-i2c.h -new file mode 100644 -index 0000000..7447aad ---- /dev/null -+++ b/drivers/media/pci/saa716x/tbsci-i2c.h -@@ -0,0 +1,26 @@ -+/* -+ TurboSight TBS CI I2C over GPIO driver -+ Copyright (C) 2011 Konstantin Dimitrov -+ -+ Copyright (C) 2011 TurboSight.com -+*/ -+ -+#ifndef TBSCI_I2C_H -+#define TBSCI_I2C_H -+ -+#include -+ -+//#define I2C_HW_B_SAA716x 0x12 -+ -+struct tbsci_i2c_state { -+ struct i2c_adapter adap; -+ struct i2c_algo_bit_data algo; -+ u8 wscl, wsda, rsda; -+ u32 state; -+ int nr; -+}; -+ -+extern int tbsci_i2c_probe(struct saa716x_adapter *adap, int tbsci_i2c_nr); -+extern void tbsci_i2c_remove(struct saa716x_adapter *adap); -+ -+#endif -diff --git a/drivers/media/pci/tbsecp3/Kconfig b/drivers/media/pci/tbsecp3/Kconfig -new file mode 100644 -index 0000000..998b343 ---- /dev/null -+++ b/drivers/media/pci/tbsecp3/Kconfig -@@ -0,0 +1,11 @@ -+config DVB_TBSECP3 -+ tristate "TBS ECP3 FPGA based cards" -+ depends on DVB_CORE && PCI && I2C -+ select I2C_ALGOBIT -+ select DVB_TAS2101 if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_AV201X if MEDIA_SUBDRV_AUTOSELECT -+ help -+ Support for cards with TBS ECP3 FPGA based PCIe bridge. -+ -+ Say Y or M if you own such a device and want to use it. -+ If unsure say N. -diff --git a/drivers/media/pci/tbsecp3/Makefile b/drivers/media/pci/tbsecp3/Makefile -new file mode 100644 -index 0000000..20cb8e5 ---- /dev/null -+++ b/drivers/media/pci/tbsecp3/Makefile -@@ -0,0 +1,9 @@ -+ -+tbsecp3-objs := tbsecp3-core.o tbsecp3-cards.o tbsecp3-i2c.o tbsecp3-dma.o tbsecp3-dvb.o tbsecp3-ca.o -+ -+obj-$(CONFIG_DVB_TBSECP3) += tbsecp3.o -+ -+ccflags-y += -Idrivers/media/tuners -+ccflags-y += -Idrivers/media/dvb-core -+ccflags-y += -Idrivers/media/dvb-frontends -+ -diff --git a/drivers/media/pci/tbsecp3/tbsecp3-ca.c b/drivers/media/pci/tbsecp3/tbsecp3-ca.c -new file mode 100644 -index 0000000..f8fe9ab ---- /dev/null -+++ b/drivers/media/pci/tbsecp3/tbsecp3-ca.c -@@ -0,0 +1,278 @@ -+/* -+ TBS ECP3 FPGA based cards PCIe driver -+ -+ 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 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+*/ -+ -+#include "tbsecp3.h" -+ -+static int tbsecp3_ca_rd_attr_mem(struct dvb_ca_en50221 *ca, -+ int slot, int address) -+{ -+ struct tbsecp3_ca *tbsca = ca->data; -+ struct tbsecp3_adapter *adapter = tbsca->adapter; -+ struct tbsecp3_dev *dev = adapter->dev; -+ u32 data = 0; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&tbsca->lock); -+ -+ data |= (address >> 8) & 0x7f; -+ data |= (address & 0xff) << 8; -+ tbs_write(TBSECP3_CA_BASE(tbsca->nr), 0x00, data); -+ udelay(150); -+ -+ data = tbs_read(TBSECP3_CA_BASE(tbsca->nr), 0x04); -+ -+ mutex_unlock(&tbsca->lock); -+ -+ return (data & 0xff); -+} -+ -+static int tbsecp3_ca_wr_attr_mem(struct dvb_ca_en50221 *ca, -+ int slot, int address, u8 value) -+{ -+ struct tbsecp3_ca *tbsca = ca->data; -+ struct tbsecp3_adapter *adapter = -+ (struct tbsecp3_adapter *) tbsca->adapter; -+ struct tbsecp3_dev *dev = adapter->dev; -+ u32 data = 0; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&tbsca->lock); -+ -+ data |= (address >> 8) & 0x7f; -+ data |= (address & 0xff) << 8; -+ data |= 0x01 << 16; -+ data |= value << 24; -+ tbs_write(TBSECP3_CA_BASE(tbsca->nr), 0x00, data); -+ udelay(150); -+ -+ mutex_unlock(&tbsca->lock); -+ -+ return 0; -+} -+ -+static int tbsecp3_ca_rd_cam_ctrl(struct dvb_ca_en50221 *ca, -+ int slot, u8 address) -+{ -+ struct tbsecp3_ca *tbsca = ca->data; -+ struct tbsecp3_adapter *adapter = -+ (struct tbsecp3_adapter *) tbsca->adapter; -+ struct tbsecp3_dev *dev = adapter->dev; -+ u32 data = 0; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&tbsca->lock); -+ -+ data |= (address & 3) << 8; -+ data |= 0x02 << 16; -+ tbs_write(TBSECP3_CA_BASE(tbsca->nr), 0x00, data); -+ udelay(150); -+ -+ data = tbs_read(TBSECP3_CA_BASE(tbsca->nr), 0x08); -+ -+ mutex_unlock(&tbsca->lock); -+ -+ return (data & 0xff); -+} -+ -+static int tbsecp3_ca_wr_cam_ctrl(struct dvb_ca_en50221 *ca, int slot, -+ u8 address, u8 value) -+{ -+ struct tbsecp3_ca *tbsca = ca->data; -+ struct tbsecp3_adapter *adapter = -+ (struct tbsecp3_adapter *) tbsca->adapter; -+ struct tbsecp3_dev *dev = adapter->dev; -+ u32 data = 0; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&tbsca->lock); -+ -+ data |= (address & 3) << 8; -+ data |= 0x03 << 16; -+ data |= value << 24; -+ tbs_write(TBSECP3_CA_BASE(tbsca->nr), 0x00, data); -+ udelay(150); -+ -+ mutex_unlock(&tbsca->lock); -+ -+ return 0; -+} -+ -+static int tbsecp3_ca_slot_reset(struct dvb_ca_en50221 *ca, int slot) -+{ -+ struct tbsecp3_ca *tbsca = ca->data; -+ struct tbsecp3_adapter *adapter = -+ (struct tbsecp3_adapter *) tbsca->adapter; -+ struct tbsecp3_dev *dev = adapter->dev; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&tbsca->lock); -+ -+ tbs_write(TBSECP3_CA_BASE(tbsca->nr), 0x04, 1); -+ msleep (5); -+ -+ tbs_write(TBSECP3_CA_BASE(tbsca->nr), 0x04, 0); -+ msleep (1400); -+ -+ mutex_unlock (&tbsca->lock); -+ return 0; -+} -+ -+static int tbsecp3_ca_slot_ctrl(struct dvb_ca_en50221 *ca, -+ int slot, int enable) -+{ -+ struct tbsecp3_ca *tbsca = ca->data; -+ struct tbsecp3_adapter *adapter = -+ (struct tbsecp3_adapter *) tbsca->adapter; -+ struct tbsecp3_dev *dev = adapter->dev; -+ u32 data; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&tbsca->lock); -+ -+ data = enable & 1; -+ tbs_write(TBSECP3_CA_BASE(tbsca->nr), 0x0c, data); -+ -+ mutex_unlock(&tbsca->lock); -+ -+ dev_info(&dev->pci_dev->dev, "CA slot %sabled for adapter%d\n", -+ enable ? "en" : "dis", -+ adapter->fe->dvb->num); -+ -+ return 0; -+} -+ -+static int tbsecp3_ca_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) -+{ -+ return tbsecp3_ca_slot_ctrl(ca, slot, 0); -+} -+ -+static int tbsecp3_ca_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) -+{ -+ return tbsecp3_ca_slot_ctrl(ca, slot, 1); -+} -+ -+static int tbsecp3_ca_poll_slot_status(struct dvb_ca_en50221 *ca, -+ int slot, int open) -+{ -+ struct tbsecp3_ca *tbsca = ca->data; -+ struct tbsecp3_adapter *adapter = -+ (struct tbsecp3_adapter *) tbsca->adapter; -+ struct tbsecp3_dev *dev = adapter->dev; -+ u32 data; -+ int ret; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&tbsca->lock); -+ data = tbs_read(TBSECP3_CA_BASE(tbsca->nr), 0x0c) & 1; -+ if (tbsca->status != data){ -+ tbs_write(TBSECP3_CA_BASE(tbsca->nr), 0x08, !data); -+ msleep(300); -+ tbsca->status = data; -+ } -+ mutex_unlock(&tbsca->lock); -+ -+ if (data & 1) -+ ret = DVB_CA_EN50221_POLL_CAM_PRESENT | -+ DVB_CA_EN50221_POLL_CAM_READY; -+ else -+ ret = 0; -+ -+ return ret; -+} -+ -+ -+struct dvb_ca_en50221 ca_config = { -+ .read_attribute_mem = tbsecp3_ca_rd_attr_mem, -+ .write_attribute_mem = tbsecp3_ca_wr_attr_mem, -+ .read_cam_control = tbsecp3_ca_rd_cam_ctrl, -+ .write_cam_control = tbsecp3_ca_wr_cam_ctrl, -+ .slot_reset = tbsecp3_ca_slot_reset, -+ .slot_shutdown = tbsecp3_ca_slot_shutdown, -+ .slot_ts_enable = tbsecp3_ca_slot_ts_enable, -+ .poll_slot_status = tbsecp3_ca_poll_slot_status, -+}; -+ -+ -+int tbsecp3_ca_init(struct tbsecp3_adapter *adap, int nr) -+{ -+ struct tbsecp3_dev *dev = adap->dev; -+ struct tbsecp3_ca *tbsca; -+ int ret; -+ -+ tbsca = kzalloc(sizeof(struct tbsecp3_ca), GFP_KERNEL); -+ if (tbsca == NULL) { -+ ret = -ENOMEM; -+ goto error1; -+ } -+ -+ adap->tbsca = tbsca; -+ -+ tbsca->nr = nr; -+ tbsca->status = 0; -+ tbsca->adapter = adap; -+ mutex_init(&tbsca->lock); -+ -+ memcpy(&tbsca->ca, &ca_config, sizeof(struct dvb_ca_en50221)); -+ tbsca->ca.owner = THIS_MODULE; -+ tbsca->ca.data = tbsca; -+ -+ dev_info(&dev->pci_dev->dev, -+ "initializing CA slot %d on adapter %d\n", -+ nr, adap->dvb_adapter.num); -+ -+ ret = dvb_ca_en50221_init(&adap->dvb_adapter, &tbsca->ca, 0, 1); -+ if (ret) -+ goto error2; -+ -+ return 0; -+ -+error2: -+ kfree(tbsca); -+error1: -+ dev_err(&dev->pci_dev->dev, -+ "adapter %d CA slot initialization failed\n", -+ adap->dvb_adapter.num); -+ return ret; -+} -+ -+void tbsecp3_ca_release(struct tbsecp3_adapter *adap) -+{ -+ struct tbsecp3_ca *tbsca = adap->tbsca; -+ if (!adap) -+ return; -+ if (!tbsca) -+ return; -+ if (!tbsca->ca.data) -+ return; -+ dvb_ca_en50221_release(&tbsca->ca); -+ kfree(tbsca); -+} -+ -diff --git a/drivers/media/pci/tbsecp3/tbsecp3-cards.c b/drivers/media/pci/tbsecp3/tbsecp3-cards.c -new file mode 100644 -index 0000000..0e109f6 ---- /dev/null -+++ b/drivers/media/pci/tbsecp3/tbsecp3-cards.c -@@ -0,0 +1,528 @@ -+/* -+ TBS ECP3 FPGA based cards PCIe driver -+ -+ 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 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+*/ -+ -+#include "tbsecp3.h" -+ -+struct tbsecp3_board tbsecp3_boards[] = { -+ [TBSECP3_BOARD_TBS6814] = { -+ .name = "Turbosight TBS 6814 (Quad ISDB-T)", -+ .i2c_speed = 39, -+ .eeprom_i2c = 1, -+ .adapters = 4, -+ .adap_config ={ -+ -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ }, -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 1, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(1, 0), -+ }, -+ { -+ .ts_in = 2, -+ .i2c_bus_nr = 2, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(2, 0), -+ }, -+ { -+ .ts_in = 3, -+ .i2c_bus_nr = 3, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(3, 0), -+ } -+ }, -+ }, -+ [TBSECP3_BOARD_TBS6209] = { -+ .name = "Turbosight TBS 6209 (Octa DVB-T/T2/C2/C(j83-a/b/c)/ISDB-T)", -+ .i2c_speed = 39, -+ .eeprom_i2c = 0, -+ .adapters = 8, -+ .adap_config ={ -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ }, -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 0, -+ }, -+ { -+ .ts_in = 2, -+ .i2c_bus_nr = 1, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(1, 0), -+ }, -+ { -+ .ts_in = 3, -+ .i2c_bus_nr = 1, -+ }, -+ { -+ .ts_in = 4, -+ .i2c_bus_nr = 2, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(2, 0), -+ -+ }, -+ { -+ .ts_in = 5, -+ .i2c_bus_nr = 2, -+ }, -+ { -+ .ts_in = 6, -+ .i2c_bus_nr = 3, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(3, 0), -+ -+ }, -+ { -+ .ts_in = 7, -+ .i2c_bus_nr = 3, -+ } -+ -+ } -+ }, -+ [TBSECP3_BOARD_TBS6704] = { -+ .name = "TurboSight TBS 6704(Quad ATSC/QAMB)", -+ .i2c_speed = 39, -+ .eeprom_i2c = 1, -+ .adapters = 4, -+ .adap_config = { -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ }, -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 1, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(1, 0), -+ }, -+ { -+ .ts_in = 2, -+ .i2c_bus_nr = 2, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(2, 0), -+ }, -+ { -+ .ts_in = 3, -+ .i2c_bus_nr = 3, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(3, 0), -+ } -+ } -+ }, -+ -+ [TBSECP3_BOARD_TBS6205] = { -+ .name = "TurboSight TBS 6205 DVB-T/T2/C ", -+ .i2c_speed = 39, -+ .eeprom_i2c = 1, -+ .adapters = 4, -+ .adap_config = { -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ }, -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 1, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(2, 0), -+ }, -+ { -+ .ts_in = 2, -+ .i2c_bus_nr = 2, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(1, 0), -+ }, -+ { -+ .ts_in = 3, -+ .i2c_bus_nr = 3, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(3, 0), -+ } -+ } -+ }, -+ [TBSECP3_BOARD_TBS6522] = { -+ .name = "TurboSight TBS 6522 DVB-S/S2/DVB-T/T2/C ", -+ .adapters = 2, -+ .i2c_speed = 39, -+ .eeprom_i2c = 0, -+ .adap_config = { -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(0, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(0, 1), -+ }, -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(1, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(1, 1), -+ }, -+ } -+ }, -+ [TBSECP3_BOARD_TBS6902] = { -+ .name = "TurboSight TBS 6902 DVB-S/S2 ", -+ .adapters = 2, -+ .i2c_speed = 39, -+ .eeprom_i2c = 0, -+ .adap_config = { -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 1, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(1, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(1, 2), -+ }, -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(0, 2), -+ } -+ -+ } -+ }, -+ [TBSECP3_BOARD_TBS6903] = { -+ .name = "TurboSight TBS 6903 DVB-S/S2 ", -+ .adapters = 2, -+ .i2c_speed = 39, -+ .eeprom_i2c = 1, -+ .adap_config = { -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(0, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(0, 1), -+ }, -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 0, -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(1, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(1, 1), -+ }, -+ } -+ }, -+ [TBSECP3_BOARD_TBS6904] = { -+ .name = "TurboSight TBS 6904 DVB-S/S2 ", -+ .adapters = 4, -+ .i2c_speed = 39, -+ .eeprom_i2c = 1, -+ .adap_config = { -+ { -+ .ts_in = 3, -+ .i2c_bus_nr = 3, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(3, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(3, 2), -+ }, -+ { -+ .ts_in = 2, -+ .i2c_bus_nr = 2, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(2, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(2, 2), -+ }, -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 1, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(1, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(1, 2), -+ }, -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(0, 2), -+ }, -+ } -+ }, -+ [TBSECP3_BOARD_TBS6905] = { -+ .name = "TurboSight TBS 6905 DVB-S/S2 ", -+ .adapters = 4, -+ .i2c_speed = 39, -+ .eeprom_i2c = 2, -+ .adap_config = { -+ { -+ .ts_in = 2, -+ .i2c_bus_nr = 2, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(2, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(2, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(2, 1), -+ }, -+ { -+ .ts_in = 3, -+ .i2c_bus_nr = 2, -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(3, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(3, 1), -+ }, -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(0, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(0, 1), -+ }, -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 0, -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(1, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(1, 1), -+ }, -+ } -+ }, -+ [TBSECP3_BOARD_TBS6908] = { -+ .name = "TurboSight TBS 6908 DVB-S/S2 ", -+ .adapters = 4, -+ .i2c_speed = 39, -+ .eeprom_i2c = 2, -+ .adap_config = { -+ { -+ .ts_in = 2, -+ .i2c_bus_nr = 2, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(2, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(2, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(2, 1), -+ }, -+ { -+ .ts_in = 3, -+ .i2c_bus_nr = 2, -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(3, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(3, 1), -+ }, -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(0, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(0, 1), -+ }, -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 0, -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(1, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(1, 1), -+ }, -+ } -+ }, -+ [TBSECP3_BOARD_TBS6909] = { -+ .name = "TurboSight TBS 6909 DVB-S/S2 ", -+ .adapters = 8, -+ .i2c_speed = 39, -+ .eeprom_i2c = 0, -+ .eeprom_addr = 0x10, -+ .adap_config = { -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ }, -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 0, -+ }, -+ { -+ .ts_in = 2, -+ .i2c_bus_nr = 0, -+ }, -+ { -+ .ts_in = 3, -+ .i2c_bus_nr = 0, -+ }, -+ { -+ .ts_in = 4, -+ .i2c_bus_nr = 0, -+ }, -+ { -+ .ts_in = 5, -+ .i2c_bus_nr = 0, -+ }, -+ { -+ .ts_in = 6, -+ .i2c_bus_nr = 0, -+ }, -+ { -+ .ts_in = 7, -+ .i2c_bus_nr = 0, -+ } -+ } -+ }, -+ [TBSECP3_BOARD_TBS6910] = { -+ .name = "TurboSight TBS 6910 DVB-S/S2 + 2xCI ", -+ .adapters = 2, -+ .i2c_speed = 39, -+ .eeprom_i2c = 1, -+ .adap_config = { -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(0, 2), -+ }, -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 1, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(1, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(1, 2), -+ }, -+ } -+ }, -+ [TBSECP3_BOARD_TBS6528] = { -+ .name = "TurboSight TBS 6528 DVB-S/S2 + CI ", -+ .adapters = 1, -+ .i2c_speed = 39, -+ .eeprom_i2c = 0, -+ .adap_config = { -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(0, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(0, 1), -+ }, -+ } -+ }, -+ [TBSECP3_BOARD_TBS6590] = { -+ .name = "TurboSight TBS 6590 DVB-S/S2 + 2xCI ", -+ .adapters = 2, -+ .i2c_speed = 39, -+ .eeprom_i2c = 0, -+ .adap_config = { -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(0, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(0, 1), -+ }, -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 0, -+ .gpio.lnb_power.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.lnb_power.nr = TBSECP3_GPIO_PIN(1, 2), -+ .gpio.lnb_voltage.lvl = TBSECP3_GPIODEF_HIGH, -+ .gpio.lnb_voltage.nr = TBSECP3_GPIO_PIN(1, 1), -+ }, -+ } -+ }, -+ [TBSECP3_BOARD_TBS6290SE] = { -+ .name = "TurboSight TBS 6290SE DVB-T/T2/C + 2xCI ", -+ .i2c_speed = 39, -+ .eeprom_i2c = 1, -+ .adapters = 2, -+ .adap_config = { -+ { -+ .ts_in = 0, -+ .i2c_bus_nr = 0, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_NONE, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ -+ }, -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 1, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_NONE, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(2, 0), -+ -+ }, -+ } -+ }, -+ [TBSECP3_BOARD_TBS6281SE] = { -+ .name = "TurboSight TBS 6281SE DVB-T/T2/C ", -+ .i2c_speed = 39, -+ .eeprom_i2c = 1, -+ .adapters = 2, -+ .adap_config = { -+ { -+ .ts_in = 1, -+ .i2c_bus_nr = 1, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(0, 0), -+ }, -+ { -+ .ts_in = 2, -+ .i2c_bus_nr = 2, -+ .gpio.demod_reset.lvl = TBSECP3_GPIODEF_LOW, -+ .gpio.demod_reset.nr = TBSECP3_GPIO_PIN(2, 0), -+ }, -+ } -+ }, -+}; -diff --git a/drivers/media/pci/tbsecp3/tbsecp3-core.c b/drivers/media/pci/tbsecp3/tbsecp3-core.c -new file mode 100644 -index 0000000..41ff805 ---- /dev/null -+++ b/drivers/media/pci/tbsecp3/tbsecp3-core.c -@@ -0,0 +1,349 @@ -+/* -+ TBS ECP3 FPGA based cards PCIe driver -+ -+ 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 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+*/ -+ -+#include "tbsecp3.h" -+ -+static bool enable_msi = true; -+module_param(enable_msi, bool, 0444); -+MODULE_PARM_DESC(enable_msi, "use an msi interrupt if available"); -+ -+ -+void tbsecp3_gpio_set_pin(struct tbsecp3_dev *dev, -+ struct tbsecp3_gpio_pin *pin, int state) -+{ -+ u32 tmp, bank, bit; -+ -+ if (pin->lvl == TBSECP3_GPIODEF_NONE) -+ return; -+ -+ if (pin->lvl == TBSECP3_GPIODEF_LOW) -+ state = !state; -+ -+ bank = (pin->nr >> 3) & ~3; -+ bit = pin->nr % 32; -+ -+ tmp = tbs_read(TBSECP3_GPIO_BASE, bank); -+ if (state) -+ tmp |= 1 << bit; -+ else -+ tmp &= ~(1 << bit); -+ tbs_write(TBSECP3_GPIO_BASE, bank, tmp); -+} -+ -+static irqreturn_t tbsecp3_irq_handler(int irq, void *dev_id) -+{ -+ struct tbsecp3_dev *dev = (struct tbsecp3_dev *) dev_id; -+ struct tbsecp3_i2c *i2c; -+ int i, in; -+ u32 stat = tbs_read(TBSECP3_INT_BASE, TBSECP3_INT_STAT); -+ -+ tbs_write(TBSECP3_INT_BASE, TBSECP3_INT_STAT, stat); -+ -+ if (stat & 0x00000ff0) { -+ /* dma */ -+ for (i = 0; i < dev->info->adapters; i++) { -+ in = dev->adapter[i].cfg->ts_in; -+ //printk("i=%d, in=%d", i, in); -+ if (stat & TBSECP3_DMA_IF(in)) { -+ if (dev->adapter[i].dma.cnt < 2) -+ dev->adapter[i].dma.cnt++; -+ else -+ tasklet_schedule(&dev->adapter[i].tasklet); -+ //printk(" X"); -+ } -+ //printk(" | "); -+ } -+ //printk("\n"); -+ } -+ if (stat & 0x0000000f) { -+ /* i2c */ -+ for (i = 0; i < 4; i++) { -+ i2c = &dev->i2c_bus[i]; -+ if (stat & TBSECP3_I2C_IF(i)) { -+ i2c->done = 1; -+ wake_up(&i2c->wq); -+ } -+ } -+ } -+ -+ tbs_write(TBSECP3_INT_BASE, TBSECP3_INT_EN, 1); -+ return IRQ_HANDLED; -+} -+ -+static int tbsecp3_adapters_attach(struct tbsecp3_dev *dev) -+{ -+ int i, ret = 0; -+ for (i = 0; i < dev->info->adapters; i++) { -+ ret = tbsecp3_dvb_init(&dev->adapter[i]); -+ if (ret) { -+ dev_err(&dev->pci_dev->dev, -+ "adapter%d attach failed\n", -+ dev->adapter[i].nr); -+ dev->adapter[i].nr = -1; -+ } -+ } -+ return 0; -+} -+ -+static void tbsecp3_adapters_detach(struct tbsecp3_dev *dev) -+{ -+ struct tbsecp3_adapter *adapter; -+ int i; -+ -+ for (i = 0; i < dev->info->adapters; i++) { -+ adapter = &dev->adapter[i]; -+ -+ /* attach has failed, nothing to do */ -+ if (adapter->nr == -1) -+ continue; -+ -+ tbsecp3_i2c_remove_clients(adapter); -+ tbsecp3_dvb_exit(adapter); -+ } -+} -+ -+static void tbsecp3_adapters_init(struct tbsecp3_dev *dev) -+{ -+ struct tbsecp3_adapter *adapter = dev->adapter; -+ int i; -+ -+ for (i = 0; i < dev->info->adapters; i++) { -+ adapter = &dev->adapter[i]; -+ adapter->nr = i; -+ adapter->cfg = &dev->info->adap_config[i]; -+ adapter->dev = dev; -+ adapter->i2c = &dev->i2c_bus[adapter->cfg->i2c_bus_nr]; -+ } -+} -+ -+static void tbsecp3_adapters_release(struct tbsecp3_dev *dev) -+{ -+ struct tbsecp3_adapter *adapter; -+ int i; -+ -+ for (i = 0; i < dev->info->adapters; i++) { -+ adapter = &dev->adapter[i]; -+ tasklet_kill(&adapter->tasklet); -+ } -+} -+ -+ -+static bool tbsecp3_enable_msi(struct pci_dev *pci_dev, struct tbsecp3_dev *dev) -+{ -+ int err; -+ -+ if (!enable_msi) { -+ dev_warn(&dev->pci_dev->dev, -+ "MSI disabled by module parameter 'enable_msi'\n"); -+ return false; -+ } -+ -+ err = pci_enable_msi(pci_dev); -+ if (err) { -+ dev_err(&dev->pci_dev->dev, -+ "Failed to enable MSI interrupt." -+ " Falling back to a shared IRQ\n"); -+ return false; -+ } -+ -+ /* no error - so request an msi interrupt */ -+ err = request_irq(pci_dev->irq, tbsecp3_irq_handler, 0, -+ "tbsecp3", dev); -+ if (err) { -+ /* fall back to legacy interrupt */ -+ dev_err(&dev->pci_dev->dev, -+ "Failed to get an MSI interrupt." -+ " Falling back to a shared IRQ\n"); -+ pci_disable_msi(pci_dev); -+ return false; -+ } -+ return true; -+} -+ -+ -+static int tbsecp3_probe(struct pci_dev *pdev, const struct pci_device_id *id) -+{ -+ struct tbsecp3_dev *dev; -+ int ret = -ENODEV; -+ -+ if (pci_enable_device(pdev) < 0) -+ return -ENODEV; -+ -+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); -+ if (ret) { -+ dev_err(&pdev->dev, "32-bit PCI DMA not supported\n"); -+ goto err0; -+ } -+ -+ dev = kzalloc(sizeof(struct tbsecp3_dev), GFP_KERNEL); -+ if (!dev) { -+ ret = -ENOMEM; -+ goto err0; -+ } -+ -+ dev->pci_dev = pdev; -+ pci_set_drvdata(pdev, dev); -+ -+ dev->info = (struct tbsecp3_board *) id->driver_data; -+ dev_info(&pdev->dev, "%s\n", dev->info->name); -+ -+ dev->lmmio = ioremap(pci_resource_start(pdev, 0), -+ pci_resource_len(pdev, 0)); -+ if (!dev->lmmio) { -+ ret = -ENOMEM; -+ goto err1; -+ } -+ -+ tbs_write(TBSECP3_INT_BASE, TBSECP3_INT_EN, 0); -+ tbs_write(TBSECP3_INT_BASE, TBSECP3_INT_STAT, 0xff); -+ -+ tbsecp3_adapters_init(dev); -+ -+ /* dma */ -+ ret = tbsecp3_dma_init(dev); -+ if (ret < 0) -+ goto err2; -+ -+ /* i2c */ -+ ret = tbsecp3_i2c_init(dev); -+ if (ret < 0) -+ goto err3; -+ -+ /* interrupts */ -+ if (tbsecp3_enable_msi(pdev, dev)) { -+ dev->msi = true; -+ } else { -+ ret = request_irq(pdev->irq, tbsecp3_irq_handler, -+ IRQF_SHARED, "tbsecp3", dev); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "%s: can't get IRQ %d\n", -+ dev->info->name, pdev->irq); -+ goto err4; -+ } -+ dev->msi = false; -+ } -+ /* global interrupt enable */ -+ tbs_write(TBSECP3_INT_BASE, TBSECP3_INT_EN, 1); -+ -+ ret = tbsecp3_adapters_attach(dev); -+ if (ret < 0) -+ goto err5; -+ -+ dev_info(&pdev->dev, "%s: PCI %s, IRQ %d, MMIO 0x%lx\n", -+ dev->info->name, pci_name(pdev), pdev->irq, -+ (unsigned long) pci_resource_start(pdev, 0)); -+ -+ //dev_info(&dev->pci_dev->dev, "%s ready\n", dev->info->name); -+ return 0; -+ -+err5: -+ tbsecp3_adapters_detach(dev); -+ -+ tbs_write(TBSECP3_INT_BASE, TBSECP3_INT_EN, 0); -+ free_irq(dev->pci_dev->irq, dev); -+ if (dev->msi) { -+ pci_disable_msi(pdev); -+ dev->msi = false; -+ } -+err4: -+ tbsecp3_i2c_exit(dev); -+err3: -+ tbsecp3_dma_free(dev); -+err2: -+ tbsecp3_adapters_release(dev); -+ iounmap(dev->lmmio); -+err1: -+ pci_set_drvdata(pdev, NULL); -+ kfree(dev); -+err0: -+ pci_disable_device(pdev); -+ dev_err(&pdev->dev, "probe error\n"); -+ return ret; -+} -+ -+static void tbsecp3_remove(struct pci_dev *pdev) -+{ -+ struct tbsecp3_dev *dev = pci_get_drvdata(pdev); -+ -+ /* disable interrupts */ -+ tbs_write(TBSECP3_INT_BASE, TBSECP3_INT_EN, 0); -+ free_irq(pdev->irq, dev); -+ if (dev->msi) { -+ pci_disable_msi(pdev); -+ dev->msi = false; -+ } -+ tbsecp3_adapters_detach(dev); -+ tbsecp3_adapters_release(dev); -+ tbsecp3_dma_free(dev); -+ tbsecp3_i2c_exit(dev); -+ iounmap(dev->lmmio); -+ pci_set_drvdata(pdev, NULL); -+ pci_disable_device(pdev); -+ kfree(dev); -+} -+ -+static int tbsecp3_resume(struct pci_dev *pdev) -+{ -+ struct tbsecp3_dev *dev = pci_get_drvdata(pdev); -+ /* re-init registers */ -+ tbsecp3_i2c_reg_init(dev); -+ tbsecp3_dma_reg_init(dev); -+ tbs_write(TBSECP3_INT_BASE, TBSECP3_INT_EN, 1); -+ return 0; -+} -+ -+/* PCI IDs */ -+#define TBSECP3_ID(_subvend) { \ -+ .vendor = TBSECP3_VID, .device = TBSECP3_PID, \ -+ .subvendor = _subvend, .subdevice = PCI_ANY_ID, \ -+ .driver_data = (unsigned long)&tbsecp3_boards[_subvend] } -+ -+static const struct pci_device_id tbsecp3_id_table[] = { -+ TBSECP3_ID(TBSECP3_BOARD_TBS6205), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6522), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6902), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6903), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6904), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6905), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6908), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6909), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6910), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6528), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6590), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6290SE), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6281SE), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6704), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6209), -+ TBSECP3_ID(TBSECP3_BOARD_TBS6814), -+ {0} -+}; -+MODULE_DEVICE_TABLE(pci, tbsecp3_id_table); -+ -+static struct pci_driver tbsecp3_driver = { -+ .name = "TBSECP3 driver", -+ .id_table = tbsecp3_id_table, -+ .probe = tbsecp3_probe, -+ .remove = tbsecp3_remove, -+ .resume = tbsecp3_resume, -+ .suspend = NULL, -+}; -+ -+module_pci_driver(tbsecp3_driver); -+ -+MODULE_AUTHOR("Luis Alves "); -+MODULE_DESCRIPTION("TBS ECP3 driver"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/pci/tbsecp3/tbsecp3-dma.c b/drivers/media/pci/tbsecp3/tbsecp3-dma.c -new file mode 100644 -index 0000000..0fa90e2 ---- /dev/null -+++ b/drivers/media/pci/tbsecp3/tbsecp3-dma.c -@@ -0,0 +1,145 @@ -+/* -+ TBS ECP3 FPGA based cards PCIe driver -+ -+ 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 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+*/ -+ -+#include "tbsecp3.h" -+ -+#define TS_PACKET_SIZE 188 -+#define TBSECP3_DMA_PAGE_SIZE (2048 * TS_PACKET_SIZE) -+#define TBSECP3_DMA_BUF_SIZE (TBSECP3_DMA_PAGE_SIZE / TBSECP3_DMA_BUFFERS) -+#define TBSECP3_BUF_PACKETS (TBSECP3_DMA_BUF_SIZE / TS_PACKET_SIZE) -+ -+static void tbsecp3_dma_tasklet(unsigned long adap) -+{ -+ struct tbsecp3_adapter *adapter = (struct tbsecp3_adapter *) adap; -+ struct tbsecp3_dev *dev = adapter->dev; -+ u8* data; -+ u32 read_buffer; -+ int i; -+ -+ spin_lock(&adapter->adap_lock); -+ -+ /* read data from two buffers below the active one */ -+ read_buffer = (tbs_read(adapter->dma.base, TBSECP3_DMA_STAT) - 2) & 7; -+ data = adapter->dma.buf[read_buffer]; -+ -+ if (data[adapter->dma.offset] != 0x47) { -+ /* find sync byte offset */ -+ for (i = 0; i < TS_PACKET_SIZE; i++) -+ if ((data[i] == 0x47) && -+ (data[i + TS_PACKET_SIZE] == 0x47) && -+ (data[i + 2 * TS_PACKET_SIZE] == 0x47)) { -+ adapter->dma.offset = i; -+ break; -+ } -+ } -+ -+ if (adapter->dma.offset != 0) { -+ data += adapter->dma.offset; -+ /* copy the remains of the last packet from buffer 0 to end of 7 */ -+ if (read_buffer == 7) { -+ memcpy( adapter->dma.buf[8], -+ adapter->dma.buf[0], adapter->dma.offset); -+ } -+ } -+ dvb_dmx_swfilter_packets(&adapter->demux, data, TBSECP3_BUF_PACKETS); -+ spin_unlock(&adapter->adap_lock); -+} -+ -+void tbsecp3_dma_enable(struct tbsecp3_adapter *adap) -+{ -+ struct tbsecp3_dev *dev = adap->dev; -+ -+ spin_lock_irq(&adap->adap_lock); -+ adap->dma.offset = 0; -+ adap->dma.cnt = 0; -+ tbs_read(adap->dma.base, TBSECP3_DMA_STAT); -+ tbs_write(TBSECP3_INT_BASE, TBSECP3_DMA_IE(adap->cfg->ts_in), 1); -+ tbs_write(adap->dma.base, TBSECP3_DMA_EN, 1); -+ spin_unlock_irq(&adap->adap_lock); -+} -+ -+void tbsecp3_dma_disable(struct tbsecp3_adapter *adap) -+{ -+ struct tbsecp3_dev *dev = adap->dev; -+ -+ spin_lock_irq(&adap->adap_lock); -+ tbs_read(adap->dma.base, TBSECP3_DMA_STAT); -+ tbs_write(TBSECP3_INT_BASE, TBSECP3_DMA_IE(adap->cfg->ts_in), 0); -+ tbs_write(adap->dma.base, TBSECP3_DMA_EN, 0); -+ spin_unlock_irq(&adap->adap_lock); -+} -+ -+void tbsecp3_dma_reg_init(struct tbsecp3_dev *dev) -+{ -+ int i; -+ struct tbsecp3_adapter *adapter = dev->adapter; -+ -+ for (i = 0; i < dev->info->adapters; i++) { -+ tbs_write(adapter->dma.base, TBSECP3_DMA_EN, 0); -+ tbs_write(adapter->dma.base, TBSECP3_DMA_ADDRH, 0); -+ tbs_write(adapter->dma.base, TBSECP3_DMA_ADDRL, (u32) adapter->dma.dma_addr); -+ tbs_write(adapter->dma.base, TBSECP3_DMA_TSIZE, TBSECP3_DMA_PAGE_SIZE); -+ tbs_write(adapter->dma.base, TBSECP3_DMA_BSIZE, TBSECP3_DMA_BUF_SIZE); -+ adapter++; -+ } -+} -+ -+void tbsecp3_dma_free(struct tbsecp3_dev *dev) -+{ -+ struct tbsecp3_adapter *adapter = dev->adapter; -+ int i; -+ for (i = 0; i < dev->info->adapters; i++) { -+ if (adapter->dma.buf[0] == NULL) -+ continue; -+ -+ pci_free_consistent(dev->pci_dev, -+ TBSECP3_DMA_PAGE_SIZE + 0x100, -+ adapter->dma.buf[0], adapter->dma.dma_addr); -+ adapter->dma.buf[0] = NULL; -+ adapter++; -+ } -+} -+ -+int tbsecp3_dma_init(struct tbsecp3_dev *dev) -+{ -+ struct tbsecp3_adapter *adapter = dev->adapter; -+ int i, j; -+ -+ for (i = 0; i < dev->info->adapters; i++) { -+ adapter->dma.buf[0] = pci_alloc_consistent(dev->pci_dev, -+ TBSECP3_DMA_PAGE_SIZE + 0x100, -+ &adapter->dma.dma_addr); -+ if (!adapter->dma.buf[0]) -+ goto err; -+ -+ adapter->dma.base = TBSECP3_DMA_BASE(adapter->cfg->ts_in); -+ adapter->dma.cnt = 0; -+ for (j = 1; j < TBSECP3_DMA_BUFFERS + 1; j++) -+ adapter->dma.buf[j] = adapter->dma.buf[j-1] + TBSECP3_DMA_BUF_SIZE; -+ -+ tasklet_init(&adapter->tasklet, tbsecp3_dma_tasklet, (unsigned long) adapter); -+ spin_lock_init(&adapter->adap_lock); -+ adapter++; -+ } -+ tbsecp3_dma_reg_init(dev); -+ return 0; -+err: -+ dev_err(&dev->pci_dev->dev, "dma: memory alloc failed\n"); -+ tbsecp3_dma_free(dev); -+ return -ENOMEM; -+} -+ -diff --git a/drivers/media/pci/tbsecp3/tbsecp3-dvb.c b/drivers/media/pci/tbsecp3/tbsecp3-dvb.c -new file mode 100644 -index 0000000..6c701e1 ---- /dev/null -+++ b/drivers/media/pci/tbsecp3/tbsecp3-dvb.c -@@ -0,0 +1,1118 @@ -+/* -+ TBS ECP3 FPGA based cards PCIe driver -+ -+ 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 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+*/ -+ -+#include "tbsecp3.h" -+ -+#include "tas2101.h" -+#include "av201x.h" -+ -+#include "si2168.h" -+#include "si2157.h" -+ -+#include "mxl5xx.h" -+ -+#include "si2183.h" -+ -+#include "stv0910.h" -+#include "stv6120.h" -+ -+#include "mn88436.h" -+#include "mxl603.h" -+ -+#include "mtv23x.h" -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+struct sec_priv { -+ struct tbsecp3_adapter *adap; -+ int (*set_voltage)(struct dvb_frontend *fe, -+ enum fe_sec_voltage voltage); -+}; -+ -+static int tbsecp3_set_voltage(struct dvb_frontend* fe, -+ enum fe_sec_voltage voltage) -+{ -+ struct sec_priv *priv = fe->sec_priv; -+ struct tbsecp3_gpio_config *cfg = &priv->adap->cfg->gpio; -+ struct tbsecp3_dev *dev = priv->adap->dev; -+ -+ dev_dbg(&dev->pci_dev->dev, "%s() %s\n", __func__, -+ voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : -+ voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : -+ "SEC_VOLTAGE_OFF"); -+ -+ switch (voltage) { -+ case SEC_VOLTAGE_13: -+ tbsecp3_gpio_set_pin(dev, &cfg->lnb_power, 1); -+ tbsecp3_gpio_set_pin(dev, &cfg->lnb_voltage, 0); -+ break; -+ case SEC_VOLTAGE_18: -+ tbsecp3_gpio_set_pin(dev, &cfg->lnb_power, 1); -+ tbsecp3_gpio_set_pin(dev, &cfg->lnb_voltage, 1); -+ break; -+ default: /* OFF */ -+ //tbsecp3_gpio_set_pin(dev, &cfg->lnb_power, 0); -+ break; -+ } -+ -+ if (priv->set_voltage) -+ return priv->set_voltage(fe, voltage); -+ else -+ return 0; -+} -+ -+static void tbsecp3_release_sec(struct dvb_frontend* fe) -+{ -+ struct sec_priv *priv; -+ -+ if (fe == NULL) -+ return; -+ -+ priv = fe->sec_priv; -+ if (priv == NULL) -+ return; -+ -+ fe->ops.set_voltage = priv->set_voltage; -+ fe->sec_priv = NULL; -+ kfree(priv); -+} -+ -+static struct dvb_frontend *tbsecp3_attach_sec(struct tbsecp3_adapter *adap, struct dvb_frontend *fe) -+{ -+ struct sec_priv *priv; -+ -+ priv = kzalloc(sizeof(struct sec_priv), GFP_KERNEL); -+ if (!priv) -+ return NULL; -+ -+ priv->set_voltage = fe->ops.set_voltage; -+ priv->adap = adap; -+ -+// fe->ops.release_sec = tbsecp3_release_sec; -+ fe->ops.set_voltage = tbsecp3_set_voltage; -+ fe->sec_priv = priv; -+ -+ return fe; -+} -+ -+static int set_mac_address(struct tbsecp3_adapter *adap) -+{ -+ struct tbsecp3_dev *dev = adap->dev; -+ u8 eeprom_bus_nr = dev->info->eeprom_i2c; -+ struct i2c_adapter *i2c = &dev->i2c_bus[eeprom_bus_nr].i2c_adap; -+ u8 eep_addr; -+ int ret; -+ -+ struct i2c_msg msg[] = { -+ { .addr = 0x50, .flags = 0, -+ .buf = &eep_addr, .len = 1 }, -+ { .addr = 0x50, .flags = I2C_M_RD, -+ .buf = adap->dvb_adapter.proposed_mac, .len = 6 } -+ }; -+ -+ if (dev->info->eeprom_addr) -+ eep_addr = dev->info->eeprom_addr; -+ else -+ eep_addr = 0xa0; -+ eep_addr += 0x10 * adap->nr; -+ ret = i2c_transfer(i2c, msg, 2); -+ if (ret != 2) { -+ dev_warn(&dev->pci_dev->dev, -+ "error reading MAC address for adapter %d\n", -+ adap->nr); -+ } else { -+ dev_info(&dev->pci_dev->dev, -+ "MAC address %pM\n", adap->dvb_adapter.proposed_mac); -+ } -+ return 0; -+}; -+ -+static int start_feed(struct dvb_demux_feed *dvbdmxfeed) -+{ -+ struct dvb_demux *dvbdmx = dvbdmxfeed->demux; -+ struct tbsecp3_adapter *adapter = dvbdmx->priv; -+ -+ if (!adapter->feeds) -+ tbsecp3_dma_enable(adapter); -+ -+ return ++adapter->feeds; -+} -+ -+static int stop_feed(struct dvb_demux_feed *dvbdmxfeed) -+{ -+ struct dvb_demux *dvbdmx = dvbdmxfeed->demux; -+ struct tbsecp3_adapter *adapter = dvbdmx->priv; -+ -+ if (--adapter->feeds) -+ return adapter->feeds; -+ -+ tbsecp3_dma_disable(adapter); -+ return 0; -+} -+ -+static void reset_demod(struct tbsecp3_adapter *adapter) -+{ -+ struct tbsecp3_dev *dev = adapter->dev; -+ struct tbsecp3_gpio_pin *reset = &adapter->cfg->gpio.demod_reset; -+ -+ tbsecp3_gpio_set_pin(dev, reset, 1); -+ usleep_range(10000, 20000); -+ -+ tbsecp3_gpio_set_pin(dev, reset, 0); -+ usleep_range(50000, 100000); -+} -+ -+ -+static struct tas2101_config tbs6902_demod_cfg[] = { -+ { -+ .i2c_address = 0x60, -+ .id = ID_TAS2101, -+ .init = {0xb0, 0x32, 0x81, 0x57, 0x64, 0x9a, 0x33}, -+ .init2 = 0, -+ }, -+ { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .init = {0xb0, 0x32, 0x81, 0x57, 0x64, 0x9a, 0x33}, // 0xb1 -+ .init2 = 0, -+ } -+}; -+ -+static struct av201x_config tbs6902_av201x_cfg = { -+ .i2c_address = 0x62, -+ .id = ID_AV2012, -+ .xtal_freq = 27000, /* kHz */ -+}; -+ -+static struct tas2101_config tbs6904_demod_cfg[] = { -+ { -+ .i2c_address = 0x60, -+ .id = ID_TAS2101, -+ .init = {0xb0, 0x32, 0x81, 0x57, 0x64, 0x9a, 0x33}, // 0xb1 -+ .init2 = 0, -+ }, -+ { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .init = {0xb0, 0x32, 0x81, 0x57, 0x64, 0x9a, 0x33}, -+ .init2 = 0, -+ }, -+ { -+ .i2c_address = 0x60, -+ .id = ID_TAS2101, -+ .init = {0xb0, 0x32, 0x81, 0x57, 0x64, 0x9a, 0x33}, -+ .init2 = 0, -+ }, -+ { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .init = {0xb0, 0x32, 0x81, 0x57, 0x64, 0x9a, 0x33}, -+ .init2 = 0, -+ } -+}; -+ -+static struct av201x_config tbs6904_av201x_cfg = { -+ .i2c_address = 0x63, -+ .id = ID_AV2012, -+ .xtal_freq = 27000, /* kHz */ -+}; -+ -+ -+static struct tas2101_config tbs6910_demod_cfg[] = { -+ { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .init = {0x21, 0x43, 0x65, 0xb0, 0xa8, 0x97, 0xb1}, -+ .init2 = 0, -+ }, -+ { -+ .i2c_address = 0x60, -+ .id = ID_TAS2101, -+ .init = {0xb0, 0xa8, 0x21, 0x43, 0x65, 0x97, 0xb1}, -+ .init2 = 0, -+ }, -+}; -+ -+static struct av201x_config tbs6910_av201x_cfg = { -+ .i2c_address = 0x62, -+ .id = ID_AV2018, -+ .xtal_freq = 27000, /* kHz */ -+}; -+ -+static int max_set_voltage(struct i2c_adapter *i2c, -+ enum fe_sec_voltage voltage, u8 rf_in) -+{ -+ struct tbsecp3_i2c *i2c_adap = i2c_get_adapdata(i2c); -+ struct tbsecp3_dev *dev = i2c_adap->dev; -+ -+ u32 val, reg; -+ -+ //printk("set voltage on %u = %d\n", rf_in, voltage); -+ -+ if (rf_in > 3) -+ return -EINVAL; -+ -+ reg = rf_in * 4; -+ val = tbs_read(TBSECP3_GPIO_BASE, reg) & ~4; -+ -+ switch (voltage) { -+ case SEC_VOLTAGE_13: -+ val &= ~2; -+ break; -+ case SEC_VOLTAGE_18: -+ val |= 2; -+ break; -+ case SEC_VOLTAGE_OFF: -+ default: -+ //val |= 4; -+ break; -+ } -+ -+ tbs_write(TBSECP3_GPIO_BASE, reg, val); -+ return 0; -+} -+ -+static int max_send_master_cmd(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd) -+{ -+ //printk("send master cmd\n"); -+ return 0; -+} -+static int max_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd burst) -+{ -+ //printk("send burst: %d\n", burst); -+ return 0; -+} -+static void RF_switch(struct i2c_adapter *i2c,u8 rf_in,u8 flag)//flag : 0: dvbs/s2 signal 1:Terrestrial and cable signal -+{ -+ struct tbsecp3_i2c *i2c_adap = i2c_get_adapdata(i2c); -+ struct tbsecp3_dev *dev = i2c_adap->dev; -+ u32 val ,reg; -+ -+ reg = 0xc-rf_in*4; -+ -+ val = tbs_read(TBSECP3_GPIO_BASE, reg); -+ if(flag) -+ val |= 2; -+ else -+ val &= ~2; -+ -+ tbs_write(TBSECP3_GPIO_BASE, reg, val); -+ -+} -+ -+static struct mxl5xx_cfg tbs6909_mxl5xx_cfg = { -+ .adr = 0x60, -+ .type = 0x01, -+ .clk = 24000000, -+ .cap = 12, -+ .fw_read = NULL, -+ -+ .set_voltage = max_set_voltage, -+}; -+ -+static struct stv0910_cfg tbs6903_stv0910_cfg = { -+ .adr = 0x68, -+ .parallel = 1, -+ .rptlvl = 3, -+ .clk = 30000000, -+ .dual_tuner = 1, -+}; -+ -+struct stv6120_cfg tbs6903_stv6120_cfg = { -+ .adr = 0x60, -+ .Rdiv = 2, -+ .xtal = 30000, -+}; -+ -+ -+static struct av201x_config tbs6522_av201x_cfg[] = { -+ { -+ .i2c_address = 0x63, -+ .id = ID_AV2018, -+ .xtal_freq = 27000, -+ }, -+ { -+ .i2c_address = 0x62, -+ .id = ID_AV2018, -+ .xtal_freq = 27000, -+ }, -+}; -+ -+ -+ -+static int tbsecp3_frontend_attach(struct tbsecp3_adapter *adapter) -+{ -+ struct tbsecp3_dev *dev = adapter->dev; -+ struct pci_dev *pci = dev->pci_dev; -+ -+ struct si2168_config si2168_config; -+ struct si2183_config si2183_config; -+ struct si2157_config si2157_config; -+ struct mn88436_config mn88436_config; -+ struct mxl603_config mxl603_config; -+ struct mtv23x_config mtv23x_config; -+ //struct av201x_config av201x_config; -+ -+ struct i2c_board_info info; -+ struct i2c_adapter *i2c = &adapter->i2c->i2c_adap; -+ struct i2c_client *client_demod, *client_tuner; -+ -+ adapter->fe = NULL; -+ adapter->fe2 = NULL; -+ adapter->i2c_client_demod = NULL; -+ adapter->i2c_client_tuner = NULL; -+ -+ reset_demod(adapter); -+ -+ set_mac_address(adapter); -+ -+ switch (pci->subsystem_vendor) { -+ case 0x6814: -+ memset(&mtv23x_config, 0, sizeof(mtv23x_config)); -+ mtv23x_config.fe = &adapter->fe; -+ mtv23x_config.clk_freq = 32000; -+ mtv23x_config.ts_mode = 6; -+ mtv23x_config.i2c_wr_max = 32; -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "mtv23x", I2C_NAME_SIZE); -+ info.addr = (adapter->nr%2)? 0x44 : 0x43; -+ info.platform_data = &mtv23x_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(i2c, &info); -+ if (client_demod == NULL || -+ client_demod->dev.driver == NULL) -+ goto frontend_atach_fail; -+ if (!try_module_get(client_demod->dev.driver->owner)) { -+ i2c_unregister_device(client_demod); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_demod = client_demod; -+ break; -+ case 0x6209: -+ /* attach demod */ -+ memset(&si2183_config, 0, sizeof(si2183_config)); -+ si2183_config.i2c_adapter = &i2c; -+ si2183_config.fe = &adapter->fe; -+ si2183_config.ts_mode = SI2183_TS_SERIAL; -+ si2183_config.ts_clock_gapped = true; -+ si2183_config.rf_in = adapter->nr; -+ si2183_config.RF_switch = NULL; -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2183", I2C_NAME_SIZE); -+ info.addr = (adapter->nr%2)? 0x67 : 0x64; -+ si2183_config.agc_mode = (adapter->nr%2)? 0x5 : 0x4; -+ info.platform_data = &si2183_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(i2c, &info); -+ if (client_demod == NULL || -+ client_demod->dev.driver == NULL) -+ goto frontend_atach_fail; -+ if (!try_module_get(client_demod->dev.driver->owner)) { -+ i2c_unregister_device(client_demod); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_demod = client_demod; -+ -+ /* terrestrial tuner */ -+ memset(adapter->fe->ops.delsys, 0, MAX_DELSYS); -+ adapter->fe->ops.delsys[0] = SYS_DVBT; -+ adapter->fe->ops.delsys[1] = SYS_DVBT2; -+ adapter->fe->ops.delsys[2] = SYS_DVBC_ANNEX_A; -+ adapter->fe->ops.delsys[3] = SYS_ISDBT; -+ adapter->fe->ops.delsys[4] = SYS_DVBC_ANNEX_B; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = adapter->fe; -+ si2157_config.if_port = 1; -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = (adapter->nr %2)? 0x60 : 0x63; -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client_tuner = i2c_new_device(i2c, &info); -+ if (client_tuner == NULL || -+ client_tuner->dev.driver == NULL) -+ goto frontend_atach_fail; -+ -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_tuner = client_tuner; -+ break; -+ case 0x6704: -+ /* attach demod */ -+ memset(&mn88436_config, 0, sizeof(mn88436_config)); -+ mn88436_config.fe = &adapter->fe; -+ mn88436_config.ts_mode = 0; -+ mn88436_config.i2c_wr_max = 32; -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "mn88436", I2C_NAME_SIZE); -+ info.addr = 0x18; -+ info.platform_data = &mn88436_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(i2c, &info); -+ if (client_demod == NULL || -+ client_demod->dev.driver == NULL) -+ goto frontend_atach_fail; -+ if (!try_module_get(client_demod->dev.driver->owner)) { -+ i2c_unregister_device(client_demod); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_demod = client_demod; -+ -+ /* attach tuner */ -+ memset(&mxl603_config, 0, sizeof(mxl603_config)); -+ mxl603_config.fe = adapter->fe; -+ mxl603_config.xtalFreqSel= 1; //0:16M ,1:24M -+ mxl603_config.agcType = 0 ; //0:self 1:external -+ mxl603_config.ifOutFreq = MXL603_IF_5MHz; -+ mxl603_config.manualIFFreqSet = false; -+ mxl603_config.manualIFOutFreqInKHz = 0 ;//if manual set ,input the freq -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "mxl603", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &mxl603_config; -+ request_module(info.type); -+ client_tuner = i2c_new_device(i2c, &info); -+ if (client_tuner == NULL || -+ client_tuner->dev.driver == NULL) -+ goto frontend_atach_fail; -+ -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_tuner = client_tuner; -+ -+ break; -+ case 0x6205: -+ case 0x6281: -+ /* attach demod */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.i2c_adapter = &i2c; -+ si2168_config.fe = &adapter->fe; -+ si2168_config.ts_mode = SI2168_TS_PARALLEL; -+ si2168_config.ts_clock_gapped = true; -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2168", I2C_NAME_SIZE); -+ info.addr = 0x64; -+ info.platform_data = &si2168_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(i2c, &info); -+ if (client_demod == NULL || -+ client_demod->dev.driver == NULL) -+ goto frontend_atach_fail; -+ if (!try_module_get(client_demod->dev.driver->owner)) { -+ i2c_unregister_device(client_demod); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_demod = client_demod; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = adapter->fe; -+ si2157_config.if_port = 1; -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client_tuner = i2c_new_device(i2c, &info); -+ if (client_tuner == NULL || -+ client_tuner->dev.driver == NULL) -+ goto frontend_atach_fail; -+ -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_tuner = client_tuner; -+ break; -+ case 0x6290: -+ /* attach demod */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.i2c_adapter = &i2c; -+ si2168_config.fe = &adapter->fe; -+ si2168_config.ts_mode = SI2168_TS_SERIAL;//zc2016/07/20 -+ si2168_config.ts_clock_gapped = true; -+ //si2168_config.ts_clock_inv=1;//zc2016/07/20 -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2168", I2C_NAME_SIZE); -+ info.addr = 0x64; -+ info.platform_data = &si2168_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(i2c, &info); -+ if (client_demod == NULL || -+ client_demod->dev.driver == NULL) -+ goto frontend_atach_fail; -+ if (!try_module_get(client_demod->dev.driver->owner)) { -+ i2c_unregister_device(client_demod); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_demod = client_demod; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = adapter->fe; -+ si2157_config.if_port = 1; -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client_tuner = i2c_new_device(i2c, &info); -+ if (client_tuner == NULL || -+ client_tuner->dev.driver == NULL) -+ goto frontend_atach_fail; -+ -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_tuner = client_tuner; -+ tbsecp3_ca_init(adapter, adapter->nr); -+ break; -+ case 0x6522: -+ /* attach demod */ -+ memset(&si2183_config, 0, sizeof(si2183_config)); -+ si2183_config.i2c_adapter = &i2c; -+ si2183_config.fe = &adapter->fe; -+ si2183_config.ts_mode = SI2183_TS_PARALLEL; -+ si2183_config.ts_clock_gapped = true; -+ si2183_config.rf_in = adapter->nr; -+ si2183_config.RF_switch = NULL; -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2183", I2C_NAME_SIZE); -+ info.addr = adapter->nr ? 0x64 : 0x67; -+ si2183_config.agc_mode = adapter->nr? 0x4 : 0x5; -+ info.platform_data = &si2183_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(i2c, &info); -+ if (client_demod == NULL || -+ client_demod->dev.driver == NULL) -+ goto frontend_atach_fail; -+ if (!try_module_get(client_demod->dev.driver->owner)) { -+ i2c_unregister_device(client_demod); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_demod = client_demod; -+ -+ -+ -+ /* dvb core doesn't support 2 tuners for 1 demod so -+ we split the adapter in 2 frontends */ -+ adapter->fe2 = &adapter->_fe2; -+ memcpy(adapter->fe2, adapter->fe, sizeof(struct dvb_frontend)); -+ -+ -+ /* terrestrial tuner */ -+ memset(adapter->fe->ops.delsys, 0, MAX_DELSYS); -+ adapter->fe->ops.delsys[0] = SYS_DVBT; -+ adapter->fe->ops.delsys[1] = SYS_DVBT2; -+ adapter->fe->ops.delsys[2] = SYS_DVBC_ANNEX_A; -+ adapter->fe->ops.delsys[3] = SYS_ISDBT; -+ adapter->fe->ops.delsys[4] = SYS_DVBC_ANNEX_B; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = adapter->fe; -+ si2157_config.if_port = 1; -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = adapter->nr ? 0x61 : 0x60; -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client_tuner = i2c_new_device(i2c, &info); -+ if (client_tuner == NULL || -+ client_tuner->dev.driver == NULL) -+ goto frontend_atach_fail; -+ -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_tuner = client_tuner; -+ -+ -+ /* sattelite tuner */ -+ memset(adapter->fe2->ops.delsys, 0, MAX_DELSYS); -+ adapter->fe2->ops.delsys[0] = SYS_DVBS; -+ adapter->fe2->ops.delsys[1] = SYS_DVBS2; -+ adapter->fe2->ops.delsys[2] = SYS_DSS; -+ adapter->fe2->id = 1; -+ if (dvb_attach(av201x_attach, adapter->fe2, &tbs6522_av201x_cfg[adapter->nr], -+ i2c) == NULL) { -+ dev_err(&dev->pci_dev->dev, -+ "frontend %d tuner attach failed\n", -+ adapter->nr); -+ goto frontend_atach_fail; -+ } -+ if (tbsecp3_attach_sec(adapter, adapter->fe2) == NULL) { -+ dev_warn(&dev->pci_dev->dev, -+ "error attaching lnb control on adapter %d\n", -+ adapter->nr); -+ } -+ -+ break; -+ case 0x6528: -+ case 0x6590: -+ /* attach demod */ -+ memset(&si2183_config, 0, sizeof(si2183_config)); -+ si2183_config.i2c_adapter = &i2c; -+ si2183_config.fe = &adapter->fe; -+ si2183_config.ts_clock_gapped = true; -+ si2183_config.RF_switch = RF_switch; -+ if(pci->subsystem_vendor==0x6528) -+ { -+ si2183_config.rf_in = 1; -+ si2183_config.ts_mode = SI2183_TS_PARALLEL; -+ } -+ else -+ { -+ si2183_config.rf_in = adapter->nr; -+ si2183_config.ts_mode = SI2183_TS_SERIAL; -+ } -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2183", I2C_NAME_SIZE); -+ if(pci->subsystem_vendor==0x6528) -+ { -+ info.addr = 0x67; -+ si2183_config.agc_mode = 0x5 ; -+ } -+ else{ -+ info.addr = adapter->nr ? 0x67 : 0x64; -+ si2183_config.agc_mode = adapter->nr? 0x5 : 0x4; -+ } -+ info.platform_data = &si2183_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(i2c, &info); -+ if (client_demod == NULL || -+ client_demod->dev.driver == NULL) -+ goto frontend_atach_fail; -+ if (!try_module_get(client_demod->dev.driver->owner)) { -+ i2c_unregister_device(client_demod); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_demod = client_demod; -+ -+ -+ -+ /* dvb core doesn't support 2 tuners for 1 demod so -+ we split the adapter in 2 frontends */ -+ adapter->fe2 = &adapter->_fe2; -+ memcpy(adapter->fe2, adapter->fe, sizeof(struct dvb_frontend)); -+ -+ -+ /* terrestrial tuner */ -+ memset(adapter->fe->ops.delsys, 0, MAX_DELSYS); -+ adapter->fe->ops.delsys[0] = SYS_DVBT; -+ adapter->fe->ops.delsys[1] = SYS_DVBT2; -+ adapter->fe->ops.delsys[2] = SYS_DVBC_ANNEX_A; -+ adapter->fe->ops.delsys[3] = SYS_ISDBT; -+ adapter->fe->ops.delsys[4] = SYS_DVBC_ANNEX_B; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = adapter->fe; -+ si2157_config.if_port = 1; -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ if(pci->subsystem_vendor==0x6528)info.addr = 0x61; -+ else -+ info.addr = adapter->nr ? 0x61 : 0x60; -+ -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client_tuner = i2c_new_device(i2c, &info); -+ if (client_tuner == NULL || -+ client_tuner->dev.driver == NULL) -+ goto frontend_atach_fail; -+ -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_tuner = client_tuner; -+ -+ -+ /* sattelite tuner */ -+ memset(adapter->fe2->ops.delsys, 0, MAX_DELSYS); -+ adapter->fe2->ops.delsys[0] = SYS_DVBS; -+ adapter->fe2->ops.delsys[1] = SYS_DVBS2; -+ adapter->fe2->ops.delsys[2] = SYS_DSS; -+ adapter->fe2->id = 1; -+ if(pci->subsystem_vendor==0x6528) -+ { -+ if (dvb_attach(av201x_attach, adapter->fe2, &tbs6522_av201x_cfg[1], -+ i2c) == NULL) { -+ dev_err(&dev->pci_dev->dev, -+ "frontend %d tuner attach failed\n", -+ adapter->nr); -+ goto frontend_atach_fail; -+ } -+ } -+ else{ -+ if (dvb_attach(av201x_attach, adapter->fe2, &tbs6522_av201x_cfg[adapter->nr], -+ i2c) == NULL) { -+ dev_err(&dev->pci_dev->dev, -+ "frontend %d tuner attach failed\n", -+ adapter->nr); -+ goto frontend_atach_fail; -+ } -+ } -+ if (tbsecp3_attach_sec(adapter, adapter->fe2) == NULL) { -+ dev_warn(&dev->pci_dev->dev, -+ "error attaching lnb control on adapter %d\n", -+ adapter->nr); -+ } -+ -+ tbsecp3_ca_init(adapter, adapter->nr); -+ -+ break; -+ -+ case 0x6902: -+ adapter->fe = dvb_attach(tas2101_attach, &tbs6902_demod_cfg[adapter->nr], i2c); -+ if (adapter->fe == NULL) -+ goto frontend_atach_fail; -+ -+ if (dvb_attach(av201x_attach, adapter->fe, &tbs6902_av201x_cfg, -+ tas2101_get_i2c_adapter(adapter->fe, 2)) == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_err(&dev->pci_dev->dev, -+ "frontend %d tuner attach failed\n", -+ adapter->nr); -+ goto frontend_atach_fail; -+ } -+ -+ if (tbsecp3_attach_sec(adapter, adapter->fe) == NULL) { -+ dev_warn(&dev->pci_dev->dev, -+ "error attaching lnb control on adapter %d\n", -+ adapter->nr); -+ } -+ break; -+ case 0x6903: -+ case 0x6905: -+ case 0x6908: -+ adapter->fe = dvb_attach(stv0910_attach, i2c, -+ &tbs6903_stv0910_cfg, adapter->nr & 1); -+ if (adapter->fe == NULL) -+ goto frontend_atach_fail; -+ -+ if (dvb_attach(stv6120_attach, adapter->fe, i2c, &tbs6903_stv6120_cfg, 1 - (adapter->nr & 1)) == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_err(&dev->pci_dev->dev, -+ "frontend %d tuner attach failed\n", -+ adapter->nr); -+ goto frontend_atach_fail; -+ } -+ if (tbsecp3_attach_sec(adapter, adapter->fe) == NULL) { -+ dev_warn(&dev->pci_dev->dev, -+ "error attaching lnb control on adapter %d\n", -+ adapter->nr); -+ } -+ -+ break; -+ case 0x6904: -+ adapter->fe = dvb_attach(tas2101_attach, &tbs6904_demod_cfg[adapter->nr], i2c); -+ if (adapter->fe == NULL) -+ goto frontend_atach_fail; -+ -+ if (dvb_attach(av201x_attach, adapter->fe, &tbs6904_av201x_cfg, -+ tas2101_get_i2c_adapter(adapter->fe, 2)) == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_err(&dev->pci_dev->dev, -+ "frontend %d tuner attach failed\n", -+ adapter->nr); -+ goto frontend_atach_fail; -+ } -+ -+ if (tbsecp3_attach_sec(adapter, adapter->fe) == NULL) { -+ dev_warn(&dev->pci_dev->dev, -+ "error attaching lnb control on adapter %d\n", -+ adapter->nr); -+ } -+#if 0 -+ /* attach tuner */ -+ memset(&av201x_config, 0, sizeof(av201x_config)); -+ av201x_config.fe = adapter->fe; -+ av201x_config.xtal_freq = 27000, -+ -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "av2012", I2C_NAME_SIZE); -+ info.addr = 0x63; -+ info.platform_data = &av201x_config; -+ request_module(info.type); -+ client_tuner = i2c_new_device(i2c, &info); -+ printk("cli_tu=%p\n", client_tuner); -+ if (client_tuner != NULL) -+ printk("cli_tu.drv=%p\n", client_tuner->dev.driver); -+ if (client_tuner == NULL || -+ client_tuner->dev.driver == NULL) { -+ printk("client tunner fail 1\n"); -+ goto frontend_atach_fail; -+ } -+ -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ printk("client tunner fail 2\n"); -+ goto frontend_atach_fail; -+ } -+ adapter->i2c_client_tuner = client_tuner; -+#endif -+ break; -+ case 0x6909: -+/* -+ tmp = tbs_read(TBS_GPIO_BASE, 0x20); -+ printk("RD 0x20 = %x\n", tmp); -+ tbs_write(TBS_GPIO_BASE, 0x20, tmp & 0xfffe); -+ tmp = tbs_read(TBS_GPIO_BASE, 0x20); -+ printk("RD 0x20 = %x\n", tmp); -+ -+ tmp = tbs_read(TBS_GPIO_BASE, 0x24); -+ printk("RD 0x24 = %x\n", tmp); -+ tbs_write(TBS_GPIO_BASE, 0x24, tmp & 0xfffc); -+ tmp = tbs_read(TBS_GPIO_BASE, 0x24); -+ printk("RD 0x24 = %x\n", tmp); -+*/ -+ -+ adapter->fe = dvb_attach(mxl5xx_attach, i2c, -+ &tbs6909_mxl5xx_cfg, adapter->nr); -+ if (adapter->fe == NULL) -+ goto frontend_atach_fail; -+ -+ // adapter->fe->ops.diseqc_send_master_cmd = max_send_master_cmd; -+ // adapter->fe->ops.diseqc_send_burst = max_send_burst; -+ -+ if (tbsecp3_attach_sec(adapter, adapter->fe) == NULL) { -+ dev_warn(&dev->pci_dev->dev, -+ "error attaching lnb control on adapter %d\n", -+ adapter->nr); -+ } -+ -+ break; -+ -+ case 0x6910: -+ adapter->fe = dvb_attach(tas2101_attach, &tbs6910_demod_cfg[adapter->nr], i2c); -+ if (adapter->fe == NULL) -+ goto frontend_atach_fail; -+ -+ if (dvb_attach(av201x_attach, adapter->fe, &tbs6910_av201x_cfg, -+ tas2101_get_i2c_adapter(adapter->fe, 2)) == NULL) { -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_err(&dev->pci_dev->dev, -+ "frontend %d tuner attach failed\n", -+ adapter->nr); -+ goto frontend_atach_fail; -+ } -+ if (tbsecp3_attach_sec(adapter, adapter->fe) == NULL) { -+ dev_warn(&dev->pci_dev->dev, -+ "error attaching lnb control on adapter %d\n", -+ adapter->nr); -+ } -+ -+ tbsecp3_ca_init(adapter, adapter->nr); -+ break; -+ default: -+ dev_warn(&dev->pci_dev->dev, "unknonw card\n"); -+ return -ENODEV; -+ break; -+ } -+ strlcpy(adapter->fe->ops.info.name,tbsecp3_boards[pci->subsystem_vendor].name,52); -+ return 0; -+ -+frontend_atach_fail: -+ tbsecp3_i2c_remove_clients(adapter); -+ if (adapter->fe != NULL) -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ dev_err(&dev->pci_dev->dev, "TBSECP3 frontend %d attach failed\n", -+ adapter->nr); -+ -+ return -ENODEV; -+} -+ -+int tbsecp3_dvb_init(struct tbsecp3_adapter *adapter) -+{ -+ struct tbsecp3_dev *dev = adapter->dev; -+ struct dvb_adapter *adap = &adapter->dvb_adapter; -+ struct dvb_demux *dvbdemux = &adapter->demux; -+ struct dmxdev *dmxdev; -+ struct dmx_frontend *fe_hw; -+ struct dmx_frontend *fe_mem; -+ int ret; -+ -+ ret = dvb_register_adapter(adap, "TBSECP3 DVB Adapter", -+ THIS_MODULE, -+ &adapter->dev->pci_dev->dev, -+ adapter_nr); -+ if (ret < 0) { -+ dev_err(&dev->pci_dev->dev, "error registering adapter\n"); -+ if (ret == -ENFILE) -+ dev_err(&dev->pci_dev->dev, -+ "increase DVB_MAX_ADAPTERS (%d)\n", -+ DVB_MAX_ADAPTERS); -+ return ret; -+ } -+ -+ adap->priv = adapter; -+ dvbdemux->priv = adapter; -+ dvbdemux->filternum = 256; -+ dvbdemux->feednum = 256; -+ dvbdemux->start_feed = start_feed; -+ dvbdemux->stop_feed = stop_feed; -+ dvbdemux->write_to_decoder = NULL; -+ dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | -+ DMX_SECTION_FILTERING | -+ DMX_MEMORY_BASED_FILTERING); -+ -+ ret = dvb_dmx_init(dvbdemux); -+ if (ret < 0) { -+ dev_err(&dev->pci_dev->dev, "dvb_dmx_init failed\n"); -+ goto err0; -+ } -+ -+ dmxdev = &adapter->dmxdev; -+ -+ dmxdev->filternum = 256; -+ dmxdev->demux = &dvbdemux->dmx; -+ dmxdev->capabilities = 0; -+ -+ ret = dvb_dmxdev_init(dmxdev, adap); -+ if (ret < 0) { -+ dev_err(&dev->pci_dev->dev, "dvb_dmxdev_init failed\n"); -+ goto err1; -+ } -+ -+ fe_hw = &adapter->fe_hw; -+ fe_mem = &adapter->fe_mem; -+ -+ fe_hw->source = DMX_FRONTEND_0; -+ ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, fe_hw); -+ if ( ret < 0) { -+ dev_err(&dev->pci_dev->dev, "dvb_dmx_init failed"); -+ goto err2; -+ } -+ -+ fe_mem->source = DMX_MEMORY_FE; -+ ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, fe_mem); -+ if (ret < 0) { -+ dev_err(&dev->pci_dev->dev, "dvb_dmx_init failed"); -+ goto err3; -+ } -+ -+ ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, fe_hw); -+ if (ret < 0) { -+ dev_err(&dev->pci_dev->dev, "dvb_dmx_init failed"); -+ goto err4; -+ } -+ -+ ret = dvb_net_init(adap, &adapter->dvbnet, adapter->dmxdev.demux); -+ if (ret < 0) { -+ dev_err(&dev->pci_dev->dev, "dvb_net_init failed"); -+ goto err5; -+ } -+ -+ tbsecp3_frontend_attach(adapter); -+ if (adapter->fe == NULL) { -+ dev_err(&dev->pci_dev->dev, "frontend attach failed\n"); -+ ret = -ENODEV; -+ goto err6; -+ } -+ -+ ret = dvb_register_frontend(adap, adapter->fe); -+ if (ret < 0) { -+ dev_err(&dev->pci_dev->dev, "frontend register failed\n"); -+ goto err7; -+ } -+ -+ if (adapter->fe2 != NULL) { -+ ret = dvb_register_frontend(adap, adapter->fe2); -+ if (ret < 0) { -+ dev_err(&dev->pci_dev->dev, "frontend2 register failed\n"); -+ } -+ } -+ -+ -+ return ret; -+ -+err7: -+ dvb_frontend_detach(adapter->fe); -+err6: -+ tbsecp3_release_sec(adapter->fe); -+ -+ dvb_net_release(&adapter->dvbnet); -+err5: -+ dvbdemux->dmx.close(&dvbdemux->dmx); -+err4: -+ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, fe_mem); -+err3: -+ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, fe_hw); -+err2: -+ dvb_dmxdev_release(dmxdev); -+err1: -+ dvb_dmx_release(dvbdemux); -+err0: -+ dvb_unregister_adapter(adap); -+ return ret; -+} -+ -+void tbsecp3_dvb_exit(struct tbsecp3_adapter *adapter) -+{ -+ struct dvb_adapter *adap = &adapter->dvb_adapter; -+ struct dvb_demux *dvbdemux = &adapter->demux; -+ -+ if (adapter->fe) { -+ tbsecp3_ca_release(adapter); -+ dvb_unregister_frontend(adapter->fe); -+ tbsecp3_release_sec(adapter->fe); -+ dvb_frontend_detach(adapter->fe); -+ adapter->fe = NULL; -+ -+ if (adapter->fe2 != NULL) { -+ dvb_unregister_frontend(adapter->fe2); -+ tbsecp3_release_sec(adapter->fe2); -+ dvb_frontend_detach(adapter->fe2); -+ adapter->fe2 = NULL; -+ } -+ } -+ dvb_net_release(&adapter->dvbnet); -+ dvbdemux->dmx.close(&dvbdemux->dmx); -+ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->fe_mem); -+ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->fe_hw); -+ dvb_dmxdev_release(&adapter->dmxdev); -+ dvb_dmx_release(&adapter->demux); -+ dvb_unregister_adapter(adap); -+} -diff --git a/drivers/media/pci/tbsecp3/tbsecp3-i2c.c b/drivers/media/pci/tbsecp3/tbsecp3-i2c.c -new file mode 100644 -index 0000000..2529e87 ---- /dev/null -+++ b/drivers/media/pci/tbsecp3/tbsecp3-i2c.c -@@ -0,0 +1,211 @@ -+/* -+ TBS ECP3 FPGA based cards PCIe driver -+ -+ 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 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+*/ -+ -+#include "tbsecp3.h" -+ -+union tbsecp3_i2c_ctrl { -+ struct { -+ u32 ctrl; -+ u32 data; -+ } raw; -+ struct { -+ u8 size:4; -+ u8 saddr:2; -+ u8 stop:1; -+ u8 start:1; -+ u8 read:1; -+ u8 addr:7; -+ u8 buf[6]; -+ } bits; -+}; -+ -+static int i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msg, int num) -+{ -+ struct tbsecp3_i2c *bus = i2c_get_adapdata(adapter); -+ struct tbsecp3_dev *dev = bus->dev; -+ union tbsecp3_i2c_ctrl i2c_ctrl; -+ int i, j, retval; -+ u16 len, remaining, xfer_max; -+ u8 *b; -+ -+ mutex_lock(&bus->lock); -+ for (i = 0; i < num; i++) { -+ -+ b = msg[i].buf; -+ remaining = msg[i].len; -+ -+ i2c_ctrl.raw.ctrl = 0; -+ i2c_ctrl.bits.start = 1; -+ i2c_ctrl.bits.addr = msg[i].addr; -+ -+ if (msg[i].flags & I2C_M_RD) { -+ i2c_ctrl.bits.read = 1; -+ xfer_max = 4; -+ } else { -+ xfer_max = 6; -+ } -+ -+ do { -+ if (remaining <= xfer_max) -+ i2c_ctrl.bits.stop = 1; -+ -+ len = remaining > xfer_max ? xfer_max : remaining; -+ i2c_ctrl.bits.size = len; -+ -+ if (!(msg[i].flags & I2C_M_RD)) { -+ for (j = 0; j < len; j++) -+ i2c_ctrl.bits.buf[j] = *b++; -+ tbs_write(bus->base, TBSECP3_I2C_DATA, i2c_ctrl.raw.data); -+ } -+ bus->done = 0; -+ tbs_write(bus->base, TBSECP3_I2C_CTRL, i2c_ctrl.raw.ctrl); -+ retval = wait_event_timeout(bus->wq, bus->done == 1, HZ); -+ if (retval == 0) { -+ dev_err(&dev->pci_dev->dev, "i2c xfer timeout\n"); -+ retval = -EIO; -+ goto i2c_xfer_exit; -+ } -+ -+ j = tbs_read(bus->base, TBSECP3_I2C_CTRL); -+ if (j & 0x04) { -+ dev_err(&dev->pci_dev->dev, "i2c nack (%x)\n", j); -+ retval = -EIO; -+ goto i2c_xfer_exit; -+ } -+ -+ if (msg[i].flags & I2C_M_RD) { -+ i2c_ctrl.raw.data = tbs_read(bus->base, TBSECP3_I2C_DATA); -+ memcpy(b, &i2c_ctrl.raw.data, len); -+ b += len; -+ } -+ -+ i2c_ctrl.bits.start = 0; -+ remaining -= len; -+ } while (remaining); -+ -+ } -+ retval = num; -+i2c_xfer_exit: -+ mutex_unlock(&bus->lock); -+ return retval; -+} -+ -+static u32 i2c_functionality(struct i2c_adapter *adap) -+{ -+ return I2C_FUNC_SMBUS_EMUL; -+} -+ -+struct i2c_algorithm tbsecp3_i2c_algo_template = { -+ .master_xfer = i2c_xfer, -+ .functionality = i2c_functionality, -+}; -+ -+static int tbsecp3_i2c_register(struct tbsecp3_i2c *bus) -+{ -+ struct tbsecp3_dev *dev = bus->dev; -+ struct i2c_adapter *adap; -+ -+ init_waitqueue_head(&bus->wq); -+ mutex_init(&bus->lock); -+ -+ adap = &bus->i2c_adap; -+ strcpy(adap->name, "tbsecp3"); -+ adap->algo = &tbsecp3_i2c_algo_template; -+ adap->algo_data = (void*) bus; -+ adap->dev.parent = &dev->pci_dev->dev; -+ adap->owner = THIS_MODULE; -+ -+ strcpy(bus->i2c_client.name, "tbsecp3cli"); -+ bus->i2c_client.adapter = adap; -+ -+ i2c_set_adapdata(&bus->i2c_adap, bus); -+ return i2c_add_adapter(&bus->i2c_adap); -+} -+ -+static void tbsecp3_i2c_unregister(struct tbsecp3_i2c *bus) -+{ -+ i2c_del_adapter(&bus->i2c_adap); -+} -+ -+/* ----------------------------------------------------------------------- */ -+ -+void tbsecp3_i2c_remove_clients(struct tbsecp3_adapter *adapter) -+{ -+ struct i2c_client *client_demod, *client_tuner; -+ -+ /* remove tuner I2C client */ -+ client_tuner = adapter->i2c_client_tuner; -+ if (client_tuner) { -+ module_put(client_tuner->dev.driver->owner); -+ i2c_unregister_device(client_tuner); -+ adapter->i2c_client_tuner = NULL; -+ } -+ -+ /* remove demodulator I2C client */ -+ client_demod = adapter->i2c_client_demod; -+ if (client_demod) { -+ module_put(client_demod->dev.driver->owner); -+ i2c_unregister_device(client_demod); -+ adapter->i2c_client_demod = NULL; -+ } -+} -+ -+void tbsecp3_i2c_reg_init(struct tbsecp3_dev *dev) -+{ -+ int i; -+ u32 baud = dev->info->i2c_speed; -+ -+ /* default to 400kbps */ -+ if (!baud) -+ baud = 9; -+ -+ for (i = 0; i < 4; i++) { -+ tbs_write(dev->i2c_bus[i].base, TBSECP3_I2C_BAUD, baud); -+ tbs_read(dev->i2c_bus[i].base, TBSECP3_I2C_STAT); -+ tbs_write(TBSECP3_INT_BASE, TBSECP3_I2C_IE(i), 1); -+ } -+} -+ -+int tbsecp3_i2c_init(struct tbsecp3_dev *dev) -+{ -+ int i, ret = 0; -+ -+ /* I2C Defaults / setup */ -+ for (i = 0; i < 4; i++) { -+ dev->i2c_bus[i].base = TBSECP3_I2C_BASE(i); -+ dev->i2c_bus[i].dev = dev; -+ ret = tbsecp3_i2c_register(&dev->i2c_bus[i]); -+ if (ret) -+ break; -+ } -+ if (ret) { -+ do { -+ tbsecp3_i2c_unregister(&dev->i2c_bus[i]); -+ } while (i-- > 0); -+ } else { -+ tbsecp3_i2c_reg_init(dev); -+ } -+ return ret; -+} -+ -+void tbsecp3_i2c_exit(struct tbsecp3_dev *dev) -+{ -+ int i; -+ for (i = 0; i < 4; i++) -+ tbsecp3_i2c_unregister(&dev->i2c_bus[i]); -+} -+ -diff --git a/drivers/media/pci/tbsecp3/tbsecp3-regs.h b/drivers/media/pci/tbsecp3/tbsecp3-regs.h -new file mode 100644 -index 0000000..82e81ff ---- /dev/null -+++ b/drivers/media/pci/tbsecp3/tbsecp3-regs.h -@@ -0,0 +1,53 @@ -+/* -+ TBS ECP3 FPGA based cards PCIe driver -+ -+ 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 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+*/ -+ -+#ifndef _TBSECP3_REGS_H_ -+#define _TBSECP3_REGS_H_ -+ -+/* GPIO */ -+#define TBSECP3_GPIO_BASE 0x0000 -+#define TBSECP3_GPIO_PIN(_bank, _pin) (((_bank) << 5) + _pin) -+ -+/* I2C */ -+#define TBSECP3_I2C_BASE(_n) (0x4000 + 0x1000 * _n) -+#define TBSECP3_I2C_STAT 0x0000 -+#define TBSECP3_I2C_CTRL 0x0000 -+#define TBSECP3_I2C_DATA 0x0004 -+#define TBSECP3_I2C_BAUD 0x0008 -+ -+/* CA */ -+#define TBSECP3_CA_BASE(_n) (0x6000 + 0x1000 * _n) -+ -+/* DMA */ -+#define TBSECP3_DMA_BASE(_n) (_n < 4) ? (0x8000 + 0x1000 * _n) : (0x8800 + 0x1000 * (_n - 4)) -+#define TBSECP3_DMA_STAT 0x0000 -+#define TBSECP3_DMA_EN 0x0000 -+#define TBSECP3_DMA_TSIZE 0x0004 -+#define TBSECP3_DMA_ADDRH 0x0008 -+#define TBSECP3_DMA_ADDRL 0x000c -+#define TBSECP3_DMA_BSIZE 0x0010 -+ -+/* INTR */ -+#define TBSECP3_INT_BASE 0xc000 -+#define TBSECP3_INT_STAT 0x0000 -+#define TBSECP3_INT_EN 0x0004 -+#define TBSECP3_I2C_IE(_n) (0x0008 + 4 * _n) -+#define TBSECP3_DMA_IE(_n) (0x0018 + 4 * _n) -+#define TBSECP3_I2C_IF(_n) (0x0001 << _n) -+#define TBSECP3_DMA_IF(_n) (0x0010 << _n) -+ -+#endif -diff --git a/drivers/media/pci/tbsecp3/tbsecp3.h b/drivers/media/pci/tbsecp3/tbsecp3.h -new file mode 100644 -index 0000000..fdfba5d ---- /dev/null -+++ b/drivers/media/pci/tbsecp3/tbsecp3.h -@@ -0,0 +1,210 @@ -+/* -+ TBS ECP3 FPGA based cards PCIe driver -+ -+ 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 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+*/ -+ -+#ifndef _TBSECP3_H_ -+#define _TBSECP3_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "demux.h" -+#include "dmxdev.h" -+#include "dvb_demux.h" -+#include "dvb_frontend.h" -+#include "dvb_net.h" -+#include "dvbdev.h" -+#include "tbsecp3-regs.h" -+#include "dvb_ca_en50221.h" -+ -+ -+#define TBSECP3_VID 0x544d -+#define TBSECP3_PID 0x6178 -+ -+#define TBSECP3_BOARD_TBS6205 0x6205 -+#define TBSECP3_BOARD_TBS6522 0x6522 -+#define TBSECP3_BOARD_TBS6902 0x6902 -+#define TBSECP3_BOARD_TBS6903 0x6903 -+#define TBSECP3_BOARD_TBS6904 0x6904 -+#define TBSECP3_BOARD_TBS6905 0x6905 -+#define TBSECP3_BOARD_TBS6908 0x6908 -+#define TBSECP3_BOARD_TBS6909 0x6909 -+#define TBSECP3_BOARD_TBS6910 0x6910 -+#define TBSECP3_BOARD_TBS6528 0x6528 -+#define TBSECP3_BOARD_TBS6590 0x6590 -+#define TBSECP3_BOARD_TBS6290SE 0x6290 -+#define TBSECP3_BOARD_TBS6281SE 0x6281 -+#define TBSECP3_BOARD_TBS6704 0x6704 -+#define TBSECP3_BOARD_TBS6209 0x6209 -+#define TBSECP3_BOARD_TBS6814 0x6814 -+ -+#define TBSECP3_MAX_ADAPTERS (8) -+#define TBSECP3_MAX_I2C_BUS (4) -+ -+#define TBSECP3_GPIODEF_NONE (0) -+#define TBSECP3_GPIODEF_HIGH (1) -+#define TBSECP3_GPIODEF_LOW (2) -+ -+#define TBSECP3_DMA_BUFFERS 8 -+ -+ -+struct tbsecp3_dev; -+ -+ -+struct tbsecp3_gpio_pin { -+ u8 lvl; -+ u8 nr; -+}; -+ -+struct tbsecp3_gpio_config { -+ struct tbsecp3_gpio_pin lnb_power; -+ struct tbsecp3_gpio_pin lnb_voltage; -+ struct tbsecp3_gpio_pin demod_reset; -+}; -+ -+struct tbsecp3_adap_config { -+ u32 ts_in; -+ u8 i2c_bus_nr; -+ struct tbsecp3_gpio_config gpio; -+}; -+ -+struct tbsecp3_board { -+ char *name; -+ int adapters; -+ u32 i2c_speed; -+ u8 eeprom_i2c; -+ u8 eeprom_addr; -+ struct tbsecp3_adap_config adap_config[8]; -+}; -+ -+struct tbsecp3_i2c { -+ struct tbsecp3_dev *dev; -+ u32 base; -+ -+ struct i2c_adapter i2c_adap; -+ struct i2c_client i2c_client; -+ -+ struct mutex lock; -+ wait_queue_head_t wq; -+ bool done; -+}; -+ -+struct tbsecp3_dma_channel { -+ u32 base; -+ dma_addr_t dma_addr; -+ u8 *buf[TBSECP3_DMA_BUFFERS + 1]; -+ u8 offset; -+ u8 cnt; -+}; -+ -+struct tbsecp3_ca { -+ int nr; -+ u32 base; -+ struct dvb_ca_en50221 ca; -+ -+ struct tbsecp3_adapter *adapter; -+ struct mutex lock; -+ int status; -+}; -+ -+struct tbsecp3_adapter { -+ int nr; -+ struct tbsecp3_adap_config *cfg; -+ -+ /* parent device */ -+ struct tbsecp3_dev *dev; -+ -+ /* i2c */ -+ struct tbsecp3_i2c *i2c; -+ struct i2c_client *i2c_client_demod; -+ struct i2c_client *i2c_client_tuner; -+ -+ /* dvb */ -+ struct dvb_adapter dvb_adapter; -+ struct dvb_frontend *fe; -+ struct dvb_frontend *fe2; -+ struct dvb_frontend _fe2; -+ struct dvb_demux demux; -+ struct dmxdev dmxdev; -+ struct dvb_net dvbnet; -+ struct dmx_frontend fe_hw; -+ struct dmx_frontend fe_mem; -+ int feeds; -+ -+ /* dma */ -+ spinlock_t adap_lock; -+ struct tasklet_struct tasklet; -+ struct tbsecp3_dma_channel dma; -+ -+ /* ca interface */ -+ struct tbsecp3_ca *tbsca; -+}; -+ -+struct tbsecp3_dev { -+ struct tbsecp3_board *info; -+ -+ /* pcie */ -+ struct pci_dev *pci_dev; -+ void __iomem *lmmio; -+ bool msi; -+ -+ /* dvb adapters */ -+ struct tbsecp3_adapter adapter[TBSECP3_MAX_ADAPTERS]; -+ -+ /* i2c */ -+ struct tbsecp3_i2c i2c_bus[TBSECP3_MAX_I2C_BUS]; -+}; -+ -+#define tbs_read(_b, _o) readl(dev->lmmio + (_b + _o)) -+#define tbs_write(_b, _o, _v) writel((_v), dev->lmmio + (_b + _o)) -+ -+ -+/* tbsecp3-core.c */ -+void tbsecp3_gpio_set_pin(struct tbsecp3_dev *dev, -+ struct tbsecp3_gpio_pin *pin, int state); -+ -+/* tbspcie-i2c.c */ -+extern int tbsecp3_i2c_init(struct tbsecp3_dev *dev); -+extern void tbsecp3_i2c_exit(struct tbsecp3_dev *dev); -+extern void tbsecp3_i2c_reg_init(struct tbsecp3_dev *dev); -+extern void tbsecp3_i2c_remove_clients(struct tbsecp3_adapter *adapter); -+ -+/* tbspcie-cards.c */ -+extern struct tbsecp3_board tbsecp3_boards[]; -+ -+/* tbspcie-dvb.c */ -+extern int tbsecp3_dvb_init(struct tbsecp3_adapter *adapter); -+extern void tbsecp3_dvb_exit(struct tbsecp3_adapter *adapter); -+ -+/* tbsecp3-dma.c */ -+extern int tbsecp3_dma_init(struct tbsecp3_dev *dev); -+extern void tbsecp3_dma_free(struct tbsecp3_dev *dev); -+extern void tbsecp3_dma_reg_init(struct tbsecp3_dev *dev); -+extern void tbsecp3_dma_enable(struct tbsecp3_adapter *adap); -+extern void tbsecp3_dma_disable(struct tbsecp3_adapter *adap); -+ -+/* tbsecp3-ca.c */ -+int tbsecp3_ca_init(struct tbsecp3_adapter *adap, int nr); -+void tbsecp3_ca_release(struct tbsecp3_adapter *adap); -+ -+#endif -diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c -index 9bf6917..998be9c 100644 ---- a/drivers/media/rc/mceusb.c -+++ b/drivers/media/rc/mceusb.c -@@ -192,6 +192,7 @@ enum mceusb_model_type { - TIVO_KIT, - MCE_GEN2_NO_TX, - HAUPPAUGE_CX_HYBRID_TV, -+ CX231XX_TBS5280, - }; - - struct mceusb_model { -@@ -251,6 +252,10 @@ static const struct mceusb_model mceusb_model[] = { - .mce_gen2 = 1, - .rc_map = RC_MAP_TIVO, - }, -+ [CX231XX_TBS5280] = { -+ .rc_map = RC_MAP_RC6_MCE, -+ .name = "TurboSight TBS 5280 (cx231xx) MCE IR", -+ }, - }; - - static struct usb_device_id mceusb_dev_table[] = { -diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig -index 05998f0..8e40db5 100644 ---- a/drivers/media/tuners/Kconfig -+++ b/drivers/media/tuners/Kconfig -@@ -49,6 +49,13 @@ config MEDIA_TUNER_TDA18271 - help - A silicon tuner module. Say Y when you want to support this tuner. - -+config MEDIA_TUNER_TDA18273 -+ tristate "NXP TDA18273 silicon tuner" -+ depends on MEDIA_SUPPORT && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ help -+ A silicon tuner module. Say Y when you want to support this tuner. -+ - config MEDIA_TUNER_TDA9887 - tristate "TDA 9885/6/7 analog IF demodulator" - depends on MEDIA_SUPPORT && I2C -@@ -277,4 +284,35 @@ config MEDIA_TUNER_QM1D1C0042 - default m if !MEDIA_SUBDRV_AUTOSELECT - help - Sharp QM1D1C0042 trellis coded 8PSK tuner driver. -+ -+config MEDIA_TUNER_AV201X -+ tristate "Airoha Technology AV201x silicon tuner" -+ depends on MEDIA_SUPPORT && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ help -+ Airoha Technology AV201x silicon tuner driver. -+ -+config MEDIA_TUNER_STV6120 -+ tristate "STV6120 silicon tuner" -+ depends on MEDIA_SUPPORT && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ help -+ STV6120 silicon tuner driver. -+ -+config MEDIA_TUNER_R848 -+ tristate "Rafael Micro R848 silicon tuner" -+ depends on MEDIA_SUPPORT && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ select BITREVERSE -+ help -+ Rafael Micro R848 silicon tuner driver. -+ -+config MEDIA_TUNER_MXL603 -+ tristate "MaxLinear mxl603 silicon tuner" -+ depends on MEDIA_SUPPORT && I2C -+ default m if !MEDIA_SUBDRV_AUTOSELECT -+ select BITREVERSE -+ help -+ A driver for the silicon tuner MXL603 from MaxLinear. -+ - endmenu -diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile -index 06a9ab6..56e7d0e 100644 ---- a/drivers/media/tuners/Makefile -+++ b/drivers/media/tuners/Makefile -@@ -15,6 +15,7 @@ obj-$(CONFIG_MEDIA_TUNER_TEA5761) += tea5761.o - obj-$(CONFIG_MEDIA_TUNER_TDA9887) += tda9887.o - obj-$(CONFIG_MEDIA_TUNER_TDA827X) += tda827x.o - obj-$(CONFIG_MEDIA_TUNER_TDA18271) += tda18271.o -+obj-$(CONFIG_MEDIA_TUNER_TDA18273) += tda18273.o - obj-$(CONFIG_MEDIA_TUNER_XC5000) += xc5000.o - obj-$(CONFIG_MEDIA_TUNER_XC4000) += xc4000.o - obj-$(CONFIG_MEDIA_TUNER_MSI001) += msi001.o -@@ -41,6 +42,10 @@ obj-$(CONFIG_MEDIA_TUNER_R820T) += r820t.o - obj-$(CONFIG_MEDIA_TUNER_MXL301RF) += mxl301rf.o - obj-$(CONFIG_MEDIA_TUNER_QM1D1C0042) += qm1d1c0042.o - obj-$(CONFIG_MEDIA_TUNER_M88RS6000T) += m88rs6000t.o -+obj-$(CONFIG_MEDIA_TUNER_AV201X) += av201x.o -+obj-$(CONFIG_MEDIA_TUNER_STV6120) += stv6120.o -+obj-$(CONFIG_MEDIA_TUNER_R848) += r848.o -+obj-$(CONFIG_MEDIA_TUNER_MXL603) += mxl603.o - - ccflags-y += -I$(srctree)/drivers/media/dvb-core - ccflags-y += -I$(srctree)/drivers/media/dvb-frontends -diff --git a/drivers/media/tuners/av201x.c b/drivers/media/tuners/av201x.c -new file mode 100644 -index 0000000..0b40cea ---- /dev/null -+++ b/drivers/media/tuners/av201x.c -@@ -0,0 +1,305 @@ -+/* -+ * AV201x Airoha Technology silicon tuner driver -+ * -+ * Copyright (C) 2014 Luis Alves -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#include "av201x.h" -+#include "av201x_priv.h" -+ -+/* write multiple (continuous) registers */ -+static int av201x_wrm(struct av201x_priv *priv, u8 *buf, int len) -+{ -+ int ret; -+ struct i2c_msg msg = { -+ .addr = priv->cfg->i2c_address, -+ .flags = 0, .buf = buf, .len = len }; -+ -+ dev_dbg(&priv->i2c->dev, "%s() i2c wrm @0x%02x (len=%d) ", -+ __func__, buf[0], len); -+ -+ ret = i2c_transfer(priv->i2c, &msg, 1); -+ if (ret < 0) { -+ dev_warn(&priv->i2c->dev, -+ "%s: i2c wrm err(%i) @0x%02x (len=%d)\n", -+ KBUILD_MODNAME, ret, buf[0], len); -+ return ret; -+ } -+ return 0; -+} -+ -+/* write one register */ -+static int av201x_wr(struct av201x_priv *priv, u8 addr, u8 data) -+{ -+ u8 buf[] = { addr, data }; -+ return av201x_wrm(priv, buf, 2); -+} -+ -+/* read multiple (continuous) registers starting at addr */ -+static int av201x_rdm(struct av201x_priv *priv, u8 addr, u8 *buf, int len) -+{ -+ int ret; -+ struct i2c_msg msg[] = { -+ { .addr = priv->cfg->i2c_address, .flags = 0, -+ .buf = &addr, .len = 1 }, -+ { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, -+ .buf = buf, .len = len } -+ }; -+ -+ dev_dbg(&priv->i2c->dev, "%s() i2c rdm @0x%02x (len=%d)\n", -+ __func__, addr, len); -+ -+ ret = i2c_transfer(priv->i2c, msg, 2); -+ if (ret < 0) { -+ dev_warn(&priv->i2c->dev, -+ "%s: i2c rdm err(%i) @0x%02x (len=%d)\n", -+ KBUILD_MODNAME, ret, addr, len); -+ return ret; -+ } -+ return 0; -+} -+ -+/* read one register */ -+static int av201x_rd(struct av201x_priv *priv, u8 addr, u8 *data) -+{ -+ return av201x_rdm(priv, addr, data, 1); -+} -+ -+/* read register, apply masks, write back */ -+static int av201x_regmask(struct av201x_priv *priv, -+ u8 reg, u8 setmask, u8 clrmask) -+{ -+ int ret; -+ u8 b = 0; -+ if (clrmask != 0xff) { -+ ret = av201x_rd(priv, reg, &b); -+ if (ret) -+ return ret; -+ b &= ~clrmask; -+ } -+ return av201x_wr(priv, reg, b | setmask); -+} -+ -+static int av201x_wrtable(struct av201x_priv *priv, -+ struct av201x_regtable *regtable, int len) -+{ -+ int ret, i; -+ -+ for (i = 0; i < len; i++) { -+ ret = av201x_regmask(priv, regtable[i].addr, -+ regtable[i].setmask, regtable[i].clrmask); -+ if (ret) -+ return ret; -+ if (regtable[i].sleep) -+ msleep(regtable[i].sleep); -+ } -+ return 0; -+} -+ -+static int av201x_release(struct dvb_frontend *fe) -+{ -+ struct av201x_priv *priv = fe->tuner_priv; -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ -+ kfree(fe->tuner_priv); -+ fe->tuner_priv = NULL; -+ return 0; -+} -+ -+static int av201x_init(struct dvb_frontend *fe) -+{ -+ struct av201x_priv *priv = fe->tuner_priv; -+ int ret; -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ -+ ret = av201x_wrtable(priv, av201x_inittuner0, -+ ARRAY_SIZE(av201x_inittuner0)); -+ -+ switch (priv->cfg->id) { -+ case ID_AV2011: -+ ret |= av201x_wrtable(priv, av201x_inittuner1a, -+ ARRAY_SIZE(av201x_inittuner1a)); -+ break; -+ case ID_AV2012: -+ default: -+ ret |= av201x_wrtable(priv, av201x_inittuner1b, -+ ARRAY_SIZE(av201x_inittuner1b)); -+ break; -+ } -+ -+ ret |= av201x_wrtable(priv, av201x_inittuner2, -+ ARRAY_SIZE(av201x_inittuner2)); -+ -+ ret |= av201x_wr(priv, REG_TUNER_CTRL, 0x96); -+ -+ msleep(120); -+ -+ if (ret) -+ dev_dbg(&priv->i2c->dev, "%s() failed\n", __func__); -+ return ret; -+} -+ -+static int av201x_sleep(struct dvb_frontend *fe) -+{ -+ struct av201x_priv *priv = fe->tuner_priv; -+ int ret; -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ -+ ret = av201x_regmask(priv, REG_TUNER_CTRL, AV201X_SLEEP, 0); -+ if (ret) -+ dev_dbg(&priv->i2c->dev, "%s() failed\n", __func__); -+ return ret; -+} -+ -+static int av201x_set_params(struct dvb_frontend *fe) -+{ -+ struct av201x_priv *priv = fe->tuner_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ u32 n, bw, bf; -+ u8 buf[5]; -+ int ret; -+ -+ dev_dbg(&priv->i2c->dev, "%s() delivery_system=%d frequency=%d " \ -+ "symbol_rate=%d\n", __func__, -+ c->delivery_system, c->frequency, c->symbol_rate); -+ -+ /* -+ ** PLL setup ** -+ RF = (pll_N * ref_freq) / pll_M -+ pll_M = fixed 0x10000 -+ PLL output is divided by 2 -+ REG_FN = pll_M<24:0> -+ */ -+ buf[0] = REG_FN; -+ n = DIV_ROUND_CLOSEST(c->frequency, priv->cfg->xtal_freq); -+ buf[1] = (n > 0xff) ? 0xff : (u8) n; -+ n = DIV_ROUND_CLOSEST((c->frequency / 1000) << 17, priv->cfg->xtal_freq / 1000); -+ buf[2] = (u8) (n >> 9); -+ buf[3] = (u8) (n >> 1); -+ buf[4] = (u8) (((n << 7) & 0x80) | 0x50); -+ ret = av201x_wrm(priv, buf, 5); -+ if (ret) -+ goto exit; -+ -+ msleep(20); -+ -+ /* set bandwidth */ -+ bw = (c->symbol_rate / 1000) * 135/200; -+ if (c->symbol_rate < 6500000) -+ bw += 6000; -+ bw += 2000; -+ bw *= 108/100; -+ -+ /* check limits (4MHz < bw < 40MHz) */ -+ if (bw > 40000) -+ bw = 40000; -+ else if (bw < 4000) -+ bw = 4000; -+ -+ /* bandwidth step = 211kHz */ -+ bf = DIV_ROUND_CLOSEST(bw * 127, 21100); -+ ret = av201x_wr(priv, REG_BWFILTER, (u8) bf); -+ -+ /* enable fine tune agc */ -+ ret |= av201x_wr(priv, REG_FT_CTRL, AV201X_FT_EN | AV201X_FT_BLK); -+ -+ ret |= av201x_wr(priv, REG_TUNER_CTRL, 0x96); -+ msleep(20); -+exit: -+ if (ret) -+ dev_dbg(&priv->i2c->dev, "%s() failed\n", __func__); -+ return ret; -+} -+ -+static int AV201x_agc [] = { 0, 82, 100, 116, 140, 162, 173, 187, 210, 223, 254, 255}; -+static int AV201x_level_dBm_10[] = { 90, -50, -263, -361, -463, -563, -661, -761, -861, -891, -904, -910}; -+ -+static int av201x_get_rf_strength(struct dvb_frontend *fe, u16 *st) -+{ -+ struct av201x_priv *priv = fe->tuner_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int if_agc, index, table_length, slope, *x, *y; -+ -+ if_agc = *st; -+ x = AV201x_agc; -+ y = AV201x_level_dBm_10; -+ table_length = sizeof(AV201x_agc)/sizeof(int); -+ -+ -+ /* Finding in which segment the if_agc value is */ -+ for (index = 0; index < table_length; index ++) -+ if (x[index] > if_agc ) break; -+ -+ /* Computing segment slope */ -+ slope = ((y[index]-y[index-1])*1000)/(x[index]-x[index-1]); -+ /* Linear approximation of rssi value in segment (rssi values will be in 0.1dBm unit: '-523' means -52.3 dBm) */ -+ *st = 1000 + ((y[index-1] + ((if_agc - x[index-1])*slope + 500)/1000))/10; -+ -+ c->strength.len = 1; -+ c->strength.stat[0].scale = FE_SCALE_DECIBEL; -+ c->strength.stat[0].svalue = ((y[index-1] + ((if_agc - x[index-1])*slope + 500)/1000)) * 100; -+ -+ return 0; -+} -+ -+ -+static const struct dvb_tuner_ops av201x_tuner_ops = { -+ .info = { -+ .name = "Airoha Technology AV201x", -+ -+ .frequency_min = 850000, -+ .frequency_max = 2300000, -+ .frequency_step = 206, -+ }, -+ -+ .release = av201x_release, -+ -+ .init = av201x_init, -+ .sleep = av201x_sleep, -+ .set_params = av201x_set_params, -+ .get_rf_strength = av201x_get_rf_strength, -+}; -+ -+struct dvb_frontend *av201x_attach(struct dvb_frontend *fe, -+ struct av201x_config *cfg, struct i2c_adapter *i2c) -+{ -+ struct av201x_priv *priv = NULL; -+ -+ priv = kzalloc(sizeof(struct av201x_priv), GFP_KERNEL); -+ if (priv == NULL) { -+ dev_dbg(&i2c->dev, "%s() attach failed\n", __func__); -+ return NULL; -+ } -+ -+ priv->cfg = cfg; -+ priv->i2c = i2c; -+ -+ dev_info(&priv->i2c->dev, -+ "%s: Airoha Technology AV201x successfully attached\n", -+ KBUILD_MODNAME); -+ -+ memcpy(&fe->ops.tuner_ops, &av201x_tuner_ops, -+ sizeof(struct dvb_tuner_ops)); -+ -+ fe->tuner_priv = priv; -+ return fe; -+} -+EXPORT_SYMBOL(av201x_attach); -+ -+MODULE_DESCRIPTION("Airoha Technology AV201x silicon tuner driver"); -+MODULE_AUTHOR("Luis Alves "); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/tuners/av201x.h b/drivers/media/tuners/av201x.h -new file mode 100644 -index 0000000..1a7b2fa ---- /dev/null -+++ b/drivers/media/tuners/av201x.h -@@ -0,0 +1,55 @@ -+/* -+ * AV201x Airoha Technology silicon tuner driver -+ * -+ * Copyright (C) 2014 Luis Alves -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#ifndef AV201X_H -+#define AV201X_H -+ -+#include -+#include "dvb_frontend.h" -+ -+typedef enum av201x_id { -+ ID_AV2011, -+ ID_AV2012, -+ ID_AV2018, -+} av201x_id_t; -+ -+struct av201x_config { -+ /* tuner i2c address */ -+ u8 i2c_address; -+ /* tuner type */ -+ av201x_id_t id; -+ -+ /* crystal freq in kHz */ -+ u32 xtal_freq; -+}; -+ -+#if IS_ENABLED(CONFIG_MEDIA_TUNER_AV201X) -+extern struct dvb_frontend *av201x_attach(struct dvb_frontend *fe, -+ struct av201x_config *cfg, struct i2c_adapter *i2c); -+#else -+static inline struct dvb_frontend *av201x_attach(struct dvb_frontend *fe, -+ struct av201x_config *cfg, struct i2c_adapter *i2c) -+{ -+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -+ return NULL; -+} -+#endif -+ -+#endif /* AV201X_H */ -diff --git a/drivers/media/tuners/av201x_priv.h b/drivers/media/tuners/av201x_priv.h -new file mode 100644 -index 0000000..c56ba20 ---- /dev/null -+++ b/drivers/media/tuners/av201x_priv.h -@@ -0,0 +1,110 @@ -+/* -+ * AV201x Airoha Technology silicon tuner driver -+ * -+ * Copyright (C) 2014 Luis Alves -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#ifndef AV201X_PRIV_H -+#define AV201X_PRIV_H -+ -+struct av201x_priv { -+ struct av201x_config *cfg; -+ struct i2c_adapter *i2c; -+}; -+ -+enum av201x_regs_addr { -+ REG_FN = 0x00, -+ REG_BWFILTER = 0x05, -+ REG_TUNER_STAT = 0x0b, -+ REG_TUNER_CTRL = 0x0c, -+ REG_FT_CTRL = 0x25, -+}; -+ -+/* REG_TUNER_STAT */ -+#define AV201X_PLLLOCK (1<<0) -+ -+/* REG_TUNER_CTRL */ -+#define AV201X_SLEEP (1<<5) -+#define AV201X_RFLP (1<<6) -+ -+/* REG_FT_CTRL */ -+#define AV201X_FT_EN (1<<1) -+#define AV201X_FT_BLK (1<<2) -+ -+struct av201x_regtable { -+ u8 addr; -+ u8 setmask; -+ u8 clrmask; -+ int sleep; -+}; -+ -+static struct av201x_regtable av201x_inittuner0[] = { -+ {0x00, 0x38, 0xff, 0}, -+ {0x01, 0x00, 0xff, 0}, -+ {0x02, 0x00, 0xff, 0}, -+ {0x03, 0x50, 0xff, 0}, -+ {0x04, 0x1f, 0xff, 0}, -+ {0x05, 0xa3, 0xff, 0}, -+ {0x06, 0xfd, 0xff, 0}, -+ {0x07, 0x58, 0xff, 0}, -+ {0x08, 0x36, 0xff, 0}, -+ {0x09, 0xc2, 0xff, 0}, -+ {0x0a, 0x88, 0xff, 0}, -+ {0x0b, 0xb4, 0xff, 20}, -+ {0x0d, 0x40, 0xff, 0}, -+}; -+ -+static struct av201x_regtable av201x_inittuner1a[] = { -+ {0x0e, 0x94, 0xff, 0}, -+ {0x0f, 0x9a, 0xff, 0}, -+}; -+ -+static struct av201x_regtable av201x_inittuner1b[] = { -+ {0x0e, 0x5b, 0xff, 0}, -+ {0x0f, 0x6a, 0xff, 0}, -+}; -+ -+static struct av201x_regtable av201x_inittuner2[] = { -+ {0x10, 0x66, 0xff, 0}, -+ {0x11, 0x40, 0xff, 0}, -+ {0x12, 0x80, 0xff, 0}, -+ {0x13, 0x2b, 0xff, 0}, -+ {0x14, 0x6a, 0xff, 0}, -+ {0x15, 0x50, 0xff, 0}, -+ {0x16, 0x91, 0xff, 0}, -+ {0x17, 0x27, 0xff, 0}, -+ {0x18, 0x8f, 0xff, 0}, -+ {0x19, 0xcc, 0xff, 0}, -+ {0x1a, 0x21, 0xff, 0}, -+ {0x1b, 0x10, 0xff, 0}, -+ {0x1c, 0x80, 0xff, 0}, -+ {0x1d, 0x02, 0xff, 0}, -+ {0x1e, 0xf5, 0xff, 0}, -+ {0x1f, 0x7f, 0xff, 0}, -+ {0x20, 0x4a, 0xff, 0}, -+ {0x21, 0x9b, 0xff, 0}, -+ {0x22, 0xe0, 0xff, 0}, -+ {0x23, 0xe0, 0xff, 0}, -+ {0x24, 0x36, 0xff, 0}, -+ {0x25, 0x00, 0xff, 0}, -+ {0x26, 0xab, 0xff, 0}, -+ {0x27, 0x97, 0xff, 0}, -+ {0x28, 0xc5, 0xff, 0}, -+ {0x29, 0xa8, 0xff, 20}, -+}; -+ -+#endif /* AV201X_PRIV_H */ -diff --git a/drivers/media/tuners/mxl603.c b/drivers/media/tuners/mxl603.c -new file mode 100644 -index 0000000..424658e ---- /dev/null -+++ b/drivers/media/tuners/mxl603.c -@@ -0,0 +1,586 @@ -+ -+ -+#include "mxl603_priv.h" -+ -+static const struct dvb_tuner_ops si2168_ops; -+ -+static int reg_read(struct i2c_client *client,u8 reg_addr,u8 *val) -+{ -+ int ret; -+ u8 reg_buf[2] = {0xFB,reg_addr}; -+ -+ struct i2c_msg msg[] = { -+ {.addr = client->addr,.flags = 0 , .buf = reg_buf, .len = 2}, -+ {.addr = client->addr, .flags = I2C_M_RD, .buf = val, .len = 1}, -+ -+ }; -+ -+ ret = i2c_transfer(client->adapter,msg,2); -+ -+ if(ret!=2) -+ { -+ pr_warn("i2c read reg error !!"); -+ if (ret < 0) -+ return ret; -+ else -+ return -EREMOTEIO; -+ } -+ return 0 ; -+ -+} -+static int reg_write(struct i2c_client *client,u8 reg_addr,u8 val) -+{ -+ int ret; -+ u8 buf[2]={reg_addr,val}; -+ struct i2c_msg msg ={.addr = client->addr, .flags = 0, .buf = buf, .len = 2}; -+ -+ if((ret = i2c_transfer (client->adapter,&msg,1))!=1){ -+ pr_warn("%s: i2c write error (addr 0x%02x, ret == %i)\n", -+ __func__, reg_addr, ret); -+ return -EREMOTEIO; -+ } -+ return 0; -+} -+static int mxl603_ctrl_programRegisters(struct i2c_client *client, PMXL603_REG_CTRL_INFO_T ctrlRegInfoPtr) -+{ -+ struct mxl603_dev* dev = i2c_get_clientdata(client); -+ int ret = 0; -+ u8 tmp =0 ; -+ u16 i = 0; -+ -+ while (!ret) -+ { -+ if ((ctrlRegInfoPtr[i].regAddr == 0) && (ctrlRegInfoPtr[i].mask == 0) && (ctrlRegInfoPtr[i].data == 0)) break; -+ -+ // Check if partial bits of register were updated -+ if (ctrlRegInfoPtr[i].mask != 0xFF) -+ { -+ ret = reg_read(dev->client,ctrlRegInfoPtr[i].regAddr, (int)&tmp); -+ if (ret) break;; -+ } -+ -+ tmp &= (u8) ~ctrlRegInfoPtr[i].mask; -+ tmp |= (u8) ctrlRegInfoPtr[i].data; -+ -+ ret = reg_write(dev->client,ctrlRegInfoPtr[i].regAddr, tmp); -+ if (ret) break; -+ -+ i++; -+ } -+ -+ -+ return ret; -+ -+} -+static int mxl603_init(struct dvb_frontend *fe) -+{ -+ struct i2c_client*client = fe->tuner_priv; -+ struct mxl603_dev*dev = i2c_get_clientdata(client); -+ -+ int ret; -+ u8 readData; -+ u8 dfeRegData; -+ u8 control = 0; -+ u16 ifFcw; -+ MXL603_REG_CTRL_INFO_T MxL603_OverwriteDefaults[] = -+ { -+ {0x14, 0xFF, 0x13}, -+ {0x6D, 0xFF, 0x8A}, -+ {0x6D, 0xFF, 0x0A}, -+ {0xDF, 0xFF, 0x19}, -+ {0x45, 0xFF, 0x1B}, -+ {0xA9, 0xFF, 0x59}, -+ {0xAA, 0xFF, 0x6A}, -+ {0xBE, 0xFF, 0x4C}, -+ {0xCF, 0xFF, 0x25}, -+ {0xD0, 0xFF, 0x34}, -+ {0x77, 0xFF, 0xE7}, -+ {0x78, 0xFF, 0xE3}, -+ {0x6F, 0xFF, 0x51}, -+ {0x7B, 0xFF, 0x84}, -+ {0x7C, 0xFF, 0x9F}, -+ {0x56, 0xFF, 0x41}, -+ {0xCD, 0xFF, 0x64}, -+ {0xC3, 0xFF, 0x2C}, -+ {0x9D, 0xFF, 0x61}, -+ {0xF7, 0xFF, 0x52}, -+ {0x58, 0xFF, 0x81}, -+ {0x00, 0xFF, 0x01}, -+ {0x62, 0xFF, 0x02}, -+ {0x00, 0xFF, 0x00}, -+ {0, 0, 0} -+ }; -+ -+ -+ /*reset the chip*/ -+ ret = reg_write(dev->client,AIC_RESET_REG, 0x00); -+ -+ ret = mxl603_ctrl_programRegisters(client,MxL603_OverwriteDefaults); -+ ret |= reg_write(dev->client,0x00,0x01); -+ ret |= reg_read(dev->client,0x31,&readData); -+ if(ret) -+ goto err; -+ -+ readData &= 0x2F; -+ readData |= 0xD0; -+ -+ ret = reg_write(dev->client,0x31,readData); -+ ret |= reg_write(dev->client,0x0,0x0); -+ -+ /*If Single supply 3.3v is used */ -+ ret |= reg_write(dev->client,MAIN_REG_AMP,0x04); -+ -+ /**setup xtal**/ -+ -+ control = ((dev->xtalFreqSel << 5) | (dev->xtalCap & 0x1F)); -+ control |= (1 << 7); -+ ret = reg_write(dev->client, XTAL_CAP_CTRL_REG, control); -+ -+ // program Clock out div & Xtal sharing -+ ret |= reg_write(dev->client, XTAL_ENABLE_DIV_REG, 0x40); -+ -+ // Main regulator re-program -+ ret |= reg_write(client, MAIN_REG_AMP, 0x14); -+ if(ret) -+ goto err; -+ -+ /*setup IF out*/ -+ ret = reg_read(client,IF_FREQ_SEL_REG, &readData); -+ if(dev->manualIFFreqSet) -+ { -+ // IF out manual setting : bit<5> -+ readData |= 0x20; -+ ret = reg_write(client, IF_FREQ_SEL_REG, readData); -+ -+ // Manual IF freq set -+ ifFcw = (u16)(dev->manualIFOutFreqInKHz * 8192 / 216000); -+ control = (ifFcw & 0xFF); // Get low 8 bit -+ ret |= reg_write(client, IF_FCW_LOW_REG, control); -+ -+ control = ((ifFcw >> 8) & 0x0F); // Get high 4 bit -+ ret |= reg_write(client, IF_FCW_HIGH_REG, control); -+ } -+ else -+ { -+ readData &= 0xC0; -+ // IF Freq <4:0> -+ readData |= dev->ifOutFreq; -+ ret |= reg_write(client, IF_FREQ_SEL_REG, readData); -+ } -+ -+ // Set spectrum invert, gain level and IF path -+ // Spectrum invert indication is bit<7:6> -+ -+ // Gain level is bit<3:0> -+ control = (dev->gainLevel & 0x0F); -+ control |= 0x20; // Enable IF out -+ ret |= reg_write(client, IF_PATH_GAIN_REG, control); -+ -+ if(ret) -+ goto err; -+ -+ /*5.setup AGC agctye :0 self ;1:externel */ -+ // AGC selecton <3:2> and mode setting <0> -+ ret = reg_read(dev->client, AGC_CONFIG_REG, &readData); -+ readData &= 0xF2; // Clear bits <3:2> & <0> -+ readData = (u8) (readData | (dev->agcType << 2) | 0x01); -+ ret |= reg_write(dev->client, AGC_CONFIG_REG, readData); -+ -+ // AGC set point <6:0> -+ ret |= reg_read(dev->client, AGC_SET_POINT_REG, &readData); -+ readData &= 0x80; // Clear bit <6:0> -+ readData |= dev->setagcPoint; -+ ret |= reg_write(dev->client, AGC_SET_POINT_REG, readData); -+ -+ // AGC Polarity <4> -+ ret |= reg_read(dev->client, AGC_FLIP_REG, &readData); -+ readData &= 0xEF; // Clear bit <4> -+ readData |= (0 << 4); -+ ret |= reg_write(dev->client, AGC_FLIP_REG, readData); -+ -+ if(ret) -+ goto err; -+ -+ -+ dev->active = true; -+ return ret; -+err: -+ pr_err("%s_failed = %d",__FUNCTION__,ret); -+ return ret; -+} -+static int mxl603_set_params(struct dvb_frontend *fe) -+{ -+ struct i2c_client *client =fe->tuner_priv; -+ struct mxl603_dev *dev = i2c_get_clientdata(client); -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ -+ int ret; -+ u8 signalMode,regData,agcData,dfeTuneData,dfeCdcData; -+ u32 freq = 0; -+ u8 tmp; -+ -+ pr_info("delivery_system=%d frequency=%d\n", -+ c->delivery_system, c->frequency); -+ if (!dev->active) { -+ ret = -EAGAIN; -+ goto err; -+ } -+ MXL603_REG_CTRL_INFO_T MxL603_DigitalDvbc[] = -+ { -+ {0x0C, 0xFF, 0x00}, -+ {0x13, 0xFF, 0x04}, -+ {0x53, 0xFF, 0x7E}, -+ {0x57, 0xFF, 0x91}, -+ {0x5C, 0xFF, 0xB1}, -+ {0x62, 0xFF, 0xF2}, -+ {0x6E, 0xFF, 0x03}, -+ {0x6F, 0xFF, 0xD1}, -+ {0x87, 0xFF, 0x77}, -+ {0x88, 0xFF, 0x55}, -+ {0x93, 0xFF, 0x33}, -+ {0x97, 0xFF, 0x03}, -+ {0xBA, 0xFF, 0x40}, -+ {0x98, 0xFF, 0xAF}, -+ {0x9B, 0xFF, 0x20}, -+ {0x9C, 0xFF, 0x1E}, -+ {0xA0, 0xFF, 0x18}, -+ {0xA5, 0xFF, 0x09}, -+ {0xC2, 0xFF, 0xA9}, -+ {0xC5, 0xFF, 0x7C}, -+ {0xCD, 0xFF, 0x64}, -+ {0xCE, 0xFF, 0x7C}, -+ {0xD5, 0xFF, 0x05}, -+ {0xD9, 0xFF, 0x00}, -+ {0xEA, 0xFF, 0x00}, -+ {0xDC, 0xFF, 0x1C}, -+ {0, 0, 0} -+ }; -+ -+ MXL603_REG_CTRL_INFO_T MxL603_DigitalIsdbtAtsc[] = -+ { -+ {0x0C, 0xFF, 0x00}, -+ {0x13, 0xFF, 0x04}, -+ {0x53, 0xFF, 0xFE}, -+ {0x57, 0xFF, 0x91}, -+ {0x62, 0xFF, 0xC2}, -+ {0x6E, 0xFF, 0x01}, -+ {0x6F, 0xFF, 0x51}, -+ {0x87, 0xFF, 0x77}, -+ {0x88, 0xFF, 0x55}, -+ {0x93, 0xFF, 0x22}, -+ {0x97, 0xFF, 0x02}, -+ {0xBA, 0xFF, 0x30}, -+ {0x98, 0xFF, 0xAF}, -+ {0x9B, 0xFF, 0x20}, -+ {0x9C, 0xFF, 0x1E}, -+ {0xA0, 0xFF, 0x18}, -+ {0xA5, 0xFF, 0x09}, -+ {0xC2, 0xFF, 0xA9}, -+ {0xC5, 0xFF, 0x7C}, -+ {0xCD, 0xFF, 0xEB}, -+ {0xCE, 0xFF, 0x7F}, -+ {0xD5, 0xFF, 0x03}, -+ {0xD9, 0xFF, 0x04}, -+ {0, 0, 0} -+ }; -+ -+ switch (c->delivery_system) { -+ case SYS_ATSC: -+ signalMode = 1; -+ ret = mxl603_ctrl_programRegisters(client, MxL603_DigitalIsdbtAtsc); -+ -+ if (dev->ifOutFreqinKHz < HIGH_IF_35250_KHZ) -+ { -+ // Low power -+ ret |= reg_write(dev->client, DIG_ANA_IF_CFG_0, 0xF9); -+ ret |= reg_write(dev->client, DIG_ANA_IF_CFG_1, 0x18); -+ ret |= reg_write(dev->client, DIG_ANA_IF_PWR, 0xF1); -+ } -+ else -+ { -+ // High power -+ ret |= reg_write(dev->client, DIG_ANA_IF_CFG_0, 0xD9); -+ ret |= reg_write(dev->client, DIG_ANA_IF_CFG_1, 0x16); -+ ret |= reg_write(dev->client, DIG_ANA_IF_PWR, 0xB1); -+ } -+ -+ if (MXL603_XTAL_16MHz == dev->xtalFreqSel) tmp = 0x0D; -+ if (MXL603_XTAL_24MHz == dev->xtalFreqSel) tmp = 0x0E; -+ -+ -+ ret |= reg_write(dev->client, DFE_CSF_SS_SEL, tmp); -+ -+ tmp = 0; -+ switch(dev->gainLevel) -+ { -+ case 0x09: tmp = 0x44; break; -+ case 0x08: tmp = 0x43; break; -+ case 0x07: tmp = 0x42; break; -+ case 0x06: tmp = 0x41; break; -+ case 0x05: tmp = 0x40; break; -+ default: break; -+ } -+ ret |= reg_write(dev->client, DFE_DACIF_GAIN, tmp); -+ -+ break; -+ case SYS_DVBC_ANNEX_B: -+ case SYS_DVBC_ANNEX_A: -+ case SYS_DVBC_ANNEX_C: -+ if(c->delivery_system == SYS_DVBC_ANNEX_B)signalMode = 3; -+ else -+ signalMode = 0; -+ ret = mxl603_ctrl_programRegisters(dev->client, MxL603_DigitalDvbc); -+ -+ if (dev->ifOutFreqinKHz < HIGH_IF_35250_KHZ) -+ { -+ // Low power -+ ret |= reg_write(dev->client, DIG_ANA_IF_CFG_0, 0xFE); -+ ret |= reg_write(dev->client, DIG_ANA_IF_CFG_1, 0x10); -+ } -+ else -+ { -+ // High power -+ ret |= reg_write(dev->client, DIG_ANA_IF_CFG_0, 0xD9); -+ ret |= reg_write(dev->client, DIG_ANA_IF_CFG_1, 0x16); -+ } -+ -+ if (dev->xtalFreqSel == MXL603_XTAL_16MHz) tmp = 0x0D; -+ if (dev->xtalFreqSel == MXL603_XTAL_24MHz) tmp = 0x0E; -+ -+ -+ ret |= reg_write(dev->client, DFE_CSF_SS_SEL, tmp); -+ break; -+ default: -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ // XTAL calibration -+ ret |= reg_write(dev->client, XTAL_CALI_SET_REG, 0x00); -+ ret |= reg_write(dev->client, XTAL_CALI_SET_REG, 0x01); -+ -+ msleep(50); -+ -+ ret = reg_write(dev->client, START_TUNE_REG, 0x00); -+ -+ // RF Frequency VCO Band Settings -+ if (c->frequency < 700000000) -+ { -+ ret |= reg_write(dev->client, 0x7C, 0x1F); -+ if ((signalMode == MXL603_DIG_DVB_C) || (signalMode == MXL603_DIG_J83B)) -+ regData = 0xC1; -+ else -+ regData = 0x81; -+ -+ } -+ else -+ { -+ ret |= reg_write(dev->client, 0x7C, 0x9F); -+ if ((signalMode == MXL603_DIG_DVB_C) || (signalMode == MXL603_DIG_J83B)) -+ regData = 0xD1; -+ else -+ regData = 0x91; -+ -+ } -+ -+ ret |= reg_write(dev->client, 0x00, 0x01); -+ ret |= reg_write(dev->client, 0x31, regData); -+ ret |= reg_write(dev->client, 0x00, 0x00); -+ -+ // Bandwidth <7:0> -+ -+ ret |= reg_write(dev->client, CHAN_TUNE_BW_REG, 0x20); -+ -+ /* Calculate RF Channel = DIV(64*RF(Hz), 1E6) */ -+ freq = (u32)((c->frequency/1000000)*64); -+ // Set RF -+ ret |= reg_write(dev->client, CHAN_TUNE_LOW_REG, (u8)(freq & 0xFF)); -+ ret |= reg_write(dev->client, CHAN_TUNE_HI_REG, (u8)((freq >> 8 ) & 0xFF)); -+ -+ -+ // Power up tuner module -+ ret |= reg_write(dev->client, TUNER_ENABLE_REG, 0x01); -+ -+ // Start Sequencer settings -+ ret |= reg_write(dev->client, PAGE_CHANGE_REG, 0x01); -+ ret |= reg_read(dev->client, DIG_ANA_GINJO_LT_REG, ®Data); -+ ret |= reg_write(dev->client, PAGE_CHANGE_REG, 0x00); -+ -+ ret |= reg_read(dev->client, 0xB6, &agcData); -+ ret |= reg_write(dev->client, PAGE_CHANGE_REG, 0x01); -+ ret |= reg_read(dev->client, 0x60, &dfeTuneData); -+ ret |= reg_read(dev->client, 0x5F, &dfeCdcData); -+ -+ // Check if LT is enabled -+ if ((regData & 0x10) == 0x10) -+ { -+ // dfe_agc_auto = 0 & dfe_agc_rf_bo_w = 14 -+ agcData &= 0xBF; -+ agcData |= 0x0E; -+ -+ // dfe_seq_tune_rf1_bo = 14 -+ dfeTuneData &= 0xC0; -+ dfeTuneData |= 0x0E; -+ -+ // dfe_seq_cdc_rf1_bo = 14 -+ dfeCdcData &= 0xC0; -+ dfeCdcData |= 0x0E; -+ } -+ else -+ { -+ // dfe_agc_auto = 1 & dfe_agc_rf_bo_w = 0 -+ agcData |= 0x40; -+ agcData &= 0xC0; -+ -+ // dfe_seq_tune_rf1_bo = 55 -+ dfeTuneData &= 0xC0; -+ dfeTuneData |= 0x37; -+ -+ // dfe_seq_cdc_rf1_bo = 55 -+ dfeCdcData &= 0xC0; -+ dfeCdcData |= 0x37; -+ } -+ -+ ret |= reg_write(dev->client, 0x60, dfeTuneData); -+ ret |= reg_write(dev->client, 0x5F, dfeCdcData); -+ ret |= reg_write(dev->client, PAGE_CHANGE_REG, 0x00); -+ ret |= reg_write(dev->client, 0xB6, agcData); -+ -+ // Bit <0> 1 : start , 0 : abort calibrations -+ ret |= reg_write(dev->client, START_TUNE_REG, 0x01); -+ -+ // Sleep 15 ms -+ msleep(15); -+ -+ // dfe_agc_auto = 1 -+ agcData = (agcData | 0x40); -+ ret |= reg_write(dev->client, 0xB6, agcData); -+ if(ret) -+ goto err; -+ -+ return ret; -+ -+err: -+ pr_err("failed = %d ",ret); -+ return ret; -+} -+ -+static int mxl603_get_status(struct dvb_frontend *fe,u32*status) -+{ -+ struct i2c_client *client =fe->tuner_priv; -+ struct mxl603_dev *dev = i2c_get_clientdata(client); -+ int ret; -+ u8 regData; -+ -+ ret = reg_read(dev->client, RF_REF_STATUS_REG, ®Data); -+ -+ if((regData & 0x03) == 0x03) -+ *status = 1; -+ else -+ *status = 0; -+ -+ return ret; -+ -+} -+ -+ -+static const struct dvb_tuner_ops mxl603_ops ={ -+ .info = { -+ .name = "MaxLinear tuner MXL603", -+ .frequency_min = 44000000, -+ .frequency_max = 1002000000, -+ }, -+ .init = mxl603_init, -+ .set_params = mxl603_set_params, -+ .get_status = mxl603_get_status, -+ -+}; -+static int mxl603_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct mxl603_config *cfg = client->dev.platform_data; -+ struct dvb_frontend *fe = cfg->fe; -+ struct mxl603_dev *dev; -+ -+ int ret; -+ u8 utemp; -+ -+ dev = kzalloc(sizeof(*dev),GFP_KERNEL); -+ if(!dev){ -+ ret = -ENOMEM; -+ dev_err(&client->dev,"kzalloc failed\n"); -+ goto err; -+ } -+ -+ dev->fe = cfg->fe; -+ dev->xtalFreqSel = cfg->xtalFreqSel; -+ dev->agcType = cfg->agcType; -+ dev->ifOutFreq = cfg->ifOutFreq; -+ dev->manualIFFreqSet = cfg->manualIFFreqSet; -+ dev->manualIFOutFreqInKHz = cfg->manualIFOutFreqInKHz; -+ dev->ifOutFreqinKHz = 5000; -+ dev->xtalCap = 31; -+ dev->gainLevel = 11; -+ dev->setagcPoint =66; -+ dev->client = client; -+ dev->active= false; -+ -+ /*check chip answers with correct chip iD*/ -+ ret = reg_read(dev->client,CHIP_ID_REQ_REG,&utemp); -+ if (ret) -+ goto err_kfree; -+ -+ pr_info("chip id = 0x%x \n",utemp); -+ -+ if(utemp!=0x1){ -+ ret = -ENODEV; -+ goto err_kfree; -+ } -+ ret = reg_write(dev->client,0x10,0x99); -+ -+ ret = reg_read(dev->client,0x10,&utemp) ; -+ -+ /**/ -+ memcpy(&fe->ops.tuner_ops,&mxl603_ops,sizeof(struct dvb_tuner_ops)); -+ fe->tuner_priv = client; -+ i2c_set_clientdata(client, dev); -+ -+ return 0; -+ -+ -+err_kfree: -+ kfree(dev); -+err: -+ pr_err("%s___failed=%d\n",__FUNCTION__, ret); -+ return ret; -+} -+static int mxl603_remove(struct i2c_client *client) -+{ -+ struct mxl603_dev *dev = i2c_get_clientdata(client); -+ -+ kfree(dev); -+ -+ return 0; -+} -+ -+ static const struct i2c_device_id mxl603_id_table[] = { -+ {"mxl603", 0}, -+ {} -+}; -+MODULE_DEVICE_TABLE(i2c, mxl603_id_table); -+ -+static struct i2c_driver mxl603_driver = { -+ .driver = { -+ .name = "mxl603", -+ }, -+ .probe = mxl603_probe, -+ .remove = mxl603_remove, -+ .id_table = mxl603_id_table, -+}; -+ -+module_i2c_driver(mxl603_driver); -+ -+MODULE_AUTHOR("Davin "); -+MODULE_DESCRIPTION("Panasonic MN88436 ATSC/QAMB demodulator driver"); -+MODULE_LICENSE("GPL"); -+ -diff --git a/drivers/media/tuners/mxl603.h b/drivers/media/tuners/mxl603.h -new file mode 100644 -index 0000000..752c2ca ---- /dev/null -+++ b/drivers/media/tuners/mxl603.h -@@ -0,0 +1,49 @@ -+#ifndef MXL603_H -+#define MXL603_H -+ -+#include -+ -+typedef enum -+{ -+ MXL603_IF_3_65MHz = 0, -+ MXL603_IF_4MHz = 1, -+ MXL603_IF_4_1MHz = 2, -+ MXL603_IF_4_15MHz = 3, -+ MXL603_IF_4_5MHz = 4, -+ MXL603_IF_4_57MHz = 5, -+ MXL603_IF_5MHz = 6, -+ MXL603_IF_5_38MHz = 7, -+ MXL603_IF_6MHz = 8, -+ MXL603_IF_6_28MHz = 9, -+ MXL603_IF_7_2MHz = 10, -+ MXL603_IF_8_25MHz = 11, -+ MXL603_IF_35_25MHz = 12, -+ MXL603_IF_36MHz = 13, -+ MXL603_IF_36_15MHz = 14, -+ MXL603_IF_36_65MHz = 15, -+ MXL603_IF_44MHz = 16 -+} MXL603_IF_FREQ_E; -+ -+#define MXL603_XTAL_16MHz 0 -+#define MXL603_XTAL_24MHz 1 -+ -+struct mxl603_config{ -+ -+ u8 xtalFreqSel; -+ -+ u8 ifOutFreq; -+ -+#define MXL603_AGC_SELF 0 -+#define MXL603_AGC_EXTERNAL 1 -+ u8 agcType; -+ -+ bool manualIFFreqSet; /*enable and disable*/ -+ u32 manualIFOutFreqInKHz; -+ -+ struct dvb_frontend *fe; -+ -+}; -+ -+ -+ -+#endif -\ No newline at end of file -diff --git a/drivers/media/tuners/mxl603_priv.h b/drivers/media/tuners/mxl603_priv.h -new file mode 100644 -index 0000000..36f85bd ---- /dev/null -+++ b/drivers/media/tuners/mxl603_priv.h -@@ -0,0 +1,133 @@ -+#ifndef MXL603_PRIV_H -+#define MXL603_PRIV_H -+ -+#include "mxl603.h" -+#include "dvb_frontend.h" -+ -+ -+struct mxl603_dev{ -+ struct i2c_client *client; -+ -+ u8 xtalFreqSel; -+ u8 xtalCap; -+ u8 ifOutFreq; -+ u8 gainLevel; -+ u8 agcType; -+ u8 setagcPoint; -+ u32 ifOutFreqinKHz; -+ -+ bool manualIFFreqSet; /*enable and disable*/ -+ u32 manualIFOutFreqInKHz; -+ -+ struct dvb_frontend *fe; -+ bool active ; -+}; -+ -+typedef struct -+{ -+ u8 regAddr; -+ u8 mask; -+ u8 data; -+} MXL603_REG_CTRL_INFO_T, *PMXL603_REG_CTRL_INFO_T; -+ -+typedef enum -+{ -+ MXL603_DIG_DVB_C = 0, /* DVB-C mode */ -+ MXL603_DIG_ISDBT_ATSC, /* ATSC/ISDB-T mode */ -+ MXL603_DIG_DVB_T_DTMB, /* DVB-T/DVB-T2 and DTMB mode */ -+ MXL603_DIG_J83B /* J.83B mode */ -+} MXL603_SIGNAL_MODE_E; /* MxL603 Application mode */ -+ -+ -+#define AIC_RESET_REG 0xFF // For MxL603 Tuner -+ -+#define PAGE_CHANGE_REG 0x00 // Page change, can configured as page 0 or page 1 -+#define XTAL_CAP_CTRL_REG 0x01 // Xtal frequency and CAP register -+#define XTAL_ENABLE_DIV_REG 0x02 // Xtal enable and frequency div 4 register -+#define XTAL_CALI_SET_REG 0x03 // Xtal calibration enable register enable register -+#define IF_FREQ_SEL_REG 0x04 // IF frequency selection and manual set bypass register -+#define IF_PATH_GAIN_REG 0x05 // IF gain level and path selection register -+#define IF_FCW_LOW_REG 0x06 // Low register of IF FCW set when manual program IF frequency -+#define IF_FCW_HIGH_REG 0x07 // High register of IF FCW set when manual program IF frequency -+#define AGC_CONFIG_REG 0x08 // AGC configuration, include AGC select and AGC type -+#define AGC_SET_POINT_REG 0x09 -+#define AGC_FLIP_REG 0x5E -+#define AGC_SLOPE_REG 0xB5 -+#define AGC_OFFSET_REG 0xB4 -+#define GPO_SETTING_REG 0x0A // GPO set and inquiring register -+#define TUNER_ENABLE_REG 0x0B // Power up register, bit<0> -+#define TUNE_MODE_REG 0x0D -+#define MAIN_REG_AMP 0x0E -+#define CHAN_TUNE_BW_REG 0x0F // Band width register -+#define CHAN_TUNE_LOW_REG 0x10 // Tune frequency set low byte -+#define CHAN_TUNE_HI_REG 0x11 // Tune frequency set high byte -+#define START_TUNE_REG 0x12 // sequencer setting register -+#define FINE_TUNE_SET_REG 0x13 // Fine tune operation register -+#define FINE_TUNE_CTRL_REG_0 0x13 // Fine tune operation register -+#define FINE_TUNE_CTRL_REG_1 0x14 // Fine tune operation register -+ -+#define FINE_TUNE_OFFSET_LOW_REG 0x14 // Fine tune frequency offset low byte -+#define FINE_TUNE_OFFSET_HIGH_REG 0x15 // Fine tune frequency offset high byte -+#define CHIP_ID_REQ_REG 0x18 // Tuner Chip ID register -+#define CHIP_VERSION_REQ_REG 0x1A // Tuner Chip Revision register -+ -+#define RFPIN_RB_LOW_REG 0x1D // RF power low 8 bit register -+#define RFPIN_RB_HIGH_REG 0x1E // RF power high 8 bit register -+#define SIGNAL_TYPE_REG 0x1E // Signal type -+ -+#define DFE_CTRL_ACCUM_LOW_REG 0x24 // Bit<7:0> -+#define DFE_CTRL_ACCUM_MID_REG 0x25 // Bit<7:0> -+#define DFE_CTRL_ACCUM_HI_REG 0x26 // Bit<1:0> -+ -+#define DFE_CTRL_TRIG_REG 0xA0 // Bit<3> -+#define DFE_CTRL_RB_HI_REG 0x7B // Bit<7:0> -+#define DFE_CTRL_RB_LOW_REG 0x7A // Bit<1:0> -+ -+#define RF_REF_STATUS_REG 0x2B // RF/REF lock status register -+ -+#define AGC_SAGCLOCK_STATUS_REG 0x2C -+ -+#define DFE_DACIF_BYP_GAIN_REG 0x43 -+#define DIG_ANA_RFRSSI_REG 0x57 -+ -+#define RSSI_RESET_REG 0x78 -+#define DIG_ANA_GINJO_LT_REG 0x96 -+#define FINE_TUNE_INIT1_REG 0xA9 -+#define FINE_TUNE_INIT2_REG 0xAA -+ -+#define DFE_AGC_CEIL1_REG 0xB0 -+ -+#define DFE_RFLUT_BYP_REG 0xDB // Dec: 220, bit<7> -+#define DFE_RFLUT_DIV_MOD_REG 0xDB // Dec: 221 -+ -+#define DFE_RFLUT_SWP1_REG 0x49 -+ -+#define DFE_RFSX_FRAC_MOD1_REG 0xDF -+#define DFE_RFSX_FRAC_MOD2_REG 0xE0 -+#define DFE_RFSX_FRAC_MOD3_REG 0xE1 -+#define DFE_RFSX_FRAC_MOD4_REG 0xE2 -+ -+#define DFE_REFLUT_BYP_REG 0xEA // Dec: 240, bit<6> -+#define DFE_REFSX_INT_MOD_REG 0xEB // Dec: 241 -+ -+#define APP_MODE_FREQ_HZ_THRESHOLD_1 358000000 -+#define APP_MODE_FREQ_HZ_THRESHOLD_2 625000000 -+ -+#define IF_GAIN_SET_POINT1 10 -+#define IF_GAIN_SET_POINT2 11 -+#define IF_GAIN_SET_POINT3 12 -+ -+#define DIG_ANA_IF_CFG_0 0x5A -+#define DIG_ANA_IF_CFG_1 0x5B -+#define DIG_ANA_IF_PWR 0x5C -+ -+#define DFE_CSF_SS_SEL 0xEA -+#define DFE_DACIF_GAIN 0xDC -+ -+#define FINE_TUNE_FREQ_INCREASE 0x01 -+#define FINE_TUNE_FREQ_DECREASE 0x02 -+ -+#define RF_SX_FRAC_N_RANGE 0xDD -+ -+#define HIGH_IF_35250_KHZ 35250 -+#endif -diff --git a/drivers/media/tuners/r848.c b/drivers/media/tuners/r848.c -new file mode 100644 -index 0000000..4d09ffa ---- /dev/null -+++ b/drivers/media/tuners/r848.c -@@ -0,0 +1,3545 @@ -+/* -+ * Rafael Micro R848 silicon tuner driver -+ * -+ * Copyright (C) 2015 Luis Alves -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#include -+#include "r848.h" -+#include "r848_priv.h" -+ -+/* read tuner registers (always starts at addr 0) */ -+static int r848_rd(struct r848_priv *priv, u8 *buf, int len) -+{ -+ int ret, i; -+ struct i2c_msg msg = { -+ .addr = priv->cfg->i2c_address, -+ .flags = I2C_M_RD, .buf = buf, .len = len }; -+ -+ ret = i2c_transfer(priv->i2c, &msg, 1); -+ if (ret == 1) { -+ for (i = 0; i < len; i++) -+ buf[i] = bitrev8(buf[i]); -+ ret = 0; -+ } else { -+ dev_warn(&priv->i2c->dev, "%s: i2c tuner rd failed=%d " \ -+ "len=%d\n", KBUILD_MODNAME, ret, len); -+ ret = -EREMOTEIO; -+ } -+ return ret; -+} -+ -+/* write registers starting at specified addr */ -+static int r848_wrm(struct r848_priv *priv, u8 addr, u8 *val, int len) -+{ -+ int ret; -+ u8 buf[len + 1]; -+ struct i2c_msg msg = { -+ .addr = priv->cfg->i2c_address, -+ .flags = 0, .buf = buf, .len = len + 1 }; -+ -+ memcpy(&buf[1], val, len); -+ buf[0] = addr; -+ ret = i2c_transfer(priv->i2c, &msg, 1); -+ if (ret == 1) { -+ ret = 0; -+ } else { -+ dev_warn(&priv->i2c->dev, "%s: i2c tuner wr failed=%d " \ -+ "len=%d\n", KBUILD_MODNAME, ret, len); -+ ret = -EREMOTEIO; -+ } -+ return ret; -+} -+ -+/* write one register */ -+static int r848_wr(struct r848_priv *priv, u8 addr, u8 data) -+{ -+ return r848_wrm(priv, addr, &data, 1); -+} -+ -+ -+static int r848_get_lock_status(struct r848_priv *priv, u8 *lock) -+{ -+ int ret; -+ u8 buf[3]; -+ -+ ret = r848_rd(priv, buf, 3); -+ if (ret) -+ return ret; -+ -+ if ((buf[2] & 0x40) == 0x00) -+ *lock = 0; -+ else -+ *lock = 1; -+ -+ return ret; -+} -+ -+ -+static int r848_init_regs(struct r848_priv *priv, u8 standard) -+{ -+ u8 *ptr; -+ -+ if (standard != R848_DVB_S) -+ ptr = R848_iniArray_hybrid; -+ else -+ ptr = R848_iniArray_dvbs; -+ -+ memcpy(priv->regs, ptr, R848_REG_NUM); -+ -+ return r848_wrm(priv, 0x08, ptr, R848_REG_NUM); -+} -+ -+static int r848_get_imr(struct r848_priv *priv, u8 *imr) -+{ -+ u8 buf[2]; -+ int i, ret = 0; -+ u16 total = 0; -+ -+ for (i = 0; i < 4; i++) { -+ ret |= r848_rd(priv, buf, 2); -+ total += (buf[1] & 0x3f); -+ } -+ *imr = (u8) (total >> 2); -+ return ret; -+} -+ -+ -+ -+ -+ -+R848_Freq_Info_Type R848_Freq_Sel(u32 LO_freq, u32 RF_freq,R848_Standard_Type R848_Standard) -+{ -+ R848_Freq_Info_Type R848_Freq_Info; -+ -+ // LNA band R13[6:5] -+ if (RF_freq < R848_LNA_LOW_LOWEST[R848_TF_BEAD]) //<164 -+ R848_Freq_Info.LNA_BAND = 0x60; // ultra low -+ else if (RF_freq < R848_LNA_MID_LOW[R848_TF_BEAD]) //164~388 -+ R848_Freq_Info.LNA_BAND = 0x40; // low -+ else if (RF_freq < R848_LNA_HIGH_MID[R848_TF_BEAD]) //388~612 -+ R848_Freq_Info.LNA_BAND = 0x20; // mid -+ else // >612 -+ R848_Freq_Info.LNA_BAND = 0x00; // high -+ -+ // IMR point -+ if (LO_freq < 133000) -+ R848_Freq_Info.IMR_MEM = 0; -+ else if (LO_freq<221000) -+ R848_Freq_Info.IMR_MEM = 1; -+ else if (LO_freq<450000) -+ R848_Freq_Info.IMR_MEM = 2; -+ else if (LO_freq<775000) -+ R848_Freq_Info.IMR_MEM = 3; -+ else -+ R848_Freq_Info.IMR_MEM = 4; -+ -+ //RF polyfilter band R33[7:6] -+ if(LO_freq < 133000) -+ R848_Freq_Info.RF_POLY = 0x80; //low -+ else if (LO_freq < 221000) -+ R848_Freq_Info.RF_POLY = 0x40; // mid -+ else if (LO_freq < 775000) -+ R848_Freq_Info.RF_POLY = 0x00; // highest -+ else -+ R848_Freq_Info.RF_POLY = 0xC0; // ultra high -+ -+ // LPF Cap, Notch -+ switch(R848_Standard) { -+ case R848_DVB_C_8M: -+ case R848_DVB_C_6M: -+ case R848_J83B: -+ case R848_DVB_C_8M_IF_5M: -+ case R848_DVB_C_6M_IF_5M: -+ case R848_J83B_IF_5M: -+ if (LO_freq<77000) { -+ R848_Freq_Info.LPF_CAP = 16; -+ R848_Freq_Info.LPF_NOTCH = 10; -+ } else if (LO_freq<85000) { -+ R848_Freq_Info.LPF_CAP = 16; -+ R848_Freq_Info.LPF_NOTCH = 4; -+ } else if (LO_freq<115000) { -+ R848_Freq_Info.LPF_CAP = 13; -+ R848_Freq_Info.LPF_NOTCH = 3; -+ } else if (LO_freq<125000) { -+ R848_Freq_Info.LPF_CAP = 11; -+ R848_Freq_Info.LPF_NOTCH = 1; -+ } else if (LO_freq<141000) { -+ R848_Freq_Info.LPF_CAP = 9; -+ R848_Freq_Info.LPF_NOTCH = 0; -+ } else if (LO_freq<157000) { -+ R848_Freq_Info.LPF_CAP = 8; -+ R848_Freq_Info.LPF_NOTCH = 0; -+ } else if (LO_freq<181000) { -+ R848_Freq_Info.LPF_CAP = 6; -+ R848_Freq_Info.LPF_NOTCH = 0; -+ } else if (LO_freq<205000) { -+ R848_Freq_Info.LPF_CAP = 3; -+ R848_Freq_Info.LPF_NOTCH = 0; -+ } else { //LO>=201M -+ R848_Freq_Info.LPF_CAP = 0; -+ R848_Freq_Info.LPF_NOTCH = 0; -+ } -+ break; -+ default: -+ if(LO_freq<73000) { -+ R848_Freq_Info.LPF_CAP = 8; -+ R848_Freq_Info.LPF_NOTCH = 10; -+ } else if (LO_freq<81000) { -+ R848_Freq_Info.LPF_CAP = 8; -+ R848_Freq_Info.LPF_NOTCH = 4; -+ } else if (LO_freq<89000) { -+ R848_Freq_Info.LPF_CAP = 8; -+ R848_Freq_Info.LPF_NOTCH = 3; -+ } else if (LO_freq<121000) { -+ R848_Freq_Info.LPF_CAP = 6; -+ R848_Freq_Info.LPF_NOTCH = 1; -+ } else if (LO_freq<145000) { -+ R848_Freq_Info.LPF_CAP = 4; -+ R848_Freq_Info.LPF_NOTCH = 0; -+ } else if (LO_freq<153000) { -+ R848_Freq_Info.LPF_CAP = 3; -+ R848_Freq_Info.LPF_NOTCH = 0; -+ } else if (LO_freq<177000) { -+ R848_Freq_Info.LPF_CAP = 2; -+ R848_Freq_Info.LPF_NOTCH = 0; -+ } else if (LO_freq<201000) { -+ R848_Freq_Info.LPF_CAP = 1; -+ R848_Freq_Info.LPF_NOTCH = 0; -+ } else { //LO>=201M -+ R848_Freq_Info.LPF_CAP = 0; -+ R848_Freq_Info.LPF_NOTCH = 0; -+ } -+ break; -+ } -+ return R848_Freq_Info; -+} -+ -+ -+ -+ -+ -+ -+R848_ErrCode R848_Cal_Prepare(struct r848_priv *priv, u8 u1CalFlag) -+{ -+ R848_Cal_Info_Type Cal_Info; -+ int ret; -+ -+ -+ // R848:R38[3] +6dB -+ Cal_Info.FILTER_6DB = 0x08; -+ // R848:R8[7] LNA power -+ Cal_Info.LNA_POWER = 0x80; -+ // R848:R12[6:5] (bit5 = RF_Buf ON(?), bit6=RF_Buf pwr) -+ Cal_Info.RFBUF_OUT = 0x20; -+ // R848:R9[2] RF_BUF_pwr -+ Cal_Info.RFBUF_POWER = 0x04; -+ // R848:R14[6:5] (bit5=TF cal ON/OFF, bit6=TF_-6dB ON/OFF) -+ Cal_Info.TF_CAL = 0x00; -+ // R848:R13[7:0] (manual: 0x9f (-97?) max, 0x80 (-128?) min) -+ Cal_Info.LNA_GAIN = 0x9F; -+ // R848:R15[4:0] (manual +8) (min(0)) -+ Cal_Info.MIXER_AMP_GAIN = 0x08; -+ // R848:R34[4:0] (manual min(0)) -+ Cal_Info.MIXER_BUFFER_GAIN = 0x10; -+ -+ switch(u1CalFlag) { -+ case R848_IMR_LNA_CAL: -+ Cal_Info.RFBUF_OUT = 0x00; -+ Cal_Info.RFBUF_POWER = 0x00; -+ Cal_Info.TF_CAL = 0x60; -+ Cal_Info.MIXER_AMP_GAIN = 0x00; -+ break; -+ case R848_TF_LNA_CAL: -+ Cal_Info.RFBUF_OUT = 0x00; -+ Cal_Info.RFBUF_POWER = 0x00; -+ Cal_Info.TF_CAL = 0x60; -+ Cal_Info.LNA_GAIN = 0x80; -+ Cal_Info.MIXER_AMP_GAIN = 0x00; -+ break; -+ case R848_LPF_LNA_CAL: -+ Cal_Info.RFBUF_OUT = 0x00; -+ Cal_Info.RFBUF_POWER = 0x00; -+ Cal_Info.TF_CAL = 0x20; -+ Cal_Info.LNA_GAIN = 0x80; -+ Cal_Info.MIXER_AMP_GAIN = 0x00; -+ break; -+ case R848_TF_CAL: -+ Cal_Info.MIXER_AMP_GAIN = 0x00; -+ break; -+ case R848_LPF_CAL: -+ case R848_IMR_CAL: -+ default: -+ break; -+ } -+ -+ // Ring From RF_Buf Output & RF_Buf Power -+ // R848:R12[5] -+ priv->regs[4] = (priv->regs[4] & 0xDF) | Cal_Info.RFBUF_OUT; -+ ret = r848_wr(priv, 0x0c, priv->regs[4]); -+ -+ // RF_Buf Power -+ priv->regs[1] = (priv->regs[1] & 0xFB) | Cal_Info.RFBUF_POWER; -+ ret |= r848_wr(priv, 0x09, priv->regs[1]); -+ -+ // (LNA power ON/OFF ) -+ // R848:R8[7] -+ priv->regs[0] = (priv->regs[0] & 0x7F) | Cal_Info.LNA_POWER; -+ ret |= r848_wr(priv, 0x08, priv->regs[0]); -+ -+ // TF cal (TF cal ON/OFF, TF_-6dB ON/OFF) -+ // R848:R14[6:5] -+ priv->regs[6] = (priv->regs[6] & 0x9F) | Cal_Info.TF_CAL; -+ ret |= r848_wr(priv, 0x0e, priv->regs[6]); -+ -+ // LNA gain -+ // R848:R13[7:0] -+ priv->regs[5] = (priv->regs[5] & 0x60) | Cal_Info.LNA_GAIN; -+ ret |= r848_wr(priv, 0x0d, priv->regs[5]); -+ -+ // Mixer Amp Gain -+ // R848:R15[4:0] 15-8=7 15(0x0F) is addr ; [7] is data -+ priv->regs[7] = (priv->regs[7] & 0xE0) | Cal_Info.MIXER_AMP_GAIN; -+ ret |= r848_wr(priv, 0x0f, priv->regs[7]); -+ -+ // Mixer Buffer Gain -+ // R848:R34[4:0] 34-8=26 34(0x22) is addr ; [26] is data -+ priv->regs[26] = (priv->regs[26] & 0xE0) | Cal_Info.MIXER_BUFFER_GAIN; -+ ret |= r848_wr(priv, 0x22, priv->regs[26]); -+ -+ // Set filter +0/6dB; NA det=OFF -+ // R848:R38[3] 38-8=30 38(0x26) is addr ; [30] is data -+ priv->regs[30] = (priv->regs[30] & 0xF7) | Cal_Info.FILTER_6DB | 0x80; -+ ret |= r848_wr(priv, 0x26, priv->regs[30]); -+ -+ // Set NA det 710 = OFF -+ // R848:R40[3] 40-8=32 40(0x28) is addr ; [32] is data -+ priv->regs[32] = (priv->regs[32] | 0x08); -+ ret |= r848_wr(priv, 0x28, priv->regs[32]); -+ -+ //---- General calibration setting ----// -+ // IMR IQ cap=0 -+ // R848:R11[1:0] 11-8=3 11(0x0B) is addr ; [3] is data -+ priv->regs[3] = (priv->regs[3] & 0xFC); -+ ret |= r848_wr(priv, 0x0b, priv->regs[3]); -+ -+ // Set RF_Flag ON(%) -+ // R848:R22[0] 22-8=14 22(0x16) is addr ; [14] is data -+ priv->regs[14] = priv->regs[14] | 0x01; //force far-end mode -+ ret |= r848_wr(priv, 0x16, priv->regs[14]); -+ -+ // RingPLL power ON -+ // R848:R18[4] 18-8=10 18(0x12) is addr ; [10] is data -+ priv->regs[10] = (priv->regs[10] & 0xEF); -+ ret |= r848_wr(priv, 0x12, priv->regs[10]); -+ -+ // LPF filter code = 15 -+ // R848:R18[3:0] 18-8=10 18(0x12) is addr ; [10] is data -+ priv->regs[10] = (priv->regs[10] & 0xF0) | 0x0F; -+ ret |= r848_wr(priv, 0x12, priv->regs[10]); -+ -+ // HPF corner=narrowest; LPF coarse=6M; 1.7M disable -+ // R848:R19[7:0] 19-8=11 19(0x13) is addr ; [11] is data -+ priv->regs[11] = (priv->regs[11] & 0x00) | 0x60; -+ ret |= r848_wr(priv, 0x13, priv->regs[11]); -+ -+ // ADC/VGA PWR on; Vga code mode(b4=1), Gain = 26.5dB; Large Code mode Gain(b5=1) -+ // ADC PWR on (b7=0) R848:R15[7] 15-8=7 15(0x0F) is addr ; [7] is data -+ priv->regs[7] = (priv->regs[7] & 0x7F); -+ ret |= r848_wr(priv, 0x0f, priv->regs[7]); -+ -+/* // VGA PWR on (b0=0) -+ // R848:R9[0] 9-8=1 9(0x09) is addr ; [1] is data -+ priv->regs[1] = (priv->regs[1] & 0xFE); -+ ret |= r848_wr(priv, 0x09, priv->regs[1]);*/ -+ -+ // VGA PWR on (b0=0) MT2 -+ // R848:R18[7] -+ priv->regs[10] = (priv->regs[10] & 0x7F); -+ ret |= r848_wr(priv, 0x12, priv->regs[10]); -+ -+ // Large Code mode Gain(b5=1) -+ // R848:R11[3] 11-8=3 11(0x0B) is addr ; [3] is data -+ priv->regs[3] = (priv->regs[3] & 0xF7) | 0x08; -+ ret |= r848_wr(priv, 0x0b, priv->regs[3]); -+ -+ // Vga code mode(b4=1) -+ // R848:R9[1] 9-8=1 9(0x09) is addr ; [1] is data -+ priv->regs[1] = (priv->regs[1] & 0xFD) | 0x02; -+ ret |= r848_wr(priv, 0x09, priv->regs[1]); -+ -+ // Gain = 26.5dB -+ // R848:R20[3:0] 20-8=12 20(0x14) is addr ; [12] is data -+ priv->regs[12] = (priv->regs[12] & 0xF0) | 0x0B; -+ ret |= r848_wr(priv, 0x14, priv->regs[12]); -+ -+ // LNA, RF, Nrb dector pw on; det2 cap=IF_det -+ // R848:R37[3:0] 37-8=29 37(0x25) is addr ; [29] is data -+ priv->regs[29] = (priv->regs[29] & 0xF0) | 0x02; -+ ret |= r848_wr(priv, 0x25, priv->regs[29]); -+ -+ return ret; -+} -+ -+R848_ErrCode R848_Xtal_Check( struct r848_priv *priv) -+{ -+ u8 i = 0; -+ u8 buf[3]; -+ int ret; -+ -+ // TF force sharp mode (for stable read) -+ priv->regs[14] = priv->regs[14] | 0x01; -+ ret = r848_wr(priv, 0x16, priv->regs[14]); -+ -+ // NA det off (for stable read) -+ priv->regs[30] = priv->regs[30] | 0x80; -+ ret |= r848_wr(priv, 0x26, priv->regs[30]); -+ -+ // Set NA det 710 = OFF -+ priv->regs[32] = (priv->regs[32] | 0x08); -+ ret |= r848_wr(priv, 0x28, priv->regs[32]); -+ -+ // Xtal_pow=lowest(11) R848:R23[6:5] -+ priv->regs[15] = (priv->regs[15] & 0x9F) | 0x60; -+ ret |= r848_wr(priv, 0x17, priv->regs[15]); -+ -+ // Xtal_Gm=SMALL(0) R848:R27[0] -+ priv->regs[19] = (priv->regs[19] & 0xFE) | 0x00; -+ ret |= r848_wr(priv, 0x1b, priv->regs[19]); -+ -+ // set pll autotune = 128kHz R848:R23[4:3] -+ priv->regs[15] = priv->regs[15] & 0xE7; -+ ret |= r848_wr(priv, 0x17, priv->regs[15]); -+ -+ // set manual initial reg = 1 000000; b5=0 => cap 30p; R848:R27[7:0] -+ priv->regs[19] = (priv->regs[19] & 0x80) | 0x40; -+ ret |= r848_wr(priv, 0x1b, priv->regs[19]); -+ -+ // set auto -+ priv->regs[19] = (priv->regs[19] & 0xBF); -+ ret |= r848_wr(priv, 0x1b, priv->regs[19]); -+ if (ret) -+ return ret; -+ -+ msleep(10); -+ -+ // Xtal_pow=lowest(11) R848:R23[6:5] -+ priv->regs[15] = (priv->regs[15] & 0x9F) | 0x60; -+ ret = r848_wr(priv, 0x17, priv->regs[15]); -+ -+ // Xtal_Gm=SMALL(0) R848:R27[0] -+ priv->regs[19] = (priv->regs[19] & 0xFE) | 0x00; -+ ret |= r848_wr(priv, 0x1b, priv->regs[19]); -+ if (ret) -+ return ret; -+ -+ -+ for (i = 0; i < XTAL_CHECK_SIZE; i++) { -+ //set power -+ if (i <= XTAL_SMALL_HIGHEST) { -+ priv->regs[15] = (priv->regs[15] & 0x9F) | ((u8)(XTAL_SMALL_HIGHEST-i)<<5); -+ priv->regs[19] = (priv->regs[19] & 0xFE) | 0x00 ; //| 0x00; //SMALL Gm(0) -+ } else if (i == XTAL_LARGE_HIGHEST) { -+ //priv->regs[15] = (priv->regs[15] & 0x87) | 0x00 | 0x18; //3v Gm, highest -+ priv->regs[15] = (priv->regs[15] & 0x9F) | 0X00 ; -+ priv->regs[19] = (priv->regs[19] & 0xFE) | 0x01 ; //| 0x00; //LARGE Gm(1) -+ } else { -+ //priv->regs[15] = (priv->regs[15] & 0x87) | 0x00 | 0x18; //3v Gm, highest -+ priv->regs[15] = (priv->regs[15] & 0x9F) | 0X00 ; -+ priv->regs[19] = (priv->regs[19] & 0xFE) | 0x01 ; //| 0x00; //LARGE Gm(1) -+ } -+ -+ ret = r848_wr(priv, 0x17, priv->regs[15]); -+ ret |= r848_wr(priv, 0x1b, priv->regs[19]); -+ if (ret) -+ return ret; -+ -+ msleep(50); -+ -+ ret = r848_rd(priv, buf, 3); -+ if (ret) -+ return ret; -+ -+ // depend on init Nint & Div value (N=59.6667, Div=16) -+ // lock to VCO band 8 if VCO=2768M for 16M Xtal -+ // lock to VCO band 46 if VCO=2768M for 24M Xtal -+ if ((buf[2] & 0x40) == 0x40) { -+ u8 v = buf[2] & 0x3F; -+ u8 ll, hl; -+ if (priv->cfg->xtal == 16000000) { -+ ll = 5; -+ hl = 11; -+ } else { -+ ll = 42; -+ hl = 48; -+ } -+ if ((v >= ll) && (v <= hl)) { -+ priv->cfg->R848_Xtal_Pwr_tmp = i; -+ break; -+ } -+ } -+ if (i == (XTAL_CHECK_SIZE-1)) { -+ priv->cfg->R848_Xtal_Pwr_tmp = i; -+ } -+ } -+ -+ return 0; -+} -+ -+ -+static int r848_set_pll(struct r848_priv *priv, u32 LO_Freq, R848_Standard_Type R848_Standard) -+{ -+ int ret; -+ u8 buf[3]; -+ -+ u8 MixDiv = 2; -+ u8 DivBuf = 0; -+ u8 Ni = 0; -+ u8 Si = 0; -+ u8 DivNum = 0; -+ u16 Nint = 0; -+ u32 VCO_Min = 2410000; -+ u32 VCO_Max = VCO_Min*2; -+ u32 VCO_Freq = 0; -+ u32 PLL_Ref = R848_Xtal; -+ u32 VCO_Fra = 0; -+ u16 Nsdm = 2; -+ u16 SDM = 0; -+ u16 SDM16to9 = 0; -+ u16 SDM8to1 = 0; -+ u8 CP_CUR = 0x00; -+ u8 CP_OFFSET = 0x00; -+ u8 SDM_RES = 0x00; -+ u8 XTAL_POW1 = 0x00; -+ u8 XTAL_POW0 = 0x00; -+ u8 XTAL_GM = 0x00; -+ u16 u2XalDivJudge; -+ u8 u1XtalDivRemain; -+ u8 VCO_current_trial = 0; -+ -+ u8 u1RfFlag = 0; -+ u8 u1PulseFlag = 0; -+ u8 u1SPulseFlag=0; -+ -+ u8 R848_XtalDiv = XTAL_DIV2; -+ -+ -+ //TF, NA fix -+ u1RfFlag = (priv->regs[14] & 0x01); //R22[0] -+ u1PulseFlag = (priv->regs[30] & 0x80); //R38[7] -+ u1SPulseFlag= (priv->regs[32] & 0x08); //R40[3] -+ -+ -+ priv->regs[14] = priv->regs[14] | 0x01; // TF force sharp mode -+ ret = r848_wr(priv, 0x16, priv->regs[14]); -+ -+ priv->regs[30] = priv->regs[30] | 0x80; // NA det off -+ ret |= r848_wr(priv, 0x26, priv->regs[30]); -+ -+ // Set NA det 710 = OFF -+ priv->regs[32] = (priv->regs[32] | 0x08); -+ ret |= r848_wr(priv, 0x28, priv->regs[32]); -+ -+ // DTV -+ CP_CUR = 0x00; //0.7m, R25[6:4]=000 -+ CP_OFFSET = 0x00; //0u, [2]=0 -+ -+ // CP current R25[6:4]=000 -+ priv->regs[17] = (priv->regs[17] & 0x8F) | CP_CUR ; -+ ret |= r848_wr(priv, 0x19, priv->regs[17]); -+ -+ // Div Cuurent R20[7:6]=2'b01(150uA) -+ priv->regs[12] = (priv->regs[12] & 0x3F) | 0x40; -+ ret |= r848_wr(priv, 0x14, priv->regs[12]); -+ -+ //CPI*2 R28[7]=1 -+ if ((R848_Standard!=R848_DVB_S) && (LO_Freq >= 865000)) -+ priv->regs[20] = (priv->regs[20] & 0x7F) | 0x80; -+ else -+ priv->regs[20] = (priv->regs[20] & 0x7F); -+ ret |= r848_wr(priv, 0x1c, priv->regs[20]); -+ -+ // R848:R26[7:5] VCO_current= 2 -+ priv->regs[18] = (priv->regs[18] & 0x1F) | 0x40; -+ ret |= r848_wr(priv, 0x1a, priv->regs[18]); -+ -+ //CP Offset R21[7] -+ priv->regs[13] = (priv->regs[13] & 0x7F) | CP_OFFSET; -+ ret |= r848_wr(priv, 0x15, priv->regs[13]); -+ if (ret) -+ return ret; -+ -+ //if(R848_Initial_done_flag==TRUE) -+ { -+ // set XTAL Power -+ if ((priv->cfg->R848_Xtal_Pwr < XTAL_SMALL_HIGH) && (LO_Freq > (64000+8500))) { -+ XTAL_POW1 = 0x00; //high, R16[4]=0 //R848:R23[7] -+ XTAL_POW0 = 0x20; //high, R15[6:5]=01 //R848:R23[6:5] -+ XTAL_GM = 0x00; //SMALL(0), R15[4:3]=00 -+ } else { -+ if(priv->cfg->R848_Xtal_Pwr <= XTAL_SMALL_HIGHEST) { -+ XTAL_POW1 = 0x00; //high, R16[4]=0 // R848:R23[7] -+ XTAL_POW0 = ((u8)(XTAL_SMALL_HIGHEST-priv->cfg->R848_Xtal_Pwr)<<5); //R848:R23[6:5] -+ XTAL_GM = 0x00; //SMALL(0), R27[0]=0 -+ } else if(priv->cfg->R848_Xtal_Pwr == XTAL_LARGE_HIGHEST) { -+ XTAL_POW1 = 0x00; //high, // R848:R23[7] -+ XTAL_POW0 = 0x00; //highest, // R848:R23[6:5] -+ XTAL_GM = 0x01; //LARGE(1), R27[0]=1 -+ } else { -+ XTAL_POW1 = 0x00; //high, // R848:R23[7] -+ XTAL_POW0 = 0x00; //highest, // R848:R23[6:5] -+ XTAL_GM = 0x01; //LARGE(1), R27[0]=1 -+ } -+ } -+ } -+// else -+// { -+// XTAL_POW1 = 0x00; //high, // R848:R23[7] -+// XTAL_POW0 = 0x00; //highest, // R848:R23[6:5] -+// XTAL_GM = 0x01; //LARGE(1), R27[0]=1 -+// } -+ -+ // Xtal_Gm=SMALL(0) R27[0] -+ priv->regs[19] = (priv->regs[19] & 0xFE) | XTAL_GM; -+ ret |= r848_wr(priv, 0x1b, priv->regs[19]); -+ -+ priv->regs[15] = (priv->regs[15] & 0x9F) | XTAL_POW0; // R23[6:5] -+ ret |= r848_wr(priv, 0x17, priv->regs[15]); -+ -+ priv->regs[15] = (priv->regs[15] & 0x7F) | XTAL_POW1; // R23[7] -+ ret |= r848_wr(priv, 0x17, priv->regs[15]); -+ -+ // IQ gen ON -+ priv->regs[31] = (priv->regs[31] & 0xFD) | 0x00; // R39[1] [0]=0'b0 -+ ret |= r848_wr(priv, 0x27, priv->regs[31]); -+ -+ // current:Dmin, Bmin -+ priv->regs[27] = (priv->regs[27] & 0xCF) | 0x00; // R848:R35[5:4]=2'b00 -+ ret |= r848_wr(priv, 0x23, priv->regs[27]); -+ -+ //set pll autotune = 128kHz (fast) R23[4:3]=2'b00 -+ priv->regs[15] = priv->regs[15] & 0xE7; -+ ret |= r848_wr(priv, 0x17, priv->regs[15]); -+ -+ //Divider -+ while(MixDiv <= 64) { -+ if (((LO_Freq * MixDiv) >= VCO_Min) && ((LO_Freq * MixDiv) < VCO_Max)) { -+ DivBuf = MixDiv; -+ while(DivBuf > 2) { -+ DivBuf = DivBuf >> 1; -+ DivNum ++; -+ } -+ break; -+ } -+ MixDiv = MixDiv << 1; -+ } -+ -+ SDM_RES = 0x00; //short, R27[4:3]=00 -+ priv->regs[19] = (priv->regs[19] & 0xE7) | SDM_RES; -+ ret |= r848_wr(priv, 0x1b, priv->regs[19]); -+ -+ // Xtal Div //R848:R24[2] -+ if(R848_Standard == R848_STD_SIZE) { //for cal -+ R848_XtalDiv = XTAL_DIV1; -+ priv->regs[16] = priv->regs[16] & 0xFB; //b2=0 // R848:R24[2] -+ PLL_Ref = R848_Xtal; -+ } else { // DTV_Standard -+ u2XalDivJudge = (u16) (LO_Freq/1000/8); -+ u1XtalDivRemain = (u8) (u2XalDivJudge % 2); -+ if(u1XtalDivRemain==1) { //odd -+ R848_XtalDiv = XTAL_DIV1; -+ priv->regs[16] = priv->regs[16] & 0xFB; //R24[2]=0 -+ PLL_Ref = R848_Xtal; -+ } else { // div2, note that agc clk also div2 -+ R848_XtalDiv = XTAL_DIV2; -+ priv->regs[16] |= 0x04; //R24[2]=1 -+ PLL_Ref = R848_Xtal / 2; -+ } -+ } -+ ret |= r848_wr(priv, 0x18, priv->regs[16]); -+ -+ //Divider num //R24[7:5] -+ priv->regs[16] &= 0x1F; -+ priv->regs[16] |= (DivNum << 5); -+ ret |= r848_wr(priv, 0x18, priv->regs[16]); -+ -+ VCO_Freq = LO_Freq * MixDiv; -+ Nint = (u16) (VCO_Freq / 2 / PLL_Ref); -+ VCO_Fra = (u16) (VCO_Freq - 2 * PLL_Ref * Nint); -+ -+ //Boundary spur prevention -+ if (VCO_Fra < PLL_Ref / 64) { //2*PLL_Ref/128 -+ VCO_Fra = 0; -+ } else if (VCO_Fra > PLL_Ref * 127/64) { //2*PLL_Ref*127/128 -+ VCO_Fra = 0; -+ Nint ++; -+ } else if((VCO_Fra > PLL_Ref * 127/128) && (VCO_Fra < PLL_Ref)) { //> 2*PLL_Ref*127/256, < 2*PLL_Ref*128/256 -+ VCO_Fra = PLL_Ref*127/128; // VCO_Fra = 2*PLL_Ref*127/256 -+ } else if((VCO_Fra > PLL_Ref) && (VCO_Fra < PLL_Ref * 129/128)) { //> 2*PLL_Ref*128/256, < 2*PLL_Ref*129/256 -+ VCO_Fra = PLL_Ref * 129/128; // VCO_Fra = 2*PLL_Ref*129/256 -+ } else { -+ VCO_Fra = VCO_Fra; -+ } -+ -+ //Ni:R848:R28[6:0] Si:R848:R20[5:4] -+ Ni = (Nint - 13) / 4; -+ Si = Nint - 4 *Ni - 13; -+ //Si -+ priv->regs[12] = (priv->regs[12] & 0xCF) | ((Si << 4)); -+ ret |= r848_wr(priv, 0x14, priv->regs[12]); -+ -+ //Ni -+ priv->regs[20] = (priv->regs[20] & 0x80) | (Ni); -+ ret |= r848_wr(priv, 0x1c, priv->regs[20]); -+ -+ //pw_sdm // R848:R27[7] -+ priv->regs[19] &= 0x7F; -+ if(VCO_Fra == 0) -+ priv->regs[19] |= 0x80; -+ ret |= r848_wr(priv, 0x1b, priv->regs[19]); -+ -+ //SDM calculator -+ while(VCO_Fra > 1) { -+ if (VCO_Fra > (2*PLL_Ref / Nsdm)) { -+ SDM = SDM + 32768 / (Nsdm/2); -+ VCO_Fra = VCO_Fra - 2*PLL_Ref / Nsdm; -+ if (Nsdm >= 0x8000) -+ break; -+ } -+ Nsdm = Nsdm << 1; -+ } -+ -+ SDM16to9 = SDM >> 8; -+ SDM8to1 = SDM - (SDM16to9 << 8); -+ -+ // R848:R30[7:0] -+ priv->regs[22] = (u8) SDM16to9; -+ ret |= r848_wr(priv, 0x1e, priv->regs[22]); -+ -+ // R848:R29[7:0] -+ priv->regs[21] = (u8) SDM8to1; -+ ret |= r848_wr(priv, 0x1d, priv->regs[21]); -+ if (ret) -+ return ret; -+ -+ //if(R848_Standard <= R848_SECAM_L1_INV) -+ if(R848_XtalDiv == XTAL_DIV2) -+ msleep(20); -+ else -+ msleep(10); -+ -+ for (VCO_current_trial = 0; VCO_current_trial < 3; VCO_current_trial++) { -+ // check PLL lock status -+ ret = r848_rd(priv, buf, 3); -+ if (ret) -+ return ret; -+ -+ // R848:R26[7:5] | Set VCO current = 011 (3) -+ if ((buf[2] & 0x40) == 0x00) { -+ //increase VCO current -+ priv->regs[18] = (priv->regs[18] & 0x1F) | ((2-VCO_current_trial) << 5); -+ ret = r848_wr(priv, 0x1a, priv->regs[18]); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ if (VCO_current_trial == 2) { -+ //check PLL lock status -+ ret = r848_rd(priv, buf, 3); -+ if (ret) -+ return ret; -+ -+ if( (buf[2] & 0x40) == 0x00) { -+ if(priv->cfg->R848_Xtal_Pwr <= XTAL_SMALL_HIGHEST) -+ XTAL_GM = 0x01; //LARGE(1), R15[4:3]=11 -+ -+ priv->regs[19] = (priv->regs[19] & 0xFE) | XTAL_GM; -+ ret = r848_wr(priv, 0x1b, priv->regs[19]); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ // set pll autotune = 8kHz (slow) -+ priv->regs[15] = (priv->regs[15] & 0xE7) | 0x10; -+ ret = r848_wr(priv, 0x17, priv->regs[15]); -+ -+ // restore TF, NA det setting -+ priv->regs[14] = (priv->regs[14] & 0xFE) | u1RfFlag; -+ ret |= r848_wr(priv, 0x16, priv->regs[14]); -+ -+ priv->regs[30] = (priv->regs[30] & 0x7F) | u1PulseFlag; -+ ret |= r848_wr(priv, 0x26, priv->regs[30]); -+ -+ // Set NA det 710 = OFF -+ priv->regs[32] = (priv->regs[32] & 0xF7) | u1SPulseFlag; -+ ret |= r848_wr(priv, 0x28, priv->regs[32]); -+ -+ return ret; -+} -+ -+ -+ -+/* -+ -+--R9-- -+[7:3]=LNA Cap -+[2]=RF_BUF_pwr -+[1]=Vga code mode -+[0]=VGA PWR on -+ -+R10 -+[5]=?(0) -+[4:0]=LNA Notch -+ -+R11 -+[7]=force plain mode -+[6]=TF current -+[3]=vga6db -+[2]=3~6 shrink -+[1:0]=IMR_Iqcap -+ -+R13 -+[6:5]=LNA band -+[4]=AGC Type (negative=0, positive=1) -+ -+R16 -+[5:0]=IMR_Gain -+ -+R17 -+[7]=LNAPD_PLUSE_ENA -+[5:0]=IMR_Phase -+ -+R33 -+[7:6]=RF Polyfilter band -+[5]=vco_band -+[3:2]=Ring PLL power -+[1:0]=ring_div2 -+ -+*/ -+ -+static int r848_set_mux(struct r848_priv *priv, u32 LO_KHz, u32 RF_KHz, R848_Standard_Type R848_Standard) -+{ -+ int ret; -+ -+ R848_Freq_Info_Type Freq_Info1; -+ u8 Reg08_IMR_Gain = 0; -+ u8 Reg09_IMR_Phase = 0; -+ u8 Reg03_IMR_Iqcap = 0; -+ Freq_Info1 = R848_Freq_Sel(LO_KHz, RF_KHz, R848_Standard); -+ -+ -+ // LNA band (depend on RF_KHz) -+ // R13[6:5] -+ priv->regs[5] = (priv->regs[5] & 0x9F) | Freq_Info1.LNA_BAND; -+ ret = r848_wr(priv, 0x0d, priv->regs[5]); -+ -+ // RF Polyfilter -+ // R33[7:6] -+ priv->regs[25] = (priv->regs[25] & 0x3F) | Freq_Info1.RF_POLY; -+ ret |= r848_wr(priv, 0x21, priv->regs[25]); -+ -+ // LNA Cap -+ // R9[7:3] -+ priv->regs[1] = (priv->regs[1] & 0x07) | (Freq_Info1.LPF_CAP<<3); -+ ret |= r848_wr(priv, 0x09, priv->regs[1]); -+ -+ // LNA Notch -+ // R10[4:0] -+ priv->regs[2] = (priv->regs[2] & 0xE0) | (Freq_Info1.LPF_NOTCH); -+ ret |= r848_wr(priv, 0x0a, priv->regs[2]); -+ -+ //Set_IMR -+ Reg08_IMR_Gain = priv->imr_data[Freq_Info1.IMR_MEM].gain_x & 0x3F; -+ Reg09_IMR_Phase = priv->imr_data[Freq_Info1.IMR_MEM].phase_y & 0x3F; -+ Reg03_IMR_Iqcap = priv->imr_data[Freq_Info1.IMR_MEM].iqcap & 0x03; -+ -+ // R16[5:0] -+ priv->regs[8] = (priv->regs[8] & 0xC0) | Reg08_IMR_Gain; -+ ret |= r848_wr(priv, 0x10, priv->regs[8]); -+ -+ // R17[5:0] -+ priv->regs[9] = (priv->regs[9] & 0xC0) | Reg09_IMR_Phase; -+ ret |= r848_wr(priv, 0x11, priv->regs[9]); -+ -+ // R11[1:0] -+ priv->regs[3] = (priv->regs[3] & 0xFC) | Reg03_IMR_Iqcap; -+ ret |= r848_wr(priv, 0x0b, priv->regs[3]); -+ -+ return ret; -+} -+ -+ -+ -+ -+//-----------------------------------------------------------------------------------/ -+// Purpose: compare IMC result aray [0][1][2], find min value and store to CorArry[0] -+// input: CorArry: three IMR data array -+//-----------------------------------------------------------------------------------/ -+static void R848_CompreCor(struct r848_priv *priv, struct r848_sect_type *CorArry) -+{ -+ struct r848_sect_type CorTemp; -+ int i; -+ -+ for (i = 3; i > 0; i--) { -+ //compare IMC result [0][1][2], find min value -+ if (CorArry[0].value > CorArry[i - 1].value) { -+ CorTemp = CorArry[0]; -+ CorArry[0] = CorArry[i - 1]; -+ CorArry[i - 1] = CorTemp; -+ } -+ } -+} -+ -+ -+//-------------------------------------------------------------------------------------------- -+// Purpose: record IMC results by input gain/phase location -+// then adjust gain or phase positive 1 step and negtive 1 step, both record results -+// input: FixPot: phase or gain -+// FlucPot phase or gain -+// PotReg: 0x10 or 0x11 for R848 -+// CompareTree: 3 IMR trace and results -+// output: TRUE or FALSE -+//-------------------------------------------------------------------------------------------- -+static int R848_IQ_Tree( struct r848_priv *priv,u8 FixPot, u8 FlucPot, u8 PotReg, struct r848_sect_type* CompareTree) -+{ -+ int ret, i; -+ u8 PntReg; -+ -+ if(PotReg == 0x10) -+ PntReg = 0x11; //phase control -+ else -+ PntReg = 0x10; //gain control -+ -+ for (i = 0; i < 3; i++) { -+ ret = r848_wr(priv, PotReg, FixPot); -+ ret |= r848_wr(priv, PntReg, FlucPot); -+ ret |= r848_get_imr(priv,&CompareTree[i].value); -+ if (ret) -+ return ret; -+ -+ if (PotReg == 0x10) { -+ CompareTree[i].gain_x = FixPot; -+ CompareTree[i].phase_y = FlucPot; -+ } else { -+ CompareTree[i].phase_y = FixPot; -+ CompareTree[i].gain_x = FlucPot; -+ } -+ -+ if(i == 0) { //try right-side point -+ FlucPot ++; -+ } else if (i == 1) { //try left-side point -+ if((FlucPot & 0x1F) == 1) { //if absolute location is 1, change I/Q direction -+ if(FlucPot & 0x20) { //b[5]:I/Q selection. 0:Q-path, 1:I-path -+ FlucPot = (FlucPot & 0xC0) | 0x01; -+ } else { -+ FlucPot = (FlucPot & 0xC0) | 0x21; -+ } -+ } else { -+ FlucPot = FlucPot - 2; -+ } -+ } -+ } -+ return ret; -+} -+ -+ -+static int R848_Section(struct r848_priv *priv, struct r848_sect_type *IQ_Pont) -+{ -+ struct r848_sect_type Compare_IQ[3]; -+ struct r848_sect_type Compare_Bet[3]; -+ -+ //Try X-1 column and save min result to Compare_Bet[0] -+ if((IQ_Pont->gain_x & 0x1F) == 0x00) -+ { -+ Compare_IQ[0].gain_x = ((IQ_Pont->gain_x) & 0xDF) + 1; //Q-path, Gain=1 -+ } -+ else -+ { -+ Compare_IQ[0].gain_x = IQ_Pont->gain_x - 1; //left point -+ } -+ Compare_IQ[0].phase_y = IQ_Pont->phase_y; -+ -+ if(R848_IQ_Tree(priv,Compare_IQ[0].gain_x, Compare_IQ[0].phase_y, 0x10, &Compare_IQ[0]) != RT_Success) // y-direction -+ return RT_Fail; -+ -+ R848_CompreCor(priv,&Compare_IQ[0]); -+ -+ Compare_Bet[0].gain_x = Compare_IQ[0].gain_x; -+ Compare_Bet[0].phase_y = Compare_IQ[0].phase_y; -+ Compare_Bet[0].value = Compare_IQ[0].value; -+ -+ //Try X column and save min result to Compare_Bet[1] -+ Compare_IQ[0].gain_x = IQ_Pont->gain_x; -+ Compare_IQ[0].phase_y = IQ_Pont->phase_y; -+ -+ if(R848_IQ_Tree(priv,Compare_IQ[0].gain_x, Compare_IQ[0].phase_y, 0x10, &Compare_IQ[0]) != RT_Success) -+ return RT_Fail; -+ -+ R848_CompreCor(priv,&Compare_IQ[0]); -+ -+ Compare_Bet[1].gain_x = Compare_IQ[0].gain_x; -+ Compare_Bet[1].phase_y = Compare_IQ[0].phase_y; -+ Compare_Bet[1].value = Compare_IQ[0].value; -+ -+ //Try X+1 column and save min result to Compare_Bet[2] -+ if((IQ_Pont->gain_x & 0x1F) == 0x00) -+ Compare_IQ[0].gain_x = ((IQ_Pont->gain_x) | 0x20) + 1; //I-path, Gain=1 -+ else -+ Compare_IQ[0].gain_x = IQ_Pont->gain_x + 1; -+ Compare_IQ[0].phase_y = IQ_Pont->phase_y; -+ -+ if(R848_IQ_Tree(priv,Compare_IQ[0].gain_x, Compare_IQ[0].phase_y, 0x10, &Compare_IQ[0]) != RT_Success) -+ return RT_Fail; -+ -+ R848_CompreCor(priv,&Compare_IQ[0]); -+ -+ Compare_Bet[2].gain_x = Compare_IQ[0].gain_x; -+ Compare_Bet[2].phase_y = Compare_IQ[0].phase_y; -+ Compare_Bet[2].value = Compare_IQ[0].value; -+ -+ R848_CompreCor(priv,&Compare_Bet[0]); -+ return RT_Fail; -+ -+ *IQ_Pont = Compare_Bet[0]; -+ -+ return RT_Success; -+} -+ -+R848_ErrCode R848_IMR_Cross( struct r848_priv *priv,struct r848_sect_type* IQ_Pont, u8* X_Direct) -+{ -+ int ret; -+ -+ struct r848_sect_type Compare_Cross[9]; //(0,0)(0,Q-1)(0,I-1)(Q-1,0)(I-1,0)+(0,Q-2)(0,I-2)(Q-2,0)(I-2,0) -+ struct r848_sect_type Compare_Temp; -+ u8 CrossCount = 0; -+ u8 Reg16 = priv->regs[8] & 0xC0; -+ u8 Reg17 = priv->regs[9] & 0xC0; -+ -+ memset(&Compare_Temp, 0, sizeof(struct r848_sect_type)); -+ Compare_Temp.value = 255; -+ -+ for(CrossCount=0; CrossCount<9; CrossCount++) -+ { -+ -+ if(CrossCount==0) -+ { -+ Compare_Cross[CrossCount].gain_x = Reg16; -+ Compare_Cross[CrossCount].phase_y = Reg17; -+ } -+ else if(CrossCount==1) -+ { -+ Compare_Cross[CrossCount].gain_x = Reg16; //0 -+ Compare_Cross[CrossCount].phase_y = Reg17 + 1; //Q-1 -+ } -+ else if(CrossCount==2) -+ { -+ Compare_Cross[CrossCount].gain_x = Reg16; //0 -+ Compare_Cross[CrossCount].phase_y = (Reg17 | 0x20) + 1; //I-1 -+ } -+ else if(CrossCount==3) -+ { -+ Compare_Cross[CrossCount].gain_x = Reg16 + 1; //Q-1 -+ Compare_Cross[CrossCount].phase_y = Reg17; -+ } -+ else if(CrossCount==4) -+ { -+ Compare_Cross[CrossCount].gain_x = (Reg16 | 0x20) + 1; //I-1 -+ Compare_Cross[CrossCount].phase_y = Reg17; -+ } -+ else if(CrossCount==5) -+ { -+ Compare_Cross[CrossCount].gain_x = Reg16; //0 -+ Compare_Cross[CrossCount].phase_y = Reg17 + 2; //Q-2 -+ } -+ else if(CrossCount==6) -+ { -+ Compare_Cross[CrossCount].gain_x = Reg16; //0 -+ Compare_Cross[CrossCount].phase_y = (Reg17 | 0x20) + 2; //I-2 -+ } -+ else if(CrossCount==7) -+ { -+ Compare_Cross[CrossCount].gain_x = Reg16 + 2; //Q-2 -+ Compare_Cross[CrossCount].phase_y = Reg17; -+ } -+ else if(CrossCount==8) -+ { -+ Compare_Cross[CrossCount].gain_x = (Reg16 | 0x20) + 2; //I-2 -+ Compare_Cross[CrossCount].phase_y = Reg17; -+ } -+ -+ ret = r848_wr(priv, 0x10, Compare_Cross[CrossCount].gain_x); -+ if (ret) -+ return ret; -+ -+ ret = r848_wr(priv, 0x11, Compare_Cross[CrossCount].phase_y); -+ if (ret) -+ return ret; -+ -+ if(r848_get_imr(priv,&Compare_Cross[CrossCount].value) != RT_Success) -+ return RT_Fail; -+ -+ if( Compare_Cross[CrossCount].value < Compare_Temp.value) -+ { -+ Compare_Temp.value = Compare_Cross[CrossCount].value; -+ Compare_Temp.gain_x = Compare_Cross[CrossCount].gain_x; -+ Compare_Temp.phase_y = Compare_Cross[CrossCount].phase_y; -+ } -+ } //end for loop -+ -+ -+ if(((Compare_Temp.phase_y & 0x3F)==0x01) || (Compare_Temp.phase_y & 0x3F)==0x02) //phase Q1 or Q2 -+ { -+ *X_Direct = (u8) 0; -+ IQ_Pont[0].gain_x = Compare_Cross[0].gain_x; //0 -+ IQ_Pont[0].phase_y = Compare_Cross[0].phase_y; //0 -+ IQ_Pont[0].value = Compare_Cross[0].value; -+ -+ IQ_Pont[1].gain_x = Compare_Cross[1].gain_x; //0 -+ IQ_Pont[1].phase_y = Compare_Cross[1].phase_y; //Q1 -+ IQ_Pont[1].value = Compare_Cross[1].value; -+ -+ IQ_Pont[2].gain_x = Compare_Cross[5].gain_x; //0 -+ IQ_Pont[2].phase_y = Compare_Cross[5].phase_y;//Q2 -+ IQ_Pont[2].value = Compare_Cross[5].value; -+ } -+ else if(((Compare_Temp.phase_y & 0x3F)==0x21) || (Compare_Temp.phase_y & 0x3F)==0x22) //phase I1 or I2 -+ { -+ *X_Direct = (u8) 0; -+ IQ_Pont[0].gain_x = Compare_Cross[0].gain_x; //0 -+ IQ_Pont[0].phase_y = Compare_Cross[0].phase_y; //0 -+ IQ_Pont[0].value = Compare_Cross[0].value; -+ -+ IQ_Pont[1].gain_x = Compare_Cross[2].gain_x; //0 -+ IQ_Pont[1].phase_y = Compare_Cross[2].phase_y; //Q1 -+ IQ_Pont[1].value = Compare_Cross[2].value; -+ -+ IQ_Pont[2].gain_x = Compare_Cross[6].gain_x; //0 -+ IQ_Pont[2].phase_y = Compare_Cross[6].phase_y;//Q2 -+ IQ_Pont[2].value = Compare_Cross[6].value; -+ } -+ else if(((Compare_Temp.gain_x & 0x3F)==0x01) || (Compare_Temp.gain_x & 0x3F)==0x02) //gain Q1 or Q2 -+ { -+ *X_Direct = (u8) 1; -+ IQ_Pont[0].gain_x = Compare_Cross[0].gain_x; //0 -+ IQ_Pont[0].phase_y = Compare_Cross[0].phase_y; //0 -+ IQ_Pont[0].value = Compare_Cross[0].value; -+ -+ IQ_Pont[1].gain_x = Compare_Cross[3].gain_x; //Q1 -+ IQ_Pont[1].phase_y = Compare_Cross[3].phase_y; //0 -+ IQ_Pont[1].value = Compare_Cross[3].value; -+ -+ IQ_Pont[2].gain_x = Compare_Cross[7].gain_x; //Q2 -+ IQ_Pont[2].phase_y = Compare_Cross[7].phase_y;//0 -+ IQ_Pont[2].value = Compare_Cross[7].value; -+ } -+ else if(((Compare_Temp.gain_x & 0x3F)==0x21) || (Compare_Temp.gain_x & 0x3F)==0x22) //gain I1 or I2 -+ { -+ *X_Direct = (u8) 1; -+ IQ_Pont[0].gain_x = Compare_Cross[0].gain_x; //0 -+ IQ_Pont[0].phase_y = Compare_Cross[0].phase_y; //0 -+ IQ_Pont[0].value = Compare_Cross[0].value; -+ -+ IQ_Pont[1].gain_x = Compare_Cross[4].gain_x; //I1 -+ IQ_Pont[1].phase_y = Compare_Cross[4].phase_y; //0 -+ IQ_Pont[1].value = Compare_Cross[4].value; -+ -+ IQ_Pont[2].gain_x = Compare_Cross[8].gain_x; //I2 -+ IQ_Pont[2].phase_y = Compare_Cross[8].phase_y;//0 -+ IQ_Pont[2].value = Compare_Cross[8].value; -+ } -+ else //(0,0) -+ { -+ *X_Direct = (u8) 1; -+ IQ_Pont[0].gain_x = Compare_Cross[0].gain_x; -+ IQ_Pont[0].phase_y = Compare_Cross[0].phase_y; -+ IQ_Pont[0].value = Compare_Cross[0].value; -+ -+ IQ_Pont[1].gain_x = Compare_Cross[3].gain_x; //Q1 -+ IQ_Pont[1].phase_y = Compare_Cross[3].phase_y; //0 -+ IQ_Pont[1].value = Compare_Cross[3].value; -+ -+ IQ_Pont[2].gain_x = Compare_Cross[4].gain_x; //I1 -+ IQ_Pont[2].phase_y = Compare_Cross[4].phase_y; //0 -+ IQ_Pont[2].value = Compare_Cross[4].value; -+ } -+ return RT_Success; -+} -+ -+//-------------------------------------------------------------------------------------// -+// Purpose: if (Gain<9 or Phase<9), Gain+1 or Phase+1 and compare with min value -+// new < min => update to min and continue -+// new > min => Exit -+// input: StepArry: three IMR data array -+// Pace: gain or phase register -+//-------------------------------------------------------------------------------------// -+R848_ErrCode R848_CompreStep( struct r848_priv *priv,struct r848_sect_type* StepArry, u8 Pace) -+{ -+ int ret; -+ struct r848_sect_type StepTemp; -+ //min value already saved in StepArry[0] -+ StepTemp.phase_y = StepArry[0].phase_y; -+ StepTemp.gain_x = StepArry[0].gain_x; -+ //StepTemp.iqcap = StepArry[0].iqcap; -+ -+ while(((StepTemp.gain_x & 0x1F) < R848_IMR_TRIAL) && ((StepTemp.phase_y & 0x1F) < R848_IMR_TRIAL)) -+ { -+ if(Pace == 0x10) -+ StepTemp.gain_x ++; -+ else -+ StepTemp.phase_y ++; -+ -+ ret = r848_wr(priv, 0x10, StepTemp.gain_x); -+ if (ret) -+ return ret; -+ -+ ret = r848_wr(priv, 0x11, StepTemp.phase_y); -+ if (ret) -+ return ret; -+ -+ if(r848_get_imr(priv,&StepTemp.value) != RT_Success) -+ return RT_Fail; -+ -+ if(StepTemp.value <= StepArry[0].value) -+ { -+ StepArry[0].gain_x = StepTemp.gain_x; -+ StepArry[0].phase_y = StepTemp.phase_y; -+ //StepArry[0].iqcap = StepTemp.iqcap; -+ StepArry[0].value = StepTemp.value; -+ } -+ else if((StepTemp.value - 2) > StepArry[0].value) -+ { -+ break; -+ } -+ -+ } //end of while() -+ -+ return RT_Success; -+} -+ -+R848_ErrCode R848_IMR_Iqcap( struct r848_priv *priv,struct r848_sect_type* IQ_Point) -+{ -+ struct r848_sect_type Compare_Temp; -+ int i = 0, ret; -+ -+ //Set Gain/Phase to right setting -+// R848_I2C.RegAddr = 0x10; // R16[5:0] -+ ret = r848_wr(priv, 0x10, IQ_Point->gain_x); -+ if (ret) -+ return ret; -+ -+// R848_I2C.RegAddr = 0x11; // R17[5:0] -+ ret = r848_wr(priv, 0x11, IQ_Point->phase_y); -+ if (ret) -+ return ret; -+ -+ //try iqcap -+ for(i=0; i<3; i++) -+ { -+ Compare_Temp.iqcap = (u8) i; -+// R848_I2C.RegAddr = 0x0B; // R11[1:0] -+ priv->regs[3] = (priv->regs[3] & 0xFC) | Compare_Temp.iqcap; -+ ret = r848_wr(priv, 0x0b, priv->regs[3]); -+ if (ret) -+ return ret; -+ -+ if(r848_get_imr(priv,&(Compare_Temp.value)) != RT_Success) -+ return RT_Fail; -+ -+ if(Compare_Temp.value < IQ_Point->value) -+ { -+ IQ_Point->value = Compare_Temp.value; -+ IQ_Point->iqcap = Compare_Temp.iqcap; -+ } -+ } -+ -+ return RT_Success; -+} -+ -+ -+R848_ErrCode R848_IQ( struct r848_priv *priv,struct r848_sect_type* IQ_Pont) -+{ -+ int ret; -+ struct r848_sect_type Compare_IQ[3]; -+ u8 VGA_Count = 0; -+ u8 VGA_Read = 0; -+ u8 X_Direction; // 1:X, 0:Y -+ -+ -+ // increase VGA power to let image significant -+ for(VGA_Count=11; VGA_Count < 16; VGA_Count ++) -+ { -+// R848_I2C.RegAddr = 0x14; // R848:R20[3:0] -+ ret = r848_wr(priv, 0x14, (priv->regs[12] & 0xF0) + VGA_Count); -+ if (ret) -+ return ret; -+ -+ msleep(10); -+ -+ if(r848_get_imr(priv,&VGA_Read) != RT_Success) -+ return RT_Fail; -+ -+ if(VGA_Read > 40) -+ break; -+ } -+ -+ Compare_IQ[0].gain_x = priv->regs[8] & 0xC0; // R16[5:0] -+ Compare_IQ[0].phase_y = priv->regs[9] & 0xC0; // R17[5:0] -+ //Compare_IQ[0].iqcap = R848_iniArray[3] & 0xFC; -+ -+ // Determine X or Y -+ if(R848_IMR_Cross(priv,&Compare_IQ[0], &X_Direction) != RT_Success) -+ return RT_Fail; -+ -+ if(X_Direction==1) -+ { -+ //compare and find min of 3 points. determine I/Q direction -+ R848_CompreCor(priv,&Compare_IQ[0]); -+ -+ //increase step to find min value of this direction -+ if(R848_CompreStep(priv,&Compare_IQ[0], 0x10) != RT_Success) //X -+ return RT_Fail; -+ } -+ else -+ { -+ //compare and find min of 3 points. determine I/Q direction -+ R848_CompreCor(priv,&Compare_IQ[0]); -+ -+ //increase step to find min value of this direction -+ if(R848_CompreStep(priv,&Compare_IQ[0], 0x11) != RT_Success) //Y -+ return RT_Fail; -+ } -+ -+ //Another direction -+ if(X_Direction==1) -+ { -+ if(R848_IQ_Tree(priv,Compare_IQ[0].gain_x, Compare_IQ[0].phase_y, 0x10, &Compare_IQ[0]) != RT_Success) //Y -+ return RT_Fail; -+ -+ //compare and find min of 3 points. determine I/Q direction -+ R848_CompreCor(priv,&Compare_IQ[0]); -+ -+ //increase step to find min value of this direction -+ if(R848_CompreStep(priv,&Compare_IQ[0], 0x11) != RT_Success) //Y -+ return RT_Fail; -+ } -+ else -+ { -+ if(R848_IQ_Tree(priv,Compare_IQ[0].phase_y, Compare_IQ[0].gain_x, 0x11, &Compare_IQ[0]) != RT_Success) //X -+ return RT_Fail; -+ -+ //compare and find min of 3 points. determine I/Q direction -+ R848_CompreCor(priv,&Compare_IQ[0]); -+ -+ //increase step to find min value of this direction -+ if(R848_CompreStep(priv,&Compare_IQ[0], 0x10) != RT_Success) //X -+ return RT_Fail; -+ } -+ -+ -+ //--- Check 3 points again---// -+ if(X_Direction==1) -+ { -+ if(R848_IQ_Tree(priv,Compare_IQ[0].phase_y, Compare_IQ[0].gain_x, 0x11, &Compare_IQ[0]) != RT_Success) //X -+ return RT_Fail; -+ } -+ else -+ { -+ if(R848_IQ_Tree(priv,Compare_IQ[0].gain_x, Compare_IQ[0].phase_y, 0x10, &Compare_IQ[0]) != RT_Success) //Y -+ return RT_Fail; -+ } -+ -+ R848_CompreCor(priv,&Compare_IQ[0]); -+ -+ //Section-9 check -+ //if(R848_F_IMR(&Compare_IQ[0]) != RT_Success) -+ if(R848_Section(priv,&Compare_IQ[0]) != RT_Success) -+ return RT_Fail; -+ -+ //clear IQ_Cap = 0 // R11[1:0] -+ Compare_IQ[0].iqcap = priv->regs[3] & 0xFC; -+ -+ if(R848_IMR_Iqcap(priv,&Compare_IQ[0]) != RT_Success) -+ return RT_Fail; -+ -+ *IQ_Pont = Compare_IQ[0]; -+ -+ //reset gain/phase/iqcap control setting -+// R848_I2C.RegAddr = 0x10; // R16[5:0] -+ priv->regs[8] = priv->regs[8] & 0xC0; -+ ret = r848_wr(priv, 0x10, priv->regs[8]); -+ if (ret) -+ return ret; -+ -+// R848_I2C.RegAddr = 0x11; // R17[5:0] -+ priv->regs[9] = priv->regs[9] & 0xC0; -+ ret = r848_wr(priv, 0x11, priv->regs[9]); -+ if (ret) -+ return ret; -+ -+// R848_I2C.RegAddr = 0x0B; // R11[1:0] -+ priv->regs[3] = priv->regs[3] & 0xFC; -+ ret = r848_wr(priv, 0x0b, priv->regs[3]); -+ if (ret) -+ return ret; -+ -+ return RT_Success; -+} -+ -+//----------------------------------------------------------------------------------------// -+// purpose: search surrounding points from previous point -+// try (x-1), (x), (x+1) columns, and find min IMR result point -+// input: IQ_Pont: previous point data(IMR Gain, Phase, ADC Result, RefRreq) -+// will be updated to final best point -+// output: TRUE or FALSE -+//----------------------------------------------------------------------------------------// -+R848_ErrCode R848_F_IMR( struct r848_priv *priv,struct r848_sect_type* IQ_Pont) -+{ -+ int ret; -+ struct r848_sect_type Compare_IQ[3]; -+ struct r848_sect_type Compare_Bet[3]; -+ u8 VGA_Count = 0; -+ u8 VGA_Read = 0; -+ -+ //VGA -+ for(VGA_Count=11; VGA_Count < 16; VGA_Count ++) -+ { -+// R848_I2C.RegAddr = 0x14; // R20[3:0] -+ ret = r848_wr(priv, 0x14, (priv->regs[12] & 0xF0) + VGA_Count); -+ if (ret) -+ return ret; -+ -+ msleep(10); -+ -+ if(r848_get_imr(priv,&VGA_Read) != RT_Success) -+ return RT_Fail; -+ -+ if(VGA_Read > 40) -+ break; -+ } -+ -+ //Try X-1 column and save min result to Compare_Bet[0] -+ if((IQ_Pont->gain_x & 0x1F) == 0x00) -+ { -+ Compare_IQ[0].gain_x = ((IQ_Pont->gain_x) & 0xDF) + 1; //Q-path, Gain=1 -+ } -+ else -+ { -+ Compare_IQ[0].gain_x = IQ_Pont->gain_x - 1; //left point -+ } -+ Compare_IQ[0].phase_y = IQ_Pont->phase_y; -+ -+ if(R848_IQ_Tree(priv,Compare_IQ[0].gain_x, Compare_IQ[0].phase_y, 0x10, &Compare_IQ[0]) != RT_Success) // y-direction -+ return RT_Fail; -+ -+ R848_CompreCor(priv,&Compare_IQ[0]); -+ -+ Compare_Bet[0].gain_x = Compare_IQ[0].gain_x; -+ Compare_Bet[0].phase_y = Compare_IQ[0].phase_y; -+ Compare_Bet[0].value = Compare_IQ[0].value; -+ -+ //Try X column and save min result to Compare_Bet[1] -+ Compare_IQ[0].gain_x = IQ_Pont->gain_x; -+ Compare_IQ[0].phase_y = IQ_Pont->phase_y; -+ -+ if(R848_IQ_Tree(priv,Compare_IQ[0].gain_x, Compare_IQ[0].phase_y, 0x10, &Compare_IQ[0]) != RT_Success) -+ return RT_Fail; -+ -+ R848_CompreCor(priv,&Compare_IQ[0]); -+ -+ Compare_Bet[1].gain_x = Compare_IQ[0].gain_x; -+ Compare_Bet[1].phase_y = Compare_IQ[0].phase_y; -+ Compare_Bet[1].value = Compare_IQ[0].value; -+ -+ //Try X+1 column and save min result to Compare_Bet[2] -+ if((IQ_Pont->gain_x & 0x1F) == 0x00) -+ Compare_IQ[0].gain_x = ((IQ_Pont->gain_x) | 0x20) + 1; //I-path, Gain=1 -+ else -+ Compare_IQ[0].gain_x = IQ_Pont->gain_x + 1; -+ Compare_IQ[0].phase_y = IQ_Pont->phase_y; -+ -+ if(R848_IQ_Tree(priv,Compare_IQ[0].gain_x, Compare_IQ[0].phase_y, 0x10, &Compare_IQ[0]) != RT_Success) -+ return RT_Fail; -+ -+ R848_CompreCor(priv,&Compare_IQ[0]); -+ -+ Compare_Bet[2].gain_x = Compare_IQ[0].gain_x; -+ Compare_Bet[2].phase_y = Compare_IQ[0].phase_y; -+ Compare_Bet[2].value = Compare_IQ[0].value; -+ -+ R848_CompreCor(priv,&Compare_Bet[0]); -+ -+ //clear IQ_Cap = 0 -+ Compare_Bet[0].iqcap = priv->regs[3] & 0xFC; // R11[1:0] -+ -+ if(R848_IMR_Iqcap(priv,&Compare_Bet[0]) != RT_Success) -+ return RT_Fail; -+ -+ *IQ_Pont = Compare_Bet[0]; -+ -+ return RT_Success; -+} -+ -+ -+R848_ErrCode R848_SetTF( struct r848_priv *priv,u32 u4FreqKHz, u8 u1TfType) -+{ -+ int ret; -+ u8 u1FreqCount = 0; -+ u32 u4Freq1 = 0; -+ u32 u4Freq2 = 0; -+ u32 u4Ratio; -+ u8 u1TF_Set_Result1 = 0; -+ u8 u1TF_Set_Result2 = 0; -+ u8 u1TF_tmp1, u1TF_tmp2; -+ u8 u1TFCalNum = R848_TF_HIGH_NUM; -+ u8 R848_TF = 0; -+ -+ if(u4FreqKHz>2)*3 + (u1TF_Set_Result1 & 0x3F); //b6 is 3xb4 -+ u1TF_tmp2 = ((u1TF_Set_Result2 & 0x40)>>2)*3 + (u1TF_Set_Result2 & 0x3F); -+ u4Ratio = (u4Freq1- u4FreqKHz)*100/(u4Freq1 - u4Freq2); -+ R848_TF = u1TF_tmp1 + (u8)((u1TF_tmp2 - u1TF_tmp1)*u4Ratio/100); -+ if(R848_TF>=0x40) -+ R848_TF = (R848_TF + 0x10); -+ -+ } -+ } -+ else if((u4FreqKHz>=R848_LNA_LOW_LOWEST[R848_TF_BEAD]) && (u4FreqKHz>2) + (u1TF_Set_Result1 & 0x3F); //b6 is 1xb4 -+ u1TF_tmp2 = ((u1TF_Set_Result2 & 0x40)>>2) + (u1TF_Set_Result2 & 0x3F); -+ u4Ratio = (u4Freq1- u4FreqKHz)*100/(u4Freq1 - u4Freq2); -+ R848_TF = u1TF_tmp1 + (u8)((u1TF_tmp2 - u1TF_tmp1)*u4Ratio/100); -+ if(R848_TF>=0x40) -+ R848_TF = (R848_TF + 0x30); -+ } -+ } -+ else if((u4FreqKHz>=R848_LNA_MID_LOW[R848_TF_BEAD]) && (u4FreqKHzregs[0] = (priv->regs[0] & 0x80) | R848_TF; -+ ret = r848_wr(priv, 0x0b, priv->regs[0]); -+ if (ret) -+ return ret; -+ -+ return RT_Success; -+} -+ -+R848_ErrCode R848_IMR( struct r848_priv *priv,u8 IMR_MEM, bool IM_Flag) -+{ -+ int ret; -+ u32 RingVCO = 0; -+ u32 RingFreq = 0; -+ u8 u1MixerGain = 8; -+ -+ struct r848_sect_type IMR_POINT; -+ -+ RingVCO = 3200000; -+ priv->regs[31] &= 0x3F; //clear ring_div1, R24[7:6] //R848:R39[7:6] 39-8=31 39(0x27) is addr ; [31] is data -+ priv->regs[25] &= 0xFC; //clear ring_div2, R25[1:0] //R848:R33[1:0] 33-8=25 33(0x21) is addr ; [25] is data -+ priv->regs[25] &= 0xDF; //clear vco_band, R25[5] //R848:R33[5] 33-8=25 33(0x21) is addr ; [25] is data -+ priv->regs[31] &= 0xC3; //clear ring_div_num, R24[3:0]//R848:R39[5:2] 39-8=31 39(0x27) is addr ; [31] is data -+ -+ switch(IMR_MEM) -+ { -+ case 0: // RingFreq = 66.66M -+ RingFreq = RingVCO/48; -+ priv->regs[31] |= 0x80; // ring_div1 /6 (2) -+ priv->regs[25] |= 0x03; // ring_div2 /8 (3) -+ priv->regs[25] |= 0x00; // vco_band = 0 (high) -+ priv->regs[31] |= 0x24; // ring_div_num = 9 -+ u1MixerGain = 8; -+ break; -+ case 1: // RingFreq = 200M -+ RingFreq = RingVCO/16; -+ priv->regs[31] |= 0x00; // ring_div1 /4 (0) -+ priv->regs[25] |= 0x02; // ring_div2 /4 (2) -+ priv->regs[25] |= 0x00; // vco_band = 0 (high) -+ priv->regs[31] |= 0x24; // ring_div_num = 9 -+ u1MixerGain = 6; -+ break; -+ case 2: // RingFreq = 400M -+ RingFreq = RingVCO/8; -+ priv->regs[31] |= 0x00; // ring_div1 /4 (0) -+ priv->regs[25] |= 0x01; // ring_div2 /2 (1) -+ priv->regs[25] |= 0x00; // vco_band = 0 (high) -+ priv->regs[31] |= 0x24; // ring_div_num = 9 -+ u1MixerGain = 6; -+ break; -+ case 3: // RingFreq = 533.33M -+ RingFreq = RingVCO/6; -+ priv->regs[31] |= 0x80; // ring_div1 /6 (2) -+ priv->regs[25] |= 0x00; // ring_div2 /1 (0) -+ priv->regs[25] |= 0x00; // vco_band = 0 (high) -+ priv->regs[31] |= 0x24; // ring_div_num = 9 -+ u1MixerGain = 8; -+ break; -+ case 4: // RingFreq = 800M -+ RingFreq = RingVCO/4; -+ priv->regs[31] |= 0x00; // ring_div1 /4 (0) -+ priv->regs[25] |= 0x00; // ring_div2 /1 (0) -+ priv->regs[25] |= 0x00; // vco_band = 0 (high) -+ priv->regs[31] |= 0x24; // ring_div_num = 9 -+ u1MixerGain = 8; -+ break; -+ default: -+ RingFreq = RingVCO/4; -+ priv->regs[31] |= 0x00; // ring_div1 /4 (0) -+ priv->regs[25] |= 0x00; // ring_div2 /1 (0) -+ priv->regs[25] |= 0x00; // vco_band = 0 (high) -+ priv->regs[31] |= 0x24; // ring_div_num = 9 -+ u1MixerGain = 8; -+ break; -+ } -+ -+ //Mixer Amp Gain -+ //R848_I2C.RegAddr = 0x0F; //R848:R15[4:0] -+ priv->regs[7] = (priv->regs[7] & 0xE0) | u1MixerGain; -+ ret = r848_wr(priv, 0x0f, priv->regs[7]); -+ -+ //write I2C to set RingPLL -+ ret |= r848_wr(priv, 0x27, priv->regs[31]); -+ ret |= r848_wr(priv, 0x21, priv->regs[25]); -+ -+ //Ring PLL power -+ //if((RingFreq>=0) && (RingFreqR848_RING_POWER_FREQ_HIGH))) //R848:R33[3:2] -+ priv->regs[25] = (priv->regs[25] & 0xF3) | 0x08; //R25[3:2]=2'b10; min_lp -+ else -+ priv->regs[25] = (priv->regs[25] & 0xF3) | 0x00; //R25[3:2]=2'b00; min -+ -+ ret |= r848_wr(priv, 0x21, priv->regs[25]); -+ -+ //Must do MUX before PLL() -+ if(r848_set_mux(priv,RingFreq - R848_IMR_IF, RingFreq, R848_STD_SIZE) != RT_Success) //IMR MUX (LO, RF) -+ return RT_Fail; -+ -+ if(r848_set_pll(priv,(RingFreq - R848_IMR_IF), R848_STD_SIZE) != RT_Success) //IMR PLL -+ return RT_Fail; -+ -+ //Set TF, place after R848_MUX( ) -+ //TF is dependent to LNA/Mixer Gain setting -+ if(R848_SetTF(priv,RingFreq, (u8)R848_TF_BEAD) != RT_Success) -+ return RT_Fail; -+ -+ //clear IQ_cap -+ IMR_POINT.iqcap = priv->regs[3] & 0xFC; // R848:R11[1:0] -+ -+ if(IM_Flag == 0) -+ { -+ if(R848_IQ(priv,&IMR_POINT) != RT_Success) -+ return RT_Fail; -+ } -+ else -+ { -+ IMR_POINT.gain_x = priv->imr_data[3].gain_x; -+ IMR_POINT.phase_y = priv->imr_data[3].phase_y; -+ IMR_POINT.value = priv->imr_data[3].value; -+ //IMR_POINT.iqcap = priv->imr_data[3].iqcap; -+ if(R848_F_IMR(priv,&IMR_POINT) != RT_Success) -+ return RT_Fail; -+ } -+ -+ //Save IMR Value -+ switch(IMR_MEM) -+ { -+ case 0: -+ priv->imr_data[0].gain_x = IMR_POINT.gain_x; -+ priv->imr_data[0].phase_y = IMR_POINT.phase_y; -+ priv->imr_data[0].value = IMR_POINT.value; -+ priv->imr_data[0].iqcap = IMR_POINT.iqcap; -+ break; -+ case 1: -+ priv->imr_data[1].gain_x = IMR_POINT.gain_x; -+ priv->imr_data[1].phase_y = IMR_POINT.phase_y; -+ priv->imr_data[1].value = IMR_POINT.value; -+ priv->imr_data[1].iqcap = IMR_POINT.iqcap; -+ break; -+ case 2: -+ priv->imr_data[2].gain_x = IMR_POINT.gain_x; -+ priv->imr_data[2].phase_y = IMR_POINT.phase_y; -+ priv->imr_data[2].value = IMR_POINT.value; -+ priv->imr_data[2].iqcap = IMR_POINT.iqcap; -+ break; -+ case 3: -+ priv->imr_data[3].gain_x = IMR_POINT.gain_x; -+ priv->imr_data[3].phase_y = IMR_POINT.phase_y; -+ priv->imr_data[3].value = IMR_POINT.value; -+ priv->imr_data[3].iqcap = IMR_POINT.iqcap; -+ break; -+ case 4: -+ priv->imr_data[4].gain_x = IMR_POINT.gain_x; -+ priv->imr_data[4].phase_y = IMR_POINT.phase_y; -+ priv->imr_data[4].value = IMR_POINT.value; -+ priv->imr_data[4].iqcap = IMR_POINT.iqcap; -+ break; -+ default: -+ priv->imr_data[4].gain_x = IMR_POINT.gain_x; -+ priv->imr_data[4].phase_y = IMR_POINT.phase_y; -+ priv->imr_data[4].value = IMR_POINT.value; -+ priv->imr_data[4].iqcap = IMR_POINT.iqcap; -+ break; -+ } -+ return ret; -+} -+ -+ -+ -+#if 0 -+static int R848_GPO( struct r848_priv *priv,R848_GPO_Type R848_GPO_Conrl) -+{ -+ if(R848_GPO_Conrl == HI_SIG) // R23[0] -+ priv->regs[15] |= 0x01; //high -+ else -+ priv->regs[15] &= 0xFE; //low -+ return r848_wr(priv, 0x17, priv->regs[15]); -+} -+#endif -+ -+ -+u8 R848_Filt_Cal_ADC( struct r848_priv *priv,u32 IF_Freq, u8 R848_BW, u8 FilCal_Gap) -+{ -+ int ret; -+ u8 u1FilterCodeResult = 0; -+ u8 u1FilterCode = 0; -+ u32 u4RingFreq = 72000; -+ u8 u1FilterCalValue = 0; -+ u8 u1FilterCalValuePre = 0; -+ u8 initial_cnt = 0; -+ u8 i = 0; -+ u8 R848_Bandwidth = 0x00; -+ u8 VGA_Count = 0; -+ u8 VGA_Read = 0; -+ -+ R848_Standard_Type R848_Standard; -+ R848_Standard=R848_ATSC; //no set R848_DVB_S -+ -+ //Write initial reg before doing calibration -+ if(r848_init_regs(priv,R848_Standard) != RT_Success) -+ return RT_Fail; -+ -+ if(R848_Cal_Prepare(priv,R848_LPF_CAL) != RT_Success) -+ return RT_Fail; -+ -+ -+ -+ // R848:R39[5:2] -+ priv->regs[31] = (priv->regs[31] & 0xC3) | 0x2C; -+ ret = r848_wr(priv, 0x27, priv->regs[31]); -+ -+ // R848_I2C.RegAddr = 0x12; //R848:R18[4] -+ priv->regs[10] = (priv->regs[10] & 0xEF) | 0x00; -+ ret |= r848_wr(priv, 0x12, priv->regs[10]); -+ -+ // R848_I2C.RegAddr = 0x25; // R848:R37[7] -+ priv->regs[29] = (priv->regs[29] & 0x7F) | 0x00; -+ ret |= r848_wr(priv, 0x25, priv->regs[29]); -+ -+ // R848_I2C.RegAddr = 0x27; // R848:R39[7:6] -+ priv->regs[31] = (priv->regs[31] & 0x3F) | 0x80; -+ ret |= r848_wr(priv, 0x27, priv->regs[31]); -+ -+ // R848_I2C.RegAddr = 0x21; // R848:R33[7:0] -+ priv->regs[25] = (priv->regs[25] & 0x00) | 0x8B; //out div=8, RF poly=low band, power=min_lp -+ ret |= r848_wr(priv, 0x21, priv->regs[25]); -+ -+ //Must do before PLL() -+ if(r848_set_mux(priv,u4RingFreq + IF_Freq, u4RingFreq, R848_STD_SIZE) != RT_Success) //FilCal MUX (LO_Freq, RF_Freq) -+ return RT_Fail; -+ -+ //Set PLL -+ if(r848_set_pll(priv,(u4RingFreq + IF_Freq), R848_STD_SIZE) != RT_Success) //FilCal PLL -+ return RT_Fail; -+ -+ //-----below must set after R848_MUX()-------// -+ //Set LNA TF for RF=72MHz. no use -+ -+ // R848_I2C.RegAddr = 0x08; // R848:R8[6:0] -+ priv->regs[0] = (priv->regs[0] & 0x80) | 0x00; -+ ret |= r848_wr(priv, 0x08, priv->regs[0]); -+ -+ //Adc=on set 0; -+ //R848_I2C.RegAddr = 0x0F; // R848:R15[7] -+ priv->regs[7] = (priv->regs[7] & 0x7F); -+ ret |= r848_wr(priv, 0x0f, priv->regs[7]); -+ -+ -+ -+ //pwd_vga vga power on set 0; -+ //R848_I2C.RegAddr = 0x12; // R848:R18[7] -+ priv->regs[10] = (priv->regs[10] & 0x7F); -+ ret |= r848_wr(priv, 0x12, priv->regs[10]); -+ -+ -+ //vga6db normal set 0; -+ //R848_I2C.RegAddr = 0x0B; // R848:R11[3] -+ priv->regs[3] = (priv->regs[3] & 0xF7); -+ ret |= r848_wr(priv, 0x0b, priv->regs[3]); -+ -+ //Vga Gain = -12dB -+ //R848_I2C.RegAddr = 0x14; // R848:R20[3:0] -+ priv->regs[12] = (priv->regs[12] & 0xF0); -+ ret |= r848_wr(priv, 0x14, priv->regs[12]); -+ -+ // vcomp = 0 -+ //R848_I2C.RegAddr = 0x26; // R848:R38[6:5] -+ priv->regs[30] = (priv->regs[30] & 0x9F); -+ ret |= r848_wr(priv, 0x26, priv->regs[30]); -+ -+ //Set BW=8M, HPF corner narrowest; 1.7M disable -+ //R848_I2C.RegAddr = 0x13; // R848:R19[7:0] -+ priv->regs[11] = (priv->regs[11] & 0x00); -+ ret |= r848_wr(priv, 0x13, priv->regs[11]); -+ -+ //------- increase VGA power to let ADC read value significant ---------// -+ -+ //R848_I2C.RegAddr = 0x12; // R848:R18[3:0] -+ priv->regs[10] = (priv->regs[10] & 0xF0) | 0; //filter code=0 -+ ret |= r848_wr(priv, 0x12, priv->regs[10]); -+ if (ret) -+ return ret; -+ -+ -+ for (VGA_Count = 0; VGA_Count < 16; VGA_Count++) { -+ //R848_I2C.RegAddr = 0x14; // R848:R20[3:0] -+ ret = r848_wr(priv, 0x14, (priv->regs[12] & 0xF0) + VGA_Count); -+ msleep(10); -+ ret |= r848_get_imr(priv,&VGA_Read); -+ if (ret) -+ return ret; -+ if (VGA_Read > 40) -+ break; -+ } -+ -+ //------- Try suitable BW --------// -+ -+ if(R848_BW==0x60) //6M -+ initial_cnt = 1; //try 7M first -+ else -+ initial_cnt = 0; //try 8M first -+ -+ for(i=initial_cnt; i<3; i++) -+ { -+ if(i==0) -+ R848_Bandwidth = 0x00; //8M -+ else if(i==1) -+ R848_Bandwidth = 0x40; //7M -+ else -+ R848_Bandwidth = 0x60; //6M -+ -+ //R848_I2C.RegAddr = 0x13; // R848:R19[7:0] -+ priv->regs[11] = (priv->regs[11] & 0x00) | R848_Bandwidth; -+ ret |= r848_wr(priv, 0x13, priv->regs[11]); -+ -+ // read code 0 -+ //R848_I2C.RegAddr = 0x12; // R848:R18[3:0] -+ priv->regs[10] = (priv->regs[10] & 0xF0) | 0; //code 0 -+ ret |= r848_wr(priv, 0x12, priv->regs[10]); -+ -+ msleep(10); //delay ms -+ -+ if(r848_get_imr(priv,&u1FilterCalValuePre) != RT_Success) -+ return RT_Fail; -+ -+ //read code 13 -+ //R848_I2C.RegAddr = 0x12; // R848:R18[3:0] -+ priv->regs[10] = (priv->regs[10] & 0xF0) | 13; //code 13 -+ ret |= r848_wr(priv, 0x12, priv->regs[10]); -+ -+ msleep(10); //delay ms -+ -+ if(r848_get_imr(priv,&u1FilterCalValue) != RT_Success) -+ return RT_Fail; -+ -+ if(u1FilterCalValuePre > (u1FilterCalValue+8)) //suitable BW found -+ break; -+ } -+ -+ //-------- Try LPF filter code ---------// -+ u1FilterCalValuePre = 0; -+ for(u1FilterCode=0; u1FilterCode<16; u1FilterCode++) -+ { -+ //R848_I2C.RegAddr = 0x12; // R848:R18[3:0] -+ priv->regs[10] = (priv->regs[10] & 0xF0) | u1FilterCode; -+ ret |= r848_wr(priv, 0x12, priv->regs[10]); -+ -+ msleep(10); //delay ms -+ -+ if(r848_get_imr(priv,&u1FilterCalValue) != RT_Success) -+ return RT_Fail; -+ -+ if(u1FilterCode==0) -+ u1FilterCalValuePre = u1FilterCalValue; -+ -+ if((u1FilterCalValue+FilCal_Gap) < u1FilterCalValuePre) -+ { -+ u1FilterCodeResult = u1FilterCode; -+ break; -+ } -+ -+ } -+ -+ if(u1FilterCode==16) -+ u1FilterCodeResult = 15; -+ -+ return u1FilterCodeResult; -+ -+} -+ -+ -+R848_ErrCode R848_DVBS_Setting(struct r848_priv *priv) -+{ -+ int ret; -+ u32 LO_KHz; -+ u8 fine_tune,Coarse_tune; -+ u32 Coarse; -+ -+ //if (priv->standard != R848_DVB_S) -+ { -+ priv->standard = R848_DVB_S; -+ if(r848_init_regs(priv,priv->standard)) -+ return RT_Fail; -+ } -+ -+ LO_KHz = priv->freq; -+ -+ if (r848_set_pll(priv, LO_KHz, priv->standard)) -+ return RT_Fail; -+ -+ //VTH/VTL -+ if ((priv->freq >= 1200000) && (priv->freq <= 1750000)) { -+ priv->regs[23]=(priv->regs[23] & 0x00) | 0x93; //R848:R31[7:0 1.24/0.64 -+ } else { -+ priv->regs[23]=(priv->regs[23] & 0x00) | 0x83; //R848:R31[7:0] 1.14/0.64 -+ } -+ ret = r848_wr(priv, 0x1f, priv->regs[23]); -+ -+ -+ -+ if(priv->freq >= 2000000) -+ { -+ priv->regs[38]=(priv->regs[38] & 0xCF) | 0x20; //R848:R46[4:5] -+ ret |= r848_wr(priv, 0x2e, priv->regs[38]); -+ } -+ -+ -+ if((priv->freq >= 1600000) && (priv->freq <= 1950000)) { -+ priv->regs[35] |= 0x20; //LNA Mode with att //R710 R2[6] R848:R43[5] -+ //priv->regs[36] |= 0x04; //Mixer Buf -3dB //R710 R8[7] R848:R44[2] -+ } else { -+ priv->regs[35] &= 0xDF; //LNA Mode no att -+ //priv->regs[36] &= 0xFB; //Mixer Buf off -+ } -+ ret |= r848_wr(priv, 0x2b, priv->regs[35]); -+ //ret |= r848_wr(priv, 0x2c, priv->regs[36]); //TEST -+ -+ -+ //Output Signal Mode ( O is diff ; 1 is single ) -+ if(priv->output_mode != SINGLEOUT) { -+ priv->regs[35] &=0x7F; -+ } else { -+ priv->regs[35] |=0x80; // R848:R43[7] -+ } -+ ret |= r848_wr(priv, 0x2b, priv->regs[35]); -+ -+ -+ //AGC Type //R13[4] Negative=0 ; Positive=1; -+ if(priv->agc_mode != AGC_POSITIVE) { -+ priv->regs[37] &= 0xF7; -+ } else { -+ priv->regs[37] |= 0x08; // R848:R45[3] -+ } -+ ret |= r848_wr(priv, 0x2d, priv->regs[37]); -+ -+ -+ if (priv->bw > 67400) { -+ fine_tune=1; -+ Coarse = ((priv->bw - 67400) / 1600) + 31; -+ if (((priv->bw - 67400) % 1600) > 0) -+ Coarse += 1; -+ } else if ((priv->bw > 62360) && (priv->bw <= 67400)) { -+ Coarse=31; -+ fine_tune=1; -+ } else if ((priv->bw > 38000) && (priv->bw <= 62360)) { -+ fine_tune=1; -+ Coarse = ((priv->bw - 38000) / 1740) + 16; -+ if (((priv->bw - 38000) % 1740) > 0) -+ Coarse+=1; -+ } else if (priv->bw <= 5000) { -+ Coarse = 0; -+ fine_tune = 0; -+ } else if ((priv->bw > 5000) && (priv->bw <= 8000)) { -+ Coarse = 0; -+ fine_tune = 1; -+ } else if ((priv->bw > 8000) && (priv->bw <= 10000)) { -+ Coarse = 1; -+ fine_tune = 1; -+ } else if ((priv->bw > 10000) && (priv->bw <= 12000)) { -+ Coarse=2; -+ fine_tune=1; -+ } else if((priv->bw>12000) && (priv->bw<=14200)) { -+ Coarse=3; -+ fine_tune=1; -+ } else if((priv->bw>14200) && (priv->bw<=16000)) { -+ Coarse=4; -+ fine_tune=1; -+ } else if((priv->bw>16000) && (priv->bw<=17800)) { -+ Coarse=5; -+ fine_tune=0; -+ } else if((priv->bw>17800) && (priv->bw<=18600)) { -+ Coarse=5; -+ fine_tune=1; -+ } else if((priv->bw>18600) && (priv->bw<=20200)) { -+ Coarse=6; -+ fine_tune=1; -+ } else if((priv->bw>20200) && (priv->bw<=22400)) { -+ Coarse=7; -+ fine_tune=1; -+ } else if((priv->bw>22400) && (priv->bw<=24600)) { -+ Coarse=9; -+ fine_tune=1; -+ } else if((priv->bw>24600) && (priv->bw<=25400)) { -+ Coarse=10; -+ fine_tune=0; -+ } else if((priv->bw>25400) && (priv->bw<=26000)) { -+ Coarse=10; -+ fine_tune=1; -+ } else if((priv->bw>26000) && (priv->bw<=27200)) { -+ Coarse=11; -+ fine_tune=0; -+ } else if((priv->bw>27200) && (priv->bw<=27800)) { -+ Coarse=11; -+ fine_tune=1; -+ } else if((priv->bw>27800) && (priv->bw<=30200)) { -+ Coarse=12; -+ fine_tune=1; -+ } else if((priv->bw>30200) && (priv->bw<=32600)) { -+ Coarse=13; -+ fine_tune=1; -+ } else if((priv->bw>32600) && (priv->bw<=33800)) { -+ Coarse=14; -+ fine_tune=1; -+ } else if((priv->bw>33800) && (priv->bw<=36800)) { -+ Coarse=15; -+ fine_tune=1; -+ } else if((priv->bw>36800) && (priv->bw<=38000)) { -+ Coarse=16; -+ fine_tune=1; -+ } -+ -+ Coarse_tune = (unsigned char) Coarse; -+ -+ priv->regs[39] &= 0x00; //47-8=39 -+ priv->regs[39] = ((priv->regs[39] | ( fine_tune<< 6 ) ) | ( Coarse_tune)); -+ ret |= r848_wr(priv, 0x2f, priv->regs[39]); -+ -+ // Set GPO Low -+ // R848:R23[4:2] -+ priv->regs[15] = (priv->regs[15] & 0xFE); -+ ret |= r848_wr(priv, 0x17, priv->regs[15]); -+ -+ return ret; -+} -+ -+ -+ -+ -+R848_Sys_Info_Type R848_Sys_Sel( struct r848_priv *priv,R848_Standard_Type R848_Standard) -+{ -+ R848_Sys_Info_Type R848_Sys_Info; -+ -+ switch (R848_Standard) -+ { -+ case R848_DVB_T_6M: -+ case R848_DVB_T2_6M: -+ R848_Sys_Info.IF_KHz=4570; //IF -+ R848_Sys_Info.BW=0x40; //BW=7M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=7450; //CAL IF -+ R848_Sys_Info.HPF_COR=0x05; //R19[3:0]=5 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x03; //R38[1:0]=11, buf 8 -+ break; -+ -+ -+ -+ case R848_DVB_T_7M: -+ case R848_DVB_T2_7M: -+ R848_Sys_Info.IF_KHz=4570; //IF -+ R848_Sys_Info.BW=0x40; //BW=7M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=7750; //CAL IF -+ R848_Sys_Info.HPF_COR=0x08; //R19[3:0]=8 (1.45M) -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x03; //R38[1:0]=11, buf 8 -+ break; -+ -+ case R848_DVB_T_8M: -+ case R848_DVB_T2_8M: -+ R848_Sys_Info.IF_KHz=4570; //IF -+ R848_Sys_Info.BW=0x00; //BW=8M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=8130; //CAL IF -+ R848_Sys_Info.HPF_COR=0x09; //R19[3:0]=9 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x03; //R38[1:0]=11, buf 8 -+ break; -+ -+ case R848_DVB_T2_1_7M: -+ R848_Sys_Info.IF_KHz=1900; -+ R848_Sys_Info.BW=0x40; //BW=7M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=7800; //CAL IF -+ R848_Sys_Info.HPF_COR=0x08; //R19[3:0]=8 -+ R848_Sys_Info.FILT_EXT_ENA=0x00; //R19[4]=0, ext disable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x00; //R38[1:0]=0, lna=max-1 -+ break; -+ -+ case R848_DVB_T2_10M: -+ R848_Sys_Info.IF_KHz=5600; -+ R848_Sys_Info.BW=0x00; //BW=8M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=10800; //CAL IF -+ R848_Sys_Info.HPF_COR=0x0C; //R19[3:0]=12 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x00; //R38[1:0]=0, lna=max-1 -+ break; -+ -+ case R848_DVB_C_8M: -+ R848_Sys_Info.IF_KHz=5070; -+ R848_Sys_Info.BW=0x00; //BW=8M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=9000; //CAL IF //9150 -+ R848_Sys_Info.HPF_COR=0x0A; //R19[3:0]=10 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x02; //R38[1:0]=10, lna=max-1 & Buf 4 -+ break; -+ -+ case R848_DVB_C_6M: -+ R848_Sys_Info.IF_KHz=5070; -+ R848_Sys_Info.BW=0x40; //BW=7M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=8025; //CAL IF -+ R848_Sys_Info.HPF_COR=0x03; //R19[3:0]=3 //3 -+ R848_Sys_Info.FILT_EXT_ENA=0x00; //R19[4]=0, ext disable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x00; //R38[1:0]=0, lna=max-1 -+ break; -+ -+ case R848_J83B: -+ R848_Sys_Info.IF_KHz=5070; -+ R848_Sys_Info.BW=0x40; //BW=7M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=8025; //CAL IF -+ R848_Sys_Info.HPF_COR=0x03; //R19[3:0]=3 //3 -+ R848_Sys_Info.FILT_EXT_ENA=0x00; //R19[4]=0, ext disable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x00; //R38[1:0]=0, lna=max-1 -+ break; -+ -+ case R848_ISDB_T: -+ R848_Sys_Info.IF_KHz=4063; -+ R848_Sys_Info.BW=0x40; //BW=7M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=7000; //CAL IF //7200 -+ R848_Sys_Info.HPF_COR=0x08; //R19[3:0]=8 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x03; //R38[1:0]=11, buf 8 -+ break; -+ case R848_ISDB_T_4570: -+ R848_Sys_Info.IF_KHz=4570; //IF -+ R848_Sys_Info.BW=0x40; //BW=7M -+ R848_Sys_Info.FILT_CAL_IF=7250; //CAL IF -+ R848_Sys_Info.HPF_COR=0x05; //R19[3:0]=5 (2.0M) -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x03; //R38[1:0]=11, buf 8, hpf+3 -+ break; -+ -+ case R848_DTMB_4570: -+ R848_Sys_Info.IF_KHz=4570; -+ R848_Sys_Info.BW=0x00; //BW=8M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=8330; //CAL IF //8130 -+ R848_Sys_Info.HPF_COR=0x0B; //R19[3:0]=11 -+ R848_Sys_Info.FILT_EXT_ENA=0x00; //R19[4]=0, ext disable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x00; //R38[1:0]=0, lna=max-1 -+ break; -+ -+ case R848_DTMB_6000: -+ R848_Sys_Info.IF_KHz=6000; -+ R848_Sys_Info.BW=0x00; //BW=8M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=9550; //CAL IF -+ R848_Sys_Info.HPF_COR=0x03; //R19[3:0]=3 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x02; //R38[1:0]=10, lna=max-1 & Buf 4 -+ break; -+ -+ case R848_DTMB_6M_BW_IF_5M: -+ R848_Sys_Info.IF_KHz=5000; -+ R848_Sys_Info.BW=0x40; //BW=7M -+ R848_Sys_Info.FILT_CAL_IF=7700; //CAL IF -+ R848_Sys_Info.HPF_COR=0x04; //R19[3:0]=4 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x00; //R38[1:0]=0, lna=max-1 & Buf 4, hpf+1 -+ break; -+ -+ case R848_DTMB_6M_BW_IF_4500: -+ R848_Sys_Info.IF_KHz=4500; -+ R848_Sys_Info.BW=0x40; //BW=7M -+ R848_Sys_Info.FILT_CAL_IF=7000; //CAL IF -+ R848_Sys_Info.HPF_COR=0x05; //R19[3:0]=5 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x02; //R38[1:0]=10, lna=max-1 & Buf 4, hpf+3 -+ break; -+ -+ case R848_ATSC: -+ R848_Sys_Info.IF_KHz=5070; -+ R848_Sys_Info.BW=0x40; //BW=7M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=7900; //CAL IF 20130621 Ryan Modify -+ R848_Sys_Info.HPF_COR=0x04; //R19[3:0]=4 -+ R848_Sys_Info.FILT_EXT_ENA=0x00; //R19[4]=0, ext disable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x00; //R38[1:0]=0, lna=max-1 -+ break; -+ -+ case R848_DVB_T_6M_IF_5M: -+ case R848_DVB_T2_6M_IF_5M: -+ R848_Sys_Info.IF_KHz=5000; //IF -+ R848_Sys_Info.BW=0x40; //BW=7M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=7800; //CAL IF -+ R848_Sys_Info.HPF_COR=0x04; //R19[3:0]=4 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x03; //R38[1:0]=11, buf 8 -+ break; -+ -+ case R848_DVB_T_7M_IF_5M: -+ case R848_DVB_T2_7M_IF_5M: -+ R848_Sys_Info.IF_KHz=5000; //IF -+ R848_Sys_Info.BW=0x00; //BW=8M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=8300; //CAL IF -+ R848_Sys_Info.HPF_COR=0x07; //R19[3:0]=7 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x03; //R38[1:0]=11, buf 8 -+ break; -+ -+ case R848_DVB_T_8M_IF_5M: -+ case R848_DVB_T2_8M_IF_5M: -+ R848_Sys_Info.IF_KHz=5000; //IF -+ R848_Sys_Info.BW=0x00; //BW=8M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=8500; //CAL IF -+ R848_Sys_Info.HPF_COR=0x08; //R19[3:0]=8 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x03; //R38[1:0]=11, buf 8 -+ break; -+ -+ case R848_DVB_T2_1_7M_IF_5M: -+ R848_Sys_Info.IF_KHz=5000; -+ R848_Sys_Info.BW=0x60; //BW=6M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=5900; //CAL IF -+ R848_Sys_Info.HPF_COR=0x01; //R19[3:0]=1 -+ R848_Sys_Info.FILT_EXT_ENA=0x00; //R19[4]=0, ext disable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x00; //R38[1:0]=0, lna=max-1 -+ break; -+ -+ case R848_DVB_C_8M_IF_5M: -+// case R848_DVB_C_CHINA_IF_5M: //RF>115MHz -+ R848_Sys_Info.IF_KHz=5000; -+ R848_Sys_Info.BW=0x00; //BW=8M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=9000; //CAL IF -+ R848_Sys_Info.HPF_COR=0x0A; //R19[3:0]=10 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x02; //R38[1:0]=10, lna=max-1 & Buf 4 -+ break; -+ -+ case R848_DVB_C_6M_IF_5M: -+ R848_Sys_Info.IF_KHz=5000; -+ R848_Sys_Info.BW=0x40; //BW=7M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=8100; //CAL IF -+ R848_Sys_Info.HPF_COR=0x04; //R19[3:0]=4 -+ R848_Sys_Info.FILT_EXT_ENA=0x00; //R19[4]=0, ext disable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x00; //R38[1:0]=0, lna=max-1 -+ break; -+ -+ case R848_J83B_IF_5M: -+ R848_Sys_Info.IF_KHz=5000; -+ R848_Sys_Info.BW=0x40; //BW=7M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=8025; //CAL IF -+ R848_Sys_Info.HPF_COR=0x03; //R19[3:0]=3 -+ R848_Sys_Info.FILT_EXT_ENA=0x00; //R19[4]=0, ext disable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x00; //R38[1:0]=0, lna=max-1 -+ break; -+ -+ case R848_ISDB_T_IF_5M: -+ R848_Sys_Info.IF_KHz=5000; -+ R848_Sys_Info.BW=0x40; //BW=7M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=7940; //CAL IF -+ R848_Sys_Info.HPF_COR=0x04; //R19[3:0]=4 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x03; //R38[1:0]=11, buf 8 -+ break; -+ -+ case R848_DTMB_IF_5M: -+ R848_Sys_Info.IF_KHz=5000; -+ R848_Sys_Info.BW=0x00; //BW=8M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=8650; //CAL IF -+ R848_Sys_Info.HPF_COR=0x09; //R19[3:0]=9 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x02; //R38[1:0]=0, lna=max-1 -+ break; -+ -+ case R848_ATSC_IF_5M: -+ R848_Sys_Info.IF_KHz=5000; -+ R848_Sys_Info.BW=0x40; //BW=7M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=7900; //CAL IF -+ R848_Sys_Info.HPF_COR=0x04; //R19[3:0]=4 -+ R848_Sys_Info.FILT_EXT_ENA=0x00; //R19[4]=0, ext disable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x00; //R38[1:0]=0, lna=max-1 -+ break; -+ -+ case R848_FM: -+ R848_Sys_Info.IF_KHz=2400; -+ R848_Sys_Info.BW=0x40; //BW=7M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=7200; //CAL IF -+ R848_Sys_Info.HPF_COR=0x02; //R19[3:0]=2 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x00; //R38[1:0]=0, lna=max-1 -+ break; -+ -+ default: //R848_DVB_T_8M -+ R848_Sys_Info.IF_KHz=4570; //IF -+ R848_Sys_Info.BW=0x00; //BW=8M R848:R19[6:5] -+ R848_Sys_Info.FILT_CAL_IF=8330; //CAL IF -+ R848_Sys_Info.HPF_COR=0x0B; //R19[3:0]=11 -+ R848_Sys_Info.FILT_EXT_ENA=0x10; //R19[4]=1, ext enable -+ R848_Sys_Info.FILT_EXT_WIDEST=0x00;//R38[2]=0, ext normal -+ R848_Sys_Info.FILT_EXT_POINT=0x00; //R38[1:0]=0, lna=max-1 -+ break; -+ -+ } -+ -+ //R848_Sys_Info.INDUC_BIAS = 0x01; //normal -+ //R848_Sys_Info.SWCAP_CLK = 0x01; //32k -+ R848_Sys_Info.SWCAP_CLK = 0x02; //8k //AGC 500Hz map to 8k R26[1:0] -+ R848_Sys_Info.NA_PWR_DET = 0x00; //on R38[7] -+ -+ R848_Sys_Info.TF_CUR = 0x40; //low R11[6]=1 -+ R848_Sys_Info.SWBUF_CUR = 0x04; //low R12[2]=1 -+ -+ -+ -+/* switch(R848_Standard) -+ { -+ case R848_DVB_T2_6M: -+ case R848_DVB_T2_7M: -+ case R848_DVB_T2_8M: -+ case R848_DVB_T2_1_7M: -+ case R848_DVB_T2_10M: -+ case R848_DVB_T2_6M_IF_5M: -+ case R848_DVB_T2_7M_IF_5M: -+ case R848_DVB_T2_8M_IF_5M: -+ case R848_DVB_T2_1_7M_IF_5M: -+ R848_Sys_Info.AGC_CLK = 0x1C; //250Hz R26[4:2] -+ break; -+ default: -+ R848_Sys_Info.AGC_CLK = 0x00; //1k R26[4:2] -+ break; -+ }*/ -+ -+ //Filter 3dB -+ switch(R848_Standard) -+ { -+ case R848_DVB_C_8M_IF_5M: -+ R848_Sys_Info.FILT_3DB = 0x08; // ON R38[3] -+ break; -+ default: -+ R848_Sys_Info.FILT_3DB = 0x00; // OFF R38[3] -+ break; -+ } -+ -+ R848_Sys_Info.FILT_COMP = 0x20; -+ R848_Sys_Info.FILT_CUR = 0x00; //highest R18[6:5] -+ -+ -+ //BW 1.7M -+ if((R848_Standard==R848_DVB_T2_1_7M) || (R848_Standard==R848_FM)) -+ R848_Sys_Info.V17M = 0x80; //enable, R19[7] -+ else -+ R848_Sys_Info.V17M = 0x00; //disable, (include DVBT2 1.7M IF=5MHz) R19[7] -+ -+ //TF Type select -+ switch(R848_Standard) -+ { -+ case R848_DTMB_4570: -+ case R848_DTMB_6000: -+ case R848_DTMB_6M_BW_IF_5M: -+ case R848_DTMB_6M_BW_IF_4500: -+ case R848_DTMB_IF_5M: -+ if(priv->cfg->R848_DetectTfType == R848_UL_USING_BEAD ) -+ { -+ priv->cfg->R848_SetTfType = R848_TF_82N_BEAD; -+ } -+ else -+ { -+ priv->cfg->R848_SetTfType = R848_TF_82N_270N; -+ } -+ break; -+ -+ default: -+ if(priv->cfg->R848_DetectTfType == R848_UL_USING_BEAD) -+ { -+ priv->cfg->R848_SetTfType = R848_TF_82N_BEAD; -+ } -+ else -+ { -+ priv->cfg->R848_SetTfType = R848_TF_82N_270N; -+ } -+ break; -+ } -+ -+ return R848_Sys_Info; -+} -+ -+ -+ -+R848_SysFreq_Info_Type R848_SysFreq_Sel(struct r848_priv *priv, R848_Standard_Type R848_Standard, u32 RF_freq) -+{ -+ R848_SysFreq_Info_Type R848_SysFreq_Info; -+ -+ switch (R848_Standard) { -+ case R848_DVB_T_6M: -+ case R848_DVB_T_7M: -+ case R848_DVB_T_8M: -+ case R848_DVB_T_6M_IF_5M: -+ case R848_DVB_T_7M_IF_5M: -+ case R848_DVB_T_8M_IF_5M: -+ case R848_DVB_T2_6M: -+ case R848_DVB_T2_7M: -+ case R848_DVB_T2_8M: -+ case R848_DVB_T2_1_7M: -+ case R848_DVB_T2_10M: -+ case R848_DVB_T2_6M_IF_5M: -+ case R848_DVB_T2_7M_IF_5M: -+ case R848_DVB_T2_8M_IF_5M: -+ case R848_DVB_T2_1_7M_IF_5M: -+ if((RF_freq>=300000)&&(RF_freq<=472000)) { -+ R848_SysFreq_Info.LNA_VTH_L=0xA4; // LNA VTH/L=1.34/0.74 (R31=0xA4) -+ R848_SysFreq_Info.MIXER_TOP=0x05; // MIXER TOP=10 (R36[3:0]=4'b0101) -+ R848_SysFreq_Info.MIXER_VTH_L=0x95; // MIXER VTH/L=1.24/0.84 (R32=0x95) -+ R848_SysFreq_Info.NRB_TOP=0xC0; // Nrb TOP=3 (R36[7:4]=4'b1100) -+ } else if((RF_freq>=184000) && (RF_freq<=299000)) { -+ R848_SysFreq_Info.LNA_VTH_L=0xA5; // LNA VTH/L=1.34/0.84 (R31=0xA5) -+ R848_SysFreq_Info.MIXER_TOP=0x04; // MIXER TOP=11 (R36[3:0]=4'b0101) -+ R848_SysFreq_Info.MIXER_VTH_L=0xA6; // MIXER VTH/L=1.34/0.94 (R32=0xA6) -+ R848_SysFreq_Info.NRB_TOP=0x70; // Nrb TOP=8 (R36[7:4]=4'b1100) -+ } else { -+ R848_SysFreq_Info.LNA_VTH_L=0xA5; // LNA VTH/L=1.34/0.84 (R31=0xA5) -+ R848_SysFreq_Info.MIXER_TOP=0x05; // MIXER TOP=10 (R36[3:0]=4'b0101) -+ R848_SysFreq_Info.MIXER_VTH_L=0x95; // MIXER VTH/L=1.24/0.84 (R32=0x95) -+ R848_SysFreq_Info.NRB_TOP=0xC0; // Nrb TOP=3 (R36[7:4]=4'b1100) -+ } -+ R848_SysFreq_Info.LNA_TOP=0x03; // LNA TOP=4 (R35[2:0]=3'b011) -+ R848_SysFreq_Info.RF_TOP=0x40; // RF TOP=5 (R34[7:5]=3'b010) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ break; -+ -+ case R848_DVB_C_8M: -+ case R848_DVB_C_6M: -+ case R848_J83B: -+ case R848_DVB_C_8M_IF_5M: -+ case R848_DVB_C_6M_IF_5M: -+ case R848_J83B_IF_5M: -+ if(RF_freq<165000) { -+ R848_SysFreq_Info.LNA_TOP=0x02; // LNA TOP=5 (R35[2:0]=3'b010) -+ R848_SysFreq_Info.LNA_VTH_L=0x94; // LNA VTH/L=1.24/0.74 (R31=0x94) -+ R848_SysFreq_Info.RF_TOP=0x80; // RF TOP=3 (R34[7:5]=3'b100) -+ R848_SysFreq_Info.NRB_TOP=0x90; // Nrb TOP=6 (R36[7:4]=4'b1001) //R848:R36[7:4] -+ } else if((RF_freq>=165000) && (RF_freq<=299000)) { -+ R848_SysFreq_Info.LNA_TOP=0x03; // LNA TOP=4 (R35[2:0]=3'b011) -+ R848_SysFreq_Info.LNA_VTH_L=0x94; // LNA VTH/L=1.24/0.74 (R31=0x94) -+ R848_SysFreq_Info.RF_TOP=0x80; // RF TOP=3 (R34[7:5]=3'b100) -+ R848_SysFreq_Info.NRB_TOP=0x90; // Nrb TOP=6 (R36[7:4]=4'b1001) -+ } else if((RF_freq>299000) && (RF_freq<=345000)) { -+ R848_SysFreq_Info.LNA_TOP=0x03; // LNA TOP=4 (R35[2:0]=3'b011) -+ R848_SysFreq_Info.LNA_VTH_L=0xA4; // LNA VTH/L=1.34/0.74 (R31=0xA4) -+ R848_SysFreq_Info.RF_TOP=0x80; // RF TOP=3 (R34[7:5]=3'b100) -+ R848_SysFreq_Info.NRB_TOP=0x90; // Nrb TOP=6 (R36[7:4]=4'b1001) -+ } else if((RF_freq>345000) && (RF_freq<=472000)) { -+ R848_SysFreq_Info.LNA_TOP=0x04; // LNA TOP=3 (R35[2:0]=3'b100) -+ R848_SysFreq_Info.LNA_VTH_L=0x93; // LNA VTH/L=1.24/0.64 (R31=0x93) -+ R848_SysFreq_Info.RF_TOP=0xA0; // RF TOP=2 (R34[7:5]=3'b101) -+ R848_SysFreq_Info.NRB_TOP=0x20; // Nrb TOP=13 (R36[7:4]=4'b0010) -+ } else { -+ R848_SysFreq_Info.LNA_TOP=0x04; // LNA TOP=3 (R35[2:0]=3'b100) -+ R848_SysFreq_Info.LNA_VTH_L=0x83; // LNA VTH/L=1.14/0.64 (R31=0x83) -+ R848_SysFreq_Info.RF_TOP=0xA0; // RF TOP=2 (R34[7:5]=3'b101) -+ R848_SysFreq_Info.NRB_TOP=0x20; // Nrb TOP=13 (R36[7:4]=4'b0010) -+ } -+ R848_SysFreq_Info.MIXER_TOP=0x05; // MIXER TOP=10 (R36[3:0]=4'b0100) -+ R848_SysFreq_Info.MIXER_VTH_L=0x95; // MIXER VTH/L=1.24/0.84 (R32=0x95) -+ break; -+ -+ case R848_ISDB_T: -+ case R848_ISDB_T_4570: -+ case R848_ISDB_T_IF_5M: -+ if((RF_freq>=300000)&&(RF_freq<=472000)) { -+ R848_SysFreq_Info.LNA_VTH_L=0xA4; // LNA VTH/L=1.34/0.74 (R31=0xA4) -+ } else { -+ R848_SysFreq_Info.LNA_VTH_L=0xA5; // LNA VTH/L=1.34/0.84 (R31=0xA5) -+ } -+ R848_SysFreq_Info.LNA_TOP=0x03; // LNA TOP=4 (R35[2:0]=3'b011) -+ R848_SysFreq_Info.MIXER_TOP=0x05; // MIXER TOP=10 (R36[3:0]=4'b0101) -+ R848_SysFreq_Info.MIXER_VTH_L=0x95; // MIXER VTH/L=1.24/0.84 (R32=0x95) -+ R848_SysFreq_Info.RF_TOP=0x60; // RF TOP=4 (R34[7:5]=3'b011) -+ //R848_SysFreq_Info.NRB_TOP=0x20; // Nrb TOP=13 (R36[7:4]=4'b0010) -+ R848_SysFreq_Info.NRB_TOP=0xB0; // Nrb TOP=4 (R36[7:4]=4'b1011) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ break; -+ case R848_DTMB_4570: -+ case R848_DTMB_6000: -+ case R848_DTMB_6M_BW_IF_5M: -+ case R848_DTMB_6M_BW_IF_4500: -+ case R848_DTMB_IF_5M: -+ if((RF_freq>=300000)&&(RF_freq<=472000)) { -+ R848_SysFreq_Info.LNA_VTH_L=0xA4; // LNA VTH/L=1.34/0.74 (R31=0xA4) -+ } else { -+ R848_SysFreq_Info.LNA_VTH_L=0xA5; // LNA VTH/L=1.34/0.84 (R31=0xA5) -+ } -+ R848_SysFreq_Info.LNA_TOP=0x03; // LNA TOP=4 (R35[2:0]=3'b011) -+ R848_SysFreq_Info.MIXER_TOP=0x05; // MIXER TOP=10 (R36[3:0]=4'b0100) -+ R848_SysFreq_Info.MIXER_VTH_L=0x95; // MIXER VTH/L=1.24/0.84 (R32=0x95) -+ R848_SysFreq_Info.RF_TOP=0x60; // RF TOP=4 (R34[7:5]=3'b011) -+ R848_SysFreq_Info.NRB_TOP=0xA0; // Nrb TOP=5 (R36[7:4]=4'b1010) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ break; -+ -+ case R848_ATSC: -+ case R848_ATSC_IF_5M: -+ if(priv->cfg->R848_DetectTfType==R848_UL_USING_BEAD) { -+ if (RF_freq < 88000) { -+ R848_SysFreq_Info.LNA_TOP=0x03; // LNA TOP=4 (R35[2:0]=3'b011) -+ R848_SysFreq_Info.LNA_VTH_L=0xA5; // LNA VTH/L=1.34/0.84 (R31=0xA5) -+ R848_SysFreq_Info.RF_TOP=0xC0; // RF TOP=1 (R34[7:5]=3'b110) -+ R848_SysFreq_Info.NRB_TOP=0x30; // Nrb TOP=12 (R36[7:4]=4'b0011) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ } else if((RF_freq>=88000) && (RF_freq<104000)) { -+ R848_SysFreq_Info.LNA_TOP=0x02; // LNA TOP=5 (R35[2:0]=3'b010) -+ R848_SysFreq_Info.LNA_VTH_L=0xA5; // LNA VTH/L=1.34/0.84 (R31=0xA5) -+ R848_SysFreq_Info.RF_TOP=0xA0; // RF TOP=2 (R34[7:5]=3'b101) -+ R848_SysFreq_Info.NRB_TOP=0x30; // Nrb TOP=12 (R36[7:4]=4'b0011) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ } else if((RF_freq>=104000) && (RF_freq<156000)) { -+ R848_SysFreq_Info.LNA_TOP=0x01; // LNA TOP=6 (R35[2:0]=3'b001) -+ R848_SysFreq_Info.LNA_VTH_L=0xA5; // LNA VTH/L=1.34/0.84 (R31=0xA5) -+ R848_SysFreq_Info.RF_TOP=0x60; // RF TOP=4 (R34[7:5]=3'b011) -+ R848_SysFreq_Info.NRB_TOP=0x30; // Nrb TOP=12 (R36[7:4]=4'b0011) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ } else if((RF_freq>=156000) && (RF_freq<464000)) { -+ R848_SysFreq_Info.LNA_TOP=0x01; // LNA TOP=6 (R35[2:0]=3'b001) -+ R848_SysFreq_Info.LNA_VTH_L=0xA5; // LNA VTH/L=1.34/0.84 (R31=0xA5) -+ R848_SysFreq_Info.RF_TOP=0x60; // RF TOP=4 (R34[7:5]=3'b011) -+ R848_SysFreq_Info.NRB_TOP=0x90; // Nrb TOP=6 (R36[7:4]=4'b1001) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ } else if((RF_freq>=464000) && (RF_freq<500000)) { -+ R848_SysFreq_Info.LNA_TOP=0x01; // LNA TOP=6 (R35[2:0]=3'b001) -+ R848_SysFreq_Info.LNA_VTH_L=0xB6; // LNA VTH/L=1.44/0.94 (R31=0xB6) -+ R848_SysFreq_Info.RF_TOP=0x60; // RF TOP=4 (R34[7:5]=3'b011) -+ R848_SysFreq_Info.NRB_TOP=0x90; // Nrb TOP=6 (R36[7:4]=4'b1001) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ } else { -+ R848_SysFreq_Info.LNA_TOP=0x01; // LNA TOP=6 (R35[2:0]=3'b001) -+ R848_SysFreq_Info.LNA_VTH_L=0x94; // LNA VTH/L=1.24/0.74 (R31=0x94) -+ R848_SysFreq_Info.RF_TOP=0x40; // RF TOP=5 (R34[7:5]=3'b010) -+ R848_SysFreq_Info.NRB_TOP=0x90; // Nrb TOP=6 (R36[7:4]=4'b1001) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ } -+ } else { //270n -+ if(RF_freq<88000) { -+ R848_SysFreq_Info.LNA_TOP=0x02; // LNA TOP=5 (R35[2:0]=3'b010) -+ R848_SysFreq_Info.LNA_VTH_L=0x94; // LNA VTH/L=1.24/0.74 (R31=0x94) -+ R848_SysFreq_Info.RF_TOP=0x80; // RF TOP=3 (R34[7:5]=3'b100) -+ R848_SysFreq_Info.NRB_TOP=0xC0; // Nrb TOP=3 (R36[7:4]=4'b1100) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ } else if((RF_freq>=88000) && (RF_freq<104000)) { -+ R848_SysFreq_Info.LNA_TOP=0x02; // LNA TOP=5 (R35[2:0]=3'b010) -+ R848_SysFreq_Info.LNA_VTH_L=0x94; // LNA VTH/L=1.24/0.74 (R31=0x94) -+ R848_SysFreq_Info.RF_TOP=0x60; // RF TOP=4 (R34[7:5]=3'b011) -+ R848_SysFreq_Info.NRB_TOP=0x90; // Nrb TOP=6 (R36[7:4]=4'b1001) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ } else if((RF_freq>=104000) && (RF_freq<248000)) { -+ R848_SysFreq_Info.LNA_TOP=0x01; // LNA TOP=6 (R35[2:0]=3'b001) -+ R848_SysFreq_Info.LNA_VTH_L=0x94; // LNA VTH/L=1.24/0.74 (R31=0x94) -+ R848_SysFreq_Info.RF_TOP=0x60; // RF TOP=4 (R34[7:5]=3'b011) -+ R848_SysFreq_Info.NRB_TOP=0x90; // Nrb TOP=6 (R36[7:4]=4'b1001) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ } else if((RF_freq>=248000) && (RF_freq<464000)) { -+ R848_SysFreq_Info.LNA_TOP=0x01; // LNA TOP=6 (R35[2:0]=3'b001) -+ R848_SysFreq_Info.LNA_VTH_L=0xA5; // LNA VTH/L=1.34/0.84 (R31=0xA5) -+ R848_SysFreq_Info.RF_TOP=0x60; // RF TOP=4 (R34[7:5]=3'b011) -+ R848_SysFreq_Info.NRB_TOP=0x90; // Nrb TOP=6 (R36[7:4]=4'b1001) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ } else if((RF_freq>=464000) && (RF_freq<500000)) { -+ R848_SysFreq_Info.LNA_TOP=0x01; // LNA TOP=6 (R35[2:0]=3'b001) -+ R848_SysFreq_Info.LNA_VTH_L=0xB6; // LNA VTH/L=1.44/0.94 (R31=0xB6) -+ R848_SysFreq_Info.RF_TOP=0x60; // RF TOP=4 (R34[7:5]=3'b011) -+ R848_SysFreq_Info.NRB_TOP=0x90; // Nrb TOP=6 (R36[7:4]=4'b1001) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ } else { -+ R848_SysFreq_Info.LNA_TOP=0x01; // LNA TOP=6 (R35[2:0]=3'b001) -+ R848_SysFreq_Info.LNA_VTH_L=0x94; // LNA VTH/L=1.24/0.74 (R31=0x94) -+ R848_SysFreq_Info.RF_TOP=0x40; // RF TOP=5 (R34[7:5]=3'b010) -+ R848_SysFreq_Info.NRB_TOP=0x90; // Nrb TOP=6 (R36[7:4]=4'b1001) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ } -+ } -+ R848_SysFreq_Info.MIXER_TOP=0x04; // MIXER TOP=11 (R36[3:0]=4'b0100) -+ R848_SysFreq_Info.MIXER_VTH_L=0xB7; // MIXER VTH/L=1.44/1.04 (R32=0xB7) -+ //R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ break; -+ case R848_FM: -+ if ((RF_freq>=300000) && (RF_freq<=472000)) { -+ R848_SysFreq_Info.LNA_VTH_L=0xA4; // LNA VTH/L=1.34/0.74 (R31=0xA4) -+ } else { -+ R848_SysFreq_Info.LNA_VTH_L=0xA5; // LNA VTH/L=1.34/0.84 (R31=0xA5) -+ } -+ R848_SysFreq_Info.LNA_TOP=0x03; // LNA TOP=4 (R35[2:0]=3'b011) -+ R848_SysFreq_Info.MIXER_TOP=0x05; // MIXER TOP=10 (R36[3:0]=4'b0100) -+ R848_SysFreq_Info.MIXER_VTH_L=0x95; // MIXER VTH/L=1.24/0.84 (R32=0x95) -+ R848_SysFreq_Info.RF_TOP=0x60; // RF TOP=4 (R34[7:5]=3'b011) -+ R848_SysFreq_Info.NRB_TOP=0x20; // Nrb TOP=13 (R36[7:4]=4'b0010) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ break; -+ default: //DVB-T 8M -+ if ((RF_freq >= 300000) && (RF_freq <= 472000)) { -+ R848_SysFreq_Info.LNA_VTH_L=0xA4; // LNA VTH/L=1.34/0.74 (R31=0xA4) -+ } else { -+ R848_SysFreq_Info.LNA_VTH_L=0xA5; // LNA VTH/L=1.34/0.84 (R31=0xA5) -+ } -+ R848_SysFreq_Info.LNA_TOP=0x03; // LNA TOP=4 (R35[2:0]=3'b011) -+ R848_SysFreq_Info.MIXER_TOP=0x05; // MIXER TOP=10 (R36[3:0]=4'b0100) -+ R848_SysFreq_Info.MIXER_VTH_L=0x95; // MIXER VTH/L=1.24/0.84 (R32=0x95) -+ R848_SysFreq_Info.RF_TOP=0x40; // RF TOP=5 (R34[7:5]=3'b010) -+ R848_SysFreq_Info.NRB_TOP=0x20; // Nrb TOP=13 (R36[7:4]=4'b0010) -+ R848_SysFreq_Info.NRB_BW=0xC0; // Nrb BW=lowest (R35[7:6]=2'b11) -+ break; -+ } -+ -+ R848_SysFreq_Info.RF_FAST_DISCHARGE = 0x00; //0 R848:R46[3:1]=3'b000 -+ R848_SysFreq_Info.RF_SLOW_DISCHARGE = 0x80; //4 R848:R22[7:5]=2'b100 -+ R848_SysFreq_Info.RFPD_PLUSE_ENA = 0x10; //1 R848:R38[4]=1 -+ -+ R848_SysFreq_Info.LNA_FAST_DISCHARGE = 0x0A; //10 R848:R43[4:0]=5'b01010 -+ R848_SysFreq_Info.LNA_SLOW_DISCHARGE = 0x00; //0 R848:R22[4:2]=3'b000 -+ R848_SysFreq_Info.LNAPD_PLUSE_ENA = 0x00 ; //0 R848:R17[7]=0 -+ -+ //AGC Clk Rate -+ R848_SysFreq_Info.AGC_CLK = 0x00; //1k R26[4:2] //default -+ -+ //TF LPF setting -+ switch (R848_Standard) { -+ case R848_DTMB_4570: -+ case R848_DTMB_6000: -+ case R848_DTMB_6M_BW_IF_5M: -+ case R848_DTMB_6M_BW_IF_4500: -+ case R848_DTMB_IF_5M: -+ R848_SysFreq_Info.BYP_LPF = 0x00; //bypass R12[6] -+ break; -+ case R848_DVB_T_6M: -+ case R848_DVB_T_7M: -+ case R848_DVB_T_8M: -+ case R848_DVB_T_6M_IF_5M: -+ case R848_DVB_T_7M_IF_5M: -+ case R848_DVB_T_8M_IF_5M: -+ case R848_DVB_T2_6M: -+ case R848_DVB_T2_7M: -+ case R848_DVB_T2_8M: -+ case R848_DVB_T2_1_7M: -+ case R848_DVB_T2_10M: -+ case R848_DVB_T2_6M_IF_5M: -+ case R848_DVB_T2_7M_IF_5M: -+ case R848_DVB_T2_8M_IF_5M: -+ case R848_DVB_T2_1_7M_IF_5M: -+ if (RF_freq >= 662000 && RF_freq <= 670000) { -+ R848_SysFreq_Info.RF_SLOW_DISCHARGE = 0x20; //1 R848:R22[7:5]=2'b001 -+ R848_SysFreq_Info.AGC_CLK = 0x18; //60Hz R26[4:2] -+ } else { -+ R848_SysFreq_Info.RF_SLOW_DISCHARGE = 0x80; //4 R848:R22[7:5]=2'b100 -+ R848_SysFreq_Info.AGC_CLK = 0x00; //1KHz R26[4:2] -+ switch(R848_Standard) { -+ case R848_DVB_T2_6M: -+ case R848_DVB_T2_7M: -+ case R848_DVB_T2_8M: -+ case R848_DVB_T2_1_7M: -+ case R848_DVB_T2_10M: -+ case R848_DVB_T2_6M_IF_5M: -+ case R848_DVB_T2_7M_IF_5M: -+ case R848_DVB_T2_8M_IF_5M: -+ case R848_DVB_T2_1_7M_IF_5M: -+ R848_SysFreq_Info.AGC_CLK = 0x1C; //250Hz R26[4:2] -+ break; -+ } -+ } -+ break; -+ default: //other standard -+ if(RF_freq<=236000) -+ R848_SysFreq_Info.BYP_LPF = 0x40; //low pass R12[6] -+ else -+ R848_SysFreq_Info.BYP_LPF = 0x00; //bypass R12[6] -+ break; -+ } -+ return R848_SysFreq_Info; -+} -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+#if 0 -+R848_ErrCode R848_RfGainMode( struct r848_priv *priv,R848_RF_Gain_TYPE R848_RfGainType) -+{ -+ int ret; -+ u8 buf[5]; -+ -+ u8 MixerGain = 0; -+ u8 RfGain = 0; -+ u8 LnaGain = 0; -+ -+ if(R848_RfGainType==RF_MANUAL) { -+ //LNA auto off -+ priv->regs[5] = priv->regs[5] | 0x80; // 848:13[7:0] -+ ret = r848_wr(priv, 0x0d, priv->regs[5]); -+ -+ //Mixer buffer off -+ priv->regs[26] = priv->regs[26] | 0x10; // 848:34[7:0] -+ ret |= r848_wr(priv, 0x22, priv->regs[26]); -+ -+ //Mixer auto off -+ priv->regs[7] = priv->regs[7] & 0xEF; //848:15[6:0] -+ ret |= r848_wr(priv, 0x0f, priv->regs[7]); -+ -+ ret = r848_rd(priv, buf, 5); -+ if (ret) -+ return ret; -+ -+ //MixerGain = (((buf[1] & 0x40) >> 6)<<3)+((buf[3] & 0xE0)>>5); //? -+ MixerGain = (buf[3] & 0x0F); //mixer // 848:3[4:0] -+ RfGain = ((buf[3] & 0xF0) >> 4); //rf // 848:3[4:0] -+ LnaGain = buf[4] & 0x1F; //lna // 848:4[4:0] -+ -+ //set LNA gain -+ priv->regs[5] = (priv->regs[5] & 0xE0) | LnaGain; // 848:13[7:0] -+ ret |= r848_wr(priv, 0x0d, priv->regs[5]); -+ -+ //set Mixer Buffer gain -+ priv->regs[26] = (priv->regs[26] & 0xF0) | RfGain; //848:34[7:0] -+ ret |= r848_wr(priv, 0x22, priv->regs[26]); -+ -+ //set Mixer gain -+ priv->regs[7] = (priv->regs[7] & 0xF0) | MixerGain; // 848:15[6:0] -+ ret |= r848_wr(priv, 0x0f, priv->regs[7]); -+ } else { -+ //LNA auto on -+ priv->regs[5] = priv->regs[5] & 0x7F; // 848:13[7:0] -+ ret = r848_wr(priv, 0x0d, priv->regs[5]); -+ -+ //Mixer buffer on -+ priv->regs[26] = priv->regs[26] & 0xEF; // 848:34[7:0] -+ ret |= r848_wr(priv, 0x22, priv->regs[26]); -+ -+ //Mixer auto on -+ priv->regs[7] = priv->regs[7] | 0x10; // 848:15[6:0] -+ ret |= r848_wr(priv, 0x0f, priv->regs[7]); -+ } -+ -+ return ret; -+} -+#endif -+ -+ -+static int R848_TF_Check(struct r848_priv *priv) -+{ -+ u32 RingVCO, RingFreq; -+ u8 divnum_ring; -+ u8 VGA_Count; -+ u8 VGA_Read; -+ int ret; -+ -+ if (R848_Xtal == 16000) { -+ divnum_ring = 11; -+ } else { //24M -+ divnum_ring = 2; -+ } -+ -+ RingVCO = (16 + divnum_ring) * 8 * R848_Xtal; -+ RingFreq = RingVCO / 48; -+ -+ if (R848_Cal_Prepare(priv, R848_TF_LNA_CAL)) -+ return RT_Fail; -+ -+ priv->regs[31] = (priv->regs[31] & 0x03) | 0x80 | (divnum_ring<<2); //pre div=6 & div_num -+ ret = r848_wr(priv, 0x27, priv->regs[31]); -+ -+ // Ring PLL PW on -+ priv->regs[18] = (priv->regs[18] & 0xEF); -+ ret |= r848_wr(priv, 0x12, priv->regs[18]); -+ -+ // NAT Det Sour : Mixer buf out -+ priv->regs[37] = (priv->regs[37] & 0x7F); -+ ret |= r848_wr(priv, 0x25, priv->regs[37]); -+ -+ // R848 R33[7:0] -+ priv->regs[25] = (priv->regs[25] & 0x00) | 0x8B; //out div=8, RF poly=low band, power=min_lp -+ if(RingVCO>=3200000) -+ priv->regs[25] = (priv->regs[25] & 0xDF); //vco_band=high, R25[5]=0 -+ else -+ priv->regs[25] = (priv->regs[25] | 0x20); //vco_band=low, R25[5]=1 -+ ret |= r848_wr(priv, 0x21, priv->regs[25]); -+ if (ret) -+ return ret; -+ -+ // Must do before PLL() -+ if (r848_set_mux(priv, RingFreq + 5000, RingFreq, R848_STD_SIZE)) //FilCal MUX (LO_Freq, RF_Freq) -+ return RT_Fail; -+ -+ // Set PLL -+ if (r848_set_pll(priv, (RingFreq + 5000), R848_STD_SIZE)) //FilCal PLL -+ return RT_Fail; -+ -+ // Set LNA TF=(1,15),for VGA training // R848 R8[6:0] -+ priv->regs[0] = (priv->regs[0] & 0x80) | 0x1F; -+ ret = r848_wr(priv, 0x08, priv->regs[0]); -+ -+ // Qctrl=off // R848 R14[5] -+ priv->regs[6] = (priv->regs[6] & 0xDF); -+ ret |= r848_wr(priv, 0x0e, priv->regs[6]); -+ -+ // FilterComp OFF // R848 R14[2] -+ priv->regs[6] = (priv->regs[6] & 0xFB); -+ ret |= r848_wr(priv, 0x0e, priv->regs[6]); -+ -+ // Byp-LPF: Bypass R848 R12[6] 12-8=4 12(0x0C) is addr ; [4] is data -+ priv->regs[4] = priv->regs[4] & 0xBF; -+ ret |= r848_wr(priv, 0x0c, priv->regs[4]); -+ -+ //Adc=on; Vga code mode, Gain = -12dB -+ //R848 R20[3:0] set 0 -+ //R848 R9[1] set 1 -+ //R848 R11[3] set 0 -+ //R848 R18[7] set 0 -+ //R848 R15[7] set 0 -+ -+ // VGA Gain = -12dB -+ priv->regs[12] = (priv->regs[12] & 0xF0); -+ ret |= r848_wr(priv, 0x14, priv->regs[12]); -+ -+ // Vga code mode -+ priv->regs[1] = (priv->regs[1] | 0x02); -+ ret |= r848_wr(priv, 0x09, priv->regs[1]); -+ -+ // VGA 6dB -+ priv->regs[3] = (priv->regs[3] & 0xF7); -+ ret |= r848_wr(priv, 0x0b, priv->regs[3]); -+ -+ // VGA PW ON -+ priv->regs[10] = (priv->regs[10] & 0x7F); -+ ret |= r848_wr(priv, 0x12, priv->regs[10]); -+ -+ // Adc on -+ priv->regs[7] = (priv->regs[7] & 0x7F); -+ ret |= r848_wr(priv, 0x0f, priv->regs[7]); -+ if (ret) -+ return ret; -+ -+ -+ // increase VGA power to let ADC read value significant -+ for (VGA_Count = 0; VGA_Count < 16; VGA_Count++) { -+ ret = r848_wr(priv, 0x14, (priv->regs[12] & 0xf0) + VGA_Count); -+ if (ret) -+ return ret; -+ msleep(10); -+ -+ if (r848_get_imr(priv,&VGA_Read)) -+ return RT_Fail; -+ -+ if (VGA_Read > 40) -+ break; -+ } -+ -+ // Set LNA TF=(0,0) -+ priv->regs[0] = (priv->regs[0] & 0x80); -+ ret = r848_wr(priv, 0x08, priv->regs[0]); -+ if (ret) -+ return ret; -+ -+ msleep(10); -+ -+ if (r848_get_imr(priv, &VGA_Read)) -+ return RT_Fail; -+ -+ if (VGA_Read > 36) -+ priv->cfg->R848_DetectTfType = R848_UL_USING_BEAD; -+ else -+ priv->cfg->R848_DetectTfType = R848_UL_USING_270NH; -+ -+ return 0; -+} -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+static int r848_set_standard(struct r848_priv *priv, u8 standard) -+{ -+ struct filter_cal *fc = &priv->fc[standard]; -+ int ret; -+ // Filter Calibration -+ u8 u1FilCalGap = 8; -+ -+ -+ if (standard != priv->standard) { -+ ret = r848_init_regs(priv, standard); -+ if (ret) -+ return ret; -+ } -+ priv->Sys_Info1 = R848_Sys_Sel(priv, standard); -+ -+ // Filter Calibration -+ if (!fc->flag) { -+ fc->code = R848_Filt_Cal_ADC(priv, priv->Sys_Info1.FILT_CAL_IF, priv->Sys_Info1.BW, u1FilCalGap); -+ fc->bw = 0;// R848_Bandwidth; -+ fc->flag = 1; -+ //Reset register and Array -+ ret = r848_init_regs(priv, standard); -+ if (ret) -+ return ret; -+ } -+ -+ // Set Filter Auto Ext -+ // R19[4] -+ priv->regs[11] = (priv->regs[11] & 0xEF) | priv->Sys_Info1.FILT_EXT_ENA; -+ ret = r848_wr(priv, 0x13, priv->regs[11]); -+ -+ if (priv->Sys_Info1.FILT_EXT_ENA == 0x10) { //(%) -+ if (fc->code< 2) -+ fc->code = 2; -+ -+ if ((priv->Sys_Info1.FILT_EXT_POINT & 0x02) == 0x02) { //HPF+3 -+ if(priv->Sys_Info1.HPF_COR > 12) -+ priv->Sys_Info1.HPF_COR = 12; -+ } else { //HPF+1 -+ if(priv->Sys_Info1.HPF_COR > 14) -+ priv->Sys_Info1.HPF_COR = 15; -+ } -+ } -+ -+ // Set LPF fine code -+ // R848:R18[3:0] -+ priv->regs[10] = (priv->regs[10] & 0xF0) | fc->code; -+ ret |= r848_wr(priv, 0x12, priv->regs[10]); -+ -+ // Set LPF coarse BW -+ // R848:R19[6:5] -+ priv->regs[11] = (priv->regs[11] & 0x9F) | fc->bw; -+ //ret |= r848_wr(priv, 0x13, priv->regs[11]); -+ -+ // Set HPF corner & 1.7M mode -+ // R848:R19[7 & 3:0] -+ priv->regs[11] = (priv->regs[11] & 0x70) | priv->Sys_Info1.HPF_COR | priv->Sys_Info1.V17M; -+ ret |= r848_wr(priv, 0x13, priv->regs[11]); -+ -+ // Set TF current -+ // R848:R11[6] -+ priv->regs[3] = (priv->regs[3] & 0xBF) | priv->Sys_Info1.TF_CUR; -+ ret |= r848_wr(priv, 0x0b, priv->regs[3]); -+ -+ // Set Filter current -+ // R848:R18[6:5] -+ priv->regs[10] = (priv->regs[10] & 0x9F) | priv->Sys_Info1.FILT_CUR; -+ //R848_Array[10] = (R848_Array[10] & 0x9F) | 0x60; //lowest -+ ret |= r848_wr(priv, 0x12, priv->regs[10]); -+ -+ // Set Switch Buffer current -+ // R848:R12[2] -+ priv->regs[4] = (priv->regs[4] & 0xFB) | priv->Sys_Info1.SWBUF_CUR; -+ ret |= r848_wr(priv, 0x0c, priv->regs[4]); -+ -+ // Set Filter Comp -+ // R848:R38[6:5] -+ priv->regs[30] = (priv->regs[30] & 0x9F) | priv->Sys_Info1.FILT_COMP; -+ //ret |= r848_wr(priv, 0x26, priv->regs[30]); -+ // Set Filter 3dB -+ // R848:R38[7] -+ priv->regs[30] = (priv->regs[30] & 0xF7) | priv->Sys_Info1.FILT_3DB; -+ // Set Filter Ext Condition (%) -+ // R848:R38[2:0] -+ priv->regs[30] = (priv->regs[30] & 0xF8) | 0x04 | priv->Sys_Info1.FILT_EXT_POINT; //ext both HPF/LPF -+ ret |= r848_wr(priv, 0x26, priv->regs[30]); -+/* -+ // Set Inductor Bias -+ R848_I2C.RegAddr = 0x04; -+ R848_Array[4] = (R848_Array[4] & 0xFE) | Sys_Info1.INDUC_BIAS; -+ R848_I2C.Data = R848_Array[4]; -+ if(I2C_Write(&R848_I2C) != RT_Success) -+ return RT_Fail; -+*/ -+ // Set sw cap clk -+ // R848:R26[1:0] -+ priv->regs[18] = (priv->regs[18] & 0xFC) | priv->Sys_Info1.SWCAP_CLK; -+ ret |= r848_wr(priv, 0x1a, priv->regs[18]); -+ -+ // Set NA det power -+ // 848:R38[7] -+ priv->regs[30] = (priv->regs[30] & 0x7F) | priv->Sys_Info1.NA_PWR_DET; -+ ret |= r848_wr(priv, 0x26, priv->regs[30]); -+ -+/* -+ // Set AGC clk -+ R848_I2C.RegAddr = 0x1A; // R848:R26[4:2] -+ R848_Array[18] = (R848_Array[18] & 0xE3) | Sys_Info1.AGC_CLK; -+ R848_I2C.Data = R848_Array[18]; -+ if(I2C_Write(&R848_I2C) != RT_Success) -+ return RT_Fail; -+*/ -+ -+ // Set GPO High -+ // R848:R23[4:2] -+ priv->regs[15] = (priv->regs[15] & 0xFE) | 0x01; -+ ret |= r848_wr(priv, 0x17, priv->regs[15]); -+ -+ priv->standard = standard; -+ -+ return ret; -+} -+ -+ -+ -+/* freq in kHz */ -+static int r848_set_frequency(struct r848_priv *priv) -+{ -+ u32 LO_KHz; -+ R848_SysFreq_Info_Type SysFreq_Info1; -+ int ret; -+ -+ // Check Input Frequency Range -+ if (priv->freq < 40000) -+ return -EINVAL; -+ -+ if (priv->standard != R848_DVB_S) { -+ if (priv->freq > 1002000) -+ return -EINVAL; -+ } else { -+ if (priv->freq > 2400000) -+ return -EINVAL; -+ } -+ -+ LO_KHz = priv->freq + priv->Sys_Info1.IF_KHz; -+ -+ // Set MUX dependent var. Must do before PLL( ) -+ if (r848_set_mux(priv, LO_KHz, priv->freq, priv->standard)) //normal MUX -+ return RT_Fail; -+ -+ // Set PLL -+ if (r848_set_pll(priv, LO_KHz, priv->standard)) -+ return RT_Fail; -+ -+ //Set TF -+ if (R848_SetTF(priv, priv->freq, priv->cfg->R848_SetTfType)) -+ return RT_Fail; -+ -+ //R848_IMR_point_num = Freq_Info1.IMR_MEM; -+ -+ //Q1.5K Q_ctrl R848:R14[4] -+ //if(R848_INFO.RF_KHzfreq <= 472000) //<472MHz -+ priv->regs[6] = priv->regs[6] | 0x10; -+ else -+ priv->regs[6] = priv->regs[6] & 0xEF; -+ -+ // medQctrl 1.5K -+ if ((priv->freq >= 300000) && (priv->freq <= 472000)) //<473MHz and >299MHz -+ priv->regs[6] = priv->regs[6] | 0x01; -+ else -+ priv->regs[6] = priv->regs[6] & 0xFE; -+ ret = r848_wr(priv, 0x0e, priv->regs[6]); // R848:R14[1] -+ -+ // 3~6 shrink -+ if ((priv->freq >= 300000) && (priv->freq <= 550000)) //<551MHz and >299MHz -+ priv->regs[3] = priv->regs[3] & 0xFB; -+ else -+ priv->regs[3] = priv->regs[3] | 0x04; -+ ret |= r848_wr(priv, 0x0b, priv->regs[3]); // R848:R11[2] -+ -+ // set Xtal AAC on=1; off=0 -+ priv->regs[16] = priv->regs[16] & 0xFD; -+ ret |= r848_wr(priv, 0x18, priv->regs[16]); // R848:R24[1] -+ -+ // Get Sys-Freq parameter -+ SysFreq_Info1 = R848_SysFreq_Sel(priv, priv->standard, priv->freq); -+ -+ // Set LNA_TOP -+ priv->regs[27] = (priv->regs[27] & 0xF8) | (SysFreq_Info1.LNA_TOP); -+ ret |= r848_wr(priv, 0x23, priv->regs[27]); // R848:R35[2:0] -+ -+ // Set LNA VTHL -+ priv->regs[23] = (priv->regs[23] & 0x00) | SysFreq_Info1.LNA_VTH_L; -+ ret |= r848_wr(priv, 0x1f, priv->regs[23]); // R848:R31[7:0] -+ -+ // Set MIXER TOP -+ priv->regs[28] = (priv->regs[28] & 0xF0) | (SysFreq_Info1.MIXER_TOP); -+ ret |= r848_wr(priv, 0x24, priv->regs[28]); // R848:R36[7:0] -+ -+ // Set MIXER VTHL -+ priv->regs[24] = (priv->regs[24] & 0x00) | SysFreq_Info1.MIXER_VTH_L; -+ ret |= r848_wr(priv, 0x20, priv->regs[24]); // R848:R32[7:0] -+ -+ // Set RF TOP -+ priv->regs[26] = (priv->regs[26] & 0x1F) | SysFreq_Info1.RF_TOP; -+ ret |= r848_wr(priv, 0x22, priv->regs[26]); // R848:R34[7:0] -+ -+ // Set Nrb TOP -+ priv->regs[28] = (priv->regs[28] & 0x0F) | SysFreq_Info1.NRB_TOP; -+ ret |= r848_wr(priv, 0x24, priv->regs[28]); // R848:R36[7:0] -+ -+ // Set Nrb BW -+ priv->regs[27] = (priv->regs[27] & 0x3F) | SysFreq_Info1.NRB_BW; -+ ret |= r848_wr(priv, 0x23, priv->regs[27]); // R848:R35[7:6] -+ -+ // Set TF LPF -+ priv->regs[4] = (priv->regs[4] & 0xBF) | SysFreq_Info1.BYP_LPF; -+ ret |= r848_wr(priv, 0x0c, priv->regs[4]); // R848:R12[6] -+ -+ priv->regs[38] = (priv->regs[38] & 0xF1) | SysFreq_Info1.RF_FAST_DISCHARGE; -+ ret |= r848_wr(priv, 0x2e, priv->regs[38]); // R848:R46[3:1] = 0b000 -+ -+ priv->regs[14] = (priv->regs[14] & 0x1F) | SysFreq_Info1.RF_SLOW_DISCHARGE; -+ ret |= r848_wr(priv, 0x16, priv->regs[14]); // R848:R22[7:5] = 0b010 -+ -+ priv->regs[30] = (priv->regs[30] & 0xEF) | SysFreq_Info1.RFPD_PLUSE_ENA; -+ ret |= r848_wr(priv, 0x26, priv->regs[30]); // R848:R38[4] = 1 -+ -+ priv->regs[35] = (priv->regs[35] & 0xE0) | SysFreq_Info1.LNA_FAST_DISCHARGE; -+ ret |= r848_wr(priv, 0x2b, priv->regs[35]); // R848:R43[4:0] = 0b01010 -+ -+ priv->regs[14] = (priv->regs[14] & 0xE3) | SysFreq_Info1.LNA_SLOW_DISCHARGE; -+ ret |= r848_wr(priv, 0x16, priv->regs[14]); // R848:R22[4:2] = 0b000 -+ -+ priv->regs[9] = (priv->regs[9] & 0x7F) | SysFreq_Info1.LNAPD_PLUSE_ENA; -+ ret |= r848_wr(priv, 0x11, priv->regs[9]); // R848:R17[7] = 0 -+ -+ // Set AGC clk -+ priv->regs[18] = (priv->regs[18] & 0xE3) | SysFreq_Info1.AGC_CLK; -+ ret |= r848_wr(priv, 0x1a, priv->regs[18]); // R848:R26[4:2] -+ -+ // no clk out -+ priv->regs[17] = (priv->regs[17] | 0x80); // R848:R25[7] -+ ret |= r848_wr(priv, 0x19, priv->regs[17]); -+ -+ // for DVB-T2 -+ switch (priv->standard) { -+ case R848_DVB_T2_6M: -+ case R848_DVB_T2_7M: -+ case R848_DVB_T2_8M: -+ case R848_DVB_T2_1_7M: -+ case R848_DVB_T2_10M: -+ case R848_DVB_T2_6M_IF_5M: -+ case R848_DVB_T2_7M_IF_5M: -+ case R848_DVB_T2_8M_IF_5M: -+ case R848_DVB_T2_1_7M_IF_5M: -+ msleep(100); -+/* -+ // AGC clk 250Hz -+ priv->regs[18] = (priv->regs[18] & 0xE3) | 0x1C; //[4:2]=111 -+ ret |= r848_wr(priv, 0x1a, priv->regs[18]); // R848:R26[4:2] -+*/ -+ // force plain mode -+ priv->regs[3] = (priv->regs[3] | 0x80); //[7]=1 -+ ret |= r848_wr(priv, 0x0b, priv->regs[3]); // R848:R11[7] -+ -+ priv->regs[2] = (priv->regs[2] & 0xDF); //[5]=0 -+ ret |= r848_wr(priv, 0x0a, priv->regs[2]); // R848:R10[5] -+ break; -+ default: -+ break; -+ } -+ -+ return ret; -+} -+ -+ -+ -+ -+ -+ -+ -+static int r848_release(struct dvb_frontend *fe) -+{ -+ struct r848_priv *priv = fe->tuner_priv; -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ -+ kfree(fe->tuner_priv); -+ fe->tuner_priv = NULL; -+ return 0; -+} -+ -+static int r848_init(struct dvb_frontend *fe) -+{ -+ struct r848_priv *priv = fe->tuner_priv; -+ int ret; -+ u8 i; -+ -+ printk("init tuner\n"); -+ -+ if (priv->inited == 1) -+ return 0; -+ -+ -+ printk("init tuner first time\n"); -+ -+ -+ for (i = 0; i < R848_STD_SIZE; i++) { -+ priv->fc[i].flag = 0; -+ priv->fc[i].code = 0; -+ priv->fc[i].bw = 0x00; -+ } -+ -+ -+ if (r848_init_regs(priv,R848_STD_SIZE) != RT_Success) -+ return RT_Fail; -+ -+ if(R848_TF_Check(priv) != RT_Success) -+ return RT_Fail; -+ -+ //start IMR calibration -+ if(r848_init_regs(priv,R848_STD_SIZE) != RT_Success) //write initial reg before doing IMR Cal -+ return RT_Fail; -+ -+ if(R848_Cal_Prepare(priv,R848_IMR_CAL) != RT_Success) -+ return RT_Fail; -+ -+ if(R848_IMR(priv,3, 0) != RT_Success) //Full K node 3 -+ return RT_Fail; -+ -+ if(R848_IMR(priv,0, 1) != RT_Success) -+ return RT_Fail; -+ -+ if(R848_IMR(priv,1, 1) != RT_Success) -+ return RT_Fail; -+ -+ if(R848_IMR(priv,2, 1) != RT_Success) -+ return RT_Fail; -+ -+ if(R848_IMR(priv,4, 0) != RT_Success) //Full K node 4 -+ return RT_Fail; -+ -+ //do Xtal check -+ if(r848_init_regs(priv,R848_STD_SIZE) != RT_Success) -+ return RT_Fail; -+ -+ priv->cfg->R848_Xtal_Pwr = XTAL_SMALL_LOWEST; -+ priv->cfg->R848_Xtal_Pwr_tmp = XTAL_SMALL_LOWEST; -+ -+ for (i=0; i<3; i++) { -+ if(R848_Xtal_Check(priv) != RT_Success) -+ return RT_Fail; -+ -+ if(priv->cfg->R848_Xtal_Pwr_tmp > priv->cfg->R848_Xtal_Pwr) -+ priv->cfg->R848_Xtal_Pwr = priv->cfg->R848_Xtal_Pwr_tmp; -+ } -+ -+ //write initial reg -+ if(r848_init_regs(priv,R848_STD_SIZE) != RT_Success) -+ return RT_Fail; -+ -+ priv->standard = R848_STD_SIZE; -+ -+ ret = 0; -+ -+ if (ret) -+ dev_dbg(&priv->i2c->dev, "%s() failed\n", __func__); -+ -+ priv->inited = 1; -+ -+ printk("init tuner done\n"); -+ return ret; -+} -+ -+static int r848_sleep(struct dvb_frontend *fe) -+{ -+ struct r848_priv *priv = fe->tuner_priv; -+ int ret = 0; -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ -+ //if (ret) -+ // dev_dbg(&priv->i2c->dev, "%s() failed\n", __func__); -+ return ret; -+} -+ -+static int r848_set_params(struct dvb_frontend *fe) -+{ -+ struct r848_priv *priv = fe->tuner_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ int ret, i; -+ u8 tuner_lock; -+ u8 standard; -+ -+ dev_info(&priv->i2c->dev, "%s() delivery_system=%d frequency=%d " \ -+ "symbol_rate=%d bandwidth_hz=%d\n", __func__, -+ c->delivery_system, c->frequency, c->symbol_rate, -+ c->bandwidth_hz); -+ -+ -+ /* failsafe */ -+ standard = R848_DVB_T2_8M_IF_5M; -+ -+ switch (c->delivery_system) { -+ case SYS_DVBC_ANNEX_A: -+ priv->freq = c->frequency / 1000; -+ if(c->bandwidth_hz <= 6000000) { -+ standard = R848_DVB_C_6M_IF_5M; -+ } else if (c->bandwidth_hz <= 8000000) { -+ standard = R848_DVB_C_8M_IF_5M; -+ } -+ -+ /* set pll data */ -+ if(r848_set_standard(priv, standard) != RT_Success) { -+ return RT_Fail; -+ } -+ if(r848_set_frequency(priv)) -+ return RT_Fail; -+ break; -+ case SYS_DVBS: -+ case SYS_DVBS2: -+ priv->freq = c->frequency; -+ priv->standard = R848_DVB_S; -+ priv->bw = (c->symbol_rate/200*135+2000000)/1000*2;//unit KHz -+ priv->output_mode = DIFFERENTIALOUT; -+ priv->agc_mode = AGC_NEGATIVE; -+ -+ /* set pll data */ -+ if(R848_DVBS_Setting(priv) != RT_Success) -+ return RT_Fail; -+ break; -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ default: -+ priv->freq = c->frequency / 1000; -+ if(c->bandwidth_hz <= 1700000) { -+ standard = R848_DVB_T2_1_7M_IF_5M; -+ } else if (c->bandwidth_hz <= 6000000) { -+ standard = R848_DVB_T2_6M_IF_5M; -+ } else if (c->bandwidth_hz <= 7000000) { -+ standard = R848_DVB_T2_7M_IF_5M; -+ } else { -+ standard = R848_DVB_T2_8M_IF_5M; -+ } -+ -+ if (r848_set_standard(priv, standard)) -+ return RT_Fail; -+ if (r848_set_frequency(priv)) -+ return RT_Fail; -+ break; -+ } -+ -+ for (i = 0; i < 5; i++) { -+ ret = r848_get_lock_status(priv, &tuner_lock); -+ if(tuner_lock) { -+ printk("Tuner Locked.\n"); -+ break; -+ } else { -+ printk("Tuner not Locked!\n"); -+ } -+ msleep(20); -+ } -+ -+ return ret; -+} -+ -+static const struct dvb_tuner_ops r848_tuner_ops = { -+ .info = { -+ .name = "Rafael R848", -+ -+// .frequency_min = 850000, -+// .frequency_max = 2300000, -+// .frequency_step = 206, -+ }, -+ -+ .release = r848_release, -+ -+ .init = r848_init, -+ .sleep = r848_sleep, -+ .set_params = r848_set_params, -+}; -+ -+struct dvb_frontend *r848_attach(struct dvb_frontend *fe, -+ struct r848_config *cfg, struct i2c_adapter *i2c) -+{ -+ struct r848_priv *priv = NULL; -+ -+ priv = kzalloc(sizeof(struct r848_priv), GFP_KERNEL); -+ if (priv == NULL) { -+ dev_dbg(&i2c->dev, "%s() attach failed\n", __func__); -+ return NULL; -+ } -+ -+ priv->cfg = cfg; -+ priv->i2c = i2c; -+ priv->inited = 0; -+ -+ dev_info(&priv->i2c->dev, -+ "%s: Rafael R848 successfully attached\n", -+ KBUILD_MODNAME); -+ -+ memcpy(&fe->ops.tuner_ops, &r848_tuner_ops, -+ sizeof(struct dvb_tuner_ops)); -+ -+ fe->tuner_priv = priv; -+ return fe; -+} -+EXPORT_SYMBOL(r848_attach); -+ -+MODULE_DESCRIPTION("Rafael R848 silicon tuner driver"); -+MODULE_AUTHOR("Luis Alves "); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/tuners/r848.h b/drivers/media/tuners/r848.h -new file mode 100644 -index 0000000..b730e12 ---- /dev/null -+++ b/drivers/media/tuners/r848.h -@@ -0,0 +1,63 @@ -+/* -+ * Rafael R848 silicon tuner driver -+ * -+ * Copyright (C) 2015 Luis Alves -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#ifndef R848_H -+#define R848_H -+ -+#include -+#include "dvb_frontend.h" -+ -+ -+ -+ -+ -+ -+ -+ -+struct r848_config { -+ /* tuner i2c address */ -+ u8 i2c_address; -+ -+ u32 xtal; -+ -+ // tuner -+ u8 R848_DetectTfType ; -+ -+ u8 R848_Xtal_Pwr ; -+ u8 R848_Xtal_Pwr_tmp ; -+ -+ /* dvbc/t */ -+ u8 R848_SetTfType; -+ -+}; -+ -+#if IS_ENABLED(CONFIG_MEDIA_TUNER_R848) -+extern struct dvb_frontend *r848_attach(struct dvb_frontend *fe, -+ struct r848_config *cfg, struct i2c_adapter *i2c); -+#else -+static inline struct dvb_frontend *r848_attach(struct dvb_frontend *fe, -+ struct r848_config *cfg, struct i2c_adapter *i2c) -+{ -+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -+ return NULL; -+} -+#endif -+ -+#endif /* R848_H */ -diff --git a/drivers/media/tuners/r848_priv.h b/drivers/media/tuners/r848_priv.h -new file mode 100644 -index 0000000..3a3d398 ---- /dev/null -+++ b/drivers/media/tuners/r848_priv.h -@@ -0,0 +1,487 @@ -+/* -+ * Rafael R848 silicon tuner driver -+ * -+ * Copyright (C) 2015 Luis Alves -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#ifndef R848_PRIV_H -+#define R848_PRIV_H -+ -+#define NUM_REGS 40 -+#define NUM_IMR 5 -+ -+ -+typedef enum _R848_Standard_Type //Don't remove standand list!! -+{ -+ R848_DVB_T_6M = 0, -+ R848_DVB_T_7M, -+ R848_DVB_T_8M, -+ R848_DVB_T2_6M, //IF=4.57M -+ R848_DVB_T2_7M, //IF=4.57M -+ R848_DVB_T2_8M, //IF=4.57M -+ R848_DVB_T2_1_7M, -+ R848_DVB_T2_10M, -+ R848_DVB_C_8M, -+ R848_DVB_C_6M, -+ R848_J83B, -+ R848_ISDB_T, //IF=4.063M -+ R848_ISDB_T_4570, //IF=4.57M -+ R848_DTMB_4570, //IF=4.57M -+ R848_DTMB_6000, //IF=6.00M -+ R848_DTMB_6M_BW_IF_5M, //IF=5.0M, BW=6M -+ R848_DTMB_6M_BW_IF_4500, //IF=4.5M, BW=6M -+ R848_ATSC, -+ R848_DVB_S, -+ R848_DVB_T_6M_IF_5M, -+ R848_DVB_T_7M_IF_5M, -+ R848_DVB_T_8M_IF_5M, -+ R848_DVB_T2_6M_IF_5M, -+ R848_DVB_T2_7M_IF_5M, -+ R848_DVB_T2_8M_IF_5M, -+ R848_DVB_T2_1_7M_IF_5M, -+ R848_DVB_C_8M_IF_5M, -+ R848_DVB_C_6M_IF_5M, -+ R848_J83B_IF_5M, -+ R848_ISDB_T_IF_5M, -+ R848_DTMB_IF_5M, -+ R848_ATSC_IF_5M, -+ R848_FM, -+ R848_STD_SIZE, -+}R848_Standard_Type; -+ -+ -+typedef struct _R848_Sys_Info_Type -+{ -+ u16 IF_KHz; -+ u16 FILT_CAL_IF; -+ u8 BW; -+ u8 V17M; -+ u8 HPF_COR; -+ u8 FILT_EXT_ENA; -+ u8 FILT_EXT_WIDEST; -+ u8 FILT_EXT_POINT; -+// u8 AGC_CLK; -+ u8 FILT_COMP; -+ u8 FILT_CUR; -+ u8 FILT_3DB; -+ u8 SWBUF_CUR; -+ u8 TF_CUR; -+ u8 INDUC_BIAS; -+ u8 SWCAP_CLK; -+ u8 NA_PWR_DET; -+}R848_Sys_Info_Type; -+ -+ -+ -+ -+ -+ -+ -+ -+struct filter_cal { -+ u8 flag; -+ u8 bw; -+ u8 code; -+}; -+ -+struct r848_sect_type { -+ u8 phase_y; -+ u8 gain_x; -+ u8 iqcap; -+ u8 value; -+}; -+ -+struct r848_priv { -+ struct r848_config *cfg; -+ struct i2c_adapter *i2c; -+ u8 inited; -+ -+ -+ u8 regs[NUM_REGS]; -+ struct r848_sect_type imr_data[NUM_IMR]; -+ -+ u8 delsys; -+ -+ /* tune settings */ -+ u32 bw; -+ u32 freq; /* kHz */ -+ u8 standard; -+ u8 output_mode; -+ u8 agc_mode; -+ -+ struct filter_cal fc[R848_STD_SIZE]; -+ -+ -+ -+ R848_Sys_Info_Type Sys_Info1; -+}; -+ -+ -+ -+ -+ -+ -+typedef struct _R848_Set_Info -+{ -+ u32 RF_KHz; -+ u32 DVBS_BW; -+ u8 R848_Standard; -+ int R848_DVBS_OutputSignal_Mode; -+ int R848_DVBS_AGC_Mode; -+} R848_Set_Info; -+ -+ -+ -+/* R848 */ -+ -+//----------------------------------------------------------// -+// Define // -+//----------------------------------------------------------// -+ -+#define VERSION "R848_GUI_2.3A" -+ -+#define R848_REG_NUM 40 -+#define R848_TF_HIGH_NUM 8 -+#define R848_TF_MID_NUM 8 -+#define R848_TF_LOW_NUM 8 -+#define R848_TF_LOWEST_NUM 8 -+#define R848_RING_POWER_FREQ_LOW 115000 -+#define R848_RING_POWER_FREQ_HIGH 450000 -+#define R848_IMR_IF 5300 -+#define R848_IMR_TRIAL 9 -+#define R848_Xtal 16000 -+//----------------------------------------------------------// -+// Internal Structure // -+//----------------------------------------------------------// -+ -+ -+typedef struct _R848_Freq_Info_Type -+{ -+ u8 RF_POLY; -+ u8 LNA_BAND; -+ u8 LPF_CAP; -+ u8 LPF_NOTCH; -+ u8 XTAL_POW0; -+ u8 CP_CUR; -+ u8 IMR_MEM; -+ u8 Q_CTRL; -+}R848_Freq_Info_Type; -+ -+typedef struct _R848_SysFreq_Info_Type -+{ -+ u8 LNA_TOP; -+ u8 LNA_VTH_L; -+ u8 MIXER_TOP; -+ u8 MIXER_VTH_L; -+ u8 RF_TOP; -+ u8 NRB_TOP; -+ u8 NRB_BW; -+ u8 BYP_LPF; -+ u8 RF_FAST_DISCHARGE; -+ u8 RF_SLOW_DISCHARGE; -+ u8 RFPD_PLUSE_ENA; -+ u8 LNA_FAST_DISCHARGE; -+ u8 LNA_SLOW_DISCHARGE; -+ u8 LNAPD_PLUSE_ENA; -+ u8 AGC_CLK; -+ -+}R848_SysFreq_Info_Type; -+ -+typedef struct _R848_Cal_Info_Type -+{ -+ u8 FILTER_6DB; -+ u8 MIXER_AMP_GAIN; -+ u8 MIXER_BUFFER_GAIN; -+ u8 LNA_GAIN; -+ u8 LNA_POWER; -+ u8 RFBUF_OUT; -+ u8 RFBUF_POWER; -+ u8 TF_CAL; -+}R848_Cal_Info_Type; -+ -+ -+ -+typedef struct _R848_TF_Result -+{ -+ u8 TF_Set; -+ u8 TF_Value; -+}R848_TF_Result; -+ -+typedef enum _R848_TF_Band_Type -+{ -+ TF_HIGH = 0, -+ TF_MID, -+ TF_LOW -+}R848_TF_Band_Type; -+ -+typedef enum _R848_TF_Type -+{ -+ R848_TF_NARROW = 0, //270n/68n (ISDB-T, DVB-T/T2) -+ R848_TF_BEAD, //Bead/68n (DTMB) -+ R848_TF_NARROW_LIN, //270n/68n (N/A) -+ R848_TF_NARROW_ATV_LIN, //270n/68n (ATV) -+ R848_TF_BEAD_LIN, //Bead/68n (PAL_DK for China Hybrid TV) -+ R848_TF_NARROW_ATSC, //270n/68n (ATSC, DVB-C, J83B) -+ R848_TF_BEAD_LIN_ATSC, //Bead/68n (ATSC, DVB-C, J83B) -+ R848_TF_82N_BEAD, //Bead/82n (DTMB) -+ R848_TF_82N_270N, //270n/82n (OTHER Standard) -+ R848_TF_SIZE -+} R848_TF_Type; -+ -+ -+ -+u32 R848_LNA_HIGH_MID[R848_TF_SIZE] = { 644000, 644000, 644000, 644000, 644000, 500000, 500000, 500000, 500000}; -+u32 R848_LNA_MID_LOW[R848_TF_SIZE] = { 388000, 388000, 348000, 348000, 348000, 300000, 300000, 300000, 300000}; -+u32 R848_LNA_LOW_LOWEST[R848_TF_SIZE] = {164000, 164000, 148000, 124000, 124000, 156000, 156000, 108000, 108000}; -+ -+ -+u32 R848_TF_Freq_High[R848_TF_SIZE][R848_TF_HIGH_NUM] = -+{ { 784000, 784000, 776000, 744000, 712000, 680000, 648000, 647000}, -+ { 784000, 784000, 776000, 744000, 712000, 680000, 648000, 647000}, -+ { 784000, 784000, 776000, 744000, 712000, 680000, 648000, 647000}, -+ { 784000, 784000, 776000, 744000, 712000, 680000, 648000, 647000}, -+ { 784000, 784000, 776000, 744000, 712000, 680000, 648000, 647000}, -+ { 784000, 784000, 776000, 680000, 608000, 584000, 536000, 504000}, -+ { 784000, 784000, 776000, 680000, 608000, 584000, 536000, 504000}, -+ { 784000, 776000, 712000, 616000, 584000, 560000, 520000, 504000}, -+ { 784000, 776000, 712000, 616000, 584000, 560000, 520000, 504000} -+}; -+ -+ -+u32 R848_TF_Freq_Mid[R848_TF_SIZE][R848_TF_MID_NUM] = -+{ {608000, 584000, 560000, 536000, 488000, 440000, 416000, 392000}, -+ {608000, 584000, 560000, 536000, 488000, 440000, 416000, 392000}, -+ {608000, 560000, 536000, 488000, 440000, 392000, 376000, 352000}, -+ {608000, 560000, 536000, 488000, 440000, 392000, 376000, 352000}, -+ {608000, 560000, 536000, 488000, 440000, 392000, 376000, 352000}, -+ {488000, 464000, 440000, 416000, 392000, 352000, 320000, 304000}, -+ {488000, 464000, 440000, 416000, 392000, 352000, 320000, 304000}, -+ {480000, 464000, 440000, 416000, 392000, 352000, 320000, 304000}, -+ {480000, 464000, 440000, 416000, 392000, 352000, 320000, 304000}, -+}; -+u32 R848_TF_Freq_Low[R848_TF_SIZE][R848_TF_LOW_NUM] = -+{ {320000, 304000, 272000, 240000, 232000, 216000, 192000, 168000}, //164~388 -+ {320000, 304000, 272000, 240000, 232000, 216000, 192000, 168000}, //164~388 -+ {256000, 240000, 232000, 224000, 216000, 192000, 168000, 160000}, //148~348 -+ {256000, 240000, 232000, 192000, 160000, 152000, 144000, 128000}, //124~348 -+ {264000, 240000, 192000, 184000, 176000, 152000, 144000, 128000}, //124~348 -+ {280000, 248000, 232000, 216000, 192000, 176000, 168000, 160000}, //156~300 -+ {280000, 248000, 232000, 216000, 192000, 176000, 168000, 160000}, //156~300 -+ {296000, 280000, 256000, 216000, 184000, 168000, 136000, 112000}, // -+ {296000, 280000, 256000, 216000, 184000, 168000, 136000, 112000} // -+}; -+u32 R848_TF_Freq_Lowest[R848_TF_SIZE][R848_TF_LOWEST_NUM] = -+{ {160000, 120000, 104000, 88000, 80000, 72000, 56000, 48000}, -+ {160000, 120000, 104000, 88000, 80000, 72000, 56000, 48000}, -+ {144000, 120000, 104000, 88000, 80000, 72000, 56000, 48000}, -+ {120000, 96000, 88000, 80000, 72000, 64000, 56000, 48000}, -+ {104000, 96000, 88000, 80000, 72000, 64000, 56000, 48000}, -+ {136000, 120000, 104000, 88000, 72000, 64000, 56000, 48000}, -+ {128000, 120000, 104000, 96000, 80000, 72000, 64000, 56000}, -+ {104000, 96000, 88000, 80000, 72000, 64000, 56000, 48000}, -+ {104000, 96000, 88000, 80000, 72000, 64000, 56000, 48000} -+}; -+ -+u8 R848_TF_Result_High[R848_TF_SIZE][R848_TF_HIGH_NUM] = -+{ {0x00, 0x00, 0x01, 0x03, 0x04, 0x05, 0x07, 0x07}, -+ {0x00, 0x00, 0x01, 0x03, 0x04, 0x05, 0x07, 0x07}, -+ {0x00, 0x00, 0x01, 0x03, 0x04, 0x05, 0x07, 0x07}, -+ {0x00, 0x00, 0x01, 0x03, 0x04, 0x05, 0x07, 0x07}, -+ {0x00, 0x00, 0x01, 0x03, 0x04, 0x05, 0x07, 0x07}, -+ {0x00, 0x00, 0x01, 0x05, 0x0A, 0x0C, 0x13, 0x19}, -+ {0x00, 0x00, 0x01, 0x05, 0x0A, 0x0C, 0x13, 0x19}, -+ {0x00, 0x03, 0x07, 0x0C, 0x0E, 0x0F, 0x1A, 0x1A}, -+ {0x00, 0x03, 0x07, 0x0C, 0x0E, 0x0F, 0x1A, 0x1A} -+}; -+ -+u8 R848_TF_Result_Mid[R848_TF_SIZE][R848_TF_MID_NUM] = -+{ {0x00, 0x01, 0x03, 0x03, 0x06, 0x0B, 0x0E, 0x11}, -+ {0x00, 0x01, 0x03, 0x03, 0x06, 0x0B, 0x0E, 0x11}, -+ {0x00, 0x03, 0x03, 0x06, 0x0B, 0x11, 0x12, 0x19}, -+ {0x00, 0x03, 0x03, 0x06, 0x0B, 0x11, 0x12, 0x19}, -+ {0x00, 0x03, 0x03, 0x06, 0x0B, 0x11, 0x12, 0x19}, -+ {0x06, 0x08, 0x0B, 0x0E, 0x13, 0x17, 0x1E, 0x1F}, -+ {0x06, 0x08, 0x0B, 0x0E, 0x13, 0x17, 0x1E, 0x1F}, -+ {0x09, 0x0D, 0x10, 0x12, 0x16, 0x1B, 0x1E, 0x1F}, -+ {0x09, 0x0D, 0x10, 0x12, 0x16, 0x1B, 0x1E, 0x1F} -+}; -+u8 R848_TF_Result_Low[R848_TF_SIZE][R848_TF_LOW_NUM] = -+{ {0x00, 0x02, 0x04, 0x07, 0x0A, 0x0B, 0x0F, 0x16}, -+ {0x00, 0x02, 0x04, 0x07, 0x0A, 0x0B, 0x0F, 0x16}, -+ {0x05, 0x07, 0x0A, 0x0B, 0x0B, 0x0F, 0x16, 0x1A}, -+ {0x05, 0x07, 0x0A, 0x0F, 0x1A, 0x1A, 0x23, 0x2A}, -+ {0x05, 0x08, 0x10, 0x13, 0x1A, 0x1A, 0x23, 0x2A}, -+ {0x05, 0x08, 0x0C, 0x0E, 0x10, 0x14, 0x18, 0x1A}, -+ {0x05, 0x08, 0x0C, 0x0E, 0x10, 0x14, 0x18, 0x1A}, -+ {0x00, 0x01, 0x03, 0x07, 0x0D, 0x11, 0x1E, 0x2F}, -+ {0x00, 0x01, 0x03, 0x07, 0x0D, 0x11, 0x1E, 0x2F} -+}; -+u8 R848_TF_Result_Lowest[R848_TF_SIZE][R848_TF_LOWEST_NUM] = -+{ {0x00, 0x06, 0x0C, 0x15, 0x1C, 0x1F, 0x3C, 0x3F}, -+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08}, -+ {0x02, 0x06, 0x0C, 0x15, 0x1C, 0x1F, 0x3C, 0x3F}, -+ {0x06, 0x11, 0x15, 0x1C, 0x1F, 0x2F, 0x3C, 0x3F}, -+ {0x04, 0x08, 0x08, 0x08, 0x10, 0x12, 0x13, 0x13}, -+ {0x06, 0x09, 0x0E, 0x18, 0x25, 0x2F, 0x3C, 0x3F}, -+ {0x00, 0x04, 0x04, 0x08, 0x08, 0x10, 0x12, 0x13}, -+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08}, -+ {0x0E, 0x14, 0x18, 0x1E, 0x25, 0x2F, 0x3C, 0x3F} -+}; -+ -+ -+u8 R848_iniArray_hybrid[R848_REG_NUM] = { -+ 0x00, 0x00, 0x40, 0x44, 0x17, 0x00, 0x06, 0xF0, 0x00, 0x41, -+ // 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 -+ 0x7B, 0x0B, 0x70, 0x06, 0x6E, 0x20, 0x70, 0x87, 0x96, 0x00, -+ // 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B -+ 0x10, 0x00, 0x80, 0xA5, 0xB7, 0x00, 0x40, 0xCB, 0x95, 0xF0, -+ // 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 -+ 0x24, 0x00, 0xFD, 0x8B, 0x17, 0x13, 0x01, 0x07, 0x01, 0x3F}; -+ // 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F -+ -+ -+ -+u8 R848_iniArray_dvbs[R848_REG_NUM] = { -+ 0x80, 0x05, 0x40, 0x40, 0x1F, 0x1F, 0x07, 0xFF, 0x00, 0x40, -+ // 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 -+ 0xF0, 0x0F, 0x4D, 0x06, 0x6F, 0x20, 0x28, 0x83, 0x96, 0x00, //0x16[1] pulse_flag HPF : Bypass ; 0x19[1:0] Deglich SW Cur : highest -+ // 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B -+ 0x1C, 0x99, 0xC1, 0x83, 0xB7, 0x00, 0x4F, 0xCB, 0x95, 0xFD, -+ // 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 -+ 0xA4, 0x01, 0x24, 0x0B, 0x4F, 0x05, 0x01, 0x47, 0x3F, 0x3F}; -+ // 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F -+ -+ -+ -+ -+ -+ -+ -+ -+typedef enum _R848_UL_TF_Type -+{ -+ R848_UL_USING_BEAD = 0, -+ R848_UL_USING_270NH, -+}R848_UL_TF_Type; -+ -+ -+ -+typedef enum _R848_Cal_Type -+{ -+ R848_IMR_CAL = 0, -+ R848_IMR_LNA_CAL, -+ R848_TF_CAL, -+ R848_TF_LNA_CAL, -+ R848_LPF_CAL, -+ R848_LPF_LNA_CAL -+}R848_Cal_Type; -+ -+typedef enum _R848_BW_Type -+{ -+ BW_6M = 0, -+ BW_7M, -+ BW_8M, -+ BW_1_7M, -+ BW_10M, -+ BW_200K -+}R848_BW_Type; -+ -+ -+enum R848_XTAL_PWR_VALUE { -+ XTAL_SMALL_LOWEST = 0, -+ XTAL_SMALL_LOW, -+ XTAL_SMALL_HIGH, -+ XTAL_SMALL_HIGHEST, -+ XTAL_LARGE_HIGHEST, -+ XTAL_CHECK_SIZE -+}; -+ -+ -+typedef enum _R848_Xtal_Div_TYPE -+{ -+ XTAL_DIV1 = 0, -+ XTAL_DIV2 -+}R848_Xtal_Div_TYPE; -+ -+ -+//----------------------------------------------------------// -+// R848 Public Parameter // -+//----------------------------------------------------------// -+typedef enum _R848_ErrCode -+{ -+ RT_Success = 0, -+ RT_Fail = 1 -+}R848_ErrCode; -+ -+ -+ -+typedef enum _R848_GPO_Type -+{ -+ HI_SIG = 0, -+ LO_SIG = 1 -+}R848_GPO_Type; -+ -+typedef enum _R848_RF_Gain_TYPE -+{ -+ RF_AUTO = 0, -+ RF_MANUAL -+}R848_RF_Gain_TYPE; -+ -+typedef enum _R848_DVBS_OutputSignal_Type -+{ -+ DIFFERENTIALOUT = 0, -+ SINGLEOUT = 1 -+}R848_DVBS_OutputSignal_Type; -+ -+typedef enum _R848_DVBS_AGC_Type -+{ -+ AGC_NEGATIVE = 0, -+ AGC_POSITIVE = 1 -+}R848_DVBS_AGC_Type; -+ -+ -+ -+ -+ -+typedef struct _R848_RF_Gain_Info -+{ -+ u16 RF_gain_comb; -+ u8 RF_gain1; -+ u8 RF_gain2; -+ u8 RF_gain3; -+}R848_RF_Gain_Info; -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+#endif /* R848_PRIV_H */ -diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c -index 57b2508..68b0dfb 100644 ---- a/drivers/media/tuners/si2157.c -+++ b/drivers/media/tuners/si2157.c -@@ -40,7 +40,7 @@ static int si2157_cmd_execute(struct i2c_client *client, struct si2157_cmd *cmd) - - if (cmd->rlen) { - /* wait cmd execution terminate */ -- #define TIMEOUT 80 -+ #define TIMEOUT 500 - timeout = jiffies + msecs_to_jiffies(TIMEOUT); - while (!time_after(jiffies, timeout)) { - ret = i2c_master_recv(client, cmd->args, cmd->rlen); -@@ -288,23 +288,25 @@ static int si2157_set_params(struct dvb_frontend *fe) - - switch (c->delivery_system) { - case SYS_ATSC: -- delivery_system = 0x00; -- if_frequency = 3250000; -- break; -- case SYS_DVBC_ANNEX_B: -- delivery_system = 0x10; -- if_frequency = 4000000; -- break; -+ delivery_system = 0x00; -+ if_frequency = 3250000; -+ break; - case SYS_DVBT: - case SYS_DVBT2: /* it seems DVB-T and DVB-T2 both are 0x20 here */ -- delivery_system = 0x20; -- break; -+ delivery_system = 0x20; -+ break; - case SYS_DVBC_ANNEX_A: -- delivery_system = 0x30; -+ delivery_system = 0x30; -+ break; -+ case SYS_DVBC_ANNEX_B: -+ delivery_system = 0x10; -+ break; -+ case SYS_ISDBT: -+ delivery_system = 0x40; - break; - default: -- ret = -EINVAL; -- goto err; -+ ret = -EINVAL; -+ goto err; - } - - memcpy(cmd.args, "\x14\x00\x03\x07\x00\x00", 6); -@@ -436,8 +438,15 @@ static int si2157_probe(struct i2c_client *client, - INIT_DELAYED_WORK(&dev->stat_work, si2157_stat_work); - - /* check if the tuner is there */ -- cmd.wlen = 0; -- cmd.rlen = 1; -+ /* wake tuner */ -+ if (dev->chiptype == SI2157_CHIPTYPE_SI2146) { -+ memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9); -+ cmd.wlen = 9; -+ } else { -+ memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15); -+ cmd.wlen = 15; -+ } -+ cmd.rlen = 1; - ret = si2157_cmd_execute(client, &cmd); - if (ret) - goto err_kfree; -diff --git a/drivers/media/tuners/stv6120.c b/drivers/media/tuners/stv6120.c -new file mode 100644 -index 0000000..9d5cc65 ---- /dev/null -+++ b/drivers/media/tuners/stv6120.c -@@ -0,0 +1,712 @@ -+/* -+ * Driver for the ST STV6120 tuner -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 only, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dvb_frontend.h" -+ -+#include "stv6120.h" -+ -+#define REG_N0 0 -+#define REG_N1_F0 1 -+#define REG_F1 2 -+#define REG_F2_ICP 3 -+#define REG_CF_PDIV 4 -+#define REG_CFHF 5 -+#define REG_CAL 6 -+ -+struct SLookup { -+ s16 Value; -+ u16 RegValue; -+}; -+ -+static struct SLookup Gain_RFAGC_LookUp[] = { -+ /*Gain *100dB*/ /*reg*/ -+ { 7429 , 0 }, /* 74.61 dB */ -+ { 7368 , 18711 }, /* 74.43 dB */ -+ { 7214 , 23432 }, /* 73.36 dB */ -+ { 7090 , 25123 }, /* 72.4 dB */ -+ { 6988 , 26305 }, /* 71.47 dB */ -+ { 6897 , 27100 }, /* 70.47 dB */ -+ { 6809 , 27741 }, /* 69.5 dB */ -+ { 6728 , 28271 }, /* 68.52 dB */ -+ { 6645 , 28737 }, /* 67.52 dB */ -+ { 6571 , 29120 }, /* 66.53 dB */ -+ { 6494 , 29504 }, /* 65.54 dB */ -+ { 6416 , 29857 }, /* 64.55 dB */ -+ { 6341 , 30180 }, /* 63.55 dB */ -+ { 6263 , 30490 }, /* 62.56 dB */ -+ { 6179 , 30815 }, /* 61.57 dB */ -+ { 6101 , 31088 }, /* 60.58 dB */ -+ { 6028 , 31345 }, /* 59.57 dB */ -+ { 5956 , 31600 }, /* 58.59 dB */ -+ { 5883 , 31840 }, /* 57.6 dB */ -+ { 5801 , 32096 }, /* 56.6 dB */ -+ { 5730 , 32320 }, /* 55.59 dB */ -+ { 5659 , 32544 }, /* 54.59 dB */ -+ { 5582 , 32752 }, /* 53.61 dB */ -+ { 5498 , 32960 }, /* 52.61 dB */ -+ { 5414 , 33184 }, /* 51.61 dB */ -+ { 5340 , 33392 }, /* 50.62 dB */ -+ { 5271 , 33584 }, /* 49.61 dB */ -+ { 5198 , 33775 }, /* 48.61 dB */ -+ { 5125 , 33967 }, /* 47.62 dB */ -+ { 5048 , 34160 }, /* 46.62 dB */ -+ { 4963 , 34352 }, /* 45.62 dB */ -+ { 4884 , 34543 }, /* 44.62 dB */ -+ { 4820 , 34719 }, /* 43.62 dB */ -+ { 4740 , 34910 }, /* 42.62 dB */ -+ { 4666 , 35103 }, /* 41.62 dB */ -+ { 4582 , 35295 }, /* 40.62 dB */ -+ { 4500 , 35488 }, /* 39.62 dB */ -+ { 4426 , 35680 }, /* 38.62 dB */ -+ { 4365 , 35870 }, /* 37.62 dB */ -+ { 4279 , 36095 }, /* 36.62 dB */ -+ { 4113 , 36289 }, /* 35.62 dB */ -+ { 4020 , 36500 }, /* 34.62 dB */ -+ { 3930 , 36704 }, /* 33.62 dB */ -+ { 3838 , 36912 }, /* 32.62 dB */ -+ { 3738 , 37152 }, /* 31.62 dB */ -+ { 3648 , 37375 }, /* 30.62 dB */ -+ { 3544 , 37600 }, /* 29.62 dB */ -+ { 3458 , 37823 }, /* 28.62 dB */ -+ { 3358 , 38048 }, /* 27.62 dB */ -+ { 3281 , 38240 }, /* 26.62 dB */ -+ { 3191 , 38479 }, /* 25.62 dB */ -+ { 3091 , 38720 }, /* 24.62 dB */ -+ { 2993 , 38976 }, /* 23.63 dB */ -+ { 2900 , 39226 }, /* 22.63 dB */ -+ { 2792 , 39520 }, /* 21.62 dB */ -+ { 2692 , 39792 }, /* 20.62 dB */ -+ { 2592 , 40064 }, /* 19.62 dB */ -+ { 2497 , 40351 }, /* 18.62 dB */ -+ { 2392 , 40640 }, /* 17.62 dB */ -+ { 2290 , 40976 }, /* 16.62 dB */ -+ { 2189 , 41295 }, /* 15.62 dB */ -+ { 2088 , 41631 }, /* 14.62 dB */ -+ { 1999 , 41934 }, /* 13.62 dB */ -+ { 1875 , 42354 }, /* 12.62 dB */ -+ { 1764 , 42815 }, /* 11.62 dB */ -+ { 1637 , 43263 }, /* 10.62 dB */ -+ { 1537 , 43743 }, /* 9.62 dB */ -+ { 1412 , 44288 }, /* 8.62 dB */ -+ { 1291 , 44913 }, /* 7.62 dB */ -+ { 1188 , 45712 }, /* 6.62 dB */ -+ { 1080 , 46720 }, /* 5.63 dB */ -+ { 976 , 48164 }, /* 4.63 dB */ -+ { 930 , 50816 }, /* 3.63 dB */ -+ { 898 , 65534 }, /* 2.94 dB */ -+ { 880 , 65535 } /* 2.95 dB */ -+}; -+ -+#ifndef ARRAY_SIZE -+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -+#endif -+ -+ -+static const u8 tuner_init[25] = { -+ 0x77, -+ 0x33, 0xce, 0x54, 0x55, 0x0d, 0x32, 0x44, 0x0e, -+ 0xf9, 0x1b, -+ 0x33, 0xce, 0x54, 0x55, 0x0d, 0x32, 0x44, 0x0e, -+ 0x00, 0x00, 0x4c, 0x00, 0x00, 0x4c, -+}; -+ -+LIST_HEAD(stvlist); -+ -+static inline u32 MulDiv32(u32 a, u32 b, u32 c) -+{ -+ u64 tmp64; -+ -+ tmp64 = (u64)a * (u64)b; -+ do_div(tmp64, c); -+ -+ return (u32) tmp64; -+} -+ -+ -+struct stv_base { -+ struct list_head stvlist; -+ -+ u8 adr; -+ struct i2c_adapter *i2c; -+ struct mutex i2c_lock; -+ struct mutex reg_lock; -+ int count; -+}; -+ -+ -+struct stv { -+ struct stv_base *base; -+ struct dvb_frontend *fe; -+ int nr; -+ -+ struct stv6120_cfg *cfg; -+ -+ u8 reg[7]; -+}; -+ -+static int i2c_read(struct i2c_adapter *adap, -+ u8 adr, u8 *msg, int len, u8 *answ, int alen) -+{ -+ struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, -+ .buf = msg, .len = len}, -+ { .addr = adr, .flags = I2C_M_RD, -+ .buf = answ, .len = alen } }; -+ if (i2c_transfer(adap, msgs, 2) != 2) { -+ pr_err("stv6120: i2c_read error\n"); -+ return -1; -+ } -+ return 0; -+} -+ -+static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) -+{ -+ struct i2c_msg msg = {.addr = adr, .flags = 0, -+ .buf = data, .len = len}; -+ -+ if (i2c_transfer(adap, &msg, 1) != 1) { -+ pr_err("stv6120: i2c_write error\n"); -+ return -1; -+ } -+ return 0; -+} -+#if 0 -+static int write_regs(struct stv *state, int reg, int len) -+{ -+ u8 d[8]; -+ -+ u8 base = 0x02 + 0xa * state->nr; -+ -+ memcpy(&d[1], &state->base->reg[reg], len); -+ d[0] = reg; -+ return i2c_write(state->base->i2c, state->base->adr, d, len + 1); -+} -+#endif -+static int write_tuner_regs(struct stv *state) -+{ -+ u8 d[8]; -+ memcpy(&d[1], state->reg, 7); -+ d[0] = 0x02 + 0xa * state->nr; -+ return i2c_write(state->base->i2c, state->base->adr, d, 8); -+} -+ -+static int read_reg(struct stv *state, u8 reg, u8 *val) -+{ -+ return i2c_read(state->base->i2c, state->base->adr, ®, 1, val, 1); -+} -+ -+static int read_regs(struct stv *state, u8 reg, u8 *val, int len) -+{ -+ return i2c_read(state->base->i2c, state->base->adr, ®, 1, val, len); -+} -+ -+#if 0 -+static void dump_regs(struct stv *state) -+{ -+ u8 d[25], *c = &state->reg[0]; -+ -+ read_regs(state, state->nr * 0xa + 2, d, 7); -+ pr_info("stv6120_regs = %02x %02x %02x %02x %02x %02x %02x\n", -+ d[0], d[1], d[2], d[3], d[4], d[5], d[6]); -+ pr_info("reg[] = %02x %02x %02x %02x %02x %02x %02x\n", -+ c[0], c[1], c[2], c[3], c[4], c[5], c[6]); -+ -+ -+ read_regs(state, 0, d, 14); -+ pr_info("global: 0=%02x a=%02x 1=%02x b=%02x\n", d[0], d[0xa], d[1], d[0xb]); -+} -+#endif -+ -+static int wait_for_call_done(struct stv *state, u8 mask) -+{ -+ int status = 0; -+ u32 LockRetryCount = 10; -+ -+ while (LockRetryCount > 0) { -+ u8 Status; -+ -+ status = read_reg(state, state->nr * 0xa + 8, &Status); -+ if (status < 0) -+ return status; -+ -+ if ((Status & mask) == 0) -+ break; -+ usleep_range(4000, 6000); -+ LockRetryCount -= 1; -+ -+ status = -1; -+ } -+ return status; -+} -+ -+static void init_regs(struct stv *state) -+{ -+ u32 clkdiv = 0; -+ u32 agcmode = 0; -+ u32 agcref = 2; -+ u32 agcset = 0xffffffff; -+ u32 bbmode = 0xffffffff; -+ -+/* -+ 0f40 00770133 02ce0354 0455050d 06320744 .w.3...T.U...2.D -+ 0f50 080e09f9 0a030b33 0cce0d54 0e550f0d .......3...T.U.. -+ -+ 0f60 10321144 120e1300 1400154c 16001700 .2.D.......L.... -+ 0f70 184c0000 00000000 00000000 00000000 .L.............. -+*/ -+ -+//i = 0 -+// rd(i) != (i+1) ? -+// wr(i, i+1) -+// repeat until 32 -+// -+// wr(0xa, 0x1b) -+ -+ //memcpy(state->base->reg, tuner_init, 25); -+/* -+ state->ref_freq = 16000; -+ -+ -+ if (clkdiv <= 3) -+ state->reg[0x00] |= (clkdiv & 0x03); -+ if (agcmode <= 3) { -+ state->reg[0x03] |= (agcmode << 5); -+ if (agcmode == 0x01) -+ state->reg[0x01] |= 0x30; -+ } -+ if (bbmode <= 3) -+ state->reg[0x01] = (state->reg[0x01] & ~0x30) | (bbmode << 4); -+ if (agcref <= 7) -+ state->reg[0x03] |= agcref; -+ if (agcset <= 31) -+ state->reg[0x02] = (state->reg[0x02] & ~0x1F) | agcset | 0x40; -+*/ -+} -+ -+static int probe(struct stv *state) -+{ -+ struct dvb_frontend *fe = state->fe; -+ int ret = 0; -+ -+ u8 d[26]; -+ -+ init_regs(state); -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 1); -+ -+ memcpy(&d[1], tuner_init, 25); -+ d[0] = 0; -+ ret = i2c_write(state->base->i2c, state->base->adr, d, 25 + 1); -+ -+ if (ret < 0) -+ goto err; -+#if 0 -+ pr_info("attach_init OK\n"); -+ dump_regs(state); -+#endif -+ -+err: -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 0); -+ return ret; -+} -+ -+static int sleep(struct dvb_frontend *fe) -+{ -+ /* struct tda_state *state = fe->tuner_priv; */ -+ -+ //pr_info("tuner sleep\n"); -+ return 0; -+} -+ -+static int init(struct dvb_frontend *fe) -+{ -+ /* struct tda_state *state = fe->tuner_priv; */ -+ //pr_info("init\n"); -+ return 0; -+} -+ -+static int release(struct dvb_frontend *fe) -+{ -+ struct stv *state = fe->tuner_priv; -+ -+ state->base->count--; -+ if (state->base->count == 0) { -+ //pr_info("remove STV tuner base\n"); -+ list_del(&state->base->stvlist); -+ kfree(state->base); -+ } -+ kfree(state); -+ fe->tuner_priv = NULL; -+ return 0; -+} -+#if 0 -+static int set_bandwidth(struct dvb_frontend *fe, u32 CutOffFrequency) -+{ -+ struct stv *state = fe->tuner_priv; -+ u32 index = (CutOffFrequency + 999999) / 1000000; -+ -+ if (index < 6) -+ index = 6; -+ if (index > 50) -+ index = 50; -+ if ((state->base->reg[0x08] & ~0xFC) == ((index-6) << 2)) -+ return 0; -+ -+ state->base->reg[0x08] = (state->base->reg[0x08] & ~0xFC) | ((index-6) << 2); -+ state->base->reg[0x09] = (state->base->reg[0x09] & ~0x0C) | 0x08; -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 1); -+ write_regs(state, 0x08, 2); -+ wait_for_call_done(state, 0x08); -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 0); -+ return 0; -+} -+ -+#endif -+ -+ -+ -+static int set_lof(struct stv *state, u32 LocalFrequency, u32 CutOffFrequency) -+{ -+ int cf_index = (CutOffFrequency / 1000000) - 5; -+ u32 Frequency = (LocalFrequency + 500) / 1000; // Hz -> kHz -+ u32 p = 1, psel = 0, fvco, div, frac; -+ u8 Icp, tmp; -+ -+ u32 freq = Frequency; -+ u8 PDIV, P; -+ -+ //pr_info("F = %u, CutOff = %u\n", Frequency, CutOffFrequency); -+ -+ -+ /* set PDIV and CF */ -+ if (cf_index < 0) -+ cf_index = 0; -+ if (cf_index > 31) -+ cf_index = 31; -+ -+ if (Frequency >= 1191000) { -+ PDIV = 0; -+ P = 2; -+ } else if (Frequency >= 596000) { -+ PDIV = 1; -+ P = 4; -+ } else if (Frequency >= 299000) { -+ PDIV = 2; -+ P = 8; -+ } else { -+ PDIV = 3; -+ P = 16; -+ } -+ -+ -+ fvco = Frequency * P; -+ div = (fvco * state->cfg->Rdiv) / state->cfg->xtal; -+ -+ /* charge pump current */ -+ Icp = 0; -+ if (fvco < 2472000) -+ Icp = 0; -+ else if (fvco < 2700000) -+ Icp = 1; -+ else if (fvco < 3021000) -+ Icp = 2; -+ else if (fvco < 3387000) -+ Icp = 3; -+ else if (fvco < 3845000) -+ Icp = 5; -+ else if (fvco < 4394000) -+ Icp = 6; -+ else -+ Icp = 7; -+ -+ -+ -+ -+ -+ frac = (fvco * state->cfg->Rdiv) % state->cfg->xtal; -+ frac = MulDiv32(frac, 0x40000, state->cfg->xtal); -+ -+ -+ state->reg[REG_N0] = div & 0xff; -+ state->reg[REG_N1_F0] = (((div >> 8) & 0x01) | ((frac & 0x7f) << 1)) & 0xff; -+ state->reg[REG_F1] = (frac >> 7) & 0xff; -+ state->reg[REG_F2_ICP] &= 0x88; -+ state->reg[REG_F2_ICP] |= (Icp << 4) | ((frac >> 15) & 0x07); -+ state->reg[REG_CF_PDIV] &= 0x9f; -+ state->reg[REG_CF_PDIV] |= ((PDIV << 5) | cf_index); -+ -+ /* Start cal vco,CF */ -+ state->reg[REG_CAL] &= 0xf8; -+ state->reg[REG_CAL] |= 0x06; -+ -+ write_tuner_regs(state); -+ -+ wait_for_call_done(state, 0x06); -+ -+ usleep_range(10000, 12000); -+ -+#if 0 -+ read_reg(state, 0x03, &tmp); -+ if (tmp & 0x10) { -+ state->base->reg[0x02] &= ~0x80; /* LNA NF Mode */ -+ write_regs(state, 2, 1); -+ } -+ read_reg(state, 0x08, &tmp); -+#endif -+ -+// dump_regs(state); -+ return 0; -+} -+ -+static int set_params(struct dvb_frontend *fe) -+{ -+ struct stv *state = fe->tuner_priv; -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ int status; -+ u32 freq, symb, cutoff; -+ u32 rolloff; -+ -+ if (p->delivery_system != SYS_DVBS && p->delivery_system != SYS_DVBS2) -+ return -EINVAL; -+ -+ switch (p->rolloff) { -+ case ROLLOFF_20: -+ rolloff = 120; -+ break; -+ case ROLLOFF_25: -+ rolloff = 125; -+ break; -+ default: -+ rolloff = 135; -+ break; -+ } -+ -+ freq = p->frequency * 1000; -+ symb = p->symbol_rate; -+ cutoff = 5000000 + MulDiv32(p->symbol_rate, rolloff, 200); -+ -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 1); -+ set_lof(state, freq, cutoff); -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 0); -+ return status; -+} -+ -+static int get_frequency(struct dvb_frontend *fe, u32 *frequency) -+{ -+ *frequency = 0; -+ return 0; -+} -+ -+static u32 AGC_Gain[] = { -+ 000, /* 0.0 */ -+ 000, /* 0.1 */ -+ 1000, /* 0.2 */ -+ 2000, /* 0.3 */ -+ 3000, /* 0.4 */ -+ 4000, /* 0.5 */ -+ 5000, /* 0.6 */ -+ 6000, /* 0.7 */ -+ 7000, /* 0.8 */ -+ 14000, /* 0.9 */ -+ 20000, /* 1.0 */ -+ 27000, /* 1.1 */ -+ 32000, /* 1.2 */ -+ 37000, /* 1.3 */ -+ 42000, /* 1.4 */ -+ 47000, /* 1.5 */ -+ 50000, /* 1.6 */ -+ 53000, /* 1.7 */ -+ 56000, /* 1.8 */ -+ 58000, /* 1.9 */ -+ 60000, /* 2.0 */ -+ 62000, /* 2.1 */ -+ 63000, /* 2.2 */ -+ 64000, /* 2.3 */ -+ 64500, /* 2.4 */ -+ 65000, /* 2.5 */ -+ 65500, /* 2.6 */ -+ 66000, /* 2.7 */ -+ 66500, /* 2.8 */ -+ 67000, /* 2.9 */ -+}; -+ -+static s32 TableLookup(struct SLookup *Table, int TableSize, u16 RegValue) -+{ -+ s32 Gain; -+ s32 RegDiff; -+ int imin = 0; -+ int imax = TableSize - 1; -+ int i; -+ -+ // Assumes Table[0].RegValue < Table[imax].RegValue -+ if( RegValue <= Table[0].RegValue ) -+ Gain = Table[0].Value; -+ else if( RegValue >= Table[imax].RegValue ) -+ Gain = Table[imax].Value; -+ else { -+ while(imax-imin > 1) { -+ i = (imax + imin) / 2; -+ if ((Table[imin].RegValue <= RegValue) && -+ (RegValue <= Table[i].RegValue) ) -+ imax = i; -+ else -+ imin = i; -+ } -+ RegDiff = Table[imax].RegValue - Table[imin].RegValue; -+ Gain = Table[imin].Value; -+ if (RegDiff != 0) -+ Gain += ((s32) (RegValue - Table[imin].RegValue) * -+ (s32)(Table[imax].Value - Table[imin].Value))/(RegDiff); -+ } -+ return Gain; -+} -+ -+static int get_rf_strength(struct dvb_frontend *fe, u16 *st) -+{ -+ struct stv *state = fe->tuner_priv; -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ -+ s32 gain = 1, ref_bbgain = 12, tilt = 6; -+ u32 freq; -+ -+ gain = TableLookup(Gain_RFAGC_LookUp, ARRAY_SIZE(Gain_RFAGC_LookUp), *st); -+ -+ gain += 100 * (6 - ref_bbgain); -+ -+ freq = p->frequency / 10000; -+ -+ if (freq<159) -+ gain -= 200; /* HMR filter 2dB gain compensation below freq=1590MHz */ -+ -+ gain-=(((freq-155)*tilt)/12)*10; -+ //pr_warn("%s: str = %u\n", __func__, *st); -+ -+ return 0; -+} -+ -+static int get_if(struct dvb_frontend *fe, u32 *frequency) -+{ -+ *frequency = 0; -+ return 0; -+} -+ -+static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -+{ -+ return 0; -+} -+ -+static struct dvb_tuner_ops tuner_ops = { -+ .info = { -+ .name = "STV6120", -+ .frequency_min = 950000, -+ .frequency_max = 2150000, -+ .frequency_step = 0 -+ }, -+ .init = init, -+ .sleep = sleep, -+ .set_params = set_params, -+ .release = release, -+// .get_frequency = get_frequency, -+// .get_if_frequency = get_if, -+// .get_bandwidth = get_bandwidth, -+ .get_rf_strength = get_rf_strength, -+// .set_bandwidth = set_bandwidth, -+}; -+ -+static struct stv_base *match_base(struct i2c_adapter *i2c, u8 adr) -+{ -+ struct stv_base *p; -+ -+ list_for_each_entry(p, &stvlist, stvlist) -+ if (p->i2c == i2c && p->adr == adr) -+ return p; -+ return NULL; -+} -+ -+ -+struct dvb_frontend *stv6120_attach(struct dvb_frontend *fe, -+ struct i2c_adapter *i2c, struct stv6120_cfg *cfg, int nr) -+{ -+ struct stv *state; -+ struct stv_base *base; -+ int stat = 0; -+ -+ state = kzalloc(sizeof(struct stv), GFP_KERNEL); -+ if (!state) -+ return NULL; -+ memcpy(&fe->ops.tuner_ops, &tuner_ops, sizeof(struct dvb_tuner_ops)); -+ state->fe = fe; -+ memcpy(state->reg, &tuner_init[2], 7); -+ -+ base = match_base(i2c, cfg->adr); -+ if (base) { -+ base->count++; -+ state->base = base; -+ } else { -+ base = kzalloc(sizeof(struct stv_base), GFP_KERNEL); -+ if (!base) -+ goto fail; -+ base->i2c = i2c; -+ base->adr = cfg->adr; -+ base->count = 1; -+ mutex_init(&base->i2c_lock); -+ mutex_init(&base->reg_lock); -+ state->base = base; -+ if (probe(state) < 0) { -+ kfree(base); -+ goto fail; -+ } -+ list_add(&base->stvlist, &stvlist); -+ } -+ -+ -+ if (cfg->xtal == 0) { -+ printk("xtal=0!!!\n"); -+ goto fail; -+ } -+ -+ state->cfg = cfg; -+ state->nr = nr; -+ -+ fe->tuner_priv = state; -+ return fe; -+fail: -+ kfree(state); -+ return NULL; -+} -+EXPORT_SYMBOL_GPL(stv6120_attach); -+ -+MODULE_DESCRIPTION("STV6120 driver"); -+MODULE_AUTHOR("Luis Alves"); -+MODULE_LICENSE("GPL"); -+ -diff --git a/drivers/media/tuners/stv6120.h b/drivers/media/tuners/stv6120.h -new file mode 100644 -index 0000000..e907e41 ---- /dev/null -+++ b/drivers/media/tuners/stv6120.h -@@ -0,0 +1,17 @@ -+#ifndef _STV6120_H_ -+#define _STV6120_H_ -+ -+ -+struct stv6120_cfg { -+ u8 adr; -+ -+ u32 xtal; -+ u8 Rdiv; -+}; -+ -+ -+ -+ -+struct dvb_frontend *stv6120_attach(struct dvb_frontend *fe, -+ struct i2c_adapter *i2c, struct stv6120_cfg *cfg, int nr); -+#endif -diff --git a/drivers/media/tuners/tda18212.c b/drivers/media/tuners/tda18212.c -index 7b80683..fd827b4 100644 ---- a/drivers/media/tuners/tda18212.c -+++ b/drivers/media/tuners/tda18212.c -@@ -95,6 +95,7 @@ static int tda18212_set_params(struct dvb_frontend *fe) - ret = -EINVAL; - goto error; - } -+ buf[0] = 0x30; - break; - case SYS_DVBT2: - switch (c->bandwidth_hz) { -@@ -114,11 +115,13 @@ static int tda18212_set_params(struct dvb_frontend *fe) - ret = -EINVAL; - goto error; - } -+ buf[0] = 0x30; - break; - case SYS_DVBC_ANNEX_A: - case SYS_DVBC_ANNEX_C: - if_khz = dev->cfg.if_dvbc; - i = DVBC_8; -+ buf[0] = 0x00; - break; - default: - ret = -EINVAL; -@@ -129,17 +132,28 @@ static int tda18212_set_params(struct dvb_frontend *fe) - if (ret) - goto error; - -+ ret = regmap_write(dev->regmap, 0x5f, 0x00); -+ if (ret) -+ goto error; -+ - ret = regmap_write(dev->regmap, 0x06, 0x00); - if (ret) - goto error; - -+ if (dev->cfg.loop_through) -+ buf[0] |= 0x80; -+ -+ ret = regmap_write(dev->regmap, 0x0c, buf[0]); -+ if (ret) -+ goto error; -+ - ret = regmap_write(dev->regmap, 0x0f, bw_params[i][0]); - if (ret) - goto error; - - buf[0] = 0x02; - buf[1] = bw_params[i][1]; -- buf[2] = 0x03; /* default value */ -+ buf[2] = dev->cfg.xtout ? 0x43 : 0x40; /* 0x03; default value */ - buf[3] = DIV_ROUND_CLOSEST(if_khz, 50); - buf[4] = ((c->frequency / 1000) >> 16) & 0xff; - buf[5] = ((c->frequency / 1000) >> 8) & 0xff; -diff --git a/drivers/media/tuners/tda18212.h b/drivers/media/tuners/tda18212.h -index 6391daf..7b1ff03 100644 ---- a/drivers/media/tuners/tda18212.h -+++ b/drivers/media/tuners/tda18212.h -@@ -34,6 +34,8 @@ struct tda18212_config { - u16 if_dvbc; - u16 if_atsc_vsb; - u16 if_atsc_qam; -+ u8 loop_through:1; -+ u8 xtout:1; - - /* - * pointer to DVB frontend -diff --git a/drivers/media/tuners/tda18273.c b/drivers/media/tuners/tda18273.c -new file mode 100644 -index 0000000..ac2cbae ---- /dev/null -+++ b/drivers/media/tuners/tda18273.c -@@ -0,0 +1,2184 @@ -+/* -+ tda18273.c - driver for the NXP TDA18273 silicon tuner -+ Copyright (C) 2014 CrazyCat -+ -+ 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. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "dvb_frontend.h" -+ -+#include "tda18273_priv.h" -+ -+static unsigned int verbose; -+module_param(verbose, int, 0644); -+MODULE_PARM_DESC(verbose, "Set Verbosity level"); -+ -+#define FE_ERROR 0 -+#define FE_NOTICE 1 -+#define FE_INFO 2 -+#define FE_DEBUG 3 -+#define FE_DEBUGREG 4 -+ -+#define dprintk(__y, __z, format, arg...) do { \ -+ if (__z) { \ -+ if ((verbose > FE_ERROR) && (verbose > __y)) \ -+ printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ -+ else if ((verbose > FE_NOTICE) && (verbose > __y)) \ -+ printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ -+ else if ((verbose > FE_INFO) && (verbose > __y)) \ -+ printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ -+ else if ((verbose > FE_DEBUG) && (verbose > __y)) \ -+ printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ -+ } else { \ -+ if (verbose > __y) \ -+ printk(format, ##arg); \ -+ } \ -+} while (0) -+ -+#define TDA18273_REG_ADD_SZ (0x01) -+#define TDA18273_REG_DATA_MAX_SZ (0x01) -+#define TDA18273_REG_MAP_NB_BYTES (0x6D) -+ -+#define TDA18273_REG_DATA_LEN(_FIRST_REG, _LAST_REG) ( (_LAST_REG.Address - _FIRST_REG.Address) + 1) -+ -+struct tda18273_state { -+ struct dvb_frontend *fe; -+ struct i2c_adapter *i2c; -+ u8 i2c_addr; -+ -+ unsigned int if_freq; -+ unsigned int freq_hz; -+ unsigned int bandwidth; -+ unsigned char freq_band; -+ unsigned char agc_mode; -+ unsigned char pll_step; -+ unsigned char pll_step_val; -+ unsigned char pll_charge_pump; -+ -+ unsigned int power_state; -+ unsigned char regmap[TDA18273_REG_MAP_NB_BYTES]; -+ -+ pTDA18273Object_t pObj; -+}; -+ -+TDA18273Object_t gTDA18273Instance = -+{ -+ 0, -+ 0, -+ 0, -+ TDA18273_StandardMode_Unknown, -+ NULL, -+ TDA18273_INSTANCE_CUSTOM_STD_DEF -+}; -+ -+ -+/* TDA18273 Register ID_byte_1 0x00 */ -+const TDA18273_BitField_t gTDA18273_Reg_ID_byte_1 = { 0x00, 0x00, 0x08, 0x00 }; -+/* MS bit(s): Indicate if Device is a Master or a Slave */ -+/* 1 => Master device */ -+/* 0 => Slave device */ -+const TDA18273_BitField_t gTDA18273_Reg_ID_byte_1__MS = { 0x00, 0x07, 0x01, 0x00 }; -+/* Ident_1 bit(s): MSB of device identifier */ -+const TDA18273_BitField_t gTDA18273_Reg_ID_byte_1__Ident_1 = { 0x00, 0x00, 0x07, 0x00 }; -+ -+ -+/* TDA18273 Register ID_byte_2 0x01 */ -+const TDA18273_BitField_t gTDA18273_Reg_ID_byte_2 = { 0x01, 0x00, 0x08, 0x00 }; -+/* Ident_2 bit(s): LSB of device identifier */ -+const TDA18273_BitField_t gTDA18273_Reg_ID_byte_2__Ident_2 = { 0x01, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register ID_byte_3 0x02 */ -+const TDA18273_BitField_t gTDA18273_Reg_ID_byte_3 = { 0x02, 0x00, 0x08, 0x00 }; -+/* Major_rev bit(s): Major revision of device */ -+const TDA18273_BitField_t gTDA18273_Reg_ID_byte_3__Major_rev = { 0x02, 0x04, 0x04, 0x00 }; -+/* Major_rev bit(s): Minor revision of device */ -+const TDA18273_BitField_t gTDA18273_Reg_ID_byte_3__Minor_rev = { 0x02, 0x00, 0x04, 0x00 }; -+ -+ -+/* TDA18273 Register Thermo_byte_1 0x03 */ -+const TDA18273_BitField_t gTDA18273_Reg_Thermo_byte_1 = { 0x03, 0x00, 0x08, 0x00 }; -+/* TM_D bit(s): Device temperature */ -+const TDA18273_BitField_t gTDA18273_Reg_Thermo_byte_1__TM_D = { 0x03, 0x00, 0x07, 0x00 }; -+ -+ -+/* TDA18273 Register Thermo_byte_2 0x04 */ -+const TDA18273_BitField_t gTDA18273_Reg_Thermo_byte_2 = { 0x04, 0x00, 0x08, 0x00 }; -+/* TM_ON bit(s): Set device temperature measurement to ON or OFF */ -+/* 1 => Temperature measurement ON */ -+/* 0 => Temperature measurement OFF */ -+const TDA18273_BitField_t gTDA18273_Reg_Thermo_byte_2__TM_ON = { 0x04, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register Power_state_byte_1 0x05 */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_state_byte_1 = { 0x05, 0x00, 0x08, 0x00 }; -+/* POR bit(s): Indicates that device just powered ON */ -+/* 1 => POR: No access done to device */ -+/* 0 => At least one access has been done to device */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_state_byte_1__POR = { 0x05, 0x07, 0x01, 0x00 }; -+/* AGCs_Lock bit(s): Indicates that AGCs are locked */ -+/* 1 => AGCs locked */ -+/* 0 => AGCs not locked */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_state_byte_1__AGCs_Lock = { 0x05, 0x02, 0x01, 0x00 }; -+/* Vsync_Lock bit(s): Indicates that VSync is locked */ -+/* 1 => VSync locked */ -+/* 0 => VSync not locked */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_state_byte_1__Vsync_Lock = { 0x05, 0x01, 0x01, 0x00 }; -+/* LO_Lock bit(s): Indicates that LO is locked */ -+/* 1 => LO locked */ -+/* 0 => LO not locked */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_state_byte_1__LO_Lock = { 0x05, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register Power_state_byte_2 0x06 */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_state_byte_2 = { 0x06, 0x00, 0x08, 0x00 }; -+/* SM bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_state_byte_2__SM = { 0x06, 0x01, 0x01, 0x00 }; -+/* SM_XT bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_state_byte_2__SM_XT = { 0x06, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register Input_Power_Level_byte 0x07 */ -+const TDA18273_BitField_t gTDA18273_Reg_Input_Power_Level_byte = { 0x07, 0x00, 0x08, 0x00 }; -+/* Power_Level bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Input_Power_Level_byte__Power_Level = { 0x07, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register IRQ_status 0x08 */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_status = { 0x08, 0x00, 0x08, 0x00 }; -+/* IRQ_status bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_status__IRQ_status = { 0x08, 0x07, 0x01, 0x00 }; -+/* MSM_XtalCal_End bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_status__MSM_XtalCal_End = { 0x08, 0x05, 0x01, 0x00 }; -+/* MSM_RSSI_End bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_status__MSM_RSSI_End = { 0x08, 0x04, 0x01, 0x00 }; -+/* MSM_LOCalc_End bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_status__MSM_LOCalc_End = { 0x08, 0x03, 0x01, 0x00 }; -+/* MSM_RFCal_End bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_status__MSM_RFCal_End = { 0x08, 0x02, 0x01, 0x00 }; -+/* MSM_IRCAL_End bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_status__MSM_IRCAL_End = { 0x08, 0x01, 0x01, 0x00 }; -+/* MSM_RCCal_End bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_status__MSM_RCCal_End = { 0x08, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register IRQ_enable 0x09 */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_enable = { 0x09, 0x00, 0x08, 0x00 }; -+/* IRQ_Enable bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_enable__IRQ_Enable = { 0x09, 0x07, 0x01, 0x00 }; -+/* MSM_XtalCal_Enable bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_enable__MSM_XtalCal_Enable = { 0x09, 0x05, 0x01, 0x00 }; -+/* MSM_RSSI_Enable bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_enable__MSM_RSSI_Enable = { 0x09, 0x04, 0x01, 0x00 }; -+/* MSM_LOCalc_Enable bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_enable__MSM_LOCalc_Enable = { 0x09, 0x03, 0x01, 0x00 }; -+/* MSM_RFCal_Enable bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_enable__MSM_RFCal_Enable = { 0x09, 0x02, 0x01, 0x00 }; -+/* MSM_IRCAL_Enable bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_enable__MSM_IRCAL_Enable = { 0x09, 0x01, 0x01, 0x00 }; -+/* MSM_RCCal_Enable bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_enable__MSM_RCCal_Enable = { 0x09, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register IRQ_clear 0x0A */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_clear = { 0x0A, 0x00, 0x08, 0x00 }; -+/* IRQ_Clear bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_clear__IRQ_Clear = { 0x0A, 0x07, 0x01, 0x00 }; -+/* MSM_XtalCal_Clear bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_clear__MSM_XtalCal_Clear = { 0x0A, 0x05, 0x01, 0x00 }; -+/* MSM_RSSI_Clear bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_clear__MSM_RSSI_Clear = { 0x0A, 0x04, 0x01, 0x00 }; -+/* MSM_LOCalc_Clear bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_clear__MSM_LOCalc_Clear = { 0x0A, 0x03, 0x01, 0x00 }; -+/* MSM_RFCal_Clear bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_clear__MSM_RFCal_Clear = { 0x0A, 0x02, 0x01, 0x00 }; -+/* MSM_IRCAL_Clear bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_clear__MSM_IRCAL_Clear = { 0x0A, 0x01, 0x01, 0x00 }; -+/* MSM_RCCal_Clear bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_clear__MSM_RCCal_Clear = { 0x0A, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register IRQ_set 0x0B */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_set = { 0x0B, 0x00, 0x08, 0x00 }; -+/* IRQ_Set bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_set__IRQ_Set = { 0x0B, 0x07, 0x01, 0x00 }; -+/* MSM_XtalCal_Set bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_set__MSM_XtalCal_Set = { 0x0B, 0x05, 0x01, 0x00 }; -+/* MSM_RSSI_Set bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_set__MSM_RSSI_Set = { 0x0B, 0x04, 0x01, 0x00 }; -+/* MSM_LOCalc_Set bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_set__MSM_LOCalc_Set = { 0x0B, 0x03, 0x01, 0x00 }; -+/* MSM_RFCal_Set bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_set__MSM_RFCal_Set = { 0x0B, 0x02, 0x01, 0x00 }; -+/* MSM_IRCAL_Set bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_set__MSM_IRCAL_Set = { 0x0B, 0x01, 0x01, 0x00 }; -+/* MSM_RCCal_Set bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IRQ_set__MSM_RCCal_Set = { 0x0B, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register AGC1_byte_1 0x0C */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC1_byte_1 = { 0x0C, 0x00, 0x08, 0x00 }; -+/* AGC1_TOP bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC1_byte_1__AGC1_TOP = { 0x0C, 0x00, 0x04, 0x00 }; -+ -+ -+/* TDA18273 Register AGC1_byte_2 0x0D */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC1_byte_2 = { 0x0D, 0x00, 0x08, 0x00 }; -+/* AGC1_Top_Mode_Val bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC1_byte_2__AGC1_Top_Mode_Val = { 0x0D, 0x03, 0x02, 0x00 }; -+/* AGC1_Top_Mode bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC1_byte_2__AGC1_Top_Mode = { 0x0D, 0x00, 0x03, 0x00 }; -+ -+ -+/* TDA18273 Register AGC2_byte_1 0x0E */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC2_byte_1 = { 0x0E, 0x00, 0x08, 0x00 }; -+/* AGC2_TOP bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC2_byte_1__AGC2_TOP = { 0x0E, 0x00, 0x03, 0x00 }; -+ -+ -+/* TDA18273 Register AGCK_byte_1 0x0F */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCK_byte_1 = { 0x0F, 0x00, 0x08, 0x00 }; -+/* AGCs_Up_Step_assym bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCK_byte_1__AGCs_Up_Step_assym = { 0x0F, 0x06, 0x02, 0x00 }; -+/* Pulse_Shaper_Disable bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCK_byte_1__Pulse_Shaper_Disable = { 0x0F, 0x04, 0x01, 0x00 }; -+/* AGCK_Step bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCK_byte_1__AGCK_Step = { 0x0F, 0x02, 0x02, 0x00 }; -+/* AGCK_Mode bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCK_byte_1__AGCK_Mode = { 0x0F, 0x00, 0x02, 0x00 }; -+ -+ -+/* TDA18273 Register RF_AGC_byte 0x10 */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_AGC_byte = { 0x10, 0x00, 0x08, 0x00 }; -+/* PD_AGC_Adapt3x bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_AGC_byte__PD_AGC_Adapt3x = { 0x10, 0x06, 0x02, 0x00 }; -+/* RFAGC_Adapt_TOP bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_AGC_byte__RFAGC_Adapt_TOP = { 0x10, 0x04, 0x02, 0x00 }; -+/* RFAGC_Low_BW bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_AGC_byte__RFAGC_Low_BW = { 0x10, 0x03, 0x01, 0x00 }; -+/* RFAGC_Top bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_AGC_byte__RFAGC_Top = { 0x10, 0x00, 0x03, 0x00 }; -+ -+ -+/* TDA18273 Register W_Filter_byte 0x11 */ -+const TDA18273_BitField_t gTDA18273_Reg_W_Filter_byte = { 0x11, 0x00, 0x08, 0x00 }; -+/* VHF_III_mode bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_W_Filter_byte__VHF_III_mode = { 0x11, 0x07, 0x01, 0x00 }; -+/* RF_Atten_3dB bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_W_Filter_byte__RF_Atten_3dB = { 0x11, 0x06, 0x01, 0x00 }; -+/* W_Filter_Enable bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_W_Filter_byte__W_Filter_Enable = { 0x11, 0x05, 0x01, 0x00 }; -+/* W_Filter_Bypass bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_W_Filter_byte__W_Filter_Bypass = { 0x11, 0x04, 0x01, 0x00 }; -+/* W_Filter bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_W_Filter_byte__W_Filter = { 0x11, 0x02, 0x02, 0x00 }; -+/* W_Filter_Offset bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_W_Filter_byte__W_Filter_Offset = { 0x11, 0x00, 0x02, 0x00 }; -+ -+ -+/* TDA18273 Register IR_Mixer_byte_1 0x12 */ -+const TDA18273_BitField_t gTDA18273_Reg_IR_Mixer_byte_1 = { 0x12, 0x00, 0x08, 0x00 }; -+/* S2D_Gain bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IR_Mixer_byte_1__S2D_Gain = { 0x12, 0x04, 0x02, 0x00 }; -+/* IR_Mixer_Top bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IR_Mixer_byte_1__IR_Mixer_Top = { 0x12, 0x00, 0x04, 0x00 }; -+ -+ -+/* TDA18273 Register AGC5_byte_1 0x13 */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC5_byte_1 = { 0x13, 0x00, 0x08, 0x00 }; -+/* AGCs_Do_Step_assym bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC5_byte_1__AGCs_Do_Step_assym = { 0x13, 0x05, 0x02, 0x00 }; -+/* AGC5_Ana bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC5_byte_1__AGC5_Ana = { 0x13, 0x04, 0x01, 0x00 }; -+/* AGC5_TOP bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC5_byte_1__AGC5_TOP = { 0x13, 0x00, 0x04, 0x00 }; -+ -+ -+/* TDA18273 Register IF_AGC_byte 0x14 */ -+const TDA18273_BitField_t gTDA18273_Reg_IF_AGC_byte = { 0x14, 0x00, 0x08, 0x00 }; -+/* IFnotchToRSSI bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IF_AGC_byte__IFnotchToRSSI = { 0x14, 0x07, 0x01, 0x00 }; -+/* LPF_DCOffset_Corr bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IF_AGC_byte__LPF_DCOffset_Corr = { 0x14, 0x06, 0x01, 0x00 }; -+/* IF_level bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IF_AGC_byte__IF_level = { 0x14, 0x00, 0x03, 0x00 }; -+ -+ -+/* TDA18273 Register IF_Byte_1 0x15 */ -+const TDA18273_BitField_t gTDA18273_Reg_IF_Byte_1 = { 0x15, 0x00, 0x08, 0x00 }; -+/* IF_HP_Fc bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IF_Byte_1__IF_HP_Fc = { 0x15, 0x06, 0x02, 0x00 }; -+/* IF_ATSC_Notch bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IF_Byte_1__IF_ATSC_Notch = { 0x15, 0x05, 0x01, 0x00 }; -+/* LP_FC_Offset bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IF_Byte_1__LP_FC_Offset = { 0x15, 0x03, 0x02, 0x00 }; -+/* LP_Fc bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IF_Byte_1__LP_Fc = { 0x15, 0x00, 0x03, 0x00 }; -+ -+ -+/* TDA18273 Register Reference_Byte 0x16 */ -+const TDA18273_BitField_t gTDA18273_Reg_Reference_Byte = { 0x16, 0x00, 0x08, 0x00 }; -+/* Digital_Clock_Mode bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode = { 0x16, 0x06, 0x02, 0x00 }; -+/* XTout bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Reference_Byte__XTout = { 0x16, 0x00, 0x02, 0x00 }; -+ -+ -+/* TDA18273 Register IF_Frequency_byte 0x17 */ -+const TDA18273_BitField_t gTDA18273_Reg_IF_Frequency_byte = { 0x17, 0x00, 0x08, 0x00 }; -+/* IF_Freq bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IF_Frequency_byte__IF_Freq = { 0x17, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register RF_Frequency_byte_1 0x18 */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Frequency_byte_1 = { 0x18, 0x00, 0x08, 0x00 }; -+/* RF_Freq_1 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Frequency_byte_1__RF_Freq_1 = { 0x18, 0x00, 0x04, 0x00 }; -+ -+ -+/* TDA18273 Register RF_Frequency_byte_2 0x19 */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Frequency_byte_2 = { 0x19, 0x00, 0x08, 0x00 }; -+/* RF_Freq_2 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Frequency_byte_2__RF_Freq_2 = { 0x19, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register RF_Frequency_byte_3 0x1A */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Frequency_byte_3 = { 0x1A, 0x00, 0x08, 0x00 }; -+/* RF_Freq_3 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Frequency_byte_3__RF_Freq_3 = { 0x1A, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register MSM_byte_1 0x1B */ -+const TDA18273_BitField_t gTDA18273_Reg_MSM_byte_1 = { 0x1B, 0x00, 0x08, 0x00 }; -+/* RSSI_Meas bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_MSM_byte_1__RSSI_Meas = { 0x1B, 0x07, 0x01, 0x00 }; -+/* RF_CAL_AV bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_MSM_byte_1__RF_CAL_AV = { 0x1B, 0x06, 0x01, 0x00 }; -+/* RF_CAL bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_MSM_byte_1__RF_CAL = { 0x1B, 0x05, 0x01, 0x00 }; -+/* IR_CAL_Loop bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_MSM_byte_1__IR_CAL_Loop = { 0x1B, 0x04, 0x01, 0x00 }; -+/* IR_Cal_Image bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_MSM_byte_1__IR_Cal_Image = { 0x1B, 0x03, 0x01, 0x00 }; -+/* IR_CAL_Wanted bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_MSM_byte_1__IR_CAL_Wanted = { 0x1B, 0x02, 0x01, 0x00 }; -+/* RC_Cal bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_MSM_byte_1__RC_Cal = { 0x1B, 0x01, 0x01, 0x00 }; -+/* Calc_PLL bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_MSM_byte_1__Calc_PLL = { 0x1B, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register MSM_byte_2 0x1C */ -+const TDA18273_BitField_t gTDA18273_Reg_MSM_byte_2 = { 0x1C, 0x00, 0x08, 0x00 }; -+/* XtalCal_Launch bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_MSM_byte_2__XtalCal_Launch = { 0x1C, 0x01, 0x01, 0x00 }; -+/* MSM_Launch bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_MSM_byte_2__MSM_Launch = { 0x1C, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register PowerSavingMode 0x1D */ -+const TDA18273_BitField_t gTDA18273_Reg_PowerSavingMode = { 0x1D, 0x00, 0x08, 0x00 }; -+/* PSM_AGC1 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_PowerSavingMode__PSM_AGC1 = { 0x1D, 0x07, 0x01, 0x00 }; -+/* PSM_Bandsplit_Filter bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_PowerSavingMode__PSM_Bandsplit_Filter = { 0x1D, 0x05, 0x02, 0x00 }; -+/* PSM_RFpoly bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_PowerSavingMode__PSM_RFpoly = { 0x1D, 0x04, 0x01, 0x00 }; -+/* PSM_Mixer bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_PowerSavingMode__PSM_Mixer = { 0x1D, 0x03, 0x01, 0x00 }; -+/* PSM_Ifpoly bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_PowerSavingMode__PSM_Ifpoly = { 0x1D, 0x02, 0x01, 0x00 }; -+/* PSM_Lodriver bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_PowerSavingMode__PSM_Lodriver = { 0x1D, 0x00, 0x02, 0x00 }; -+ -+ -+/* TDA18273 Register Power_Level_byte_2 0x1E */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_Level_byte_2 = { 0x1E, 0x00, 0x08, 0x00 }; -+/* PD_PLD_read bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_Level_byte_2__PD_PLD_read = { 0x1E, 0x07, 0x01, 0x00 }; -+/* IR_Target bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_Level_byte_2__PLD_Temp_Slope = { 0x1E, 0x05, 0x02, 0x00 }; -+/* IR_GStep bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_Level_byte_2__PLD_Gain_Corr = { 0x1E, 0x00, 0x05, 0x00 }; -+ -+ -+/* TDA18273 Register Adapt_Top_byte 0x1F */ -+const TDA18273_BitField_t gTDA18273_Reg_Adapt_Top_byte = { 0x1F, 0x00, 0x08, 0x00 }; -+/* Fast_Mode_AGC bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Adapt_Top_byte__Fast_Mode_AGC = { 0x1F, 0x06, 0x01, 0x00 }; -+/* Range_LNA_Adapt bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Adapt_Top_byte__Range_LNA_Adapt = { 0x1F, 0x05, 0x01, 0x00 }; -+/* Index_K_LNA_Adapt bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Adapt_Top_byte__Index_K_LNA_Adapt = { 0x1F, 0x03, 0x02, 0x00 }; -+/* Index_K_Top_Adapt bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Adapt_Top_byte__Index_K_Top_Adapt = { 0x1F, 0x01, 0x02, 0x00 }; -+/* Ovld_Udld_FastUp bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Adapt_Top_byte__Ovld_Udld_FastUp = { 0x1F, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register Vsync_byte 0x20 */ -+const TDA18273_BitField_t gTDA18273_Reg_Vsync_byte = { 0x20, 0x00, 0x08, 0x00 }; -+/* Neg_modulation bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Vsync_byte__Neg_modulation = { 0x20, 0x07, 0x01, 0x00 }; -+/* Tracer_Step bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Vsync_byte__Tracer_Step = { 0x20, 0x05, 0x02, 0x00 }; -+/* Vsync_int bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Vsync_byte__Vsync_int = { 0x20, 0x04, 0x01, 0x00 }; -+/* Vsync_Thresh bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Vsync_byte__Vsync_Thresh = { 0x20, 0x02, 0x02, 0x00 }; -+/* Vsync_Len bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Vsync_byte__Vsync_Len = { 0x20, 0x00, 0x02, 0x00 }; -+ -+ -+/* TDA18273 Register Vsync_Mgt_byte 0x21 */ -+const TDA18273_BitField_t gTDA18273_Reg_Vsync_Mgt_byte = { 0x21, 0x00, 0x08, 0x00 }; -+/* PD_Vsync_Mgt bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Vsync_Mgt_byte__PD_Vsync_Mgt = { 0x21, 0x07, 0x01, 0x00 }; -+/* PD_Ovld bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Vsync_Mgt_byte__PD_Ovld = { 0x21, 0x06, 0x01, 0x00 }; -+/* PD_Ovld_RF bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Vsync_Mgt_byte__PD_Ovld_RF = { 0x21, 0x05, 0x01, 0x00 }; -+/* AGC_Ovld_TOP bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Vsync_Mgt_byte__AGC_Ovld_TOP = { 0x21, 0x02, 0x03, 0x00 }; -+/* Up_Step_Ovld bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Vsync_Mgt_byte__Up_Step_Ovld = { 0x21, 0x01, 0x01, 0x00 }; -+/* AGC_Ovld_Timer bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Vsync_Mgt_byte__AGC_Ovld_Timer = { 0x21, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register IR_Mixer_byte_2 0x22 */ -+const TDA18273_BitField_t gTDA18273_Reg_IR_Mixer_byte_2 = { 0x22, 0x00, 0x08, 0x00 }; -+/* IR_Mixer_loop_off bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IR_Mixer_byte_2__IR_Mixer_loop_off = { 0x22, 0x07, 0x01, 0x00 }; -+/* IR_Mixer_Do_step bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IR_Mixer_byte_2__IR_Mixer_Do_step = { 0x22, 0x05, 0x02, 0x00 }; -+/* Hi_Pass bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IR_Mixer_byte_2__Hi_Pass = { 0x22, 0x01, 0x01, 0x00 }; -+/* IF_Notch bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IR_Mixer_byte_2__IF_Notch = { 0x22, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register AGC1_byte_3 0x23 */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC1_byte_3 = { 0x23, 0x00, 0x08, 0x00 }; -+/* AGC1_loop_off bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC1_byte_3__AGC1_loop_off = { 0x23, 0x07, 0x01, 0x00 }; -+/* AGC1_Do_step bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC1_byte_3__AGC1_Do_step = { 0x23, 0x05, 0x02, 0x00 }; -+/* Force_AGC1_gain bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC1_byte_3__Force_AGC1_gain = { 0x23, 0x04, 0x01, 0x00 }; -+/* AGC1_Gain bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC1_byte_3__AGC1_Gain = { 0x23, 0x00, 0x04, 0x00 }; -+ -+ -+/* TDA18273 Register RFAGCs_Gain_byte_1 0x24 */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_1 = { 0x24, 0x00, 0x08, 0x00 }; -+/* PLD_DAC_Scale bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_1__PLD_DAC_Scale = { 0x24, 0x07, 0x01, 0x00 }; -+/* PLD_CC_Enable bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_1__PLD_CC_Enable = { 0x24, 0x06, 0x01, 0x00 }; -+/* PLD_Temp_Enable bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_1__PLD_Temp_Enable = { 0x24, 0x05, 0x01, 0x00 }; -+/* TH_AGC_Adapt34 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_1__TH_AGC_Adapt34 = { 0x24, 0x04, 0x01, 0x00 }; -+/* RFAGC_Sense_Enable bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_1__RFAGC_Sense_Enable = { 0x24, 0x02, 0x01, 0x00 }; -+/* RFAGC_K_Bypass bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_1__RFAGC_K_Bypass = { 0x24, 0x01, 0x01, 0x00 }; -+/* RFAGC_K_8 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_1__RFAGC_K_8 = { 0x24, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register RFAGCs_Gain_byte_2 0x25 */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_2 = { 0x25, 0x00, 0x08, 0x00 }; -+/* RFAGC_K bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_2__RFAGC_K = { 0x25, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register AGC5_byte_2 0x26 */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC5_byte_2 = { 0x26, 0x00, 0x08, 0x00 }; -+/* AGC5_loop_off bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC5_byte_2__AGC5_loop_off = { 0x26, 0x07, 0x01, 0x00 }; -+/* AGC5_Do_step bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC5_byte_2__AGC5_Do_step = { 0x26, 0x05, 0x02, 0x00 }; -+/* Force_AGC5_gain bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC5_byte_2__Force_AGC5_gain = { 0x26, 0x03, 0x01, 0x00 }; -+/* AGC5_Gain bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGC5_byte_2__AGC5_Gain = { 0x26, 0x00, 0x03, 0x00 }; -+ -+ -+/* TDA18273 Register RF_Cal_byte_1 0x27 */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_1 = { 0x27, 0x00, 0x08, 0x00 }; -+/* RFCAL_Offset_Cprog0 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_1__RFCAL_Offset_Cprog0 = { 0x27, 0x06, 0x02, 0x00 }; -+/* RFCAL_Offset_Cprog1 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_1__RFCAL_Offset_Cprog1 = { 0x27, 0x04, 0x02, 0x00 }; -+/* RFCAL_Offset_Cprog2 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_1__RFCAL_Offset_Cprog2 = { 0x27, 0x02, 0x02, 0x00 }; -+/* RFCAL_Offset_Cprog3 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_1__RFCAL_Offset_Cprog3 = { 0x27, 0x00, 0x02, 0x00 }; -+ -+ -+/* TDA18273 Register RF_Cal_byte_2 0x28 */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_2 = { 0x28, 0x00, 0x08, 0x00 }; -+/* RFCAL_Offset_Cprog4 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_2__RFCAL_Offset_Cprog4 = { 0x28, 0x06, 0x02, 0x00 }; -+/* RFCAL_Offset_Cprog5 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_2__RFCAL_Offset_Cprog5 = { 0x28, 0x04, 0x02, 0x00 }; -+/* RFCAL_Offset_Cprog6 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_2__RFCAL_Offset_Cprog6 = { 0x28, 0x02, 0x02, 0x00 }; -+/* RFCAL_Offset_Cprog7 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_2__RFCAL_Offset_Cprog7 = { 0x28, 0x00, 0x02, 0x00 }; -+ -+ -+/* TDA18273 Register RF_Cal_byte_3 0x29 */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_3 = { 0x29, 0x00, 0x08, 0x00 }; -+/* RFCAL_Offset_Cprog8 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_3__RFCAL_Offset_Cprog8 = { 0x29, 0x06, 0x02, 0x00 }; -+/* RFCAL_Offset_Cprog9 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_3__RFCAL_Offset_Cprog9 = { 0x29, 0x04, 0x02, 0x00 }; -+/* RFCAL_Offset_Cprog10 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_3__RFCAL_Offset_Cprog10 = { 0x29, 0x02, 0x02, 0x00 }; -+/* RFCAL_Offset_Cprog11 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Cal_byte_3__RFCAL_Offset_Cprog11 = { 0x29, 0x00, 0x02, 0x00 }; -+ -+ -+/* TDA18273 Register Bandsplit_Filter_byte 0x2A */ -+const TDA18273_BitField_t gTDA18273_Reg_Bandsplit_Filter_byte = { 0x2A, 0x00, 0x08, 0x00 }; -+/* Bandsplit_Filter_SubBand bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Bandsplit_Filter_byte__Bandsplit_Filter_SubBand = { 0x2A, 0x00, 0x02, 0x00 }; -+ -+ -+/* TDA18273 Register RF_Filters_byte_1 0x2B */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Filters_byte_1 = { 0x2B, 0x00, 0x08, 0x00 }; -+/* RF_Filter_Bypass bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Filters_byte_1__RF_Filter_Bypass = { 0x2B, 0x07, 0x01, 0x00 }; -+/* AGC2_loop_off bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Filters_byte_1__AGC2_loop_off = { 0x2B, 0x05, 0x01, 0x00 }; -+/* Force_AGC2_gain bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Filters_byte_1__Force_AGC2_gain = { 0x2B, 0x04, 0x01, 0x00 }; -+/* RF_Filter_Gv bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Filters_byte_1__RF_Filter_Gv = { 0x2B, 0x02, 0x02, 0x00 }; -+/* RF_Filter_Band bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Filters_byte_1__RF_Filter_Band = { 0x2B, 0x00, 0x02, 0x00 }; -+ -+ -+/* TDA18273 Register RF_Filters_byte_2 0x2C */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Filters_byte_2 = { 0x2C, 0x00, 0x08, 0x00 }; -+/* RF_Filter_Cap bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Filters_byte_2__RF_Filter_Cap = { 0x2C, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register RF_Filters_byte_3 0x2D */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Filters_byte_3 = { 0x2D, 0x00, 0x08, 0x00 }; -+/* AGC2_Do_step bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Filters_byte_3__AGC2_Do_step = { 0x2D, 0x06, 0x02, 0x00 }; -+/* Gain_Taper bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Filters_byte_3__Gain_Taper = { 0x2D, 0x00, 0x06, 0x00 }; -+ -+ -+/* TDA18273 Register RF_Band_Pass_Filter_byte 0x2E */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Band_Pass_Filter_byte = { 0x2E, 0x00, 0x08, 0x00 }; -+/* RF_BPF_Bypass bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Band_Pass_Filter_byte__RF_BPF_Bypass = { 0x2E, 0x07, 0x01, 0x00 }; -+/* RF_BPF bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RF_Band_Pass_Filter_byte__RF_BPF = { 0x2E, 0x00, 0x03, 0x00 }; -+ -+ -+/* TDA18273 Register CP_Current_byte 0x2F */ -+const TDA18273_BitField_t gTDA18273_Reg_CP_Current_byte = { 0x2F, 0x00, 0x08, 0x00 }; -+/* LO_CP_Current bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_CP_Current_byte__LO_CP_Current = { 0x2F, 0x07, 0x01, 0x00 }; -+/* N_CP_Current bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_CP_Current_byte__N_CP_Current = { 0x2F, 0x00, 0x07, 0x00 }; -+ -+ -+/* TDA18273 Register AGCs_DetOut_byte 0x30 */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCs_DetOut_byte = { 0x30, 0x00, 0x08, 0x00 }; -+/* Up_AGC5 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCs_DetOut_byte__Up_AGC5 = { 0x30, 0x07, 0x01, 0x00 }; -+/* Do_AGC5 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCs_DetOut_byte__Do_AGC5 = { 0x30, 0x06, 0x01, 0x00 }; -+/* Up_AGC4 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCs_DetOut_byte__Up_AGC4 = { 0x30, 0x05, 0x01, 0x00 }; -+/* Do_AGC4 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCs_DetOut_byte__Do_AGC4 = { 0x30, 0x04, 0x01, 0x00 }; -+/* Up_AGC2 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCs_DetOut_byte__Up_AGC2 = { 0x30, 0x03, 0x01, 0x00 }; -+/* Do_AGC2 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCs_DetOut_byte__Do_AGC2 = { 0x30, 0x02, 0x01, 0x00 }; -+/* Up_AGC1 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCs_DetOut_byte__Up_AGC1 = { 0x30, 0x01, 0x01, 0x00 }; -+/* Do_AGC1 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_AGCs_DetOut_byte__Do_AGC1 = { 0x30, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register RFAGCs_Gain_byte_3 0x31 */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_3 = { 0x31, 0x00, 0x08, 0x00 }; -+/* AGC2_Gain_Read bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_3__AGC2_Gain_Read = { 0x31, 0x04, 0x02, 0x00 }; -+/* AGC1_Gain_Read bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_3__AGC1_Gain_Read = { 0x31, 0x00, 0x04, 0x00 }; -+ -+ -+/* TDA18273 Register RFAGCs_Gain_byte_4 0x32 */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_4 = { 0x32, 0x00, 0x08, 0x00 }; -+/* Cprog_Read bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_4__Cprog_Read = { 0x32, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register RFAGCs_Gain_byte_5 0x33 */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_5 = { 0x33, 0x00, 0x08, 0x00 }; -+/* RFAGC_Read_K_8 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_5__RFAGC_Read_K_8 = { 0x33, 0x07, 0x01, 0x00 }; -+/* Do_AGC1bis bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_5__Do_AGC1bis = { 0x33, 0x06, 0x01, 0x00 }; -+/* AGC1_Top_Adapt_Low bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_5__AGC1_Top_Adapt_Low = { 0x33, 0x05, 0x01, 0x00 }; -+/* Up_LNA_Adapt bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_5__Up_LNA_Adapt = { 0x33, 0x04, 0x01, 0x00 }; -+/* Do_LNA_Adapt bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_5__Do_LNA_Adapt = { 0x33, 0x03, 0x01, 0x00 }; -+/* TOP_AGC3_Read bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_5__TOP_AGC3_Read = { 0x33, 0x00, 0x03, 0x00 }; -+ -+ -+/* TDA18273 Register RFAGCs_Gain_byte_6 0x34 */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_6 = { 0x34, 0x00, 0x08, 0x00 }; -+/* RFAGC_Read_K bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RFAGCs_Gain_byte_6__RFAGC_Read_K = { 0x34, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register IFAGCs_Gain_byte 0x35 */ -+const TDA18273_BitField_t gTDA18273_Reg_IFAGCs_Gain_byte = { 0x35, 0x00, 0x08, 0x00 }; -+/* AGC5_Gain_Read bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IFAGCs_Gain_byte__AGC5_Gain_Read = { 0x35, 0x03, 0x03, 0x00 }; -+/* AGC4_Gain_Read bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IFAGCs_Gain_byte__AGC4_Gain_Read = { 0x35, 0x00, 0x03, 0x00 }; -+ -+ -+/* TDA18273 Register RSSI_byte_1 0x36 */ -+const TDA18273_BitField_t gTDA18273_Reg_RSSI_byte_1 = { 0x36, 0x00, 0x08, 0x00 }; -+/* RSSI bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RSSI_byte_1__RSSI = { 0x36, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register RSSI_byte_2 0x37 */ -+const TDA18273_BitField_t gTDA18273_Reg_RSSI_byte_2 = { 0x37, 0x00, 0x08, 0x00 }; -+/* RSSI_AV bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RSSI_byte_2__RSSI_AV = { 0x37, 0x05, 0x01, 0x00 }; -+/* RSSI_Cap_Reset_En bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RSSI_byte_2__RSSI_Cap_Reset_En = { 0x37, 0x03, 0x01, 0x00 }; -+/* RSSI_Cap_Val bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RSSI_byte_2__RSSI_Cap_Val = { 0x37, 0x02, 0x01, 0x00 }; -+/* RSSI_Ck_Speed bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RSSI_byte_2__RSSI_Ck_Speed = { 0x37, 0x01, 0x01, 0x00 }; -+/* RSSI_Dicho_not bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_RSSI_byte_2__RSSI_Dicho_not = { 0x37, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register Misc_byte 0x38 */ -+const TDA18273_BitField_t gTDA18273_Reg_Misc_byte = { 0x38, 0x00, 0x08, 0x00 }; -+/* RFCALPOR_I2C bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Misc_byte__RFCALPOR_I2C = { 0x38, 0x06, 0x01, 0x00 }; -+/* PD_Underload bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Misc_byte__PD_Underload = { 0x38, 0x05, 0x01, 0x00 }; -+/* DDS_Polarity bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Misc_byte__DDS_Polarity = { 0x38, 0x04, 0x01, 0x00 }; -+/* IRQ_Mode bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Misc_byte__IRQ_Mode = { 0x38, 0x01, 0x01, 0x00 }; -+/* IRQ_Polarity bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Misc_byte__IRQ_Polarity = { 0x38, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register rfcal_log_0 0x39 */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_0 = { 0x39, 0x00, 0x08, 0x00 }; -+/* rfcal_log_0 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_0__rfcal_log_0 = { 0x39, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register rfcal_log_1 0x3A */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_1 = { 0x3A, 0x00, 0x08, 0x00 }; -+/* rfcal_log_1 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_1__rfcal_log_1 = { 0x3A, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register rfcal_log_2 0x3B */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_2 = { 0x3B, 0x00, 0x08, 0x00 }; -+/* rfcal_log_2 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_2__rfcal_log_2 = { 0x3B, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register rfcal_log_3 0x3C */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_3 = { 0x3C, 0x00, 0x08, 0x00 }; -+/* rfcal_log_3 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_3__rfcal_log_3 = { 0x3C, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register rfcal_log_4 0x3D */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_4 = { 0x3D, 0x00, 0x08, 0x00 }; -+/* rfcal_log_4 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_4__rfcal_log_4 = { 0x3D, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register rfcal_log_5 0x3E */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_5 = { 0x3E, 0x00, 0x08, 0x00 }; -+/* rfcal_log_5 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_5__rfcal_log_5 = { 0x3E, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register rfcal_log_6 0x3F */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_6 = { 0x3F, 0x00, 0x08, 0x00 }; -+/* rfcal_log_6 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_6__rfcal_log_6 = { 0x3F, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register rfcal_log_7 0x40 */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_7 = { 0x40, 0x00, 0x08, 0x00 }; -+/* rfcal_log_7 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_7__rfcal_log_7 = { 0x40, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register rfcal_log_8 0x41 */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_8 = { 0x41, 0x00, 0x08, 0x00 }; -+/* rfcal_log_8 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_8__rfcal_log_8 = { 0x41, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register rfcal_log_9 0x42 */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_9 = { 0x42, 0x00, 0x08, 0x00 }; -+/* rfcal_log_9 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_9__rfcal_log_9 = { 0x42, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register rfcal_log_10 0x43 */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_10 = { 0x43, 0x00, 0x08, 0x00 }; -+/* rfcal_log_10 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_10__rfcal_log_10 = { 0x43, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register rfcal_log_11 0x44 */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_11 = { 0x44, 0x00, 0x08, 0x00 }; -+/* rfcal_log_11 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_rfcal_log_11__rfcal_log_11 = { 0x44, 0x00, 0x08, 0x00 }; -+ -+ -+ -+/* TDA18273 Register Main_Post_Divider_byte 0x51 */ -+const TDA18273_BitField_t gTDA18273_Reg_Main_Post_Divider_byte = { 0x51, 0x00, 0x08, 0x00 }; -+/* LOPostDiv bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Main_Post_Divider_byte__LOPostDiv = { 0x51, 0x04, 0x03, 0x00 }; -+/* LOPresc bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Main_Post_Divider_byte__LOPresc = { 0x51, 0x00, 0x04, 0x00 }; -+ -+ -+/* TDA18273 Register Sigma_delta_byte_1 0x52 */ -+const TDA18273_BitField_t gTDA18273_Reg_Sigma_delta_byte_1 = { 0x52, 0x00, 0x08, 0x00 }; -+/* LO_Int bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Sigma_delta_byte_1__LO_Int = { 0x52, 0x00, 0x07, 0x00 }; -+ -+ -+/* TDA18273 Register Sigma_delta_byte_2 0x53 */ -+const TDA18273_BitField_t gTDA18273_Reg_Sigma_delta_byte_2 = { 0x53, 0x00, 0x08, 0x00 }; -+/* LO_Frac_2 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Sigma_delta_byte_2__LO_Frac_2 = { 0x53, 0x00, 0x07, 0x00 }; -+ -+ -+/* TDA18273 Register Sigma_delta_byte_3 0x54 */ -+const TDA18273_BitField_t gTDA18273_Reg_Sigma_delta_byte_3 = { 0x54, 0x00, 0x08, 0x00 }; -+/* LO_Frac_1 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Sigma_delta_byte_3__LO_Frac_1 = { 0x54, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register Sigma_delta_byte_4 0x55 */ -+const TDA18273_BitField_t gTDA18273_Reg_Sigma_delta_byte_4 = { 0x55, 0x00, 0x08, 0x00 }; -+/* LO_Frac_0 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Sigma_delta_byte_4__LO_Frac_0 = { 0x55, 0x00, 0x08, 0x00 }; -+ -+ -+/* TDA18273 Register Sigma_delta_byte_5 0x56 */ -+const TDA18273_BitField_t gTDA18273_Reg_Sigma_delta_byte_5 = { 0x56, 0x00, 0x08, 0x00 }; -+/* N_K_correct_manual bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Sigma_delta_byte_5__N_K_correct_manual = { 0x56, 0x01, 0x01, 0x00 }; -+/* LO_Calc_Disable bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Sigma_delta_byte_5__LO_Calc_Disable = { 0x56, 0x00, 0x01, 0x00 }; -+ -+ -+/* TDA18273 Register Regulators_byte 0x58 */ -+const TDA18273_BitField_t gTDA18273_Reg_Regulators_byte = { 0x58, 0x00, 0x08, 0x00 }; -+/* RF_Reg bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Regulators_byte__RF_Reg = { 0x58, 0x02, 0x02, 0x00 }; -+ -+ -+/* TDA18273 Register IR_Cal_byte_5 0x5B */ -+const TDA18273_BitField_t gTDA18273_Reg_IR_Cal_byte_5 = { 0x5B, 0x00, 0x08, 0x00 }; -+/* Mixer_Gain_Bypass bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IR_Cal_byte_5__Mixer_Gain_Bypass = { 0x5B, 0x07, 0x01, 0x00 }; -+/* IR_Mixer_Gain bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_IR_Cal_byte_5__IR_Mixer_Gain = { 0x5B, 0x04, 0x03, 0x00 }; -+ -+ -+/* TDA18273 Register Power_Down_byte_2 0x5F */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_Down_byte_2 = { 0x5F, 0x00, 0x08, 0x00 }; -+/* PD_LNA bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_Down_byte_2__PD_LNA = { 0x5F, 0x07, 0x01, 0x00 }; -+/* PD_Det4 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_Down_byte_2__PD_Det4 = { 0x5F, 0x03, 0x01, 0x00 }; -+/* PD_Det3 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_Down_byte_2__PD_Det3 = { 0x5F, 0x02, 0x01, 0x00 }; -+/* PD_Det1 bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_Down_byte_2__PD_Det1 = { 0x5F, 0x00, 0x01, 0x00 }; -+ -+/* TDA18273 Register Power_Down_byte_3 0x60 */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_Down_byte_3 = { 0x60, 0x00, 0x08, 0x00 }; -+/* Force_Soft_Reset bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_Down_byte_3__Force_Soft_Reset = { 0x60, 0x01, 0x01, 0x00 }; -+/* Soft_Reset bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Power_Down_byte_3__Soft_Reset = { 0x60, 0x00, 0x01, 0x00 }; -+ -+/* TDA18273 Register Charge_pump_byte 0x64 */ -+const TDA18273_BitField_t gTDA18273_Reg_Charge_pump_byte = { 0x64, 0x00, 0x08, 0x00 }; -+/* ICP_Bypass bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Charge_pump_byte__ICP_Bypass = { 0x64, 0x07, 0x01, 0x00 }; -+/* ICP bit(s): */ -+const TDA18273_BitField_t gTDA18273_Reg_Charge_pump_byte__ICP = { 0x64, 0x00, 0x02, 0x00 }; -+ -+ -+static int tda18273_readreg(struct tda18273_state *priv, unsigned char reg, unsigned char *val) -+{ -+ int ret = TDA_RESULT_SUCCESS; -+ struct dvb_frontend *fe = priv->fe; -+ -+ struct i2c_msg msg[2] = { -+ { .addr = priv->i2c_addr, -+ .flags = 0, .buf = ®, .len = 1}, -+ { .addr = priv->i2c_addr, -+ .flags = I2C_M_RD, .buf = val, .len = 1}, -+ }; -+ -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 1); -+ -+ ret = i2c_transfer(priv->i2c, msg, 2); -+ -+ if (ret != 2) { -+ dprintk(FE_ERROR, 1, "I2C read failed"); -+ ret = TDA_RESULT_I2C_READ_FAILURE; -+ } -+ -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 0); -+ -+ return ret; -+} -+ -+static int tda18273_readregs(struct tda18273_state *priv, const TDA18273_BitField_t* pBitField, unsigned char *val, tmbslFrontEndBusAccess_t eBusAccess) -+{ -+ unsigned char RegAddr = 0; -+ unsigned char RegMask = 0; -+ unsigned char RegData = 0; -+ unsigned char* pRegData = NULL; -+ -+ RegAddr = pBitField->Address; -+ -+ if(RegAddr < TDA18273_REG_MAP_NB_BYTES) { -+ pRegData = (unsigned char *)(&(priv->regmap)) + RegAddr; -+ } else { -+ pRegData = &RegData; -+ } -+ -+ if((eBusAccess & Bus_NoRead) == 0x00) { -+ if(tda18273_readreg(priv, RegAddr, pRegData) == TDA_RESULT_I2C_READ_FAILURE) { -+ return TDA_RESULT_I2C_READ_FAILURE; -+ } -+ } -+ -+ *val = *pRegData; -+ -+ RegMask = ((1 << pBitField->WidthInBits) - 1) << pBitField->PositionInBits; -+ -+ *val &= RegMask; -+ *val = (*val) >> pBitField->PositionInBits; -+ -+ return TDA_RESULT_SUCCESS; -+} -+ -+static int tda18273_readregmap(struct tda18273_state *priv, unsigned char reg, unsigned int len) -+{ -+ int ret, i; -+ unsigned char* pRegData = NULL; -+ -+ if((reg < TDA18273_REG_MAP_NB_BYTES) && ((reg + len) <= TDA18273_REG_MAP_NB_BYTES)) { -+ pRegData = (unsigned char *)(&(priv->regmap)) + reg; -+ -+ for(i=0; ife; -+ unsigned char tmp[2] = {reg, val}; -+ -+ struct i2c_msg msg = { -+ .addr = priv->i2c_addr, -+ .flags = 0, .buf = tmp, .len = 2}; -+ -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 1); -+ -+ ret = i2c_transfer(priv->i2c, &msg, 1); -+ -+ if (ret != 1) { -+ dprintk(FE_ERROR, 1, "I2C write failed"); -+ ret = TDA_RESULT_I2C_READ_FAILURE; -+ } -+ -+ if (fe->ops.i2c_gate_ctrl) -+ fe->ops.i2c_gate_ctrl(fe, 0); -+ -+ return ret; -+} -+ -+static int tda18273_writeregs(struct tda18273_state *priv, const TDA18273_BitField_t* pBitField, unsigned char val, tmbslFrontEndBusAccess_t eBusAccess) -+{ -+ unsigned char RegAddr = 0; -+ unsigned char RegData = 0; -+ unsigned char RegMask = 0; -+ unsigned char* pRegData = NULL; -+ -+ RegAddr = pBitField->Address; -+ -+ if(RegAddr < TDA18273_REG_MAP_NB_BYTES) { -+ pRegData = (unsigned char *)(&(priv->regmap)) + RegAddr; -+ } else { -+ pRegData = &RegData; -+ } -+ -+ if((eBusAccess & Bus_NoRead) == 0x00) { -+ if(tda18273_readreg(priv, RegAddr, pRegData) == TDA_RESULT_I2C_READ_FAILURE) { -+ return TDA_RESULT_I2C_READ_FAILURE; -+ } -+ } -+ -+ RegMask = (1 << pBitField->WidthInBits) - 1; -+ val &= RegMask; -+ -+ RegMask = RegMask << pBitField->PositionInBits; -+ *pRegData &= (UInt8)(~RegMask); -+ *pRegData |= val << pBitField->PositionInBits; -+ -+ if((eBusAccess & Bus_NoWrite) == 0x00) { -+ if(tda18273_writereg(priv, RegAddr, *pRegData) == TDA_RESULT_I2C_READ_FAILURE) { -+ return TDA_RESULT_I2C_READ_FAILURE; -+ } -+ } -+ -+ return TDA_RESULT_SUCCESS; -+} -+ -+static int tda18273_writeregmap(struct tda18273_state *priv, unsigned char reg, unsigned int len) -+{ -+ int ret, i; -+ unsigned char* pRegData = NULL; -+ -+ if((reg < TDA18273_REG_MAP_NB_BYTES) && ((reg + len) <= TDA18273_REG_MAP_NB_BYTES)) { -+ pRegData = (unsigned char *)(&(priv->regmap)) + reg; -+ -+ for(i=0; i data : 0x%02x", i, val); -+ } -+} -+ -+static int tda18273_get_lock_status(struct tda18273_state *priv, unsigned short *lock_status) -+{ -+ int ret; -+ unsigned char val=0; -+ unsigned char val_lo=0; -+ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_Power_state_byte_1__LO_Lock, &val_lo, Bus_RW); -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_IRQ_status__IRQ_status, &val, Bus_RW); -+ *lock_status = val & val_lo; -+ -+ dprintk(FE_INFO, 1, "lock=0x%02X/0x%02x, lock_status=0x%x", val, val_lo, *lock_status); -+ -+ return 0; -+} -+ -+static int tda18273_pwr_state(struct dvb_frontend *fe, int pwr_state) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ int ret=0; -+ -+ if(priv->power_state != pwr_state) { -+ if(pwr_state == tmPowerOn) { -+ /* Set TDA18273 power state to Normal Mode */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Power_Down_byte_2__PD_LNA, 0x1, Bus_RW); /* PD LNA */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Power_Down_byte_2__PD_Det1, 0x1, Bus_NoRead); /* PD Detector AGC1 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGC1_byte_3__AGC1_loop_off, 0x1, Bus_RW); /* AGC1 Detector loop off */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Power_state_byte_2, TDA18273_SM_NONE, Bus_RW); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode, 0x03, Bus_RW); /* Set digital clock mode to sub-LO if normal mode is entered */ -+ } else if(pwr_state == tmPowerStandby) { -+ /* Set TDA18273 power state to standby with Xtal ON */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode, 0x00, Bus_RW); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Power_state_byte_2, 0x02, Bus_RW); -+ } -+ -+ priv->power_state = pwr_state; -+ } -+ -+ return 0; -+} -+ -+static int tda18273_firstpass_lnapwr(struct dvb_frontend *fe) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ int ret; -+ -+ /* PD LNA */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Power_Down_byte_2__PD_LNA, 0x1, Bus_RW); -+ /* PD Detector AGC1 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Power_Down_byte_2__PD_Det1, 0x1, Bus_NoRead); -+ /* AGC1 Detector loop off */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGC1_byte_3__AGC1_loop_off, 0x1, Bus_RW); -+ -+ return 0; -+} -+ -+static int tda18273_lastpass_lnapwr(struct dvb_frontend *fe) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ unsigned char val = 0; -+ int ret; -+ -+ /* Check if LNA is PD */ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_Power_Down_byte_2__PD_LNA, &val, Bus_NoWrite); -+ -+ if(val == 1) { -+ /* LNA is Powered Down, so power it up */ -+ /* Force gain to -10dB */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGC1_byte_3__AGC1_Gain, 0x0, Bus_RW); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGC1_byte_3__Force_AGC1_gain, 0x1, Bus_NoRead); -+ /* PD LNA */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Power_Down_byte_2__PD_LNA, 0x0, Bus_NoRead); -+ /* Release LNA gain control */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGC1_byte_3__Force_AGC1_gain, 0x0, Bus_NoRead); -+ /* PD Detector AGC1 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Power_Down_byte_2__PD_Det1, 0x0, Bus_NoRead); -+ /* AGC1 Detector loop off */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGC1_byte_3__AGC1_loop_off, 0x0, Bus_NoRead); -+ } -+ -+ return 0; -+} -+ -+static int tda18273_llpwr_state(struct dvb_frontend *fe, int llpwr_state) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ unsigned char val = 0; -+ int ret; -+ -+ if(llpwr_state == TDA18273_PowerNormalMode) { -+ /* If we come from any standby mode, then power on the IC with LNA off */ -+ /* Then powering on LNA with the minimal gain on AGC1 to avoid glitches at RF input will */ -+ /* be done during SetRF */ -+ -+ /* Workaround to limit the spurs occurence on RF input, do it before entering normal mode */ -+ /* PD LNA */ -+ ret = tda18273_firstpass_lnapwr(fe); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Power_state_byte_2, TDA18273_SM_NONE, Bus_RW); -+ /* Set digital clock mode to sub-LO if normal mode is entered */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode, 0x03, Bus_RW); -+ -+ /* Reset val to use it as a flag for below test */ -+ val = 0; -+ } else if(llpwr_state == TDA18273_PowerStandbyWithXtalOn) { -+ val = TDA18273_SM; -+ } else if(llpwr_state == TDA18273_PowerStandby) { -+ /* power state not supported */ -+ val = TDA18273_SM|TDA18273_SM_XT; -+ } -+ -+ if(val) { -+ /* Set digital clock mode to 16 Mhz before entering standby */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode, 0x00, Bus_RW); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Power_state_byte_2, val, Bus_RW); -+ } -+ -+ return 0; -+} -+ -+static int tda18273_check_calcpll(struct dvb_frontend *fe) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ int ret; -+ unsigned char val; -+ -+ /* Check if Calc_PLL algorithm is in automatic mode */ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_Sigma_delta_byte_5__LO_Calc_Disable, &val, Bus_None); -+ -+ if(val != 0x00) { -+ /* Enable Calc_PLL algorithm by putting PLL in automatic mode */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Sigma_delta_byte_5__N_K_correct_manual, 0x00, Bus_None); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Sigma_delta_byte_5__LO_Calc_Disable, 0x00, Bus_NoRead); -+ } -+ -+ return 0; -+} -+ -+static int tda18273_set_msm(struct dvb_frontend *fe, unsigned char val, int launch) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ int ret; -+ -+ /* Set state machine and Launch it */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_MSM_byte_1, val, Bus_None); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_MSM_byte_2__MSM_Launch, 0x01, Bus_None); -+ ret = tda18273_writeregmap(priv, gTDA18273_Reg_MSM_byte_1.Address, (launch ? 0x02 : 0x01)); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_MSM_byte_2__MSM_Launch, 0x00, Bus_None); -+ -+ return 0; -+} -+ -+static int tda18273_override_bandsplit(struct dvb_frontend *fe) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ int ret; -+ unsigned char Bandsplit = 0; -+ unsigned char uPrevPSM_Bandsplit_Filter = 0; -+ unsigned char PSM_Bandsplit_Filter = 0; -+ -+ /* Setting PSM bandsplit at -3.9 mA for some RF frequencies */ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_Bandsplit_Filter_byte__Bandsplit_Filter_SubBand, &Bandsplit, Bus_None); -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_PowerSavingMode__PSM_Bandsplit_Filter, &uPrevPSM_Bandsplit_Filter, Bus_None); -+ -+ switch(Bandsplit) -+ { -+ default: -+ case 0: /* LPF0 133MHz - LPF1 206MHz - HPF0 422MHz */ -+ if(priv->pObj->uProgRF < 133000000) { -+ /* Set PSM bandsplit at -3.9 mA */ -+ PSM_Bandsplit_Filter = 0x03; -+ } else { -+ /* Set PSM bandsplit at nominal */ -+ PSM_Bandsplit_Filter = 0x02; -+ } -+ break; -+ case 1: /* LPF0 139MHz - LPF1 218MHz - HPF0 446MHz */ -+ if(priv->pObj->uProgRF < 139000000) { -+ /* Set PSM bandsplit at -3.9 mA */ -+ PSM_Bandsplit_Filter = 0x03; -+ } else { -+ /* Set PSM bandsplit at nominal */ -+ PSM_Bandsplit_Filter = 0x02; -+ } -+ break; -+ case 2: /* LPF0 145MHz - LPF1 230MHz - HPF0 470MHz */ -+ if(priv->pObj->uProgRF < 145000000) { -+ /* Set PSM bandsplit at -3.9 mA */ -+ PSM_Bandsplit_Filter = 0x03; -+ } else { -+ /* Set PSM bandsplit at nominal */ -+ PSM_Bandsplit_Filter = 0x02; -+ } -+ break; -+ case 3: /* LPF0 151MHz - LPF1 242MHz - HPF0 494MHz */ -+ if(priv->pObj->uProgRF < 151000000) { -+ /* Set PSM bandsplit at -3.9 mA */ -+ PSM_Bandsplit_Filter = 0x03; -+ } else { -+ /* Set PSM bandsplit at nominal */ -+ PSM_Bandsplit_Filter = 0x02; -+ } -+ break; -+ } -+ -+ if(uPrevPSM_Bandsplit_Filter != PSM_Bandsplit_Filter) { -+ /* Write PSM bandsplit */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_PowerSavingMode__PSM_Bandsplit_Filter, PSM_Bandsplit_Filter, Bus_NoRead); -+ } -+ -+ return 0; -+} -+ -+static int tda18273_set_standardmode(struct dvb_frontend *fe, TDA18273StandardMode_t StandardMode) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ int ret; -+ -+ unsigned char wantedValue=0; -+ unsigned char checked=0; -+ -+ priv->pObj->StandardMode = StandardMode; -+ -+ if((priv->pObj->StandardMode > TDA18273_StandardMode_Unknown) && (priv->pObj->StandardMode < TDA18273_StandardMode_Max)) { -+ /* Update standard map pointer */ -+ priv->pObj->pStandard = &priv->pObj->Std_Array[priv->pObj->StandardMode - 1]; -+ -+ /****************************************************************/ -+ /* IF SELECTIVITY Settings */ -+ /****************************************************************/ -+ /* Set LPF */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IF_Byte_1__LP_Fc, priv->pObj->pStandard->LPF, Bus_None); -+ /* Set LPF Offset */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IF_Byte_1__LP_FC_Offset, priv->pObj->pStandard->LPF_Offset, Bus_None); -+ /* Set DC_Notch_IF_PPF */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IR_Mixer_byte_2__IF_Notch, priv->pObj->pStandard->DC_Notch_IF_PPF, Bus_None); -+ /* Enable/disable HPF */ -+ if(priv->pObj->pStandard->IF_HPF == TDA18273_IF_HPF_Disabled) { -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IR_Mixer_byte_2__Hi_Pass, 0x00, Bus_None); -+ } else { -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IR_Mixer_byte_2__Hi_Pass, 0x01, Bus_None); -+ /* Set IF HPF */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IF_Byte_1__IF_HP_Fc, (UInt8)(priv->pObj->pStandard->IF_HPF - 1), Bus_None); -+ } -+ /* Set IF Notch */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IF_Byte_1__IF_ATSC_Notch, priv->pObj->pStandard->IF_Notch, Bus_None); -+ /* Set IF notch to RSSI */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IF_AGC_byte__IFnotchToRSSI, priv->pObj->pStandard->IFnotchToRSSI, Bus_None); -+ -+ /****************************************************************/ -+ /* AGC TOP Settings */ -+ /****************************************************************/ -+ /* Set AGC1 TOP I2C DN/UP */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGC1_byte_1__AGC1_TOP, priv->pObj->pStandard->AGC1_TOP_I2C_DN_UP, Bus_None); -+ /* Set AGC1 Adapt TOP DN/UP */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGC1_byte_2__AGC1_Top_Mode_Val, priv->pObj->pStandard->AGC1_Adapt_TOP_DN_UP, Bus_None); -+ /* Set AGC1 DN Time Constant */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGC1_byte_3__AGC1_Do_step, priv->pObj->pStandard->AGC1_DN_Time_Constant, Bus_None); -+ /* Set AGC1 mode */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGC1_byte_2__AGC1_Top_Mode, priv->pObj->pStandard->AGC1_Mode, Bus_None); -+ /* Set Range_LNA_Adapt */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Adapt_Top_byte__Range_LNA_Adapt, priv->pObj->pStandard->Range_LNA_Adapt, Bus_None); -+ /* Set LNA_Adapt_RFAGC_Gv_Threshold */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Adapt_Top_byte__Index_K_LNA_Adapt, priv->pObj->pStandard->LNA_Adapt_RFAGC_Gv_Threshold, Bus_None); -+ /* Set AGC1_Top_Adapt_RFAGC_Gv_Threshold */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Adapt_Top_byte__Index_K_Top_Adapt, priv->pObj->pStandard->AGC1_Top_Adapt_RFAGC_Gv_Threshold, Bus_None); -+ /* Set AGC2 TOP DN/UP */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGC2_byte_1__AGC2_TOP, priv->pObj->pStandard->AGC2_TOP_DN_UP, Bus_None); -+ /* Set AGC2 DN Time Constant */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_Filters_byte_3__AGC2_Do_step, priv->pObj->pStandard->AGC2_DN_Time_Constant, Bus_None); -+ /* Set AGC4 TOP DN/UP */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IR_Mixer_byte_1__IR_Mixer_Top, priv->pObj->pStandard->AGC4_TOP_DN_UP, Bus_None); -+ /* Set AGC5 TOP DN/UP */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGC5_byte_1__AGC5_TOP, priv->pObj->pStandard->AGC5_TOP_DN_UP, Bus_None); -+ /* Set AGC3_Top_Adapt_Algorithm */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_AGC_byte__PD_AGC_Adapt3x, priv->pObj->pStandard->AGC3_Top_Adapt_Algorithm, Bus_None); -+ /* Set AGC Overload TOP */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Vsync_Mgt_byte__AGC_Ovld_TOP, priv->pObj->pStandard->AGC_Overload_TOP, Bus_None); -+ /* Set Adapt TOP 34 Gain Threshold */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RFAGCs_Gain_byte_1__TH_AGC_Adapt34, priv->pObj->pStandard->TH_AGC_Adapt34, Bus_None); -+ /* Set RF atten 3dB */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_W_Filter_byte__RF_Atten_3dB, priv->pObj->pStandard->RF_Atten_3dB, Bus_None); -+ /* Set IF Output Level */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IF_AGC_byte__IF_level, priv->pObj->pStandard->IF_Output_Level, Bus_None); -+ /* Set S2D gain */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IR_Mixer_byte_1__S2D_Gain, priv->pObj->pStandard->S2D_Gain, Bus_None); -+ /* Set Negative modulation, write into register directly because vsync_int bit is checked afterwards */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Vsync_byte__Neg_modulation, priv->pObj->pStandard->Negative_Modulation, Bus_RW); -+ -+ /****************************************************************/ -+ /* GSK Settings */ -+ /****************************************************************/ -+ /* Set AGCK Step */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGCK_byte_1__AGCK_Step, priv->pObj->pStandard->AGCK_Steps, Bus_None); -+ /* Set AGCK Time Constant */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGCK_byte_1__AGCK_Mode, priv->pObj->pStandard->AGCK_Time_Constant, Bus_None); -+ /* Set AGC5 HPF */ -+ wantedValue = priv->pObj->pStandard->AGC5_HPF; -+ if(priv->pObj->pStandard->AGC5_HPF == TDA18273_AGC5_HPF_Enabled) { -+ /* Check if Internal Vsync is selected */ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_Vsync_byte__Vsync_int, &checked, Bus_RW); -+ -+ if(checked == 0) { -+ /* Internal Vsync is OFF, so override setting to OFF */ -+ wantedValue = TDA18273_AGC5_HPF_Disabled; -+ } -+ } -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGC5_byte_1__AGC5_Ana, wantedValue, Bus_None); -+ /* Set Pulse Shaper Disable */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_AGCK_byte_1__Pulse_Shaper_Disable, priv->pObj->pStandard->Pulse_Shaper_Disable, Bus_None); -+ -+ /****************************************************************/ -+ /* H3H5 Settings */ -+ /****************************************************************/ -+ /* Set VHF_III_Mode */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_W_Filter_byte__VHF_III_mode, priv->pObj->pStandard->VHF_III_Mode, Bus_None); -+ -+ /****************************************************************/ -+ /* PLL Settings */ -+ /****************************************************************/ -+ /* Set LO_CP_Current */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_CP_Current_byte__LO_CP_Current, priv->pObj->pStandard->LO_CP_Current, Bus_None); -+ -+ /****************************************************************/ -+ /* IF Settings */ -+ /****************************************************************/ -+ /* Set IF */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IF_Frequency_byte__IF_Freq, (UInt8)((priv->pObj->pStandard->IF - priv->pObj->pStandard->CF_Offset)/50000), Bus_None); -+ -+ /****************************************************************/ -+ /* MISC Settings */ -+ /****************************************************************/ -+ /* Set PD Underload */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Misc_byte__PD_Underload, priv->pObj->pStandard->PD_Underload, Bus_None); -+ -+ /****************************************************************/ -+ /* Update Registers */ -+ /****************************************************************/ -+ /* Write AGC1_byte_1 (0x0C) to IF_Byte_1 (0x15) Registers */ -+ ret = tda18273_writeregmap(priv, gTDA18273_Reg_AGC1_byte_1.Address, TDA18273_REG_DATA_LEN(gTDA18273_Reg_AGC1_byte_1, gTDA18273_Reg_IF_Byte_1)); -+ /* Write IF_Frequency_byte (0x17) Register */ -+ ret = tda18273_writeregmap(priv, gTDA18273_Reg_IF_Frequency_byte.Address, 1); -+ /* Write Adapt_Top_byte (0x1F) Register */ -+ ret = tda18273_writeregmap(priv, gTDA18273_Reg_Adapt_Top_byte.Address, 1); -+ /* Write Vsync_byte (0x20) to RFAGCs_Gain_byte_1 (0x24) Registers */ -+ ret = tda18273_writeregmap(priv, gTDA18273_Reg_Vsync_byte.Address, TDA18273_REG_DATA_LEN(gTDA18273_Reg_Vsync_byte, gTDA18273_Reg_RFAGCs_Gain_byte_1)); -+ /* Write RF_Filters_byte_3 (0x2D) Register */ -+ ret = tda18273_writeregmap(priv, gTDA18273_Reg_RF_Filters_byte_3.Address, 1); -+ /* Write CP_Current_byte (0x2F) Register */ -+ ret = tda18273_writeregmap(priv, gTDA18273_Reg_CP_Current_byte.Address, 1); -+ /* Write Misc_byte (0x38) Register */ -+ ret = tda18273_writeregmap(priv, gTDA18273_Reg_Misc_byte.Address, 1); -+ } -+ -+ return 0; -+} -+ -+typedef struct _TDA18273_PostDivPrescalerTableDef_ -+{ -+ unsigned int LO_max; -+ unsigned int LO_min; -+ unsigned char Prescaler; -+ unsigned char PostDiv; -+} TDA18273_PostDivPrescalerTableDef; -+ -+/* Table that maps LO vs Prescaler & PostDiv values */ -+static TDA18273_PostDivPrescalerTableDef PostDivPrescalerTable[35] = -+{ -+ /* PostDiv 1 */ -+ {974000, 852250, 7, 1}, -+ {852250, 745719, 8, 1}, -+ {757556, 662861, 9, 1}, -+ {681800, 596575, 10, 1}, -+ {619818, 542341, 11, 1}, -+ {568167, 497146, 12, 1}, -+ {524462, 458904, 13, 1}, -+ /* PostDiv 2 */ -+ {487000, 426125, 7, 2}, -+ {426125, 372859, 8, 2}, -+ {378778, 331431, 9, 2}, -+ {340900, 298288, 10, 2}, -+ {309909, 271170, 11, 2}, -+ {284083, 248573, 12, 2}, -+ {262231, 229452, 13, 2}, -+ /* PostDiv 4 */ -+ {243500, 213063, 7, 4}, -+ {213063, 186430, 8, 4}, -+ {189389, 165715, 9, 4}, -+ {170450, 149144, 10, 4}, -+ {154955, 135585, 11, 4}, -+ {142042, 124286, 12, 4}, -+ {131115, 114726, 13, 4}, -+ /* PostDiv 8 */ -+ {121750, 106531, 7, 8}, -+ {106531, 93215, 8, 8}, -+ {94694, 82858, 9, 8}, -+ {85225, 74572, 10, 8}, -+ {77477, 67793, 11, 8}, -+ {71021, 62143, 12, 8}, -+ {65558, 57363, 13, 8}, -+ /* PostDiv 16 */ -+ {60875, 53266, 7, 16}, -+ {53266, 46607, 8, 16}, -+ {47347, 41429, 9, 16}, -+ {42613, 37286, 10, 16}, -+ {38739, 33896, 11, 16}, -+ {35510, 31072, 12, 16}, -+ {32779, 28681, 13, 16} -+}; -+ -+static int tda18273_calculate_postdivandprescaler(unsigned int LO, int growingOrder, unsigned char* PostDiv, unsigned char* Prescaler) -+{ -+ int ret = 0; -+ -+ unsigned char index; -+ unsigned char sizeTable = sizeof(PostDivPrescalerTable) / sizeof(TDA18273_PostDivPrescalerTableDef); -+ -+ if(growingOrder == 1) { -+ /* Start from LO = 28.681 kHz */ -+ for(index=(sizeTable-1); index>=0; index--) { -+ if((LO > PostDivPrescalerTable[index].LO_min) && (LO < PostDivPrescalerTable[index].LO_max)) { -+ /* We are at correct index in the table */ -+ break; -+ } -+ } -+ } else { -+ /* Start from LO = 974000 kHz */ -+ for(index=0; index PostDivPrescalerTable[index].LO_min) && (LO < PostDivPrescalerTable[index].LO_max)) { -+ /* We are at correct index in the table */ -+ break; -+ } -+ } -+ } -+ -+ if((index == -1) || (index == sizeTable)) { -+ ret = -1; -+ } else { -+ /* Write Prescaler */ -+ *Prescaler = PostDivPrescalerTable[index].Prescaler; -+ -+ /* Decode PostDiv */ -+ *PostDiv = PostDivPrescalerTable[index].PostDiv; -+ } -+ -+ return ret; -+} -+ -+/* Middle of VCO frequency excursion : VCOmin + (VCOmax - VCOmin)/2 in KHz */ -+#define TDA18273_MIDDLE_FVCO_RANGE ((6818000 - 5965750) / 2 + 5965750) -+ -+static int tda18273_find_postdivandprescalerwithbettermargin(unsigned int LO, unsigned char* PostDiv, unsigned char* Prescaler) -+{ -+ int ret; -+ -+ unsigned char PostDivGrowing; -+ unsigned char PrescalerGrowing; -+ unsigned char PostDivDecreasing = 0; -+ unsigned char PrescalerDecreasing = 0; -+ unsigned int FCVOGrowing = 0; -+ unsigned int DistanceFCVOGrowing = 0; -+ unsigned int FVCODecreasing = 0; -+ unsigned int DistanceFVCODecreasing = 0; -+ -+ /* Get the 2 possible values for PostDiv & Prescaler to find the one -+ which provides the better margin on LO */ -+ ret = tda18273_calculate_postdivandprescaler(LO, 1, &PostDivGrowing, &PrescalerGrowing); -+ if(ret != -1) { -+ /* Calculate corresponding FVCO value in kHz */ -+ FCVOGrowing = LO * PrescalerGrowing * PostDivGrowing; -+ } -+ -+ ret = tda18273_calculate_postdivandprescaler(LO, 0, &PostDivDecreasing, &PrescalerDecreasing); -+ if(ret != -1) { -+ /* Calculate corresponding FVCO value in kHz */ -+ FVCODecreasing = LO * PrescalerDecreasing * PostDivDecreasing; -+ } -+ -+ /* Now take the values that are providing the better margin, the goal is +-2 MHz on LO */ -+ /* So take the point that is the nearest of (FVCOmax - FVCOmin)/2 = 6391,875 MHz */ -+ if(FCVOGrowing != 0) { -+ if(FCVOGrowing >= TDA18273_MIDDLE_FVCO_RANGE) { -+ DistanceFCVOGrowing = FCVOGrowing - TDA18273_MIDDLE_FVCO_RANGE; -+ } else { -+ DistanceFCVOGrowing = TDA18273_MIDDLE_FVCO_RANGE - FCVOGrowing; -+ } -+ } -+ -+ if(FVCODecreasing != 0) { -+ if(FVCODecreasing >= TDA18273_MIDDLE_FVCO_RANGE) { -+ DistanceFVCODecreasing = FVCODecreasing - TDA18273_MIDDLE_FVCO_RANGE; -+ } else { -+ DistanceFVCODecreasing = TDA18273_MIDDLE_FVCO_RANGE - FVCODecreasing; -+ } -+ } -+ -+ if(FCVOGrowing == 0) { -+ if(FVCODecreasing == 0) { -+ /* No value at all are found */ -+ ret = -1; -+ } else { -+ /* No value in growing mode, so take the decreasing ones */ -+ *PostDiv = PostDivDecreasing; -+ *Prescaler = PrescalerDecreasing; -+ } -+ } else { -+ if(FVCODecreasing == 0) { -+ /* No value in decreasing mode, so take the growing ones */ -+ *PostDiv = PostDivGrowing; -+ *Prescaler = PrescalerGrowing; -+ } else { -+ /* Find the value which are the nearest of the middle of VCO range */ -+ if(DistanceFCVOGrowing <= DistanceFVCODecreasing) { -+ *PostDiv = PostDivGrowing; -+ *Prescaler = PrescalerGrowing; -+ } else { -+ *PostDiv = PostDivDecreasing; -+ *Prescaler = PrescalerDecreasing; -+ } -+ } -+ } -+ -+ return ret; -+} -+ -+static int tda18273_calculate_nintkint(unsigned int LO, unsigned char PostDiv, unsigned char Prescaler, unsigned int* NInt, unsigned int* KInt) -+{ -+ /* Algorithm that calculates N_K */ -+ unsigned int FVCO = 0; -+ unsigned int N_K_prog = 0; -+ -+ /* Algorithm that calculates N, K corrected */ -+ unsigned int Nprime = 0; -+ unsigned int KforceK0_1 = 0; -+ unsigned int K2msb = 0; -+ unsigned int N0 = 0; -+ unsigned int Nm1 = 0; -+ -+ /* Calculate N_K_Prog */ -+ FVCO = LO * Prescaler * PostDiv; -+ N_K_prog = (FVCO * 128) / 125; -+ -+ /* Calculate N & K corrected values */ -+ Nprime = N_K_prog & 0xFF0000; -+ -+ /* Force LSB to 1 */ -+ KforceK0_1 = 2*(((N_K_prog - Nprime) << 7) / 2) + 1; -+ -+ /* Check MSB bit around 2 */ -+ K2msb = KforceK0_1 >> 21; -+ if(K2msb < 1) { -+ N0 = 1; -+ } else { -+ if (K2msb >= 3) { -+ N0 = 1; -+ } else { -+ N0 = 0; -+ } -+ } -+ -+ if(K2msb < 1) { -+ Nm1 = 1; -+ } else { -+ Nm1 = 0; -+ } -+ -+ /* Calculate N */ -+ *NInt = (2 * ((Nprime >> 16) - Nm1) + N0) - 128; -+ -+ /* Calculate K */ -+ if(K2msb < 1) { -+ *KInt = KforceK0_1 + (2 << 21); -+ } else { -+ if (K2msb >= 3) { -+ *KInt = KforceK0_1 - (2 << 21); -+ } else { -+ *KInt = KforceK0_1; -+ } -+ } -+ -+ /* Force last 7 bits of K_int to 0x5D, as the IC is doing for spurs optimization */ -+ *KInt &= 0xFFFFFF80; -+ *KInt |= 0x5D; -+ -+ return 0; -+} -+ -+ -+static int tda18273_set_pll(struct dvb_frontend *fe) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ int ret; -+ -+ /* LO wanted = RF wanted + IF in KHz */ -+ unsigned int LO = 0; -+ -+ /* Algorithm that calculates PostDiv */ -+ unsigned char PostDiv = 0; /* absolute value */ -+ unsigned char LOPostDiv = 0; /* register value */ -+ -+ /* Algorithm that calculates Prescaler */ -+ unsigned char Prescaler = 0; -+ -+ /* Algorithm that calculates N, K */ -+ unsigned int N_int = 0; -+ unsigned int K_int = 0; -+ -+ /* Calculate wanted LO = RF + IF in Hz */ -+ LO = (priv->pObj->uRF + priv->pObj->uIF) / 1000; -+ -+ /* Calculate the best PostDiv and Prescaler : the ones that provide the best margin */ -+ /* in case of fine tuning +-2 MHz */ -+ ret = tda18273_find_postdivandprescalerwithbettermargin(LO, &PostDiv, &Prescaler); -+ -+ if(ret != -1) { -+ /* Program the PLL only if valid values are found, in that case err == TM_OK */ -+ /* Decode PostDiv */ -+ switch(PostDiv) { -+ case 1: LOPostDiv = 1; break; -+ case 2: LOPostDiv = 2; break; -+ case 4: LOPostDiv = 3; break; -+ case 8: LOPostDiv = 4; break; -+ case 16: LOPostDiv = 5; break; -+ default: dprintk(FE_INFO, 1, "%s *PostDiv value is wrong.", __func__); break; -+ } -+ -+ /* Affect register map without writing into IC */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Main_Post_Divider_byte__LOPostDiv, LOPostDiv, Bus_None); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Main_Post_Divider_byte__LOPresc, Prescaler, Bus_None); -+ /* Calculate N & K values of the PLL */ -+ ret = tda18273_calculate_nintkint(LO, PostDiv, Prescaler, &N_int, &K_int); -+ /* Affect registers map without writing to IC */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Sigma_delta_byte_4__LO_Frac_0, (UInt8)(K_int & 0xFF), Bus_None); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Sigma_delta_byte_3__LO_Frac_1, (UInt8)((K_int >> 8) & 0xFF), Bus_None); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Sigma_delta_byte_2__LO_Frac_2, (UInt8)((K_int >> 16) & 0xFF), Bus_None); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Sigma_delta_byte_1__LO_Int, (UInt8)(N_int & 0xFF), Bus_None); -+ /* Force manual selection mode : 0x3 at @0x56 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Sigma_delta_byte_5__N_K_correct_manual, 0x01, Bus_None); -+ /* Force manual selection mode : 0x3 at @0x56 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Sigma_delta_byte_5__LO_Calc_Disable, 0x01, Bus_None); -+ /* Write bytes Main_Post_Divider_byte (0x51) to Sigma_delta_byte_5 (0x56) */ -+ ret = tda18273_writeregmap(priv, gTDA18273_Reg_Main_Post_Divider_byte.Address, TDA18273_REG_DATA_LEN(gTDA18273_Reg_Main_Post_Divider_byte, gTDA18273_Reg_Sigma_delta_byte_5)); -+ } -+ -+ return 0; -+} -+ -+static int tda18273_override_icp(struct dvb_frontend *fe, unsigned int uRF) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ int ret; -+ unsigned int uIF = 0; -+ unsigned char ProgIF = 0; -+ unsigned char LOPostdiv = 0; -+ unsigned char LOPrescaler = 0; -+ unsigned int FVCO = 0; -+ unsigned char uICPBypass = 0; -+ unsigned char ICP = 0; -+ unsigned char uPrevICP = 0; -+ -+ /* Read PostDiv et Prescaler */ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_Main_Post_Divider_byte, &LOPostdiv, Bus_RW); -+ /* PostDiv */ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_Main_Post_Divider_byte__LOPostDiv, &LOPostdiv, Bus_NoRead); -+ /* Prescaler */ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_Main_Post_Divider_byte__LOPresc, &LOPrescaler, Bus_NoRead); -+ /* IF */ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_IF_Frequency_byte__IF_Freq, &ProgIF, Bus_NoRead); -+ /* Decode IF */ -+ uIF = ProgIF*50000; -+ /* Decode PostDiv */ -+ switch(LOPostdiv) { -+ case 1: LOPostdiv = 1; break; -+ case 2: LOPostdiv = 2; break; -+ case 3: LOPostdiv = 4; break; -+ case 4: LOPostdiv = 8; break; -+ case 5: LOPostdiv = 16; break; -+ default: ret = -1; break; -+ } -+ -+ if(ret != -1) { -+ /* Calculate FVCO in MHz*/ -+ FVCO = LOPostdiv * LOPrescaler * ((uRF + uIF) / 1000000); -+ /* Set correct ICP */ -+ if(FVCO < 6352) { -+ /* Set ICP to 01 (= 150)*/ -+ ICP = 0x01; -+ } else if(FVCO < 6592) { -+ /* Set ICP to 10 (= 300)*/ -+ ICP = 0x02; -+ } else { -+ /* Set ICP to 00 (= 500)*/ -+ ICP = 0x00; -+ } -+ /* Get ICP_bypass bit */ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_Charge_pump_byte__ICP_Bypass, &uICPBypass, Bus_RW); -+ /* Get ICP */ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_Charge_pump_byte__ICP, &uPrevICP, Bus_NoRead); -+ -+ if(uICPBypass == 0x0 || uPrevICP != ICP) { -+ /* Set ICP_bypass bit */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Charge_pump_byte__ICP_Bypass, 0x01, Bus_None); -+ /* Set ICP */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Charge_pump_byte__ICP, ICP, Bus_None); -+ /* Write Charge_pump_byte register */ -+ ret = tda18273_writeregmap(priv, gTDA18273_Reg_Charge_pump_byte.Address, 1); -+ } -+ } -+ -+ return ret; -+} -+ -+static int tda18273_override_digitalclock(struct dvb_frontend *fe, unsigned int uRF) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ int ret; -+ unsigned char uDigClock = 0; -+ unsigned char uPrevDigClock = 0; -+ unsigned char uProgIF = 0; -+ -+ /* LO < 55 MHz then Digital Clock set to 16 MHz else subLO */ -+ /* Read Current IF */ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_IF_Frequency_byte__IF_Freq, &uProgIF, Bus_NoWrite); -+ /* Read Current Digital Clock */ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode, &uPrevDigClock, Bus_NoWrite); -+ /* LO = RF + IF */ -+ if((uRF + (uProgIF*50000)) < 55000000) { -+ uDigClock = 0; /* '00' = 16 MHz */ -+ } else { -+ uDigClock = 3; /* '11' = subLO */ -+ } -+ -+ if(uPrevDigClock != uDigClock) { -+ /* Set Digital Clock bits */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode, uDigClock, Bus_NoRead); -+ } -+ -+ return 0; -+} -+ -+static int tda18273_set_rffreq(struct dvb_frontend *fe) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ int ret; -+ unsigned int uRF=priv->pObj->uProgRF; -+ unsigned int uRFLocal=0; -+ -+ /* Set the proper settings depending on the standard & RF frequency */ -+ /****************************************************************/ -+ /* AGC TOP Settings */ -+ /****************************************************************/ -+ /* Set AGC3 RF AGC Top */ -+ if(uRF < priv->pObj->pStandard->Freq_Start_LTE) { -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_AGC_byte__RFAGC_Top, priv->pObj->pStandard->AGC3_TOP_I2C_Low_Band, Bus_RW); -+ } else { -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_AGC_byte__RFAGC_Top, priv->pObj->pStandard->AGC3_TOP_I2C_High_Band, Bus_RW); -+ } -+ /* Set AGC3 Adapt TOP */ -+ if(uRF < priv->pObj->pStandard->Freq_Start_LTE) { -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_AGC_byte__RFAGC_Adapt_TOP, priv->pObj->pStandard->AGC3_Adapt_TOP_Low_Band, Bus_NoRead); -+ } else { -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_AGC_byte__RFAGC_Adapt_TOP, priv->pObj->pStandard->AGC3_Adapt_TOP_High_Band, Bus_NoRead); -+ } -+ /* Set IRQ_clear */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IRQ_clear, TDA18273_IRQ_Global|TDA18273_IRQ_SetRF, Bus_NoRead); -+ /* Set RF */ -+ uRFLocal = (uRF + 500) / 1000; -+ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_Frequency_byte_1__RF_Freq_1, (unsigned char)((uRFLocal & 0x00FF0000) >> 16), Bus_None); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_Frequency_byte_2__RF_Freq_2, (unsigned char)((uRFLocal & 0x0000FF00) >> 8), Bus_None); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_Frequency_byte_3__RF_Freq_3, (unsigned char)(uRFLocal & 0x000000FF), Bus_None); -+ ret = tda18273_writeregmap(priv, gTDA18273_Reg_RF_Frequency_byte_1.Address, TDA18273_REG_DATA_LEN(gTDA18273_Reg_RF_Frequency_byte_1, gTDA18273_Reg_RF_Frequency_byte_3)); -+ /* Set state machine and Launch it */ -+ ret = tda18273_set_msm(fe, TDA18273_MSM_SetRF, 0x1); -+ /* Wait for IRQ to trigger */ -+ //ret = iTDA18273_WaitIRQ(pObj, 50, 5, TDA18273_IRQ_SetRF); -+ mdelay(50); -+ -+ /* Override the calculated PLL to get the best margin in case fine tuning is used */ -+ /* which means set the PLL in manual mode that provides the best occurence of LO tuning (+-2 MHz) */ -+ /* without touching PostDiv and Prescaler */ -+ ret = tda18273_set_pll(fe); -+ /* Override ICP */ -+ ret = tda18273_override_icp(fe, priv->pObj->uProgRF); -+ /* Override Digital Clock */ -+ if(ret != -1) { -+ ret = tda18273_override_digitalclock(fe, priv->pObj->uProgRF); -+ } -+ -+ return 0; -+} -+ -+static int tda18273_set_rf(struct dvb_frontend *fe, unsigned int uRF) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ priv->pObj->uRF = uRF; -+ priv->pObj->uProgRF = priv->pObj->uRF + priv->pObj->pStandard->CF_Offset; -+ -+ tda18273_llpwr_state(fe, TDA18273_PowerNormalMode); -+ tda18273_lastpass_lnapwr(fe); -+ tda18273_check_calcpll(fe); -+ tda18273_override_bandsplit(fe); -+ tda18273_set_rffreq(fe); -+ -+ return 0; -+} -+ -+static int tda18273_hw_reset(struct dvb_frontend *fe) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ int ret; -+ -+ tda18273_pwr_state(fe, tmPowerStandby); -+ tda18273_llpwr_state(fe, TDA18273_PowerNormalMode); -+ -+ /* Set digital clock mode to 16 Mhz before resetting the IC to avoid unclocking the digital part */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Reference_Byte__Digital_Clock_Mode, 0x00, Bus_RW); -+ /* Perform a SW reset to reset the digital calibrations & the IC machine state */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Power_Down_byte_3, 0x03, Bus_RW); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Power_Down_byte_3, 0x00, Bus_NoRead); -+ /* Set power state on */ -+ //ret = tda18273_llpwr_state(fe, TDA18273_PowerNormalMode); -+ -+#if 0 -+ /* Only if tuner has a XTAL */ -+ if(1) { //if (priv->bBufferMode == False) -+ /* Reset XTALCAL_End bit */ -+ /* Set IRQ_clear */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IRQ_clear, TDA18273_IRQ_Global|TDA18273_IRQ_XtalCal|TDA18273_IRQ_HwInit|TDA18273_IRQ_IrCal, Bus_NoRead); -+ /* Launch XTALCAL */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_MSM_byte_2__XtalCal_Launch, 0x01, Bus_NoRead); -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_MSM_byte_2__XtalCal_Launch, 0x00, Bus_None); -+ /* Wait XTALCAL_End bit */ -+ //ret = iTDA18273_WaitXtalCal_End(priv, 100, 10); -+ } -+#endif -+ -+ /* Read all bytes */ -+ ret = tda18273_readregmap(priv, 0x00, TDA18273_REG_MAP_NB_BYTES); -+ /* Check if Calc_PLL algorithm is in automatic mode */ -+ ret = tda18273_check_calcpll(fe); -+ /* Up_Step_Ovld: POR = 1 -> 0 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Vsync_Mgt_byte__Up_Step_Ovld, 0x00, Bus_NoRead); -+ /* PLD_CC_Enable: POR = 1 -> 0 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RFAGCs_Gain_byte_1__PLD_CC_Enable, 0x00, Bus_NoRead); -+ /* RFCAL_Offset0 : 0 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_Cal_byte_1__RFCAL_Offset_Cprog0, 0x00, Bus_None); -+ /* RFCAL_Offset1 : 0 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_Cal_byte_1__RFCAL_Offset_Cprog1, 0x00, Bus_None); -+ /* RFCAL_Offset2 : 0 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_Cal_byte_1__RFCAL_Offset_Cprog2, 0x00, Bus_None); -+ /* RFCAL_Offset3 : 0 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_Cal_byte_1__RFCAL_Offset_Cprog3, 0x00, Bus_None); -+ /* RFCAL_Offset4 : 3 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_Cal_byte_2__RFCAL_Offset_Cprog4, 0x03, Bus_None); -+ /* RFCAL_Offset5 : 0 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_Cal_byte_2__RFCAL_Offset_Cprog5, 0x00, Bus_None); -+ /* RFCAL_Offset6 : 3 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_Cal_byte_2__RFCAL_Offset_Cprog6, 0x03, Bus_None); -+ /* RFCAL_Offset7 : 3 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_Cal_byte_2__RFCAL_Offset_Cprog7, 0x03, Bus_None); -+ /* RFCAL_Offset8 : 1 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RF_Cal_byte_3__RFCAL_Offset_Cprog8, 0x01, Bus_None); -+ /* Write RF_Cal_byte_1 (0x27) to RF_Cal_byte_3 (0x29) Registers */ -+ ret = tda18273_writeregmap(priv, gTDA18273_Reg_RF_Cal_byte_1.Address, TDA18273_REG_DATA_LEN(gTDA18273_Reg_RF_Cal_byte_1, gTDA18273_Reg_RF_Cal_byte_3)); -+ /* PLD_Temp_Enable: POR = 1 -> 0 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_RFAGCs_Gain_byte_1__PLD_Temp_Enable, 0x00, Bus_NoRead); -+ /* Power Down Vsync Management: POR = 0 -> 1 */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_Vsync_Mgt_byte__PD_Vsync_Mgt, 0x01, Bus_NoRead); -+ /* Set IRQ_clear */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IRQ_clear, TDA18273_IRQ_Global|TDA18273_IRQ_HwInit|TDA18273_IRQ_IrCal, Bus_NoRead); -+ /* Set state machine (all CALs except IRCAL) and Launch it */ -+ ret = tda18273_set_msm(fe, TDA18273_MSM_HwInit, 0x1); -+ /* Inform that init phase has started */ -+ /* State reached after 500 ms max */ -+ //ret = iTDA18273_WaitIRQ(priv, 500, 10, TDA18273_IRQ_HwInit); -+ mdelay(500); -+ /* Set IRQ_clear */ -+ ret = tda18273_writeregs(priv, &gTDA18273_Reg_IRQ_clear, TDA18273_IRQ_Global|TDA18273_IRQ_HwInit|TDA18273_IRQ_IrCal, Bus_NoRead); -+ /* Launch IRCALs after all other CALs are finished */ -+ ret = tda18273_set_msm(fe, TDA18273_MSM_IrCal, 0x1); -+ /* State reached after 500 ms max, 10 ms step due to CAL ~ 30ms */ -+ //ret = iTDA18273_WaitIRQ(priv, 500, 10, TDA18273_IRQ_IrCal); -+ mdelay(500); -+ -+ tda18273_llpwr_state(fe, TDA18273_PowerStandbyWithXtalOn); -+ -+ return 0; -+} -+ -+static int tda18273_hw_init(struct dvb_frontend *fe) -+{ -+ tda18273_pwr_state(fe, tmPowerOn); -+ -+ tda18273_hw_reset(fe); -+ -+ return 0; -+} -+ -+static int tda18273_init(struct dvb_frontend *fe) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ int ret; -+ unsigned char val=0; -+ unsigned short id=0; -+ unsigned char major; -+ unsigned char minor; -+ -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_ID_byte_1__Ident_1, &val, Bus_RW); -+ id = val << 8; -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_ID_byte_2__Ident_2, &val, Bus_RW); -+ id |= val; -+ -+ if(ret == TDA_RESULT_SUCCESS) { -+ if(id == TDA_DEVICE_TYPE) { -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_ID_byte_3__Major_rev, &major, Bus_RW); -+ ret = tda18273_readregs(priv, &gTDA18273_Reg_ID_byte_3__Minor_rev, &minor, Bus_RW); -+ dprintk(FE_INFO, 1, "id:%d / ver:%d.%d", id, major, minor); -+ } else { -+ return -1; -+ } -+ } else { -+ return -1; -+ } -+ -+ priv->pObj = &gTDA18273Instance; -+ -+ tda18273_hw_init(fe); -+ -+ return 0; -+} -+ -+static int tda18273_get_status(struct dvb_frontend *fe, u32 *status) -+{ -+ struct tda18273_state *priv = (struct tda18273_state*)fe->tuner_priv; -+ unsigned short lock_status = 0; -+ int ret = 0; -+ -+ ret = tda18273_get_lock_status(priv, &lock_status); -+ if (ret) -+ goto err; -+err: -+ dprintk(FE_DEBUG, 1, "ret=%d", ret); -+ return ret; -+} -+#if 0 -+static int tda18273_get_state(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ int ret; -+ -+ switch (param) { -+ case DVBFE_TUNER_FREQUENCY: -+ state->frequency = priv->freq_hz; -+ ret = 0; -+ break; -+ case DVBFE_TUNER_TUNERSTEP: -+ state->tunerstep = fe->ops.tuner_ops.info.frequency_step; -+ ret = 0; -+ break; -+ case DVBFE_TUNER_IFFREQ: -+ state->ifreq = priv->if_freq; -+ ret = 0; -+ break; -+ case DVBFE_TUNER_BANDWIDTH: -+ if (fe->ops.info.type == FE_OFDM) -+ state->bandwidth = priv->bandwidth; -+ ret = 0; -+ break; -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ return ret; -+} -+#endif -+static int tda18273_set_params(struct dvb_frontend *fe) -+{ -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ struct tda18273_state *priv = fe->tuner_priv; -+ u32 delsys = c->delivery_system; -+ u32 bw = c->bandwidth_hz; -+ u32 freq = c->frequency; -+ unsigned short lock = 0; -+ int ret; -+ -+ BUG_ON(!priv); -+ -+ dprintk(FE_DEBUG, 1, "freq=%d, bw=%d", freq, bw); -+ -+ switch (delsys) { -+ case SYS_ATSC: -+ tda18273_set_standardmode(fe, TDA18273_ATSC_6MHz); -+ break; -+ case SYS_DVBT: -+ case SYS_DVBT2: -+ switch (bw) { -+ case 1700000: -+ tda18273_set_standardmode(fe, TDA18273_DVBT_1_7MHz); -+ break; -+ case 6000000: -+ tda18273_set_standardmode(fe, TDA18273_DVBT_6MHz); -+ break; -+ case 7000000: -+ tda18273_set_standardmode(fe, TDA18273_DVBT_7MHz); -+ break; -+ case 8000000: -+ tda18273_set_standardmode(fe, TDA18273_DVBT_8MHz); -+ break; -+ case 10000000: -+ tda18273_set_standardmode(fe, TDA18273_DVBT_10MHz); -+ break; -+ default: -+ ret = -EINVAL; -+ goto err; -+ } -+ break; -+ case SYS_DVBC_ANNEX_A: -+ case SYS_DVBC_ANNEX_C: -+ tda18273_set_standardmode(fe, TDA18273_QAM_8MHz); -+ break; -+ case SYS_DVBC_ANNEX_B: -+ tda18273_set_standardmode(fe, TDA18273_QAM_6MHz); -+ break; -+ } -+ -+ ret = tda18273_pwr_state(fe, tmPowerOn); -+ if (ret) -+ goto err; -+ -+ dprintk(FE_DEBUG, 1, "if_freq=%d", priv->pObj->pStandard->IF); -+ -+ ret = tda18273_set_rf(fe, freq + priv->pObj->pStandard->IF); -+ if (ret) -+ goto err; -+ -+ msleep(100); -+ tda18273_get_lock_status(priv, &lock); -+ -+ tda18273_regall_debug(priv); -+ -+ dprintk(FE_INFO, 1, "Lock status = %d", lock); -+ if (lock) { -+ priv->freq_hz = freq; -+ priv->if_freq = priv->pObj->pStandard->IF; -+ priv->bandwidth = bw; -+ } -+err: -+ dprintk(FE_DEBUG, 1, "ret=%d", ret); -+ return ret; -+} -+ -+static int tda18273_get_freq(struct dvb_frontend *fe, u32 *frequency) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ *frequency = priv->freq_hz; -+ return 0; -+} -+ -+static int tda18273_get_if_freq(struct dvb_frontend *fe, u32 *frequency) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ *frequency = priv->if_freq; -+ return 0; -+} -+ -+static int tda18273_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ *bandwidth = priv->bandwidth; -+ return 0; -+} -+ -+static int tda18273_release(struct dvb_frontend *fe) -+{ -+ struct tda18273_state *priv = fe->tuner_priv; -+ -+ BUG_ON(!priv); -+ -+ if(priv->power_state != tmPowerOff) { -+ tda18273_pwr_state(fe, tmPowerStandby); -+ } -+ -+ fe->tuner_priv = NULL; -+ kfree(priv); -+ return 0; -+} -+ -+static struct dvb_tuner_ops tda18273_ops = { -+ .info = { -+ .name = "TDA18273 Silicon Tuner", -+ .frequency_min = 42000000, -+ .frequency_max = 870000000, -+ .frequency_step = 50000, -+ }, -+ .init = tda18273_init, -+// .sleep = tda18273_sleep, -+ .get_status = tda18273_get_status, -+ .set_params = tda18273_set_params, -+ .get_frequency = tda18273_get_freq, -+ .get_bandwidth = tda18273_get_bandwidth, -+ .get_if_frequency = tda18273_get_if_freq, -+ .release = tda18273_release -+}; -+ -+struct dvb_frontend *tda18273_attach(struct dvb_frontend *fe, -+ struct i2c_adapter *i2c, -+ const u8 i2c_addr) -+{ -+ struct tda18273_state *tda18273; -+ int ret; -+ -+ BUG_ON(!i2c); -+ -+ tda18273 = kzalloc(sizeof (struct tda18273_state), GFP_KERNEL); -+ if (!tda18273) -+ goto err; -+ -+ tda18273->i2c = i2c; -+ tda18273->fe = fe; -+ tda18273->i2c_addr = i2c_addr; -+ tda18273->power_state = tmPowerOff; -+ -+ fe->tuner_priv = tda18273; -+ fe->ops.tuner_ops = tda18273_ops; -+ -+ ret = tda18273_init(fe); -+ if (ret) { -+ dprintk(FE_ERROR, 1, "Error Initializing!"); -+ goto err; -+ } -+ -+ dprintk(FE_DEBUG, 1, "Done"); -+ return tda18273->fe; -+err: -+ kfree(tda18273); -+ return NULL; -+} -+EXPORT_SYMBOL(tda18273_attach); -+ -+MODULE_AUTHOR("Manu Abraham"); -+MODULE_DESCRIPTION("TDA18273 Silicon tuner"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/tuners/tda18273.h b/drivers/media/tuners/tda18273.h -new file mode 100644 -index 0000000..534b85f ---- /dev/null -+++ b/drivers/media/tuners/tda18273.h -@@ -0,0 +1,38 @@ -+/* -+ tda18273.h - header for the NXP TDA18273 silicon tuner -+ Copyright (C) 2014 CrazyCat -+ -+ 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. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#ifndef __TDA18273_H -+#define __TDA18273_H -+ -+#if IS_ENABLED(CONFIG_MEDIA_TUNER_TDA18273) -+extern struct dvb_frontend *tda18273_attach(struct dvb_frontend *fe, -+ struct i2c_adapter *i2c, -+ const u8 i2c_addr); -+ -+#else -+static inline struct dvb_frontend *tda18273_attach(struct dvb_frontend *fe, -+ struct i2c_adapter *i2c, -+ const u8 i2c_addr) -+{ -+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -+ return NULL; -+} -+#endif -+ -+#endif /* __TDA18273_H */ -diff --git a/drivers/media/tuners/tda18273_priv.h b/drivers/media/tuners/tda18273_priv.h -new file mode 100644 -index 0000000..a282b14 ---- /dev/null -+++ b/drivers/media/tuners/tda18273_priv.h -@@ -0,0 +1,1427 @@ -+/* -+ tda18273-priv.h - private header for the NXP TDA18273 silicon tuner -+ Copyright (C) 2014 CrazyCat -+ -+ 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. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+*/ -+ -+#ifndef __TDA18273_PRIV -+#define __TDA18273_PRIV -+ -+#define TDA18273_TUNER_RESET 0 -+ -+#define TDA_FREQ_LOW_BAND 1 -+#define TDA_FREQ_MID_BAND 2 -+#define TDA_FREQ_HIGH_BAND 4 -+ -+#define TDA_AGC_115dBuV 1 -+#define TDA_AGC_112dBuV 2 -+#define TDA_AGC_109dBuV 3 -+#define TDA_AGC_106dBuV 4 -+#define TDA_AGC_103dBuV 5 -+#define TDA_AGC_EXTERNAL 6 -+#define TDA_AGC_DISABLE 7 -+ -+#define TDA_PLL_CP_50uA 6 -+#define TDA_PLL_CP_125uA 7 -+#define TDA_PLL_CP_250uA 0x0e -+#define TDA_PLL_CP_650uA 0x0f -+ -+#define TDA_PLLref_DIVIDER_64 3 -+#define TDA_PLLref_DIVIDER_24 2 -+ -+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -+ -+typedef unsigned char UInt8; -+typedef unsigned int UInt32; -+typedef int Int32; -+ -+ -+/* Result codes */ -+#define TDA_RESULT_SUCCESS 0 -+#define TDA_RESULT_RESET_FAILURE 1 -+#define TDA_RESULT_I2C_WRITE_FAILURE 2 -+#define TDA_RESULT_I2C_READ_FAILURE 3 -+#define TDA_RESULT_OUT_OF_RANGE 5 -+ -+ -+/* Product id */ -+#define TDA_DEVICE_TYPE 18273 -+ -+/* Register Bit-Field Definition */ -+typedef struct _TDA18273_BitField_t { -+ UInt8 Address; -+ UInt8 PositionInBits; -+ UInt8 WidthInBits; -+ UInt8 Attributes; -+} TDA18273_BitField_t, *pTDA18273_BitField_t; -+ -+/* Bus Access */ -+typedef enum _tmbslFrontEndBusAccess_t { -+ Bus_RW = 0x00, /* RW Bus access */ -+ Bus_NoRead = 0x01, /* No Read Bus access */ -+ Bus_NoWrite = 0x02, /* No Write Bus access */ -+ Bus_None = Bus_NoRead|Bus_NoWrite, /* No Bus access. Update RegMap only */ -+ Bus_Max -+} tmbslFrontEndBusAccess_t; -+ -+typedef enum tmPowerState -+{ -+ tmPowerOn = 0, /* Device powered on (D0 state) */ -+ tmPowerStandby, /* Device power standby (D1 state) */ -+ tmPowerSuspend, /* Device power suspended (D2 state) */ -+ tmPowerOff, /* Device powered off (D3 state) */ -+ tmPowerMax /* Device power max */ -+} tmPowerState_t, *ptmPowerState_t; -+ -+typedef enum _TDA18273PowerState_t { -+ TDA18273_PowerNormalMode = 0, /* Device normal mode */ -+ TDA18273_PowerStandbyWithXtalOn, /* Device standby mode with Xtal Output */ -+ TDA18273_PowerStandby, /* Device standby mode */ -+ TDA18273_PowerMax -+} TDA18273PowerState_t, *pTDA18273PowerState_t; -+ -+typedef enum _TDA18273StandardMode_t { -+ TDA18273_StandardMode_Unknown = 0, /* Unknown standard */ -+ TDA18273_QAM_6MHz, /* Digital TV QAM 6MHz */ -+ TDA18273_QAM_8MHz, /* Digital TV QAM 8MHz */ -+ TDA18273_ATSC_6MHz, /* Digital TV ATSC 6MHz */ -+ TDA18273_ISDBT_6MHz, /* Digital TV ISDBT 6MHz */ -+ TDA18273_DVBT_1_7MHz, /* Digital TV DVB-T/T2 6MHz */ -+ TDA18273_DVBT_6MHz, /* Digital TV DVB-T/T2 6MHz */ -+ TDA18273_DVBT_7MHz, /* Digital TV DVB-T/T2 7MHz */ -+ TDA18273_DVBT_8MHz, /* Digital TV DVB-T/T2 8MHz */ -+ TDA18273_DVBT_10MHz, /* Digital TV DVB-T/T2 10MHz */ -+ TDA18273_DMBT_8MHz, /* Digital TV DMB-T 8MHz */ -+ TDA18273_FM_Radio, /* Analog FM Radio */ -+ TDA18273_ANLG_MN, /* Analog TV M/N */ -+ TDA18273_ANLG_B, /* Analog TV B */ -+ TDA18273_ANLG_GH, /* Analog TV G/H */ -+ TDA18273_ANLG_I, /* Analog TV I */ -+ TDA18273_ANLG_DK, /* Analog TV D/K */ -+ TDA18273_ANLG_L, /* Analog TV L */ -+ TDA18273_ANLG_LL, /* Analog TV L' */ -+ TDA18273_Scanning, /* Analog Preset Blind Scanning */ -+ TDA18273_ScanXpress, /* ScanXpress */ -+ TDA18273_StandardMode_Max -+} TDA18273StandardMode_t, *pTDA18273StandardMode_t; -+ -+/* TDA18273 Driver State Machine */ -+typedef enum _TDA18273HwState_t { -+ TDA18273_HwState_Unknown = 0, /* Hw State Unknown */ -+ TDA18273_HwState_InitNotDone, /* Hw Init Not Done */ -+ TDA18273_HwState_InitPending, /* Hw Init Pending */ -+ TDA18273_HwState_InitDone, /* Hw Init Done */ -+ TDA18273_HwState_SetStdDone, /* Set Standard Done */ -+ TDA18273_HwState_SetRFDone, /* Set RF Done */ -+ TDA18273_HwState_SetFineRFDone, /* Set Fine RF Done */ -+ TDA18273_HwState_Max -+} TDA18273HwState_t, *pTDA18273HwState_t; -+ -+typedef enum _TDA18273HwStateCaller_t { -+ TDA18273_HwStateCaller_Unknown = 0, /* Caller Unknown */ -+ TDA18273_HwStateCaller_SetPower, /* Caller SetPowerState */ -+ TDA18273_HwStateCaller_HwInit, /* Caller HwInit */ -+ TDA18273_HwStateCaller_SetStd, /* Caller SetStandardMode */ -+ TDA18273_HwStateCaller_SetRF, /* Caller SetRF */ -+ TDA18273_HwStateCaller_SetFineRF, /* Caller SetFineRF */ -+ TDA18273_HwStateCaller_GetRSSI, /* Caller GetRSSI */ -+ TDA18273_HwStateCaller_SetRawRF, /* Caller SetRawRF */ -+ TDA18273_HwStateCaller_Max -+} TDA18273HwStateCaller_t, *pTDA18273HwStateCaller_t; -+ -+/* TDA18273 specific powerstate bits: */ -+typedef enum _TDA18273SM_Reg_t { -+ TDA18273_SM_NONE = 0x00, /* No SM bit to set */ -+ TDA18273_SM_XT = 0x01, /* SM_XT bit to set */ -+ TDA18273_SM = 0x02 /* SM bit to set */ -+} TDA18273SM_Reg_t, *pTDA18273SM_Reg_t; -+ -+/* TDA18273 specific MSM: */ -+typedef enum _TDA18273MSM_t { -+ TDA18273_MSM_Calc_PLL = 0x01, /* Calc_PLL bit */ -+ TDA18273_MSM_RC_Cal = 0x02, /* RC_Cal bit */ -+ TDA18273_MSM_IR_CAL_Wanted = 0x04, /* IR_CAL_Wanted bit */ -+ TDA18273_MSM_IR_Cal_Image = 0x08, /* IR_Cal_Image bit */ -+ TDA18273_MSM_IR_CAL_Loop = 0x10, /* IR_CAL_Loop bit */ -+ TDA18273_MSM_RF_CAL = 0x20, /* RF_CAL bit */ -+ TDA18273_MSM_RF_CAL_AV = 0x40, /* RF_CAL_AV bit */ -+ TDA18273_MSM_RSSI_Meas = 0x80, /* RSSI_Meas bit */ -+ /* Performs all CALs except IR_CAL */ -+ TDA18273_MSM_HwInit = TDA18273_MSM_Calc_PLL\ -+ |TDA18273_MSM_RC_Cal\ -+ |TDA18273_MSM_RF_CAL, -+ /* Performs all IR_CAL */ -+ TDA18273_MSM_IrCal = TDA18273_MSM_IR_Cal_Image\ -+ |TDA18273_MSM_IR_CAL_Loop, -+ TDA18273_MSM_SetRF = TDA18273_MSM_Calc_PLL\ -+ |TDA18273_MSM_RF_CAL_AV, -+ TDA18273_MSM_GetPowerLevel = TDA18273_MSM_RSSI_Meas -+} TDA18273MSM_t, *pTDA18273MSM_t; -+ -+/* TDA18273 specific IRQ clear: */ -+typedef enum _TDA18273IRQ_t { -+ TDA18273_IRQ_MSM_RCCal = 0x01, /* MSM_RCCal bit */ -+ TDA18273_IRQ_MSM_IRCAL = 0x02, /* MSM_IRCAL bit */ -+ TDA18273_IRQ_MSM_RFCal = 0x04, /* MSM_RFCal bit */ -+ TDA18273_IRQ_MSM_LOCalc = 0x08, /* MSM_LOCalc bit */ -+ TDA18273_IRQ_MSM_RSSI = 0x10, /* MSM_RSSI bit */ -+ TDA18273_IRQ_XtalCal = 0x20, /* XtalCal bit */ -+ TDA18273_IRQ_Global = 0x80, /* IRQ_status bit */ -+ TDA18273_IRQ_HwInit = TDA18273_IRQ_MSM_RCCal\ -+ |TDA18273_IRQ_MSM_RFCal\ -+ |TDA18273_IRQ_MSM_LOCalc\ -+ |TDA18273_IRQ_MSM_RSSI, -+ TDA18273_IRQ_IrCal = TDA18273_IRQ_MSM_IRCAL\ -+ |TDA18273_IRQ_MSM_LOCalc\ -+ |TDA18273_IRQ_MSM_RSSI, -+ TDA18273_IRQ_SetRF = TDA18273_IRQ_MSM_RFCal\ -+ |TDA18273_IRQ_MSM_LOCalc, -+ TDA18273_IRQ_GetPowerLevel = TDA18273_IRQ_MSM_RSSI -+} TDA18273IRQ_t, *pTDA18273IRQ_t; -+ -+/* TDA18273 Standard settings: */ -+typedef enum _TDA18273LPF_t { -+ TDA18273_LPF_6MHz = 0, /* 6MHz LPFc */ -+ TDA18273_LPF_7MHz, /* 7MHz LPFc */ -+ TDA18273_LPF_8MHz, /* 8MHz LPFc */ -+ TDA18273_LPF_9MHz, /* 9MHz LPFc */ -+ TDA18273_LPF_1_5MHz, /* 1.5MHz LPFc */ -+ TDA18273_LPF_Max -+} TDA18273LPF_t, *pTDA18273LPF_t; -+ -+typedef enum _TDA18273LPFOffset_t { -+ TDA18273_LPFOffset_0pc = 0, /* LPFc 0% */ -+ TDA18273_LPFOffset_min_4pc, /* LPFc -4% */ -+ TDA18273_LPFOffset_min_8pc, /* LPFc -8% */ -+ TDA18273_LPFOffset_min_12pc, /* LPFc -12% */ -+ TDA18273_LPFOffset_Max -+} TDA18273LPFOffset_t, *pTDA18273LPFOffset_t; -+ -+typedef enum TDA18273DC_Notch_IF_PPF_t { -+ TDA18273_DC_Notch_IF_PPF_Disabled = 0, /* IF Notch Disabled */ -+ TDA18273_DC_Notch_IF_PPF_Enabled, /* IF Notch Enabled */ -+ TDA18273_DC_Notch_IF_PPF_Max -+} TDA18273DC_Notch_IF_PPF_t, *pTDA18273DC_Notch_IF_PPF_t; -+ -+typedef enum _TDA18273IF_HPF_t { -+ TDA18273_IF_HPF_Disabled = 0, /* IF HPF disabled */ -+ TDA18273_IF_HPF_0_4MHz, /* IF HPF 0.4MHz */ -+ TDA18273_IF_HPF_0_85MHz, /* IF HPF 0.85MHz */ -+ TDA18273_IF_HPF_1MHz, /* IF HPF 1MHz */ -+ TDA18273_IF_HPF_1_5MHz, /* IF HPF 1.5MHz */ -+ TDA18273_IF_HPF_Max -+} TDA18273IF_HPF_t, *pTDA18273IF_HPF_t; -+ -+typedef enum _TDA18273IF_Notch_t { -+ TDA18273_IF_Notch_Disabled = 0, /* IF Notch Disabled */ -+ TDA18273_IF_Notch_Enabled, /* IF Notch Enabled */ -+ TDA18273_IF_Notch_Max -+} TDA18273IF_Notch_t, *pTDA18273IF_Notch_t; -+ -+typedef enum _TDA18273IFnotchToRSSI_t { -+ TDA18273_IFnotchToRSSI_Disabled = 0, /* IFnotchToRSSI Disabled */ -+ TDA18273_IFnotchToRSSI_Enabled, /* IFnotchToRSSI Enabled */ -+ TDA18273_IFnotchToRSSI_Max -+} TDA18273IFnotchToRSSI_t, *pTDA18273IFnotchToRSSI_t; -+ -+typedef enum _TDA18273AGC1_TOP_I2C_DN_UP_t { -+ TDA18273_AGC1_TOP_I2C_DN_UP_d88_u82dBuV = 0, /* AGC1 TOP I2C DN/UP down 88 up 82 dBuV */ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d90_u84dBuV, /* AGC1 TOP I2C DN/UP down 90 up 84 dBuV */ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89wdBuV, /* AGC1 TOP I2C DN/UP down 95 up 89 dBuV */ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d93_u87dBuV, /* AGC1 TOP I2C DN/UP down 93 up 87 dBuV */ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP down 95 up 89 dBuV */ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d99_u84dBuV, /* AGC1 TOP I2C DN/UP down 99 up 84 dBuV */ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d100_u82dBuV, /* AGC1 TOP I2C DN/UP down 100 up 82 dBuV */ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d100_u94bisdBuV, /* AGC1 TOP I2C DN/UP down 100 up 94 dBuV */ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d102_u82dBuV, /* AGC1 TOP I2C DN/UP down 102 up 82 dBuV */ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d102_u84dBuV, /* AGC1 TOP I2C DN/UP down 102 up 84 dBuV */ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d100_u94dBuV, /* AGC1 TOP I2C DN/UP down 100 up 94 dBuV */ -+ TDA18273_AGC1_TOP_I2C_DN_UP_Max -+} TDA18273AGC1_TOP_I2C_DN_UP_t, *pTDA18273AGC1_TOP_I2C_DN_UP_t; -+ -+typedef enum _TDA18273AGC1_Adapt_TOP_DN_UP_t { -+ TDA18273_AGC1_Adapt_TOP_DN_UP_0_Step = 0, /* AGC1 Adapt TOP DN/UP 0 Step */ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_1_Step, /* AGC1 Adapt TOP DN/UP 1 Step */ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_2_Step, /* AGC1 Adapt TOP DN/UP 2 Step */ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_3_Step, /* AGC1 Adapt TOP DN/UP 3 Step */ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_Max -+} TDA18273AGC1_Adapt_TOP_DN_UP_t, *pTDA18273AGC1_Adapt_TOP_DN_UP_t; -+ -+typedef enum _TDA18273AGC1_Mode_t { -+ TDA18273_AGC1_Mode_No_Mode = 0, /* AGC1 Mode */ -+ TDA18273_AGC1_Mode_TOP_ADAPT, /* AGC1 Mode: TOP ADAPT */ -+ TDA18273_AGC1_Mode_LNA_ADAPT, /* AGC1 Mode: LNA ADAPT */ -+ TDA18273_AGC1_Mode_LNA_ADAPT_TOP_ADAPT, /* AGC1 Mode: LNA ADAPT & TOP ADAPT */ -+ TDA18273_AGC1_Mode_FREEZE, /* AGC1 Mode: FREEZE */ -+ TDA18273_AGC1_Mode_WIDE, /* AGC1 Mode: WIDE */ -+ TDA18273_AGC1_Mode_LNA_ADAPT_FREEZE, /* AGC1 Mode: LNA ADAPT & FREEZE */ -+ TDA18273_AGC1_Mode_LNA_ADAPT_WIDE, /* AGC1 Mode: LNA ADAPT & WIDE */ -+ TDA18273_AGC1_Mode_Max -+} TDA18273AGC1_Mode_t, *pTDA18273AGC1_Mode_t; -+ -+typedef enum _TDA18273Range_LNA_Adapt_t { -+ TDA18273_Range_LNA_Adapt_20dB_8dB = 0, /* Range LNA Adapt 20dB-8dB */ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt 20dB-11dB */ -+ TDA18273_Range_LNA_Adapt_Max -+} TDA18273Range_LNA_Adapt_t, *pTDA18273Range_LNA_Adapt_t; -+ -+typedef enum _TDA18273LNA_Adapt_RFAGC_Gv_Threshold { -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB = 0, /* 18.25dB */ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_16_75dB, /* 16.75dB */ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_15_25dB, /* 15.25dB */ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_13_75dB, /* 13.75dB */ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_Max -+} TDA18273LNA_Adapt_RFAGC_Gv_Threshold, *pTDA18273LNA_Adapt_RFAGC_Gv_Threshold; -+ -+typedef enum _TDA18273AGC1_Top_Adapt_RFAGC_Gv_Threshold { -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_16_75dB = 0, /* 16.75dB */ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_15_25dB, /* 15.25dB */ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_13_75dB, /* 13.75dB */ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_12_25dB, /* 12.25dB */ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_Max -+} TDA18273AGC1_Top_Adapt_RFAGC_Gv_Threshold, *pTDA18273AGC1_Top_Adapt_RFAGC_Gv_Threshold; -+ -+typedef enum _TDA18273AGC1_DN_Time_Constant_t { -+ TDA18273_AGC1_DN_Time_Constant_32_752ms = 0, /* 32.752 ms */ -+ TDA18273_AGC1_DN_Time_Constant_16_376ms, /* 16.376 ms */ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* 8.188 ms */ -+ TDA18273_AGC1_DN_Time_Constant_4_094ms /* 4.094 ms */ -+} TDA18273AGC1_DN_Time_Constant_t, *pTDA18273AGC1_DN_Time_Constant_t; -+ -+typedef enum _TDA18273AGC2_TOP_DN_UP_t { -+ TDA18273_AGC2_TOP_DN_UP_d88_u81dBuV = 0, /* AGC2 TOP DN/UP down 88 up 81 dBuV */ -+ TDA18273_AGC2_TOP_DN_UP_d90_u83dBuV, /* AGC2 TOP DN/UP down 90 up 83 dBuV */ -+ TDA18273_AGC2_TOP_DN_UP_d93_u86dBuV, /* AGC2 TOP DN/UP down 93 up 86 dBuV */ -+ TDA18273_AGC2_TOP_DN_UP_d95_u88dBuV, /* AGC2 TOP DN/UP down 95 up 88 dBuV */ -+ TDA18273_AGC2_TOP_DN_UP_d88_u82dBuV, /* AGC2 TOP DN/UP down 88 up 82 dBuV */ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP down 90 up 84 dBuV */ -+ TDA18273_AGC2_TOP_DN_UP_d93_u87dBuV, /* AGC2 TOP DN/UP down 93 up 87 dBuV */ -+ TDA18273_AGC2_TOP_DN_UP_d95_u89dBuV, /* AGC2 TOP DN/UP down 95 up 89 dBuV */ -+ TDA18273_AGC2_TOP_DN_UP_Max -+} TDA18273AGC2_TOP_DN_UP_t, *pTDA18273AGC2_TOP_DN_UP_t; -+ -+typedef enum _TDA18273AGC2_DN_Time_Constant_t { -+ TDA18273_AGC2_DN_Time_Constant_16_376ms = 0, /* 16.376 ms */ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* 8.188 ms */ -+ TDA18273_AGC2_DN_Time_Constant_4_094ms, /* 4.094 ms */ -+ TDA18273_AGC2_DN_Time_Constant_2_047ms, /* 2.047 ms */ -+} TDA18273AGC2_DN_Time_Constant_t, *pTDA18273AGC2_DN_Time_Constant_t; -+ -+typedef enum _TDA18273AGC3_TOP_I2C_t { -+ TDA18273_AGC3_TOP_I2C_94dBuV = 0, /* AGC3 TOP I2C 94 dBuV */ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C 96 dBuV */ -+ TDA18273_AGC3_TOP_I2C_98dBuV, /* AGC3 TOP I2C 98 dBuV */ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C 100 dBuV */ -+ TDA18273_AGC3_TOP_I2C_102dBuV, /* AGC3 TOP I2C 102 dBuV */ -+ TDA18273_AGC3_TOP_I2C_104dBuV, /* AGC3 TOP I2C 104 dBuV */ -+ TDA18273_AGC3_TOP_I2C_106dBuV, /* AGC3 TOP I2C 106 dBuV */ -+ TDA18273_AGC3_TOP_I2C_107dBuV, /* AGC3 TOP I2C 107 dBuV */ -+ TDA18273_AGC3_TOP_I2C_Max -+} TDA18273AGC3_TOP_I2C_t, *pTDA18273AGC3_TOP_I2C_t; -+ -+typedef enum _TDA18273AGC4_TOP_DN_UP_t { -+ TDA18273_AGC4_TOP_DN_UP_d105_u99dBuV = 0, /* AGC4 TOP DN/UP down 105 up 99 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d105_u100dBuV, /* AGC4 TOP DN/UP down 105 up 100 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d105_u101dBuV, /* AGC4 TOP DN/UP down 105 up 101 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d107_u101dBuV, /* AGC4 TOP DN/UP down 107 up 101 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d107_u102dBuV, /* AGC4 TOP DN/UP down 107 up 102 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d107_u103dBuV, /* AGC4 TOP DN/UP down 107 up 103 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d108_u102dBuV, /* AGC4 TOP DN/UP down 108 up 102 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d109_u103dBuV, /* AGC4 TOP DN/UP down 109 up 103 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d109_u104dBuV, /* AGC4 TOP DN/UP down 109 up 104 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d109_u105dBuV, /* AGC4 TOP DN/UP down 109 up 105 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d110_u104dBuV, /* AGC4 TOP DN/UP down 110 up 104 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d110_u105dBuV, /* AGC4 TOP DN/UP down 110 up 105 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d110_u106dBuV, /* AGC4 TOP DN/UP down 110 up 106 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d112_u106dBuV, /* AGC4 TOP DN/UP down 112 up 106 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d112_u107dBuV, /* AGC4 TOP DN/UP down 112 up 107 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_d112_u108dBuV, /* AGC4 TOP DN/UP down 112 up 108 dBuV */ -+ TDA18273_AGC4_TOP_DN_UP_Max -+} TDA18273AGC4_TOP_DN_UP_t, *pTDA18273AGC4_TOP_DN_UP_t; -+ -+typedef enum _TDA18273AGC5_TOP_DN_UP_t { -+ TDA18273_AGC5_TOP_DN_UP_d105_u99dBuV = 0, /* AGC5 TOP DN/UP down 105 up 99 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d105_u100dBuV, /* AGC5 TOP DN/UP down 105 up 100 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d105_u101dBuV, /* AGC5 TOP DN/UP down 105 up 101 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d107_u101dBuV, /* AGC5 TOP DN/UP down 107 up 101 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d107_u102dBuV, /* AGC5 TOP DN/UP down 107 up 102 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d107_u103dBuV, /* AGC5 TOP DN/UP down 107 up 103 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d108_u102dBuV, /* AGC5 TOP DN/UP down 108 up 102 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d109_u103dBuV, /* AGC5 TOP DN/UP down 109 up 103 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d109_u104dBuV, /* AGC5 TOP DN/UP down 109 up 104 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d109_u105dBuV, /* AGC5 TOP DN/UP down 109 up 105 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d110_u104dBuV, /* AGC5 TOP DN/UP down 108 up 104 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d110_u105dBuV, /* AGC5 TOP DN/UP down 108 up 105 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d110_u106dBuV, /* AGC5 TOP DN/UP down 108 up 106 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d112_u106dBuV, /* AGC5 TOP DN/UP down 108 up 106 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d112_u107dBuV, /* AGC5 TOP DN/UP down 108 up 107 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_d112_u108dBuV, /* AGC5 TOP DN/UP down 108 up 108 dBuV */ -+ TDA18273_AGC5_TOP_DN_UP_Max -+} TDA18273AGC5_TOP_DN_UP_t, *pTDA18273AGC5_TOP_DN_UP_t; -+ -+typedef enum _TDA18273AGC3_Top_Adapt_Algorithm { -+ TDA18273_Top_Adapt_NO_TOP_ADAPT = 0, /* NO TOP ADAPT */ -+ TDA18273_Top_Adapt_TOP_ADAPT35, /* TOP ADAPT35 */ -+ TDA18273_Top_Adapt_TOP_ADAPT34, /* TOP ADAPT34 */ -+ TDA18273_Top_Adapt_Max -+} TDA18273AGC3_Top_Adapt_Algorithm, *pTDA18273AGC3_Top_Adapt_Algorithm; -+ -+typedef enum _TDA18273AGC3_Adapt_TOP_t { -+ TDA18273_AGC3_Adapt_TOP_0_Step = 0, /* same level as AGC3 TOP */ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* 1 level below AGC3 TOP */ -+ TDA18273_AGC3_Adapt_TOP_2_Step, /* 2 level below AGC3 TOP */ -+ TDA18273_AGC3_Adapt_TOP_3_Step /* 3 level below AGC3 TOP */ -+} TDA18273AGC3_Adapt_TOP_t, *pTDA18273AGC3_Adapt_TOP_t; -+ -+typedef enum _TDA18273AGC_Overload_TOP_t { -+ TDA18273_AGC_Overload_TOP_plus_9_plus_3_5_min_3_5 = 0, /* +9/+3.5/-3.5 */ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_4_5, /* +9/+4.5/-4.5 */ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* +9/+4.5/-3.5 */ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_6_min_4_5, /* +9/+6/-4.5 */ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_6_min_6, /* +9/+6/-6 */ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_6_min_9, /* +9/+6/-9 */ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_7_5_min_9, /* +9/+7.5/-9 */ -+ TDA18273_AGC_Overload_TOP_plus_12_plus_7_5_min_9 /* +12/+7.5/-9 */ -+} TDA18273AGC_Overload_TOP_t, *pTDA18273AGC_Overload_TOP_t; -+ -+typedef enum _TDA18273TH_AGC_Adapt34_t { -+ TDA18273_TH_AGC_Adapt34_2dB = 0, /* Adapt TOP 34 Gain Threshold 2dB */ -+ TDA18273_TH_AGC_Adapt34_5dB /* Adapt TOP 34 Gain Threshold 5dB */ -+} TDA18273TH_AGC_Adapt34_t, *pTDA18273TH_AGC_Adapt34_t; -+ -+typedef enum _TDA18273RF_Atten_3dB_t { -+ TDA18273_RF_Atten_3dB_Disabled = 0, /* RF_Atten_3dB Disabled */ -+ TDA18273_RF_Atten_3dB_Enabled, /* RF_Atten_3dB Enabled */ -+ TDA18273_RF_Atten_3dB_Max -+} TDA18273RF_Atten_3dB_t, *pTDA18273RF_Atten_3dB_t; -+ -+typedef enum _TDA18273IF_Output_Level_t { -+ TDA18273_IF_Output_Level_2Vpp_0_30dB = 0, /* 2Vpp 0 - 30dB */ -+ TDA18273_IF_Output_Level_1_25Vpp_min_4_26dB, /* 1.25Vpp -4 - 26dB */ -+ TDA18273_IF_Output_Level_1Vpp_min_6_24dB, /* 1Vpp -6 - 24dB */ -+ TDA18273_IF_Output_Level_0_8Vpp_min_8_22dB, /* 0.8Vpp -8 - 22dB */ -+ TDA18273_IF_Output_Level_0_85Vpp_min_7_5_22_5dB, /* 0.85Vpp -7.5 - 22.5dB */ -+ TDA18273_IF_Output_Level_0_7Vpp_min_9_21dB, /* 0.7Vpp -9 - 21dB */ -+ TDA18273_IF_Output_Level_0_6Vpp_min_10_3_19_7dB, /* 0.6Vpp -10.3 - 19.7dB */ -+ TDA18273_IF_Output_Level_0_5Vpp_min_12_18dB, /* 0.5Vpp -12 - 18dB */ -+ TDA18273_IF_Output_Level_Max -+} TDA18273IF_Output_Level_t, *pTDA18273IF_Output_Level_t; -+ -+typedef enum _TDA18273S2D_Gain_t { -+ TDA18273_S2D_Gain_3dB = 0, /* 3dB */ -+ TDA18273_S2D_Gain_6dB, /* 6dB */ -+ TDA18273_S2D_Gain_9dB, /* 9dB */ -+ TDA18273_S2D_Gain_Max -+} TDA18273S2D_Gain_t, *pTDA18273S2D_Gain_t; -+ -+typedef enum _TDA18273Negative_Modulation_t { -+ TDA18273_Negative_Modulation_Disabled = 0, -+ TDA18273_Negative_Modulation_Enabled, -+ TDA18273_Negative_Modulation_Max -+} TDA18273Negative_Modulation_t, *pTDA18273Negative_Modulation_t; -+ -+typedef enum _TDA18273AGCK_Steps_t { -+ TDA18273_AGCK_Steps_0_2dB = 0, /* 0.2dB */ -+ TDA18273_AGCK_Steps_0_4dB, /* 0.4dB */ -+ TDA18273_AGCK_Steps_0_6dB, /* 0.6dB */ -+ TDA18273_AGCK_Steps_0_8dB, /* 0.8dB */ -+ TDA18273_AGCK_Steps_Max -+} TDA18273AGCK_Steps_t, *pTDA18273AGCK_Steps_t; -+ -+typedef enum _TDA18273AGCK_Time_Constant_t { -+ TDA18273_AGCK_Time_Constant_1_STEP_EACH_VSYNC_RISING_EDGE = 0, /* 1 Step Each VSYNC Rising Edge */ -+ TDA18273_AGCK_Time_Constant_0_512ms, /* 0.512ms */ -+ TDA18273_AGCK_Time_Constant_8_192ms, /* 8.192ms */ -+ TDA18273_AGCK_Time_Constant_32_768ms, /* 32.768ms */ -+ TDA18273_AGCK_Time_Constant_Max -+} TDA18273AGCK_Time_Constant_t, *pTDA18273AGCK_Time_Constant_t; -+ -+typedef enum _TDA18273AGC5_HPF_t { -+ TDA18273_AGC5_HPF_Disabled = 0, /* AGC5 HPF Disabled */ -+ TDA18273_AGC5_HPF_Enabled, /* AGC5 HPF Enabled */ -+ TDA18273_AGC5_HPF_Max -+} TDA18273AGC5_HPF_t, *pTDA18273AGC5_HPF_t; -+ -+typedef enum _TDA18273Pulse_Shaper_Disable_t { -+ TDA18273_Pulse_Shaper_Disable_Disabled = 0, -+ TDA18273_Pulse_Shaper_Disable_Enabled, -+ TDA18273_Pulse_Shaper_Disable_Max -+} TDA18273Pulse_Shaper_Disable_t, *pTDA18273Pulse_Shaper_Disable_t; -+ -+typedef enum _TDA18273VHF_III_Mode_t { -+ TDA18273_VHF_III_Mode_Disabled = 0, /* VHF_III_Mode Disabled */ -+ TDA18273_VHF_III_Mode_Enabled, /* VHF_III_Mode Enabled */ -+ TDA18273_VHF_III_Mode_Max -+} TDA18273VHF_III_Mode_t, *pTDA18273VHF_III_Mode_t; -+ -+typedef enum _TDA18273LO_CP_Current_t { -+ TDA18273_LO_CP_Current_Disabled = 0, /* LO CP Current Disabled */ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current Enabled */ -+ TDA18273_LO_CP_Current_Max -+} TDA18273LO_CP_Current_t, *pTDA18273LO_CP_Current_t; -+ -+typedef enum _TDA18273PD_Underload_t { -+ TDA18273_PD_Underload_Disabled = 0, /* PD Underload Disabled */ -+ TDA18273_PD_Underload_Enabled, /* PD Underload Enabled */ -+ TDA18273_PD_Underload_Max -+} TDA18273PD_Underload_t, *pTDA18273PD_Underload_t; -+ -+typedef struct _TDA18273StdCoefficients -+{ -+ /****************************************************************/ -+ /* IF Settings */ -+ /****************************************************************/ -+ UInt32 IF; /* IF Frequency */ -+ Int32 CF_Offset; -+ -+ /****************************************************************/ -+ /* IF SELECTIVITY Settings */ -+ /****************************************************************/ -+ TDA18273LPF_t LPF; /* LPF Cut off */ -+ TDA18273LPFOffset_t LPF_Offset; /* LPF offset */ -+ TDA18273DC_Notch_IF_PPF_t DC_Notch_IF_PPF; /* DC notch IF PPF */ -+ TDA18273IF_HPF_t IF_HPF; /* Hi Pass */ -+ TDA18273IF_Notch_t IF_Notch; /* IF notch */ -+ TDA18273IFnotchToRSSI_t IFnotchToRSSI; /* IFnotchToRSSI */ -+ -+ /****************************************************************/ -+ /* AGC TOP Settings */ -+ /****************************************************************/ -+ TDA18273AGC1_TOP_I2C_DN_UP_t AGC1_TOP_I2C_DN_UP; /* AGC1 TOP I2C DN/UP */ -+ TDA18273AGC1_Adapt_TOP_DN_UP_t AGC1_Adapt_TOP_DN_UP; /* AGC1 Adapt TOP DN/UP */ -+ TDA18273AGC1_DN_Time_Constant_t AGC1_DN_Time_Constant; /* AGC1 DN Time Constant */ -+ TDA18273AGC1_Mode_t AGC1_Mode; /* AGC1 mode */ -+ TDA18273Range_LNA_Adapt_t Range_LNA_Adapt; /* Range_LNA_Adapt */ -+ TDA18273LNA_Adapt_RFAGC_Gv_Threshold LNA_Adapt_RFAGC_Gv_Threshold; /* LNA_Adapt_RFAGC_Gv_Threshold */ -+ TDA18273AGC1_Top_Adapt_RFAGC_Gv_Threshold AGC1_Top_Adapt_RFAGC_Gv_Threshold; /* AGC1_Top_Adapt_RFAGC_Gv_Threshold */ -+ TDA18273AGC2_TOP_DN_UP_t AGC2_TOP_DN_UP; /* AGC2 TOP DN/UP */ -+ TDA18273AGC2_DN_Time_Constant_t AGC2_DN_Time_Constant; /* AGC2 DN Time Constant */ -+ TDA18273AGC3_TOP_I2C_t AGC3_TOP_I2C_Low_Band; /* AGC3 TOP I2C Low Band */ -+ TDA18273AGC3_TOP_I2C_t AGC3_TOP_I2C_High_Band; /* AGC3 TOP I2C High Band */ -+ TDA18273AGC4_TOP_DN_UP_t AGC4_TOP_DN_UP; /* AGC4 TOP DN/UP */ -+ TDA18273AGC5_TOP_DN_UP_t AGC5_TOP_DN_UP; /* AGC5 TOP DN/UP */ -+ TDA18273AGC3_Top_Adapt_Algorithm AGC3_Top_Adapt_Algorithm; /* AGC3_Top_Adapt_Algorithm */ -+ TDA18273AGC3_Adapt_TOP_t AGC3_Adapt_TOP_Low_Band; /* AGC3 Adapt TOP Low Band */ -+ TDA18273AGC3_Adapt_TOP_t AGC3_Adapt_TOP_High_Band; /* AGC3 Adapt TOP High Band */ -+ TDA18273AGC_Overload_TOP_t AGC_Overload_TOP; /* AGC Overload TOP */ -+ TDA18273TH_AGC_Adapt34_t TH_AGC_Adapt34; /* Adapt TOP 34 Gain Threshold */ -+ TDA18273RF_Atten_3dB_t RF_Atten_3dB; /* RF atten 3dB */ -+ TDA18273IF_Output_Level_t IF_Output_Level; /* IF Output Level */ -+ TDA18273S2D_Gain_t S2D_Gain; /* S2D gain */ -+ TDA18273Negative_Modulation_t Negative_Modulation; /* Negative modulation */ -+ -+ /****************************************************************/ -+ /* GSK Settings */ -+ /****************************************************************/ -+ TDA18273AGCK_Steps_t AGCK_Steps; /* Step */ -+ TDA18273AGCK_Time_Constant_t AGCK_Time_Constant; /* AGCK Time Constant */ -+ TDA18273AGC5_HPF_t AGC5_HPF; /* AGC5 HPF */ -+ TDA18273Pulse_Shaper_Disable_t Pulse_Shaper_Disable; /* Pulse Shaper Disable */ -+ -+ /****************************************************************/ -+ /* H3H5 Settings */ -+ /****************************************************************/ -+ TDA18273VHF_III_Mode_t VHF_III_Mode; /* VHF_III_Mode */ -+ -+ /****************************************************************/ -+ /* PLL Settings */ -+ /****************************************************************/ -+ TDA18273LO_CP_Current_t LO_CP_Current; /* LO_CP_Current */ -+ -+ /****************************************************************/ -+ /* MISC Settings */ -+ /****************************************************************/ -+ TDA18273PD_Underload_t PD_Underload; /* PD Underload */ -+ UInt32 Freq_Start_LTE; /* Frequency start of high band for LTE */ -+} TDA18273StdCoefficients, *pTDA18273StdCoefficients; -+ -+typedef struct _TDA18273Object_t -+{ -+ UInt32 uRF; -+ UInt32 uProgRF; -+ UInt32 uIF; -+ TDA18273StandardMode_t StandardMode; -+ pTDA18273StdCoefficients pStandard; -+ TDA18273StdCoefficients Std_Array[TDA18273_StandardMode_Max-1]; -+} TDA18273Object_t, *pTDA18273Object_t, **ppTDA18273Object_t; -+ -+/* Standard Preset Definitions: */ -+#define TDA18273_INSTANCE_CUSTOM_STD_QAM_6MHZ \ -+ { /* QAM 6MHz */ \ -+ 3600000, /* IF */ \ -+ 0, /* CF_Offset */ \ -+ TDA18273_LPF_6MHz, /* LPF */ \ -+ TDA18273_LPFOffset_min_4pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Enabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_1MHz, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Enabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Enabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89wdBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_0_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT_WIDE, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_16_75dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d110_u105dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d110_u105dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_NO_TOP_ADAPT, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_0_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_0_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Disabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_1Vpp_min_6_24dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_32_768ms, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Disabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Disabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_QAM_8MHZ \ -+ { /* QAM 8MHz */ \ -+ 5000000, /* IF */ \ -+ 0, /* CF_Offset */ \ -+ TDA18273_LPF_9MHz, /* LPF */ \ -+ TDA18273_LPFOffset_min_8pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Enabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_0_85MHz, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Disabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Disabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89wdBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_0_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT_WIDE, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_16_75dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d110_u105dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d110_u105dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_NO_TOP_ADAPT, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_0_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_0_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Disabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_1Vpp_min_6_24dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_32_768ms, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Disabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Disabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_ATSC_6MHZ \ -+ { /* ATSC */ \ -+ 3250000, /* IF */ \ -+ 0, /* CF_Offset */ \ -+ TDA18273_LPF_6MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Enabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_0_4MHz, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Enabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Disabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d100_u94dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_0_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_16_75dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_104dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_104dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d112_u107dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d112_u107dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT35, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_3_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_3_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Enabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_0_6Vpp_min_10_3_19_7dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_3dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_32_768ms, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Disabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Enabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 662000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_ISDBT_6MHZ \ -+ { /* ISDBT */ \ -+ 3250000, /* IF */ \ -+ 0, /* CF_Offset */ \ -+ TDA18273_LPF_6MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Enabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_0_4MHz, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Enabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Disabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_0_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_16_75dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d110_u105dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d110_u105dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT35, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_2_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_2_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Enabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_0_6Vpp_min_10_3_19_7dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_32_768ms, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Disabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Enabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_DVBT_1_7MHZ \ -+ { /* DVB-T/T2 1.7MHz */ \ -+ 850000, /* IF */ \ -+ 0, /* CF_Offset */ \ -+ TDA18273_LPF_1_5MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Disabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_Disabled, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Disabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Enabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_0_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_4_094ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_16_75dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_2_047ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_94dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d110_u105dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d110_u105dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT35, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_2_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_0_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Enabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_1Vpp_min_6_24dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_32_768ms, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Disabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Enabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Enabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_DVBT_6MHZ \ -+ { /* DVB-T/T2 6MHz */ \ -+ 3250000, /* IF */ \ -+ 0, /* CF_Offset */ \ -+ TDA18273_LPF_6MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Enabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_0_4MHz, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Enabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Disabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_0_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_4_094ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_16_75dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_2_047ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_94dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d110_u105dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d110_u105dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT35, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_2_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_0_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Enabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_1Vpp_min_6_24dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_32_768ms, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Disabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Enabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Enabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_DVBT_7MHZ \ -+ { /* DVB-T/T2 7MHz */ \ -+ 3500000, /* IF */ \ -+ 0, /* CF_Offset */ \ -+ TDA18273_LPF_7MHz, /* LPF */ \ -+ TDA18273_LPFOffset_min_8pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Enabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_Disabled, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Enabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Disabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_0_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_4_094ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_16_75dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_2_047ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_94dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d110_u105dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d110_u105dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT35, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_2_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_0_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Enabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_1Vpp_min_6_24dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_32_768ms, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Disabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Enabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Enabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_DVBT_8MHZ \ -+ { /* DVB-T/T2 8MHz */ \ -+ 4000000, /* IF */ \ -+ 0, /* CF_Offset */ \ -+ TDA18273_LPF_8MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Enabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_Disabled, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Enabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Disabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_0_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_4_094ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_16_75dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_2_047ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_94dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d110_u105dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d110_u105dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT35, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_2_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_0_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Enabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_1Vpp_min_6_24dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_32_768ms, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Disabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Enabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Enabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_DVBT_10MHZ \ -+ { /* DVB-T/T2 10MHz */ \ -+ 5000000, /* IF */ \ -+ 0, /* CF_Offset */ \ -+ TDA18273_LPF_9MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Enabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_Disabled, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Disabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Enabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_0_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_16_75dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d110_u105dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d110_u105dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT35, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_2_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_2_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Enabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_1Vpp_min_6_24dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_32_768ms, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Disabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Enabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_DMBT_8MHZ \ -+ { /* DMB-T */ \ -+ 4000000, /* IF */ \ -+ 0, /* CF_Offset */ \ -+ TDA18273_LPF_8MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Enabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_Disabled, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Enabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Disabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_0_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_16_75dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d110_u105dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d110_u105dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT35, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_2_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_2_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Enabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_1Vpp_min_6_24dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_32_768ms, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Disabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Enabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_ANALOG_FM_RADIO \ -+ { /* FM */ \ -+ 1250000, /* IF */ \ -+ 0, /* CF_Offset */ \ -+ TDA18273_LPF_1_5MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Enabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_0_85MHz, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Disabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Disabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_1_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT_TOP_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_15_25dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d105_u100dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d105_u100dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT34, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Disabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_0_8Vpp_min_8_22dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_32_768ms, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Disabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Disabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_ANALOG_MN \ -+ { /* NTSC M/N */ \ -+ 5400000, /* IF */ \ -+ 1750000, /* CF_Offset */ \ -+ TDA18273_LPF_6MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Disabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_Disabled, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Disabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Enabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_1_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT_TOP_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_15_25dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d105_u100dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d105_u100dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT34, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Disabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_0_7Vpp_min_9_21dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Enabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_1_STEP_EACH_VSYNC_RISING_EDGE, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Enabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Disabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_ANALOG_B \ -+ { /* PAL B */ \ -+ 6400000, /* IF */ \ -+ 2250000, /* CF_Offset */ \ -+ TDA18273_LPF_7MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Disabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_Disabled, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Disabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Enabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_1_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT_TOP_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_15_25dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d105_u100dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d105_u100dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT34, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Disabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_0_7Vpp_min_9_21dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Enabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_1_STEP_EACH_VSYNC_RISING_EDGE, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Enabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Disabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_ANALOG_GH \ -+ { /* PAL G/H */ \ -+ 6750000, /* IF */ \ -+ 2750000, /* CF_Offset */ \ -+ TDA18273_LPF_8MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Disabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_Disabled, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Disabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Enabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_1_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT_TOP_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_15_25dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d105_u100dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d105_u100dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT34, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Disabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_0_7Vpp_min_9_21dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Enabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_1_STEP_EACH_VSYNC_RISING_EDGE, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Enabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Disabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_ANALOG_I \ -+ { /* PAL I */ \ -+ 7250000, /* IF */ \ -+ 2750000, /* CF_Offset */ \ -+ TDA18273_LPF_8MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Disabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_Disabled, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Disabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Enabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_1_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT_TOP_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_15_25dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d105_u100dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d105_u100dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT34, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Disabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_0_7Vpp_min_9_21dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Enabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_1_STEP_EACH_VSYNC_RISING_EDGE, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Enabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Disabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_ANALOG_DK \ -+ { /* SECAM D/K */ \ -+ 6850000, /* IF */ \ -+ 2750000, /* CF_Offset */ \ -+ TDA18273_LPF_8MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Disabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_Disabled, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Enabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Disabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_1_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT_TOP_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_15_25dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d105_u100dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d105_u100dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT34, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Disabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_0_7Vpp_min_9_21dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Enabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_1_STEP_EACH_VSYNC_RISING_EDGE, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Enabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Disabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_ANALOG_L \ -+ { /* SECAM L */ \ -+ 6750000, /* IF */ \ -+ 2750000, /* CF_Offset */ \ -+ TDA18273_LPF_8MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Disabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_Disabled, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Enabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Disabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_1_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT_TOP_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_15_25dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d105_u100dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d105_u100dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT34, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_6_min_9, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Disabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_0_7Vpp_min_9_21dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_1_STEP_EACH_VSYNC_RISING_EDGE, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Enabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Disabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_ANALOG_LL \ -+ { /* SECAM L' */ \ -+ 1250000, /* IF */ \ -+ -2750000, /* CF_Offset */ \ -+ TDA18273_LPF_8MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Disabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_Disabled, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Disabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Enabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_1_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT_TOP_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_15_25dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d105_u100dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d105_u100dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT34, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_6_min_9, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Disabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_0_7Vpp_min_9_21dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_1_STEP_EACH_VSYNC_RISING_EDGE, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Disabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Disabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_ANALOG_BLIND_SCANNING \ -+ { /* Blind Scanning copy of PAL-I */ \ -+ 7250000, /* IF */ \ -+ 2750000, /* CF_Offset */ \ -+ TDA18273_LPF_8MHz, /* LPF */ \ -+ TDA18273_LPFOffset_0pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Disabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_Disabled, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Disabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Enabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89dBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_1_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT_TOP_ADAPT, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_15_25dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_96dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d105_u100dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d105_u100dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_TOP_ADAPT34, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_1_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Disabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_0_7Vpp_min_9_21dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_1_STEP_EACH_VSYNC_RISING_EDGE, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Enabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Disabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+#define TDA18273_INSTANCE_CUSTOM_STD_SCANXPRESS \ -+ { /* ScanXpress */ \ -+ 5000000, /* IF */ \ -+ 0, /* CF_Offset */ \ -+ TDA18273_LPF_9MHz, /* LPF */ \ -+ TDA18273_LPFOffset_min_8pc, /* LPF_Offset */ \ -+ TDA18273_DC_Notch_IF_PPF_Enabled, /* DC notch IF PPF */ \ -+ TDA18273_IF_HPF_0_85MHz, /* Hi Pass */ \ -+ TDA18273_IF_Notch_Disabled, /* IF notch */ \ -+ TDA18273_IFnotchToRSSI_Enabled, /* IF notch To RSSI */ \ -+ TDA18273_AGC1_TOP_I2C_DN_UP_d95_u89wdBuV, /* AGC1 TOP I2C DN/UP */ \ -+ TDA18273_AGC1_Adapt_TOP_DN_UP_0_Step, /* AGC1 Adapt TOP DN/UP */ \ -+ TDA18273_AGC1_DN_Time_Constant_8_188ms, /* AGC1 DN Time Constant */ \ -+ TDA18273_AGC1_Mode_LNA_ADAPT_WIDE, /* AGC1 mode */ \ -+ TDA18273_Range_LNA_Adapt_20dB_11dB, /* Range LNA Adapt */ \ -+ TDA18273_LNA_Adapt_RFAGC_Gv_Threshold_18_25dB, /* LNA Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC1_Top_Adapt_RFAGC_Gv_Threshold_16_75dB, /* AGC1 TOP Adapt RFAGC Gv Threshold */ \ -+ TDA18273_AGC2_TOP_DN_UP_d90_u84dBuV, /* AGC2 TOP DN/UP */ \ -+ TDA18273_AGC2_DN_Time_Constant_8_188ms, /* AGC2 DN Time Constant */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C Low Band */ \ -+ TDA18273_AGC3_TOP_I2C_100dBuV, /* AGC3 TOP I2C High Band */ \ -+ TDA18273_AGC4_TOP_DN_UP_d110_u105dBuV, /* AGC4 TOP DN/UP */ \ -+ TDA18273_AGC5_TOP_DN_UP_d110_u105dBuV, /* AGC5 TOP DN/UP */ \ -+ TDA18273_Top_Adapt_NO_TOP_ADAPT, /* AGC3 TOP Adapt Algorithm */ \ -+ TDA18273_AGC3_Adapt_TOP_0_Step, /* AGC3 Adapt Low Band */ \ -+ TDA18273_AGC3_Adapt_TOP_0_Step, /* AGC3 Adapt High Band */ \ -+ TDA18273_AGC_Overload_TOP_plus_9_plus_4_5_min_3_5, /* AGC Overload TOP */ \ -+ TDA18273_TH_AGC_Adapt34_5dB, /* Adapt TOP 34 Gain Threshold */ \ -+ TDA18273_RF_Atten_3dB_Disabled, /* RF Atten 3dB */ \ -+ TDA18273_IF_Output_Level_1Vpp_min_6_24dB, /* IF Output Level */ \ -+ TDA18273_S2D_Gain_6dB, /* S2D Gain */ \ -+ TDA18273_Negative_Modulation_Disabled, /* Negative Modulation */ \ -+ TDA18273_AGCK_Steps_0_2dB, /* Step */ \ -+ TDA18273_AGCK_Time_Constant_32_768ms, /* AGCK Time Constant */ \ -+ TDA18273_AGC5_HPF_Disabled, /* AGC5 HPF */ \ -+ TDA18273_Pulse_Shaper_Disable_Enabled, /* Pulse Shaper Disable */ \ -+ TDA18273_VHF_III_Mode_Disabled, /* VHF III Mode */ \ -+ TDA18273_LO_CP_Current_Enabled, /* LO CP Current */ \ -+ TDA18273_PD_Underload_Disabled, /* PD Underload */ \ -+ 754000000 /* Frequency Start LTE */ \ -+ } -+ -+/* Standard Presets Aggregation: */ -+#define TDA18273_INSTANCE_CUSTOM_STD_DEF \ -+ { \ -+ TDA18273_INSTANCE_CUSTOM_STD_QAM_6MHZ, \ -+ TDA18273_INSTANCE_CUSTOM_STD_QAM_8MHZ, \ -+ TDA18273_INSTANCE_CUSTOM_STD_ATSC_6MHZ, \ -+ TDA18273_INSTANCE_CUSTOM_STD_ISDBT_6MHZ, \ -+ TDA18273_INSTANCE_CUSTOM_STD_DVBT_1_7MHZ, \ -+ TDA18273_INSTANCE_CUSTOM_STD_DVBT_6MHZ, \ -+ TDA18273_INSTANCE_CUSTOM_STD_DVBT_7MHZ, \ -+ TDA18273_INSTANCE_CUSTOM_STD_DVBT_8MHZ, \ -+ TDA18273_INSTANCE_CUSTOM_STD_DVBT_10MHZ, \ -+ TDA18273_INSTANCE_CUSTOM_STD_DMBT_8MHZ, \ -+ TDA18273_INSTANCE_CUSTOM_STD_ANALOG_FM_RADIO, \ -+ TDA18273_INSTANCE_CUSTOM_STD_ANALOG_MN, \ -+ TDA18273_INSTANCE_CUSTOM_STD_ANALOG_B, \ -+ TDA18273_INSTANCE_CUSTOM_STD_ANALOG_GH, \ -+ TDA18273_INSTANCE_CUSTOM_STD_ANALOG_I, \ -+ TDA18273_INSTANCE_CUSTOM_STD_ANALOG_DK, \ -+ TDA18273_INSTANCE_CUSTOM_STD_ANALOG_L, \ -+ TDA18273_INSTANCE_CUSTOM_STD_ANALOG_LL, \ -+ TDA18273_INSTANCE_CUSTOM_STD_ANALOG_BLIND_SCANNING, \ -+ TDA18273_INSTANCE_CUSTOM_STD_SCANXPRESS \ -+ } -+ -+#endif /* __TDA18273_PRIV */ -diff --git a/drivers/media/usb/cx231xx/Kconfig b/drivers/media/usb/cx231xx/Kconfig -index 0cced3e..c7d9e6a 100644 ---- a/drivers/media/usb/cx231xx/Kconfig -+++ b/drivers/media/usb/cx231xx/Kconfig -@@ -51,6 +51,11 @@ config VIDEO_CX231XX_DVB - select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT - select DVB_SI2165 if MEDIA_SUBDRV_AUTOSELECT - select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_CXD2820R if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_TAS2101 if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_AV201X if MEDIA_SUBDRV_AUTOSELECT - - ---help--- - This adds support for DVB cards based on the -diff --git a/drivers/media/usb/cx231xx/Makefile b/drivers/media/usb/cx231xx/Makefile -index 52cf769..21e041d 100644 ---- a/drivers/media/usb/cx231xx/Makefile -+++ b/drivers/media/usb/cx231xx/Makefile -@@ -6,7 +6,8 @@ cx231xx-alsa-objs := cx231xx-audio.o - - obj-$(CONFIG_VIDEO_CX231XX) += cx231xx.o - obj-$(CONFIG_VIDEO_CX231XX_ALSA) += cx231xx-alsa.o --obj-$(CONFIG_VIDEO_CX231XX_DVB) += cx231xx-dvb.o -+obj-$(CONFIG_VIDEO_CX231XX_DVB) += cx231xx-dvb-ci.o -+cx231xx-dvb-ci-objs += cx231xx-dvb.o tbscxci.o - - ccflags-y += -Idrivers/media/i2c - ccflags-y += -Idrivers/media/tuners -diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c -index 2f52d66..af189af 100644 ---- a/drivers/media/usb/cx231xx/cx231xx-avcore.c -+++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c -@@ -360,6 +360,9 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, - case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL: - case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC: - case CX231XX_BOARD_OTG102: -+ case CX231XX_BOARD_TBS_5280: -+ case CX231XX_BOARD_TBS_5281: -+ case CX231XX_BOARD_TBS_5990: - if (avmode == POLARIS_AVMODE_ANALOGT_TV) { - while (afe_power_status != (FLD_PWRDN_TUNING_BIAS | - FLD_PWRDN_ENABLE_PLL)) { -@@ -2667,7 +2670,7 @@ EXPORT_SYMBOL_GPL(cx231xx_capture_start); - /***************************************************************************** - * G P I O B I T control functions * - ******************************************************************************/ --static int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u32 gpio_val) -+ int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u32 gpio_val) - { - int status = 0; - -@@ -2677,7 +2680,10 @@ static int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u32 gpio_val) - return status; - } - --static int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u32 *gpio_val) -+ -+EXPORT_SYMBOL_GPL(cx231xx_set_gpio_bit); -+ -+ int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u32 *gpio_val) - { - __le32 tmp; - int status = 0; -@@ -2688,6 +2694,8 @@ static int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u32 *gpio_val - return status; - } - -+EXPORT_SYMBOL_GPL(cx231xx_get_gpio_bit); -+ - /* - * cx231xx_set_gpio_direction - * Sets the direction of the GPIO pin to input or output -@@ -2723,6 +2731,8 @@ int cx231xx_set_gpio_direction(struct cx231xx *dev, - return status; - } - -+EXPORT_SYMBOL_GPL(cx231xx_set_gpio_direction); -+ - /* - * cx231xx_set_gpio_value - * Sets the value of the GPIO pin to Logic high or low. The Pin under -@@ -2767,6 +2777,10 @@ int cx231xx_set_gpio_value(struct cx231xx *dev, int pin_number, int pin_value) - return status; - } - -+EXPORT_SYMBOL_GPL(cx231xx_set_gpio_value); -+ -+ -+ - /***************************************************************************** - * G P I O I2C related functions * - ******************************************************************************/ -diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c -index 36bc254..19851a1 100644 ---- a/drivers/media/usb/cx231xx/cx231xx-cards.c -+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c -@@ -106,6 +106,7 @@ struct cx231xx_board cx231xx_boards[] = { - .tuner_i2c_master = I2C_1_MUX_3, - .demod_i2c_master = I2C_2, - .has_dvb = 1, -+ .adap_cnt = 1, - .demod_addr = 0x02, - .norm = V4L2_STD_PAL, - -@@ -146,6 +147,7 @@ struct cx231xx_board cx231xx_boards[] = { - .tuner_i2c_master = I2C_1_MUX_3, - .demod_i2c_master = I2C_2, - .has_dvb = 1, -+ .adap_cnt = 1, - .demod_addr = 0x32, - .norm = V4L2_STD_NTSC, - -@@ -186,6 +188,7 @@ struct cx231xx_board cx231xx_boards[] = { - .tuner_i2c_master = I2C_1_MUX_3, - .demod_i2c_master = I2C_2, - .has_dvb = 1, -+ .adap_cnt = 1, - .demod_addr = 0x02, - .norm = V4L2_STD_PAL, - -@@ -227,6 +230,7 @@ struct cx231xx_board cx231xx_boards[] = { - .tuner_i2c_master = I2C_1_MUX_3, - .demod_i2c_master = I2C_2, - .has_dvb = 1, -+ .adap_cnt = 1, - .demod_addr = 0x02, - .norm = V4L2_STD_PAL, - -@@ -298,6 +302,7 @@ struct cx231xx_board cx231xx_boards[] = { - .tuner_i2c_master = I2C_1_MUX_3, - .demod_i2c_master = I2C_2, - .has_dvb = 1, -+ .adap_cnt = 1, - .demod_addr = 0x02, - .norm = V4L2_STD_PAL, - -@@ -326,6 +331,7 @@ struct cx231xx_board cx231xx_boards[] = { - .tuner_i2c_master = I2C_1_MUX_3, - .demod_i2c_master = I2C_2, - .has_dvb = 1, -+ .adap_cnt = 1, - .demod_addr = 0x32, - .norm = V4L2_STD_NTSC, - -@@ -354,6 +360,7 @@ struct cx231xx_board cx231xx_boards[] = { - .tuner_i2c_master = I2C_1_MUX_1, - .demod_i2c_master = I2C_1_MUX_1, - .has_dvb = 1, -+ .adap_cnt = 1, - .demod_addr = 0x0e, - .norm = V4L2_STD_NTSC, - -@@ -419,6 +426,7 @@ struct cx231xx_board cx231xx_boards[] = { - .demod_i2c_master = I2C_1_MUX_3, - .ir_i2c_master = I2C_2, - .has_dvb = 1, -+ .adap_cnt = 1, - .demod_addr = 0x10, - .norm = V4L2_STD_PAL_M, - .input = {{ -@@ -457,6 +465,7 @@ struct cx231xx_board cx231xx_boards[] = { - .demod_i2c_master = I2C_1_MUX_3, - .ir_i2c_master = I2C_2, - .has_dvb = 1, -+ .adap_cnt = 1, - .demod_addr = 0x10, - .norm = V4L2_STD_NTSC_M, - .input = {{ -@@ -496,6 +505,7 @@ struct cx231xx_board cx231xx_boards[] = { - .ir_i2c_master = I2C_2, - .rc_map_name = RC_MAP_PIXELVIEW_002T, - .has_dvb = 1, -+ .adap_cnt = 1, - .demod_addr = 0x10, - .norm = V4L2_STD_PAL_M, - .input = {{ -@@ -793,6 +803,7 @@ struct cx231xx_board cx231xx_boards[] = { - .tuner_i2c_master = I2C_1_MUX_3, - .demod_i2c_master = I2C_1_MUX_3, - .has_dvb = 1, -+ .adap_cnt = 1, - .demod_addr = 0x0e, - .norm = V4L2_STD_NTSC, - -@@ -841,6 +852,121 @@ struct cx231xx_board cx231xx_boards[] = { - .gpio = NULL, - } }, - }, -+ [CX231XX_BOARD_TBS_5280] = { -+ .name = "TurboSight TBS 5280", -+ .tuner_type = TUNER_ABSENT, -+ .decoder = CX231XX_AVDECODER, -+ .output_mode = OUT_MODE_VIP11, -+ .demod_xfer_mode = 0, -+ .ctl_pin_status_mask = 0xFFFFFFC4, -+ .agc_analog_digital_select_gpio = 0x00, -+ .tuner_sif_gpio = -1, -+ .tuner_scl_gpio = -1, -+ .tuner_sda_gpio = -1, -+ .gpio_pin_status_mask = 0x4001000, -+ .tuner_i2c_master = 2, -+ .demod_i2c_master = 1, -+ .has_dvb = 1, -+ .adap_cnt = 2, -+ .demod_addr = 0x6c, -+ .norm = V4L2_STD_PAL_M, -+ -+ .input = {{ -+ .type = CX231XX_VMUX_TELEVISION, -+ .vmux = CX231XX_VIN_3_1, -+ .amux = CX231XX_AMUX_VIDEO, -+ .gpio = NULL, -+ }, { -+ .type = CX231XX_VMUX_COMPOSITE1, -+ .vmux = CX231XX_VIN_2_1, -+ .amux = CX231XX_AMUX_LINE_IN, -+ .gpio = NULL, -+ }, { -+ .type = CX231XX_VMUX_SVIDEO, -+ .vmux = CX231XX_VIN_1_1 | -+ (CX231XX_VIN_1_2 << 8) | -+ CX25840_SVIDEO_ON, -+ .amux = CX231XX_AMUX_LINE_IN, -+ .gpio = NULL, -+ } }, -+ }, -+ [CX231XX_BOARD_TBS_5281] = { -+ .name = "TurboSight TBS 5281", -+ .tuner_type = TUNER_ABSENT, -+ .decoder = CX231XX_AVDECODER, -+ .output_mode = OUT_MODE_VIP11, -+ .demod_xfer_mode = 0, -+ .ctl_pin_status_mask = 0xFFFFFFC4, -+ .agc_analog_digital_select_gpio = 0x00, -+ .tuner_sif_gpio = -1, -+ .tuner_scl_gpio = -1, -+ .tuner_sda_gpio = -1, -+ .gpio_pin_status_mask = 0x4001000, -+ .tuner_i2c_master = I2C_2, -+ .demod_i2c_master = I2C_1, -+ .has_dvb = 1, -+ .adap_cnt = 2, -+ .demod_addr = 0x6c, -+ .norm = V4L2_STD_PAL_M, -+ -+ .input = {{ -+ .type = CX231XX_VMUX_TELEVISION, -+ .vmux = CX231XX_VIN_3_1, -+ .amux = CX231XX_AMUX_VIDEO, -+ .gpio = NULL, -+ }, { -+ .type = CX231XX_VMUX_COMPOSITE1, -+ .vmux = CX231XX_VIN_2_1, -+ .amux = CX231XX_AMUX_LINE_IN, -+ .gpio = NULL, -+ }, { -+ .type = CX231XX_VMUX_SVIDEO, -+ .vmux = CX231XX_VIN_1_1 | -+ (CX231XX_VIN_1_2 << 8) | -+ CX25840_SVIDEO_ON, -+ .amux = CX231XX_AMUX_LINE_IN, -+ .gpio = NULL, -+ } }, -+ }, -+ [CX231XX_BOARD_TBS_5990] = { -+ .name = "TurboSight TBS 5990", -+ .tuner_type = TUNER_ABSENT, -+ .decoder = CX231XX_AVDECODER, -+ .output_mode = OUT_MODE_VIP11, -+ .demod_xfer_mode = 0, -+ .ctl_pin_status_mask = 0xFFFFFFC4, -+ .agc_analog_digital_select_gpio = 0x00, -+ .tuner_sif_gpio = -1, -+ .tuner_scl_gpio = -1, -+ .tuner_sda_gpio = -1, -+ .gpio_pin_status_mask = 0x4001000, -+ .tuner_i2c_master = I2C_2, -+ .demod_i2c_master = I2C_1, -+ .has_dvb = 1, -+ .adap_cnt = 2, -+ .demod_addr = 0x60, -+ .norm = V4L2_STD_PAL_M, -+ -+ .input = {{ -+ .type = CX231XX_VMUX_TELEVISION, -+ .vmux = CX231XX_VIN_3_1, -+ .amux = CX231XX_AMUX_VIDEO, -+ .gpio = NULL, -+ }, { -+ .type = CX231XX_VMUX_COMPOSITE1, -+ .vmux = CX231XX_VIN_2_1, -+ .amux = CX231XX_AMUX_LINE_IN, -+ .gpio = NULL, -+ }, { -+ .type = CX231XX_VMUX_SVIDEO, -+ .vmux = CX231XX_VIN_1_1 | -+ (CX231XX_VIN_1_2 << 8) | -+ CX25840_SVIDEO_ON, -+ .amux = CX231XX_AMUX_LINE_IN, -+ .gpio = NULL, -+ } }, -+ }, -+ - }; - const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); - -@@ -908,6 +1034,13 @@ struct usb_device_id cx231xx_id_table[] = { - .driver_info = CX231XX_BOARD_OTG102}, - {USB_DEVICE(USB_VID_TERRATEC, 0x00a6), - .driver_info = CX231XX_BOARD_TERRATEC_GRABBY}, -+ {USB_DEVICE(0x734c, 0x5280), -+ .driver_info = CX231XX_BOARD_TBS_5280}, -+ {USB_DEVICE(0x734c, 0x5281), -+ .driver_info = CX231XX_BOARD_TBS_5281}, -+ {USB_DEVICE(0x734c, 0x5990), -+ .driver_info = CX231XX_BOARD_TBS_5990}, -+ - {}, - }; - -@@ -1358,7 +1491,7 @@ static void request_module_async(struct work_struct *work) - request_module("cx231xx-alsa"); - - if (dev->board.has_dvb) -- request_module("cx231xx-dvb"); -+ request_module("cx231xx-dvb-ci"); - - } - -@@ -1674,6 +1807,44 @@ static int cx231xx_usb_probe(struct usb_interface *interface, - } - } - -+ if (dev->current_pcb_config.ts2_source != 0xff) { -+ /* compute alternate max packet sizes for TS2 */ -+ idx = dev->current_pcb_config.hs_config_info[0].interface_info.ts2_index + 1; -+ if (idx >= dev->max_iad_interface_count) { -+ dev_err(d, "TS2 PCB interface #%d doesn't exist\n", -+ idx); -+ retval = -ENODEV; -+ goto err_video_alt; -+ } -+ uif = udev->actconfig->interface[idx]; -+ -+ dev->ts2_mode.end_point_addr = -+ uif->altsetting[0].endpoint[isoc_pipe]. -+ desc.bEndpointAddress; -+ -+ dev->ts2_mode.num_alt = uif->num_altsetting; -+ dev_info(d, -+ "TS EndPoint Addr 0x%x, Alternate settings: %i\n", -+ dev->ts2_mode.end_point_addr, -+ dev->ts2_mode.num_alt); -+ -+ dev->ts2_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->ts2_mode.num_alt, GFP_KERNEL); -+ if (dev->ts2_mode.alt_max_pkt_size == NULL) { -+ retval = -ENOMEM; -+ goto err_video_alt; -+ } -+ -+ for (i = 0; i < dev->ts2_mode.num_alt; i++) { -+ u16 tmp = le16_to_cpu(uif->altsetting[i]. -+ endpoint[isoc_pipe].desc. -+ wMaxPacketSize); -+ dev->ts2_mode.alt_max_pkt_size[i] = -+ (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); -+ dev_dbg(d, "Alternate setting %i, max size= %i\n", -+ i, dev->ts2_mode.alt_max_pkt_size[i]); -+ } -+ } -+ - if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) { - cx231xx_enable_OSC(dev); - cx231xx_reset_out(dev); -diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c -index 550ec93..ceb0344 100644 ---- a/drivers/media/usb/cx231xx/cx231xx-core.c -+++ b/drivers/media/usb/cx231xx/cx231xx-core.c -@@ -542,6 +542,10 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) - usb_interface_index = - dev->current_pcb_config.hs_config_info[0].interface_info. - ts2_index + 1; -+ dev->ts2_mode.alt = alt; -+ if (dev->ts2_mode.alt_max_pkt_size != NULL) -+ max_pkt_size = dev->ts2_mode.max_pkt_size = -+ dev->ts2_mode.alt_max_pkt_size[dev->ts2_mode.alt]; - break; - case INDEX_AUDIO: - usb_interface_index = -@@ -728,7 +732,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode) - case CX231XX_BOARD_CNXT_RDE_250: - case CX231XX_BOARD_CNXT_SHELBY: - case CX231XX_BOARD_CNXT_RDU_250: -- errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1); -+ errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1); - break; - case CX231XX_BOARD_CNXT_RDE_253S: - case CX231XX_BOARD_CNXT_RDU_253S: -@@ -737,6 +741,9 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode) - case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: - case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL: - case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC: -+ case CX231XX_BOARD_TBS_5280: -+ case CX231XX_BOARD_TBS_5281: -+ case CX231XX_BOARD_TBS_5990: - errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0); - break; - default: -@@ -826,6 +833,47 @@ static void cx231xx_isoc_irq_callback(struct urb *urb) - urb->status); - } - } -+ -+static void cx231xx_isoc_irq_callback_ts2(struct urb *urb) -+{ -+ struct cx231xx_dmaqueue *dma_q = urb->context; -+ struct cx231xx_video_mode *vmode = -+ container_of(dma_q, struct cx231xx_video_mode, vidq); -+ struct cx231xx *dev = container_of(vmode, struct cx231xx, ts2_mode); -+ int i; -+ -+ switch (urb->status) { -+ case 0: /* success */ -+ case -ETIMEDOUT: /* NAK */ -+ break; -+ case -ECONNRESET: /* kill */ -+ case -ENOENT: -+ case -ESHUTDOWN: -+ return; -+ default: /* error */ -+ cx231xx_isocdbg("urb completition error %d.\n", urb->status); -+ break; -+ } -+ -+ /* Copy data from URB */ -+ spin_lock(&dev->ts2_mode.slock); -+ dev->ts2_mode.isoc_ctl.isoc_copy(dev, urb); -+ spin_unlock(&dev->ts2_mode.slock); -+ -+ /* Reset urb buffers */ -+ for (i = 0; i < urb->number_of_packets; i++) { -+ urb->iso_frame_desc[i].status = 0; -+ urb->iso_frame_desc[i].actual_length = 0; -+ } -+ urb->status = 0; -+ -+ urb->status = usb_submit_urb(urb, GFP_ATOMIC); -+ if (urb->status) { -+ cx231xx_isocdbg("urb resubmit failed (error=%i)\n", -+ urb->status); -+ } -+} -+ - /***************************************************************** - * URB Streaming functions * - ******************************************************************/ -@@ -927,6 +975,54 @@ void cx231xx_uninit_isoc(struct cx231xx *dev) - } - EXPORT_SYMBOL_GPL(cx231xx_uninit_isoc); - -+void cx231xx_uninit_isoc_ts2(struct cx231xx *dev) -+{ -+ struct cx231xx_dmaqueue *dma_q_ts2 = &dev->ts2_mode.vidq; -+ struct urb *urb; -+ int i; -+ -+ cx231xx_isocdbg("cx231xx: called cx231xx_uninit_isoc_ts2\n"); -+ -+ dev->ts2_mode.isoc_ctl.nfields = -1; -+ for (i = 0; i < dev->ts2_mode.isoc_ctl.num_bufs; i++) { -+ urb = dev->ts2_mode.isoc_ctl.urb[i]; -+ if (urb) { -+ if (!irqs_disabled()) -+ usb_kill_urb(urb); -+ else -+ usb_unlink_urb(urb); -+ -+ if (dev->ts2_mode.isoc_ctl.transfer_buffer[i]) { -+ usb_free_coherent(dev->udev, -+ urb->transfer_buffer_length, -+ dev->ts2_mode.isoc_ctl. -+ transfer_buffer[i], -+ urb->transfer_dma); -+ } -+ usb_free_urb(urb); -+ dev->ts2_mode.isoc_ctl.urb[i] = NULL; -+ } -+ dev->ts2_mode.isoc_ctl.transfer_buffer[i] = NULL; -+ } -+ -+ kfree(dev->ts2_mode.isoc_ctl.urb); -+ kfree(dev->ts2_mode.isoc_ctl.transfer_buffer); -+ kfree(dma_q_ts2->p_left_data); -+ -+ dev->ts2_mode.isoc_ctl.urb = NULL; -+ dev->ts2_mode.isoc_ctl.transfer_buffer = NULL; -+ dev->ts2_mode.isoc_ctl.num_bufs = 0; -+ dma_q_ts2->p_left_data = NULL; -+ -+ if (dev->mode_tv == 0) -+ cx231xx_capture_start(dev, 0, Raw_Video); -+ else -+ cx231xx_capture_start(dev, 0, TS2); -+ -+ -+} -+EXPORT_SYMBOL_GPL(cx231xx_uninit_isoc_ts2); -+ - /* - * Stop and Deallocate URBs - */ -@@ -1121,6 +1217,141 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, - } - EXPORT_SYMBOL_GPL(cx231xx_init_isoc); - -+int cx231xx_init_isoc_ts2(struct cx231xx *dev, int max_packets, -+ int num_bufs, int max_pkt_size, -+ int (*isoc_copy) (struct cx231xx *dev, struct urb *urb)) -+{ -+ struct cx231xx_dmaqueue *dma_q_ts2 = &dev->ts2_mode.vidq; -+ int i; -+ int sb_size, pipe; -+ struct urb *urb; -+ int j, k; -+ int rc; -+ -+ /* De-allocates all pending stuff */ -+ cx231xx_uninit_isoc_ts2(dev); -+ -+ dma_q_ts2->p_left_data = kzalloc(4096, GFP_KERNEL); -+ if (dma_q_ts2->p_left_data == NULL) -+ return -ENOMEM; -+ -+ dev->ts2_mode.isoc_ctl.isoc_copy = isoc_copy; -+ dev->ts2_mode.isoc_ctl.num_bufs = num_bufs; -+ dma_q_ts2->pos = 0; -+ dma_q_ts2->is_partial_line = 0; -+ dma_q_ts2->last_sav = 0; -+ dma_q_ts2->current_field = -1; -+ dma_q_ts2->field1_done = 0; -+ dma_q_ts2->lines_per_field = dev->height / 2; -+ dma_q_ts2->bytes_left_in_line = dev->width << 1; -+ dma_q_ts2->lines_completed = 0; -+ dma_q_ts2->mpeg_buffer_done = 0; -+ dma_q_ts2->left_data_count = 0; -+ dma_q_ts2->mpeg_buffer_completed = 0; -+ dma_q_ts2->add_ps_package_head = CX231XX_NEED_ADD_PS_PACKAGE_HEAD; -+ dma_q_ts2->ps_head[0] = 0x00; -+ dma_q_ts2->ps_head[1] = 0x00; -+ dma_q_ts2->ps_head[2] = 0x01; -+ dma_q_ts2->ps_head[3] = 0xBA; -+ for (i = 0; i < 8; i++) -+ dma_q_ts2->partial_buf[i] = 0; -+ -+ dev->ts2_mode.isoc_ctl.urb = -+ kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); -+ if (!dev->ts2_mode.isoc_ctl.urb) { -+ dev_err(dev->dev, -+ "cannot alloc memory for usb buffers\n"); -+ return -ENOMEM; -+ } -+ -+ dev->ts2_mode.isoc_ctl.transfer_buffer = -+ kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); -+ if (!dev->ts2_mode.isoc_ctl.transfer_buffer) { -+ dev_err(dev->dev, -+ "cannot allocate memory for usbtransfer\n"); -+ kfree(dev->ts2_mode.isoc_ctl.urb); -+ return -ENOMEM; -+ } -+ -+ dev->ts2_mode.isoc_ctl.max_pkt_size = max_pkt_size; -+ dev->ts2_mode.isoc_ctl.buf = NULL; -+ -+ sb_size = max_packets * dev->ts2_mode.isoc_ctl.max_pkt_size; -+ -+ if (dev->mode_tv == 1) -+ dev->ts2_mode.end_point_addr = 0x82; -+ else -+ dev->ts2_mode.end_point_addr = 0x84; -+ -+ -+ /* allocate urbs and transfer buffers */ -+ for (i = 0; i < dev->ts2_mode.isoc_ctl.num_bufs; i++) { -+ urb = usb_alloc_urb(max_packets, GFP_KERNEL); -+ if (!urb) { -+ dev_err(dev->dev, -+ "cannot alloc isoc_ctl.urb %i\n", i); -+ cx231xx_uninit_isoc_ts2(dev); -+ return -ENOMEM; -+ } -+ dev->ts2_mode.isoc_ctl.urb[i] = urb; -+ -+ dev->ts2_mode.isoc_ctl.transfer_buffer[i] = -+ usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, -+ &urb->transfer_dma); -+ if (!dev->ts2_mode.isoc_ctl.transfer_buffer[i]) { -+ dev_err(dev->dev, -+ "unable to allocate %i bytes for transfer" -+ " buffer %i%s\n", -+ sb_size, i, -+ in_interrupt() ? " while in int" : ""); -+ cx231xx_uninit_isoc_ts2(dev); -+ return -ENOMEM; -+ } -+ memset(dev->ts2_mode.isoc_ctl.transfer_buffer[i], 0, sb_size); -+ -+ pipe = -+ usb_rcvisocpipe(dev->udev, dev->ts2_mode.end_point_addr); -+ -+ usb_fill_int_urb(urb, dev->udev, pipe, -+ dev->ts2_mode.isoc_ctl.transfer_buffer[i], -+ sb_size, cx231xx_isoc_irq_callback_ts2, dma_q_ts2, 1); -+ -+ urb->number_of_packets = max_packets; -+ urb->transfer_flags = URB_ISO_ASAP; -+ -+ k = 0; -+ for (j = 0; j < max_packets; j++) { -+ urb->iso_frame_desc[j].offset = k; -+ urb->iso_frame_desc[j].length = -+ dev->ts2_mode.isoc_ctl.max_pkt_size; -+ k += dev->ts2_mode.isoc_ctl.max_pkt_size; -+ } -+ } -+ -+ init_waitqueue_head(&dma_q_ts2->wq); -+ -+ /* submit urbs and enables IRQ */ -+ for (i = 0; i < dev->ts2_mode.isoc_ctl.num_bufs; i++) { -+ rc = usb_submit_urb(dev->ts2_mode.isoc_ctl.urb[i], -+ GFP_ATOMIC); -+ if (rc) { -+ dev_err(dev->dev, -+ "submit of urb %i failed (error=%i)\n", i, -+ rc); -+ cx231xx_uninit_isoc_ts2(dev); -+ return rc; -+ } -+ } -+ -+ if (dev->mode_tv == 0) -+ cx231xx_capture_start(dev, 1, Raw_Video); -+ else -+ cx231xx_capture_start(dev, 1, TS2); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(cx231xx_init_isoc_ts2); -+ - /* - * Allocate URBs and start IRQ - */ -@@ -1348,8 +1579,9 @@ int cx231xx_dev_init(struct cx231xx *dev) - - /* scan the real bus segments in the order of physical port numbers */ - cx231xx_do_i2c_scan(dev, I2C_0); -- cx231xx_do_i2c_scan(dev, I2C_1_MUX_1); -+ cx231xx_do_i2c_scan(dev, I2C_1); - cx231xx_do_i2c_scan(dev, I2C_2); -+ cx231xx_do_i2c_scan(dev, I2C_1_MUX_1); - cx231xx_do_i2c_scan(dev, I2C_1_MUX_3); - - /* init hardware */ -@@ -1388,6 +1620,7 @@ int cx231xx_dev_init(struct cx231xx *dev) - __func__, errCode); - return errCode; - } -+ - errCode = cx231xx_afe_init_channels(dev); - if (errCode < 0) { - dev_err(dev->dev, -@@ -1395,7 +1628,6 @@ int cx231xx_dev_init(struct cx231xx *dev) - __func__, errCode); - return errCode; - } -- - /* Set DIF in By pass mode */ - errCode = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); - if (errCode < 0) { -@@ -1404,7 +1636,6 @@ int cx231xx_dev_init(struct cx231xx *dev) - __func__, errCode); - return errCode; - } -- - /* I2S block related functions */ - errCode = cx231xx_i2s_blk_initialize(dev); - if (errCode < 0) { -@@ -1413,7 +1644,6 @@ int cx231xx_dev_init(struct cx231xx *dev) - __func__, errCode); - return errCode; - } -- - /* init control pins */ - errCode = cx231xx_init_ctrl_pin_status(dev); - if (errCode < 0) { -@@ -1422,7 +1652,6 @@ int cx231xx_dev_init(struct cx231xx *dev) - __func__, errCode); - return errCode; - } -- - /* set AGC mode to Analog */ - switch (dev->model) { - case CX231XX_BOARD_CNXT_CARRAERA: -@@ -1438,6 +1667,9 @@ int cx231xx_dev_init(struct cx231xx *dev) - case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: - case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL: - case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC: -+ case CX231XX_BOARD_TBS_5280: -+ case CX231XX_BOARD_TBS_5281: -+ case CX231XX_BOARD_TBS_5990: - errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0); - break; - default: -@@ -1449,15 +1681,19 @@ int cx231xx_dev_init(struct cx231xx *dev) - __func__, errCode); - return errCode; - } -- - /* set all alternate settings to zero initially */ - cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0); - cx231xx_set_alt_setting(dev, INDEX_VANC, 0); - cx231xx_set_alt_setting(dev, INDEX_HANC, 0); -- if (dev->board.has_dvb) -+ if (dev->board.has_dvb) { - cx231xx_set_alt_setting(dev, INDEX_TS1, 0); -+ if (dev->board.adap_cnt == 2) -+ cx231xx_set_alt_setting(dev, INDEX_TS2, 0); -+ } -+ -+ -+ errCode = cx231xx_enable_i2c_port_3( dev,true); - -- errCode = 0; - return errCode; - } - EXPORT_SYMBOL_GPL(cx231xx_dev_init); -diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c -index 2868546..5fafc20 100644 ---- a/drivers/media/usb/cx231xx/cx231xx-dvb.c -+++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c -@@ -35,7 +35,13 @@ - #include "si2165.h" - #include "mb86a20s.h" - #include "si2157.h" -+#include "si2168.h" - #include "lgdt3306a.h" -+#include "tda18212.h" -+#include "cxd2820r.h" -+#include "tas2101.h" -+#include "av201x.h" -+#include "tbscxci.h" - - MODULE_DESCRIPTION("driver for cx231xx based DVB cards"); - MODULE_AUTHOR("Srinivasa Deevi "); -@@ -51,24 +57,6 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - #define CX231XX_DVB_MAX_PACKETSIZE 564 - #define CX231XX_DVB_MAX_PACKETS 64 - --struct cx231xx_dvb { -- struct dvb_frontend *frontend; -- -- /* feed count management */ -- struct mutex lock; -- int nfeeds; -- -- /* general boilerplate stuff */ -- struct dvb_adapter adapter; -- struct dvb_demux demux; -- struct dmxdev dmxdev; -- struct dmx_frontend fe_hw; -- struct dmx_frontend fe_mem; -- struct dvb_net net; -- struct i2c_client *i2c_client_demod; -- struct i2c_client *i2c_client_tuner; --}; -- - static struct s5h1432_config dvico_s5h1432_config = { - .output_mode = S5H1432_SERIAL_OUTPUT, - .gpio = S5H1432_GPIO_ON, -@@ -163,6 +151,28 @@ static struct lgdt3306a_config hauppauge_955q_lgdt3306a_config = { - .xtalMHz = 25, - }; - -+static struct cxd2820r_config cxd2820r_config0 = { -+ .i2c_address = 0x6c, /* (0xd8 >> 1) */ -+ .ts_mode = 0x08, -+}; -+ -+static struct cxd2820r_config cxd2820r_config1 = { -+ .i2c_address = 0x6d, /* (0xda >> 1) */ -+ .ts_mode = 0x08, -+}; -+ -+static struct tda18212_config tda18212_config = { -+ .if_dvbt_6 = 3550, -+ .if_dvbt_7 = 3700, -+ .if_dvbt_8 = 4150, -+ .if_dvbt2_6 = 3250, -+ .if_dvbt2_7 = 4000, -+ .if_dvbt2_8 = 4000, -+ .if_dvbc = 5000, -+ .loop_through = 1, -+ .xtout = 1 -+}; -+ - static inline void print_err_status(struct cx231xx *dev, int packet, int status) - { - char *errmsg = "Unknown"; -@@ -228,7 +238,41 @@ static inline int dvb_isoc_copy(struct cx231xx *dev, struct urb *urb) - continue; - } - -- dvb_dmx_swfilter(&dev->dvb->demux, -+ dvb_dmx_swfilter(&dev->dvb[0]->demux, -+ urb->transfer_buffer + -+ urb->iso_frame_desc[i].offset, -+ urb->iso_frame_desc[i].actual_length); -+ } -+ -+ return 0; -+} -+ -+static inline int dvb_isoc_copy_ts2(struct cx231xx *dev, struct urb *urb) -+{ -+ int i; -+ -+ if (!dev) -+ return 0; -+ -+ if (dev->state & DEV_DISCONNECTED) -+ return 0; -+ -+ if (urb->status < 0) { -+ print_err_status(dev, -1, urb->status); -+ if (urb->status == -ENOENT) -+ return 0; -+ } -+ -+ for (i = 0; i < urb->number_of_packets; i++) { -+ int status = urb->iso_frame_desc[i].status; -+ -+ if (status < 0) { -+ print_err_status(dev, i, status); -+ if (urb->iso_frame_desc[i].status != -EPROTO) -+ continue; -+ } -+ -+ dvb_dmx_swfilter(&dev->dvb[1]->demux, - urb->transfer_buffer + - urb->iso_frame_desc[i].offset, - urb->iso_frame_desc[i].actual_length); -@@ -252,7 +296,7 @@ static inline int dvb_bulk_copy(struct cx231xx *dev, struct urb *urb) - } - - /* Feed the transport payload into the kernel demux */ -- dvb_dmx_swfilter(&dev->dvb->demux, -+ dvb_dmx_swfilter(&dev->dvb[0]->demux, - urb->transfer_buffer, urb->actual_length); - - return 0; -@@ -265,26 +309,43 @@ static int start_streaming(struct cx231xx_dvb *dvb) - - if (dev->USE_ISO) { - dev_dbg(dev->dev, "DVB transfer mode is ISO.\n"); -- cx231xx_set_alt_setting(dev, INDEX_TS1, 4); -+ mutex_lock(&dev->i2c_lock); -+ cx231xx_enable_i2c_port_3(dev, false); -+ if (dvb->count == 0) -+ cx231xx_set_alt_setting(dev, INDEX_TS1, 4); -+ if (dvb->count == 1) -+ cx231xx_set_alt_setting(dev, INDEX_TS2, 4); -+ cx231xx_enable_i2c_port_3(dev, true); -+ mutex_unlock(&dev->i2c_lock); - rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); - if (rc < 0) - return rc; - dev->mode_tv = 1; -+ if (dvb->count == 1) -+ return cx231xx_init_isoc_ts2(dev, CX231XX_DVB_MAX_PACKETS, -+ CX231XX_DVB_NUM_BUFS, -+ dev->ts2_mode.max_pkt_size, -+ dvb_isoc_copy_ts2); -+ else - return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS, -- CX231XX_DVB_NUM_BUFS, -- dev->ts1_mode.max_pkt_size, -- dvb_isoc_copy); -+ CX231XX_DVB_NUM_BUFS, -+ dev->ts1_mode.max_pkt_size, -+ dvb_isoc_copy); - } else { - dev_dbg(dev->dev, "DVB transfer mode is BULK.\n"); -- cx231xx_set_alt_setting(dev, INDEX_TS1, 0); -+ if (dvb->count == 0) -+ cx231xx_set_alt_setting(dev, INDEX_TS1, 0); -+ if (dvb->count == 1) -+ cx231xx_set_alt_setting(dev, INDEX_TS2, 0); - rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); - if (rc < 0) - return rc; - dev->mode_tv = 1; - return cx231xx_init_bulk(dev, CX231XX_DVB_MAX_PACKETS, -- CX231XX_DVB_NUM_BUFS, -- dev->ts1_mode.max_pkt_size, -- dvb_bulk_copy); -+ CX231XX_DVB_NUM_BUFS, -+ dvb->count ? dev->ts2_mode.max_pkt_size -+ : dev->ts1_mode.max_pkt_size, -+ dvb_bulk_copy); - } - - } -@@ -294,7 +355,10 @@ static int stop_streaming(struct cx231xx_dvb *dvb) - struct cx231xx *dev = dvb->adapter.priv; - - if (dev->USE_ISO) -- cx231xx_uninit_isoc(dev); -+ if (dvb->count == 0) -+ cx231xx_uninit_isoc(dev); -+ if (dvb->count == 1) -+ cx231xx_uninit_isoc_ts2(dev); - else - cx231xx_uninit_bulk(dev); - -@@ -363,7 +427,52 @@ static struct xc5000_config cnxt_rdu250_tunerconfig = { - .i2c_address = 0x61, - .if_khz = 3250, - }; -+static void tbs5990_lnb_power(struct dvb_frontend *fe, -+ int enpwr_pin, int onoff) -+{ -+ struct cx231xx *dev = fe->dvb->priv; -+ -+ /* lnb power, active low */ -+ cx231xx_set_gpio_direction(dev, enpwr_pin, 1); -+ if (onoff) -+ cx231xx_set_gpio_value(dev, enpwr_pin, 0); -+ else -+ cx231xx_set_gpio_value(dev, enpwr_pin, 1); -+} -+ -+static void tbs5990_lnb0_power(struct dvb_frontend *fe, int onoff) -+{ -+ tbs5990_lnb_power(fe, 26, onoff); -+} -+ -+static void tbs5990_lnb1_power(struct dvb_frontend *fe, int onoff) -+{ -+ tbs5990_lnb_power(fe, 22, onoff); -+} - -+static struct tas2101_config tbs5990_config0 ={ -+ .i2c_address = 0x60, -+ .id = ID_TAS2101, -+ .reset_demod = NULL, -+ .lnb_power = tbs5990_lnb0_power, -+ .init = {0x80, 0xAB, 0x47, 0x61, 0x25, 0x93, 0x31}, -+ .init2 = 0, -+ -+}; -+static struct tas2101_config tbs5990_config1 ={ -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .reset_demod = NULL, -+ .lnb_power = tbs5990_lnb1_power, -+ .init = {0xB0, 0xA8, 0x21, 0x53, 0x74, 0x96, 0x31}, -+ .init2 = 0, -+ -+}; -+static struct av201x_config tbs5990_tuner_config = { -+ .i2c_address = 0x63, -+ .id = ID_AV2012, -+ .xtal_freq = 27000, -+}; - /* ------------------------------------------------------------------ */ - #if 0 - static int attach_xc5000(u8 addr, struct cx231xx *dev) -@@ -398,9 +507,9 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) - - int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq) - { -- if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) { -+ if ((dev->dvb[0] != NULL) && (dev->dvb[0]->frontend != NULL)) { - -- struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops; -+ struct dvb_tuner_ops *dops = &dev->dvb[0]->frontend->ops.tuner_ops; - - if (dops->set_analog_params != NULL) { - struct analog_parameters params; -@@ -411,7 +520,7 @@ int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq) - /*params.audmode = ; */ - - /* Set the analog parameters to set the frequency */ -- dops->set_analog_params(dev->dvb->frontend, ¶ms); -+ dops->set_analog_params(dev->dvb[0]->frontend, ¶ms); - } - - } -@@ -423,15 +532,15 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev) - { - int status = 0; - -- if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) { -+ if ((dev->dvb[0] != NULL) && (dev->dvb[0]->frontend != NULL)) { - -- struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops; -+ struct dvb_tuner_ops *dops = &dev->dvb[0]->frontend->ops.tuner_ops; - - if (dops->init != NULL && !dev->xc_fw_load_done) { - - dev_dbg(dev->dev, - "Reloading firmware for XC5000\n"); -- status = dops->init(dev->dvb->frontend); -+ status = dops->init(dev->dvb[0]->frontend); - if (status == 0) { - dev->xc_fw_load_done = 1; - dev_dbg(dev->dev, -@@ -457,8 +566,6 @@ static int register_dvb(struct cx231xx_dvb *dvb, - int result; - - mutex_init(&dvb->lock); -- -- - /* register adapter */ - result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, - adapter_nr); -@@ -468,13 +575,13 @@ static int register_dvb(struct cx231xx_dvb *dvb, - dev->name, result); - goto fail_adapter; - } -- dvb_register_media_controller(&dvb->adapter, dev->media_dev); -+// dvb_register_media_controller(&dvb->adapter, dev->media_dev); - - /* Ensure all frontends negotiate bus access */ -- dvb->frontend->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl; -+// dvb->frontend->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl; - - dvb->adapter.priv = dev; -- -+#if 0 - /* register frontend */ - result = dvb_register_frontend(&dvb->adapter, dvb->frontend); - if (result < 0) { -@@ -483,7 +590,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, - dev->name, result); - goto fail_frontend; - } -- -+#endif - /* register demux stuff */ - dvb->demux.dmx.capabilities = - DMX_TS_FILTERING | DMX_SECTION_FILTERING | -@@ -545,7 +652,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, - dev->tuner_type == TUNER_ABSENT); - if (result < 0) - goto fail_create_graph; -- -+ - return 0; - - fail_create_graph: -@@ -592,18 +699,51 @@ static void unregister_dvb(struct cx231xx_dvb *dvb) - dvb_unregister_adapter(&dvb->adapter); - } - -+static int tbs_cx_mac(struct i2c_adapter *i2c_adap, u8 count, u8 *mac) -+{ -+ u8 b[64], e[256]; -+ int ret, i; -+ -+ struct i2c_msg msg[] = { -+ { .addr = 0x50, .flags = 0, -+ .buf = b, .len = 1 }, -+ { .addr = 0x50, .flags = I2C_M_RD, -+ .buf = b, .len = 64 } -+ }; -+ -+ for (i = 0; i < 4; i++) { -+ b[0] = 0x40 * i; -+ -+ ret = i2c_transfer(i2c_adap, msg, 2); -+ -+ if (ret != 2) { -+ printk("TBS CX read MAC failed\n"); -+ return -1; -+ } -+ -+ memcpy(&e[0x40 * i], b , 64); -+ } -+ -+ memcpy(mac, &e[0x58 + 6 + 0x10*count], 6); -+ -+ return 0; -+} -+ - static int dvb_init(struct cx231xx *dev) - { -- int result = 0; -+ int i, result = 0; - struct cx231xx_dvb *dvb; - struct i2c_adapter *tuner_i2c; - struct i2c_adapter *demod_i2c; -- -+ u8 mac[6] = {0,0,0,0,0,0}; - if (!dev->board.has_dvb) { - /* This device does not support the extension */ - return 0; - } -+ -+ mutex_lock(&dev->lock); - -+ for (i = 0; i < dev->board.adap_cnt; i++) { - dvb = kzalloc(sizeof(struct cx231xx_dvb), GFP_KERNEL); - - if (dvb == NULL) { -@@ -611,13 +751,19 @@ static int dvb_init(struct cx231xx *dev) - "cx231xx_dvb: memory allocation failed\n"); - return -ENOMEM; - } -- dev->dvb = dvb; -+ -+ dvb->count = i; -+ -+ dev->dvb[i] = dvb; - dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq; - dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner; - - tuner_i2c = cx231xx_get_i2c_adap(dev, dev->board.tuner_i2c_master); - demod_i2c = cx231xx_get_i2c_adap(dev, dev->board.demod_i2c_master); -- mutex_lock(&dev->lock); -+ -+ result = register_dvb(dev->dvb[i],THIS_MODULE,dev,&dev->udev->dev); -+ -+ - cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); - cx231xx_demod_reset(dev); - /* init frontend */ -@@ -625,11 +771,11 @@ static int dvb_init(struct cx231xx *dev) - case CX231XX_BOARD_CNXT_CARRAERA: - case CX231XX_BOARD_CNXT_RDE_250: - -- dev->dvb->frontend = dvb_attach(s5h1432_attach, -+ dev->dvb[i]->frontend = dvb_attach(s5h1432_attach, - &dvico_s5h1432_config, - demod_i2c); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb[i]->frontend == NULL) { - dev_err(dev->dev, - "Failed to attach s5h1432 front end\n"); - result = -EINVAL; -@@ -639,7 +785,7 @@ static int dvb_init(struct cx231xx *dev) - /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; - -- if (!dvb_attach(xc5000_attach, dev->dvb->frontend, -+ if (!dvb_attach(xc5000_attach, dev->dvb[i]->frontend, - tuner_i2c, - &cnxt_rde250_tunerconfig)) { - result = -EINVAL; -@@ -650,11 +796,11 @@ static int dvb_init(struct cx231xx *dev) - case CX231XX_BOARD_CNXT_SHELBY: - case CX231XX_BOARD_CNXT_RDU_250: - -- dev->dvb->frontend = dvb_attach(s5h1411_attach, -+ dev->dvb[i]->frontend = dvb_attach(s5h1411_attach, - &xc5000_s5h1411_config, - demod_i2c); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb[i]->frontend == NULL) { - dev_err(dev->dev, - "Failed to attach s5h1411 front end\n"); - result = -EINVAL; -@@ -664,7 +810,7 @@ static int dvb_init(struct cx231xx *dev) - /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; - -- if (!dvb_attach(xc5000_attach, dev->dvb->frontend, -+ if (!dvb_attach(xc5000_attach, dev->dvb[i]->frontend, - tuner_i2c, - &cnxt_rdu250_tunerconfig)) { - result = -EINVAL; -@@ -673,11 +819,11 @@ static int dvb_init(struct cx231xx *dev) - break; - case CX231XX_BOARD_CNXT_RDE_253S: - -- dev->dvb->frontend = dvb_attach(s5h1432_attach, -+ dev->dvb[i]->frontend = dvb_attach(s5h1432_attach, - &dvico_s5h1432_config, - demod_i2c); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb[i]->frontend == NULL) { - dev_err(dev->dev, - "Failed to attach s5h1432 front end\n"); - result = -EINVAL; -@@ -687,7 +833,7 @@ static int dvb_init(struct cx231xx *dev) - /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; - -- if (!dvb_attach(tda18271_attach, dev->dvb->frontend, -+ if (!dvb_attach(tda18271_attach, dev->dvb[i]->frontend, - 0x60, tuner_i2c, - &cnxt_rde253s_tunerconfig)) { - result = -EINVAL; -@@ -697,11 +843,11 @@ static int dvb_init(struct cx231xx *dev) - case CX231XX_BOARD_CNXT_RDU_253S: - case CX231XX_BOARD_KWORLD_UB445_USB_HYBRID: - -- dev->dvb->frontend = dvb_attach(s5h1411_attach, -+ dev->dvb[i]->frontend = dvb_attach(s5h1411_attach, - &tda18271_s5h1411_config, - demod_i2c); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb[i]->frontend == NULL) { - dev_err(dev->dev, - "Failed to attach s5h1411 front end\n"); - result = -EINVAL; -@@ -711,7 +857,7 @@ static int dvb_init(struct cx231xx *dev) - /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; - -- if (!dvb_attach(tda18271_attach, dev->dvb->frontend, -+ if (!dvb_attach(tda18271_attach, dev->dvb[i]->frontend, - 0x60, tuner_i2c, - &cnxt_rde253s_tunerconfig)) { - result = -EINVAL; -@@ -724,11 +870,11 @@ static int dvb_init(struct cx231xx *dev) - "%s: looking for tuner / demod on i2c bus: %d\n", - __func__, i2c_adapter_id(tuner_i2c)); - -- dev->dvb->frontend = dvb_attach(lgdt3305_attach, -+ dev->dvb[i]->frontend = dvb_attach(lgdt3305_attach, - &hcw_lgdt3305_config, - demod_i2c); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb[i]->frontend == NULL) { - dev_err(dev->dev, - "Failed to attach LG3305 front end\n"); - result = -EINVAL; -@@ -738,7 +884,7 @@ static int dvb_init(struct cx231xx *dev) - /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; - -- dvb_attach(tda18271_attach, dev->dvb->frontend, -+ dvb_attach(tda18271_attach, dev->dvb[i]->frontend, - 0x60, tuner_i2c, - &hcw_tda18271_config); - break; -@@ -751,7 +897,7 @@ static int dvb_init(struct cx231xx *dev) - - /* attach demod */ - memset(&si2165_pdata, 0, sizeof(si2165_pdata)); -- si2165_pdata.fe = &dev->dvb->frontend; -+ si2165_pdata.fe = &dev->dvb[i]->frontend; - si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL, - si2165_pdata.ref_freq_Hz = 16000000, - -@@ -761,7 +907,7 @@ static int dvb_init(struct cx231xx *dev) - info.platform_data = &si2165_pdata; - request_module(info.type); - client = i2c_new_device(demod_i2c, &info); -- if (client == NULL || client->dev.driver == NULL || dev->dvb->frontend == NULL) { -+ if (client == NULL || client->dev.driver == NULL || dev->dvb[i]->frontend == NULL) { - dev_err(dev->dev, - "Failed to attach SI2165 front end\n"); - result = -EINVAL; -@@ -776,12 +922,12 @@ static int dvb_init(struct cx231xx *dev) - - dvb->i2c_client_demod = client; - -- dev->dvb->frontend->ops.i2c_gate_ctrl = NULL; -+ dev->dvb[i]->frontend->ops.i2c_gate_ctrl = NULL; - - /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; - -- dvb_attach(tda18271_attach, dev->dvb->frontend, -+ dvb_attach(tda18271_attach, dev->dvb[i]->frontend, - 0x60, - tuner_i2c, - &hcw_tda18271_config); -@@ -798,7 +944,7 @@ static int dvb_init(struct cx231xx *dev) - - /* attach demod */ - memset(&si2165_pdata, 0, sizeof(si2165_pdata)); -- si2165_pdata.fe = &dev->dvb->frontend; -+ si2165_pdata.fe = &dev->dvb[i]->frontend; - si2165_pdata.chip_mode = SI2165_MODE_PLL_EXT, - si2165_pdata.ref_freq_Hz = 24000000, - -@@ -808,7 +954,7 @@ static int dvb_init(struct cx231xx *dev) - info.platform_data = &si2165_pdata; - request_module(info.type); - client = i2c_new_device(demod_i2c, &info); -- if (client == NULL || client->dev.driver == NULL || dev->dvb->frontend == NULL) { -+ if (client == NULL || client->dev.driver == NULL || dev->dvb[i]->frontend == NULL) { - dev_err(dev->dev, - "Failed to attach SI2165 front end\n"); - result = -EINVAL; -@@ -825,14 +971,14 @@ static int dvb_init(struct cx231xx *dev) - - memset(&info, 0, sizeof(struct i2c_board_info)); - -- dev->dvb->frontend->ops.i2c_gate_ctrl = NULL; -+ dev->dvb[i]->frontend->ops.i2c_gate_ctrl = NULL; - - /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; - - /* attach tuner */ - memset(&si2157_config, 0, sizeof(si2157_config)); -- si2157_config.fe = dev->dvb->frontend; -+ si2157_config.fe = dev->dvb[i]->frontend; - #ifdef CONFIG_MEDIA_CONTROLLER_DVB - si2157_config.mdev = dev->media_dev; - #endif -@@ -847,21 +993,21 @@ static int dvb_init(struct cx231xx *dev) - tuner_i2c, - &info); - if (client == NULL || client->dev.driver == NULL) { -- dvb_frontend_detach(dev->dvb->frontend); -+ dvb_frontend_detach(dev->dvb[i]->frontend); - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); -- dvb_frontend_detach(dev->dvb->frontend); -+ dvb_frontend_detach(dev->dvb[i]->frontend); - result = -ENODEV; - goto out_free; - } - - dev->cx231xx_reset_analog_tuner = NULL; - -- dev->dvb->i2c_client_tuner = client; -+ dev->dvb[i]->i2c_client_tuner = client; - break; - } - case CX231XX_BOARD_HAUPPAUGE_955Q: -@@ -872,26 +1018,26 @@ static int dvb_init(struct cx231xx *dev) - - memset(&info, 0, sizeof(struct i2c_board_info)); - -- dev->dvb->frontend = dvb_attach(lgdt3306a_attach, -+ dev->dvb[i]->frontend = dvb_attach(lgdt3306a_attach, - &hauppauge_955q_lgdt3306a_config, - demod_i2c - ); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb[i]->frontend == NULL) { - dev_err(dev->dev, - "Failed to attach LGDT3306A frontend.\n"); - result = -EINVAL; - goto out_free; - } - -- dev->dvb->frontend->ops.i2c_gate_ctrl = NULL; -+ dev->dvb[i]->frontend->ops.i2c_gate_ctrl = NULL; - - /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; - - /* attach tuner */ - memset(&si2157_config, 0, sizeof(si2157_config)); -- si2157_config.fe = dev->dvb->frontend; -+ si2157_config.fe = dev->dvb[i]->frontend; - #ifdef CONFIG_MEDIA_CONTROLLER_DVB - si2157_config.mdev = dev->media_dev; - #endif -@@ -906,21 +1052,21 @@ static int dvb_init(struct cx231xx *dev) - tuner_i2c, - &info); - if (client == NULL || client->dev.driver == NULL) { -- dvb_frontend_detach(dev->dvb->frontend); -+ dvb_frontend_detach(dev->dvb[i]->frontend); - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); -- dvb_frontend_detach(dev->dvb->frontend); -+ dvb_frontend_detach(dev->dvb[i]->frontend); - result = -ENODEV; - goto out_free; - } - - dev->cx231xx_reset_analog_tuner = NULL; - -- dev->dvb->i2c_client_tuner = client; -+ dev->dvb[i]->i2c_client_tuner = client; - break; - } - case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: -@@ -930,11 +1076,11 @@ static int dvb_init(struct cx231xx *dev) - "%s: looking for demod on i2c bus: %d\n", - __func__, i2c_adapter_id(tuner_i2c)); - -- dev->dvb->frontend = dvb_attach(mb86a20s_attach, -+ dev->dvb[i]->frontend = dvb_attach(mb86a20s_attach, - &pv_mb86a20s_config, - demod_i2c); - -- if (dev->dvb->frontend == NULL) { -+ if (dev->dvb[i]->frontend == NULL) { - dev_err(dev->dev, - "Failed to attach mb86a20s demod\n"); - result = -EINVAL; -@@ -944,17 +1090,162 @@ static int dvb_init(struct cx231xx *dev) - /* define general-purpose callback pointer */ - dvb->frontend->callback = cx231xx_tuner_callback; - -- dvb_attach(tda18271_attach, dev->dvb->frontend, -+ dvb_attach(tda18271_attach, dev->dvb[i]->frontend, - 0x60, tuner_i2c, - &pv_tda18271_config); - break; - -+ case CX231XX_BOARD_TBS_5280: -+ { -+ struct i2c_client *client; -+ struct i2c_board_info board_info = { -+ .type = "tda18212", -+ .platform_data = &tda18212_config, -+ }; -+ -+ -+ board_info.addr = (i == 0) ? 0x60 : 0x63; -+ -+ dev->dvb[i]->frontend = dvb_attach(cxd2820r_attach, -+ i ? &cxd2820r_config1 : &cxd2820r_config0, -+ demod_i2c, NULL); -+ -+ if (dev->dvb[i]->frontend == NULL) { -+ dev_err(dev->dev, -+ "Failed to attach demod cxd2820r %d\n", i); -+ result = -EINVAL; -+ goto out_free; -+ } -+ -+ /* define general-purpose callback pointer */ -+ dvb->frontend->callback = cx231xx_tuner_callback; -+ -+ /* attach tuner */ -+ tda18212_config.fe = dev->dvb[i]->frontend; -+ request_module("tda18212"); -+ client = i2c_new_device(tuner_i2c, &board_info); /* could it be demod_i2c ?? */ -+ if (client == NULL || client->dev.driver == NULL) { -+ dvb_frontend_detach(dev->dvb[i]->frontend); -+ result = -ENODEV; -+ goto out_free; -+ } -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ dvb_frontend_detach(dev->dvb[i]->frontend); -+ result = -ENODEV; -+ goto out_free; -+ } -+ dev->dvb[i]->i2c_client_tuner = client; -+ -+ break; -+ } -+ case CX231XX_BOARD_TBS_5281: -+ { -+ struct i2c_adapter *adapter; -+ struct i2c_client *client_demod; -+ struct i2c_client *client_tuner; -+ struct i2c_board_info info; -+ struct si2168_config si2168_config; -+ struct si2157_config si2157_config; -+ -+ demod_i2c = cx231xx_get_i2c_adap(dev, dev->board.demod_i2c_master+i); -+ /* attach frontend */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.i2c_adapter = &adapter; -+ si2168_config.fe = &dev->dvb[i]->frontend; -+ si2168_config.ts_mode = SI2168_TS_SERIAL; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2168", I2C_NAME_SIZE); -+ info.addr = 0x64; -+ info.platform_data = &si2168_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(demod_i2c, &info); -+ if (client_demod == NULL || client_demod->dev.driver == NULL) { -+ result = -ENODEV; -+ goto out_free; -+ } -+ -+ if (!try_module_get(client_demod->dev.driver->owner)) { -+ i2c_unregister_device(client_demod); -+ result = -ENODEV; -+ goto out_free; -+ } -+ -+ /* define general-purpose callback pointer */ -+ dvb->frontend->callback = cx231xx_tuner_callback; -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = dev->dvb[i]->frontend; -+ si2157_config.if_port = 1; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client_tuner = i2c_new_device(adapter, &info); -+ if (client_tuner == NULL || client_tuner->dev.driver == NULL) { -+ module_put(client_demod->dev.driver->owner); -+ i2c_unregister_device(client_demod); -+ result = -ENODEV; -+ goto out_free; -+ } -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ module_put(client_demod->dev.driver->owner); -+ i2c_unregister_device(client_demod); -+ result = -ENODEV; -+ goto out_free; -+ } -+ -+ dev->dvb[i]->i2c_client_demod = client_demod; -+ dev->dvb[i]->i2c_client_tuner = client_tuner; -+ -+ break; -+ } -+ case CX231XX_BOARD_TBS_5990: -+ { -+ dev->dvb[i]->frontend = dvb_attach(tas2101_attach,i ? &tbs5990_config1 : &tbs5990_config0, -+ &dev->i2c_bus[1+i].i2c_adap); -+ if (dev->dvb[i]->frontend == NULL) { -+ dev_err(dev->dev, -+ "Failed to attach demod TAS2101 %d\n", i); -+ result = -EINVAL; -+ goto out_free; -+ } -+ -+ /*attach tuner*/ -+ if(dvb_attach(av201x_attach,dev->dvb[i]->frontend, -+ &tbs5990_tuner_config,tas2101_get_i2c_adapter(dev->dvb[i]->frontend, 2))==NULL) -+ { -+ dvb_frontend_detach(dev->dvb[i]->frontend); -+ result = -ENODEV; -+ goto out_free; -+ } -+ -+ if (i == 0) { -+ tbs_cx_mac(&dev->i2c_bus[1].i2c_adap, 0, mac); -+ } -+ -+ if (i == 1) { -+ memcpy(dev->dvb[0]->adapter.proposed_mac, mac, 6); -+ printk(KERN_INFO "TurboSight TBS5990 MAC Addresse bas: %pM\n", mac); -+ mac[5] +=1; -+ memcpy(dev->dvb[1]->adapter.proposed_mac, mac, 6); -+ } -+ -+ /* define general-purpose callback pointer */ -+ dvb->frontend->callback = cx231xx_tuner_callback; -+ -+ break; -+ } - default: - dev_err(dev->dev, - "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", - dev->name); - break; - } -+ - if (NULL == dvb->frontend) { - dev_err(dev->dev, - "%s/2: frontend initialization failed\n", dev->name); -@@ -962,13 +1253,19 @@ static int dvb_init(struct cx231xx *dev) - goto out_free; - } - -- /* register everything */ -- result = register_dvb(dvb, THIS_MODULE, dev, dev->dev); -+ strlcpy(dev->dvb[i]->frontend->ops.info.name,dev->board.name,52); - -+ result = dvb_register_frontend(&dev->dvb[i]->adapter,dev->dvb[i]->frontend); - if (result < 0) - goto out_free; -+ switch(dev->model){ -+ case CX231XX_BOARD_TBS_5990: -+ tbscxci_init(dev->dvb[i], i); -+ } - - -+ } -+ - dev_info(dev->dev, "Successfully loaded cx231xx-dvb\n"); - - ret: -@@ -978,20 +1275,29 @@ static int dvb_init(struct cx231xx *dev) - - out_free: - kfree(dvb); -- dev->dvb = NULL; -+ dev->dvb[i] = NULL; - goto ret; - } - - static int dvb_fini(struct cx231xx *dev) - { -+ int i; -+ - if (!dev->board.has_dvb) { - /* This device does not support the extension */ - return 0; - } - -- if (dev->dvb) { -- unregister_dvb(dev->dvb); -- dev->dvb = NULL; -+ for (i = 0; i < dev->board.adap_cnt; i++) { -+ if (dev->dvb[i]) { -+ switch (dev->model) { -+ case CX231XX_BOARD_TBS_5990: -+ tbscxci_release(dev->dvb[i]); -+ break; -+ } -+ unregister_dvb(dev->dvb[i]); -+ dev->dvb[i] = NULL; -+ } - } - - return 0; -diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c -index 35e9acf..95d9a017 100644 ---- a/drivers/media/usb/cx231xx/cx231xx-i2c.c -+++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c -@@ -94,7 +94,7 @@ static int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap, - u8 *buf_ptr = NULL; - u16 saddr = 0; - u8 need_gpio = 0; -- -+ - if (is_tuner(dev, bus, msg, TUNER_XC5000)) { - size = msg->len; - -@@ -173,6 +173,37 @@ static int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap, - - } else { /* regular case */ - -+ if (bus->nr == 2) { -+ size = msg->len; -+ buf_ptr = (u8 *) msg->buf; -+ do { -+ /* prepare xfer_data struct */ -+ req_data.dev_addr = msg->addr; -+ req_data.direction = msg->flags; -+ req_data.saddr_len = 0; -+ req_data.saddr_dat = 0; -+ req_data.buf_size = size > 4 ? 4 : size; -+ req_data.p_buffer = (u8 *) (buf_ptr + loop * 4); -+ -+ bus->i2c_nostop = (size > 4) ? 1 : 0; -+ bus->i2c_reserve = (loop == 0) ? 0 : 1; -+ -+ /* usb send command */ -+ status = dev->cx231xx_send_usb_command(bus, &req_data); -+ loop++; -+ -+ if (size >= 4) -+ size -= 4; -+ else -+ size = 0; -+ -+ } while (size > 0); -+ -+ bus->i2c_nostop = 0; -+ bus->i2c_reserve = 0; -+ -+ }else{ -+ - /* prepare xfer_data struct */ - req_data.dev_addr = msg->addr; - req_data.direction = msg->flags; -@@ -183,6 +214,7 @@ static int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap, - - /* usb send command */ - status = dev->cx231xx_send_usb_command(bus, &req_data); -+ } - } - - return status < 0 ? status : 0; -@@ -353,11 +385,11 @@ static int cx231xx_i2c_check_for_device(struct i2c_adapter *i2c_adap, - - /* prepare xfer_data struct */ - req_data.dev_addr = msg->addr; -- req_data.direction = I2C_M_RD; -+ req_data.direction = msg->flags; - req_data.saddr_len = 0; - req_data.saddr_dat = 0; -- req_data.buf_size = 1; -- req_data.p_buffer = buf; -+ req_data.buf_size = 0; -+ req_data.p_buffer = NULL; - - /* usb send command */ - status = dev->cx231xx_send_usb_command(bus, &req_data); -@@ -376,6 +408,7 @@ static int cx231xx_i2c_xfer(struct i2c_adapter *i2c_adap, - struct cx231xx *dev = bus->dev; - int addr, rc, i, byte; - -+ - if (num <= 0) - return 0; - mutex_lock(&dev->i2c_lock); -@@ -472,7 +505,6 @@ static struct i2c_adapter cx231xx_adap_template = { - * incomplete list of known devices - */ - static const char *i2c_devs[128] = { -- [0x20 >> 1] = "demod", - [0x60 >> 1] = "colibri", - [0x88 >> 1] = "hammerhead", - [0x8e >> 1] = "CIR", -@@ -492,6 +524,7 @@ void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port) - unsigned char buf; - int i, rc; - struct i2c_client client; -+ i2c_scan=1; - - if (!i2c_scan) - return; -diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h -index 90c8676..5c4821e 100644 ---- a/drivers/media/usb/cx231xx/cx231xx.h -+++ b/drivers/media/usb/cx231xx/cx231xx.h -@@ -78,6 +78,9 @@ - #define CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx 20 - #define CX231XX_BOARD_HAUPPAUGE_955Q 21 - #define CX231XX_BOARD_TERRATEC_GRABBY 22 -+#define CX231XX_BOARD_TBS_5280 23 -+#define CX231XX_BOARD_TBS_5281 24 -+#define CX231XX_BOARD_TBS_5990 25 - - /* Limits minimum and default number of buffers */ - #define CX231XX_MIN_BUF 4 -@@ -342,6 +345,8 @@ struct cx231xx_board { - int demod_addr; - u8 demod_xfer_mode; /* 0 - Serial; 1 - parallel */ - -+ int adap_cnt; -+ - /* GPIO Pins */ - struct cx231xx_reg_seq *dvb_gpio; - struct cx231xx_reg_seq *suspend_gpio; -@@ -584,6 +589,31 @@ struct cx231xx_tsport { - void *port_priv; - }; - -+ -+ -+struct cx231xx_dvb { -+ struct dvb_frontend *frontend; -+ -+ /* feed count management */ -+ struct mutex lock; -+ int nfeeds; -+ u8 count; -+ -+ /* general boilerplate stuff */ -+ struct dvb_adapter adapter; -+ struct dvb_demux demux; -+ struct dmxdev dmxdev; -+ struct dmx_frontend fe_hw; -+ struct dmx_frontend fe_mem; -+ struct dvb_net net; -+ struct i2c_client *i2c_client_demod; -+ struct i2c_client *i2c_client_tuner; -+ -+ void *adap_priv; -+}; -+ -+ -+ - /* main device struct */ - struct cx231xx { - /* generic device properties */ -@@ -673,6 +703,7 @@ struct cx231xx { - struct cx231xx_video_mode vbi_mode; - struct cx231xx_video_mode sliced_cc_mode; - struct cx231xx_video_mode ts1_mode; -+ struct cx231xx_video_mode ts2_mode; - - atomic_t devlist_count; - -@@ -686,6 +717,7 @@ struct cx231xx { - char *buf, int len); - int (*cx231xx_send_usb_command) (struct cx231xx_i2c *i2c_bus, - struct cx231xx_i2c_xfer_data *req_data); -+ - int (*cx231xx_gpio_i2c_read) (struct cx231xx *dev, u8 dev_addr, - u8 *buf, u8 len); - int (*cx231xx_gpio_i2c_write) (struct cx231xx *dev, u8 dev_addr, -@@ -696,7 +728,7 @@ struct cx231xx { - - enum cx231xx_mode mode; - -- struct cx231xx_dvb *dvb; -+ struct cx231xx_dvb *dvb[2]; - - /* Cx231xx supported PCB config's */ - struct pcb_config current_pcb_config; -@@ -873,6 +905,8 @@ int cx231xx_gpio_i2c_write_nak(struct cx231xx *dev); - - int cx231xx_gpio_i2c_read(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len); - int cx231xx_gpio_i2c_write(struct cx231xx *dev, u8 dev_addr, u8 *buf, u8 len); -+int cx231xx_set_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u32 gpio_val); -+int cx231xx_get_gpio_bit(struct cx231xx *dev, u32 gpio_bit, u32 *gpio_val); - - /* audio related functions */ - int cx231xx_set_audio_decoder_input(struct cx231xx *dev, -@@ -887,6 +921,10 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, - int num_bufs, int max_pkt_size, - int (*isoc_copy) (struct cx231xx *dev, - struct urb *urb)); -+int cx231xx_init_isoc_ts2(struct cx231xx *dev, int max_packets, -+ int num_bufs, int max_pkt_size, -+ int (*isoc_copy) (struct cx231xx *dev, -+ struct urb *urb)); - int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, - int num_bufs, int max_pkt_size, - int (*bulk_copy) (struct cx231xx *dev, -@@ -894,6 +932,7 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, - void cx231xx_stop_TS1(struct cx231xx *dev); - void cx231xx_start_TS1(struct cx231xx *dev); - void cx231xx_uninit_isoc(struct cx231xx *dev); -+void cx231xx_uninit_isoc_ts2(struct cx231xx *dev); - void cx231xx_uninit_bulk(struct cx231xx *dev); - int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode); - int cx231xx_unmute_audio(struct cx231xx *dev); -diff --git a/drivers/media/usb/cx231xx/tbscxci.c b/drivers/media/usb/cx231xx/tbscxci.c -new file mode 100644 -index 0000000..5558cd1 ---- /dev/null -+++ b/drivers/media/usb/cx231xx/tbscxci.c -@@ -0,0 +1,353 @@ -+/* -+ TurboSight TBS CI driver for CX23102 -+ Copyright (C) 2014 Konstantin Dimitrov -+ -+ Copyright (C) 2014 TurboSight.com -+*/ -+ -+#include "tbscxci.h" -+ -+#define TBSCXCI_I2C_ADDR 0x1b -+ -+ -+struct tbscxci_state { -+ struct dvb_ca_en50221 ca; -+ struct mutex ca_mutex; -+ struct i2c_adapter *i2c_adap; -+ int nr; -+ void *priv; /* struct cx231xx_dvb *priv; */ -+}; -+ -+int tbscxci_i2c_read(struct tbscxci_state *state) -+{ -+ int ret; -+ u8 buf = 0; -+ -+ struct i2c_msg msg = { .addr = TBSCXCI_I2C_ADDR, .flags = I2C_M_RD, -+ .buf = &buf, .len = 1 }; -+ -+ if (state->nr == 1) -+ msg.addr -= 1; -+ -+ ret = i2c_transfer(state->i2c_adap, &msg, 1); -+ -+ if (ret != 1) { -+ printk("tbscxci: read error=%d\n", ret); -+ return -EREMOTEIO; -+ } -+ -+ return buf; -+}; -+ -+int tbscxci_i2c_write(struct tbscxci_state *state, -+ u8 addr, u8 data[], int len) -+{ -+ int ret; -+ unsigned char buf[len + 1]; -+ -+ struct i2c_msg msg = { .addr = TBSCXCI_I2C_ADDR, .flags = 0, -+ .buf = &buf[0], .len = len + 1 }; -+ -+ if (state->nr == 1) -+ msg.addr -= 1; -+ -+ memcpy(&buf[1], data, len); -+ buf[0] = addr; -+ -+ ret = i2c_transfer(state->i2c_adap, &msg, 1); -+ -+ if (ret != 1) { -+ /* printk("tbscxci: error=%d\n", ret); */ -+ return -EREMOTEIO; -+ } -+ -+ return 0; -+}; -+ -+int tbscxci_read_cam_control(struct dvb_ca_en50221 *ca, -+ int slot, u8 address) -+{ -+ struct tbscxci_state *state = ca->data; -+ int ret; -+ unsigned char data; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ data = (address & 3); -+ ret = tbscxci_i2c_write(state, 0x80, &data, 1); -+ data = tbscxci_i2c_read(state); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return data; -+} -+ -+int tbscxci_write_cam_control(struct dvb_ca_en50221 *ca, int slot, -+ u8 address, u8 value) -+{ -+ struct tbscxci_state *state = ca->data; -+ int ret; -+ unsigned char data[2]; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ data[0] = (address & 3); -+ data[1] = value; -+ ret = tbscxci_i2c_write(state, 0x80, data, 2); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+int tbscxci_read_attribute_mem(struct dvb_ca_en50221 *ca, -+ int slot, int address) -+{ -+ struct tbscxci_state *state = ca->data; -+ int ret; -+ unsigned char data; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ data = (address & 0xff); -+ ret = tbscxci_i2c_write(state, -+ ((address >> 8) & 0x7f), &data, 1); -+ data = tbscxci_i2c_read(state); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return data; -+} -+ -+int tbscxci_write_attribute_mem(struct dvb_ca_en50221 *ca, -+ int slot, int address, u8 value) -+{ -+ struct tbscxci_state *state = ca->data; -+ int ret; -+ unsigned char data[2]; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ data[0] = (address & 0xff); -+ data[1] = value; -+ ret = tbscxci_i2c_write(state, -+ ((address >> 8) & 0x7f), data, 2); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int tbscxci_set_video_port(struct dvb_ca_en50221 *ca, -+ int slot, int enable) -+{ -+ struct tbscxci_state *state = ca->data; -+ struct cx231xx_dvb *adap = state->priv; -+ unsigned char data; -+ int ret; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ data = enable & 1; -+ ret = tbscxci_i2c_write(state, 0xc0, &data, 1); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ printk("tbscxci: Adapter %d CI slot %sabled\n", -+// adap->fe->dvb->num, -+ adap->adapter.num, -+ enable ? "en" : "dis"); -+ -+ return 0; -+} -+ -+int tbscxci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) -+{ -+ return tbscxci_set_video_port(ca, slot, /* enable */ 0); -+} -+ -+int tbscxci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) -+{ -+ return tbscxci_set_video_port(ca, slot, /* enable */ 1); -+} -+ -+int tbscxci_slot_reset(struct dvb_ca_en50221 *ca, int slot) -+{ -+ struct tbscxci_state *state = ca->data; -+ int ret; -+ unsigned char data; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock (&state->ca_mutex); -+ -+ data = 1; -+ ret = tbscxci_i2c_write(state, 0xc1, &data, 1); -+ msleep (5); -+ -+ data = 0; -+ ret = tbscxci_i2c_write(state, 0xc1, &data, 1); -+ msleep (1400); -+ -+ mutex_unlock (&state->ca_mutex); -+ -+ if (ret != 0) -+ return ret; -+ -+ return 0; -+} -+ -+int tbscxci_poll_slot_status(struct dvb_ca_en50221 *ca, -+ int slot, int open) -+{ -+ struct tbscxci_state *state = ca->data; -+ struct cx231xx_dvb *adap = state->priv; -+ struct cx231xx *dev = adap->adapter.priv; -+ unsigned char data; -+ -+ if (slot != 0) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ cx231xx_get_gpio_bit(dev, dev->gpio_dir, &dev->gpio_val); -+ data = dev->gpio_val >> (state->nr ? 25 : 27); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (data & 1) { -+ return (DVB_CA_EN50221_POLL_CAM_PRESENT | -+ DVB_CA_EN50221_POLL_CAM_READY); -+ } else { -+ return 0; -+ } -+} -+ -+int tbscxci_init(struct cx231xx_dvb *adap, int nr) -+{ -+ struct cx231xx *dev = adap->adapter.priv; -+ struct tbscxci_state *state; -+ int ret; -+ unsigned char data; -+ -+ /* allocate memory for the internal state */ -+ state = kzalloc(sizeof(struct tbscxci_state), GFP_KERNEL); -+ if (state == NULL) { -+ ret = -ENOMEM; -+ goto error1; -+ } -+ -+ adap->adap_priv = state; -+ -+ state->nr = nr; -+ -+ mutex_init(&state->ca_mutex); -+ -+ switch (state->nr) { -+ case 0: -+ state->i2c_adap = &dev->i2c_bus[1].i2c_adap; -+ dev->gpio_dir &= ~(1 << 27); -+ cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); -+ break; -+ case 1: -+ state->i2c_adap = &dev->i2c_bus[2].i2c_adap; -+ dev->gpio_dir &= ~(1 << 25); -+ cx231xx_set_gpio_bit(dev, dev->gpio_dir, dev->gpio_val); -+ break; -+ } -+ -+ state->ca.owner = THIS_MODULE; -+ state->ca.read_attribute_mem = tbscxci_read_attribute_mem; -+ state->ca.write_attribute_mem = tbscxci_write_attribute_mem; -+ state->ca.read_cam_control = tbscxci_read_cam_control; -+ state->ca.write_cam_control = tbscxci_write_cam_control; -+ state->ca.slot_reset = tbscxci_slot_reset; -+ state->ca.slot_shutdown = tbscxci_slot_shutdown; -+ state->ca.slot_ts_enable = tbscxci_slot_ts_enable; -+ state->ca.poll_slot_status = tbscxci_poll_slot_status; -+ state->ca.data = state; -+ state->priv = adap; -+ -+ data = 1; -+ tbscxci_i2c_write(state, 0xc2, &data, 1); -+ data = tbscxci_i2c_read(state); -+ -+ switch (data) { -+ case 0x62: -+ case 0x60: -+ printk("tbscxci: Initializing TBS CX CI#%d slot\n", nr); -+ break; -+ default: -+ ret = -EREMOTEIO; -+ goto error2; -+ } -+ -+ ret = dvb_ca_en50221_init(&adap->adapter, &state->ca, -+ /* flags */ 0, /* n_slots */ 1); -+ if (ret != 0) goto error2; -+ -+ printk("tbscxci: Adapter %d CI slot initialized\n", -+ adap->adapter.num); -+ -+ ret = tbscxci_poll_slot_status(&state->ca, 0, 0); -+ if (0 == ret) -+ tbscxci_set_video_port(&state->ca, /* slot */ 0, /* enable */ 0); -+ -+ return 0; -+ -+error2: -+ //memset (&state->ca, 0, sizeof (state->ca)); -+ kfree(state); -+error1: -+ printk("tbscxci: Adapter %d CI slot initialization failed\n", -+ adap->adapter.num); -+ return ret; -+} -+ -+void tbscxci_release(struct cx231xx_dvb *adap) -+{ -+ struct tbscxci_state *state; -+ -+ if (NULL == adap) return; -+ -+ state = (struct tbscxci_state *)adap->adap_priv; -+ -+ if (NULL == state) return; -+ -+ if (NULL == state->ca.data) return; -+ -+ dvb_ca_en50221_release(&state->ca); -+ //memset(&state->ca, 0, sizeof(state->ca)); -+ kfree(state); -+} -diff --git a/drivers/media/usb/cx231xx/tbscxci.h b/drivers/media/usb/cx231xx/tbscxci.h -new file mode 100644 -index 0000000..f2d52e5 ---- /dev/null -+++ b/drivers/media/usb/cx231xx/tbscxci.h -@@ -0,0 +1,34 @@ -+/* -+ TurboSight TBS CI driver for CX23102 -+ Copyright (C) 2014 Konstantin Dimitrov -+ -+ Copyright (C) 2014 TurboSight.com -+*/ -+ -+#ifndef TBSCXCI_H -+#define TBSCXCI_H -+ -+#include "cx231xx.h" -+ -+#include "dvb_ca_en50221.h" -+ -+extern int tbscxci_read_attribute_mem(struct dvb_ca_en50221 *en50221, -+ int slot, int addr); -+extern int tbscxci_write_attribute_mem(struct dvb_ca_en50221 *en50221, -+ int slot, int addr, u8 data); -+extern int tbscxci_read_cam_control(struct dvb_ca_en50221 *en50221, -+ int slot, u8 addr); -+extern int tbscxci_write_cam_control(struct dvb_ca_en50221 *en50221, -+ int slot, u8 addr, u8 data); -+extern int tbscxci_slot_reset(struct dvb_ca_en50221 *en50221, -+ int slot); -+extern int tbscxci_slot_shutdown(struct dvb_ca_en50221 *en50221, -+ int slot); -+extern int tbscxci_slot_ts_enable(struct dvb_ca_en50221 *en50221, -+ int slot); -+extern int tbscxci_poll_slot_status(struct dvb_ca_en50221 *en50221, -+ int slot, int open); -+extern int tbscxci_init(struct cx231xx_dvb *adap, int nr); -+extern void tbscxci_release(struct cx231xx_dvb *adap); -+ -+#endif -diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig -index 959fa09..803e5b8 100644 ---- a/drivers/media/usb/dvb-usb/Kconfig -+++ b/drivers/media/usb/dvb-usb/Kconfig -@@ -331,3 +331,111 @@ config DVB_USB_TECHNISAT_USB2 - select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT - help - Say Y here to support the Technisat USB2 DVB-S/S2 device -+ -+config DVB_USB_TBSQBOX -+ tristate "TurboSight QBOX DVB-S2 USB2.0 support" -+ depends on DVB_USB -+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STB6000 if MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y here to support the TurboSight QBOX DVB-S USB2.0 receivers -+ -+config DVB_USB_TBSQBOX2 -+ tristate "TurboSight QBOX2 DVB-S2 USB2.0 support" -+ depends on DVB_USB -+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y here to support the TurboSight QBOX2 DVB-S USB2.0 receivers -+ -+config DVB_USB_TBSQBOX22 -+ tristate "TurboSight QBOX22 DVB-S2 USB2.0 support" -+ depends on DVB_USB -+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_TAS2101 if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_AV201X if MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y here to support the TurboSight QBOX22 DVB-S USB2.0 receivers -+ -+ -+config DVB_USB_TBS5922SE -+ tristate "TurboSight 5922SE DVB-S2 USB2.0 support" -+ depends on DVB_USB -+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_TAS2101 if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_AV201X if MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y here to support the TurboSight 5922SE DVB-S USB2.0 receivers -+ -+config DVB_USB_TBSQBOXS2 -+ tristate "TurboSight QBOX2 DVB-S2 USB2.0 support" -+ depends on DVB_USB -+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y here to support the TurboSight QBOX2 DVB-S USB2.0 receivers -+ -+config DVB_USB_TBSQBOX2CI -+ tristate "TurboSight QBOX2 CI DVB-S2 USB2.0 support" -+ depends on DVB_USB -+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y here to support the TurboSight QBOX2 CI DVB-S USB2.0 receivers -+ -+config DVB_USB_TBS5925 -+ tristate "TurboSight TBS5925 DVB-S2 USB2.0 support" -+ depends on DVB_USB -+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y here to support the TurboSight TBS5925 DVB-S USB2.0 receivers -+ -+config DVB_USB_TBS5880 -+ tristate "TurboSight TBS5880 DVB-T/T2/C USB2.0 support" -+ depends on DVB_USB -+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_CXD2820R if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y here to support the TurboSight TBS5880 DVB-T/T2/C USB2.0 receivers -+ -+config DVB_USB_TBS5220 -+ tristate "TurboSight TBS5220 DVB-T/T2/C USB2.0 support" -+ depends on DVB_USB -+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y here to support the TurboSight TBS5220 DVB-T/T2/C USB2.0 receivers -+ -+config DVB_USB_TBS5881 -+ tristate "TurboSight TBS5881 DVB-T/T2/C USB2.0 support" -+ depends on DVB_USB -+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y here to support the TurboSight TBS5881 DVB-T/T2/C USB2.0 receivers -+ -+config DVB_USB_TBS5520 -+ tristate "Turbosight TBS5520 support" -+ depends on DVB_USB -+ select DVB_AVL6882 if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_R848 if MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y here to support the Turbosight TBS5520 USB2 DVB-T/T2/C/S/S2 device -+ -+config DVB_USB_TBS5927 -+ tristate "TurboSight TBS5927 DVB-S2 USB2.0 support" -+ depends on DVB_USB -+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_STV0910 if MEDIA_SUBDRV_AUTOSELECT -+ select MEDIA_TUNER_STV6120 if MEDIA_SUBDRV_AUTOSELECT -+ help -+ Say Y here to support the TurboSight TBS5927 DVB-S USB2.0 receivers -diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile -index 3b3f32b..6b48da0 100644 ---- a/drivers/media/usb/dvb-usb/Makefile -+++ b/drivers/media/usb/dvb-usb/Makefile -@@ -79,6 +79,42 @@ obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o - dvb-usb-technisat-usb2-objs := technisat-usb2.o - obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o - -+dvb-usb-tbsqbox-objs = tbs-qbox.o -+obj-$(CONFIG_DVB_USB_TBSQBOX) += dvb-usb-tbsqbox.o -+ -+dvb-usb-tbsqbox2-objs = tbs-qbox2.o -+obj-$(CONFIG_DVB_USB_TBSQBOX2) += dvb-usb-tbsqbox2.o -+ -+dvb-usb-tbsqbox22-objs = tbs-qbox22.o -+obj-$(CONFIG_DVB_USB_TBSQBOX22) += dvb-usb-tbsqbox22.o -+ -+dvb-usb-tbs5922se-objs = tbs5922se.o -+obj-$(CONFIG_DVB_USB_TBS5922SE) += dvb-usb-tbs5922se.o -+ -+dvb-usb-tbsqboxs2-objs = tbs-qboxs2.o -+obj-$(CONFIG_DVB_USB_TBSQBOXS2) += dvb-usb-tbsqboxs2.o -+ -+dvb-usb-tbsqbox2ci-objs = tbs-qbox2ci.o -+obj-$(CONFIG_DVB_USB_TBSQBOX2CI) += dvb-usb-tbsqbox2ci.o -+ -+dvb-usb-tbs5925-objs = tbs5925.o -+obj-$(CONFIG_DVB_USB_TBS5925) += dvb-usb-tbs5925.o -+ -+dvb-usb-tbs5880-objs = tbs5880.o -+obj-$(CONFIG_DVB_USB_TBS5880) += dvb-usb-tbs5880.o -+ -+dvb-usb-tbs5220-objs = tbs5220.o -+obj-$(CONFIG_DVB_USB_TBS5220) += dvb-usb-tbs5220.o -+ -+dvb-usb-tbs5881-objs = tbs5881.o -+obj-$(CONFIG_DVB_USB_TBS5881) += dvb-usb-tbs5881.o -+ -+dvb-usb-tbs5520-objs := tbs5520.o -+obj-$(CONFIG_DVB_USB_TBS5520) += dvb-usb-tbs5520.o -+ -+dvb-usb-tbs5927-objs = tbs5927.o -+obj-$(CONFIG_DVB_USB_TBS5927) += dvb-usb-tbs5927.o -+ - ccflags-y += -I$(srctree)/drivers/media/dvb-core - ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/ - # due to tuner-xc3028 -diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c -index 9b8771e..7c59c47 100644 ---- a/drivers/media/usb/dvb-usb/cxusb.c -+++ b/drivers/media/usb/dvb-usb/cxusb.c -@@ -1366,8 +1366,6 @@ static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) - return -ENODEV; - } - -- st->i2c_client_demod = client_demod; -- - /* attach tuner */ - memset(&si2157_config, 0, sizeof(si2157_config)); - si2157_config.fe = adap->fe_adap[0].fe; -@@ -1390,6 +1388,7 @@ static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) - return -ENODEV; - } - -+ st->i2c_client_demod = client_demod; - st->i2c_client_tuner = client_tuner; - - /* hook fe: need to resync the slave fifo when signal locks. */ -diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c -index e1be7a3..8ebc26f 100644 ---- a/drivers/media/usb/dvb-usb/dw2102.c -+++ b/drivers/media/usb/dvb-usb/dw2102.c -@@ -2,7 +2,7 @@ - * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, - * TeVii S421, S480, S482, S600, S630, S632, S650, S660, S662, - * Prof 1100, 7500, -- * Geniatech SU3000, T220, -+ * Geniatech SU3000, T220, T220A, - * TechnoTrend S2-4600, - * Terratec Cinergy S2 cards - * Copyright (C) 2008-2012 Igor M. Liplianin (liplianin@me.by) -@@ -33,8 +33,10 @@ - #include "stb6100_proc.h" - #include "m88rs2000.h" - #include "tda18271.h" -+#include "tda18273.h" - #include "cxd2820r.h" - #include "m88ds3103.h" -+#include "ts2020.h" - - /* Max transfer size done by I2C transfer functions */ - #define MAX_XFER_SIZE 64 -@@ -1410,6 +1412,56 @@ static int t220_frontend_attach(struct dvb_usb_adapter *d) - return -EIO; - } - -+static int t220a_frontend_attach(struct dvb_usb_adapter *d) -+{ -+ u8 obuf[3] = { 0xe, 0x87, 0 }; -+ u8 ibuf[] = { 0 }; -+ -+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) -+ err("command 0x0e transfer failed."); -+ -+ obuf[0] = 0xe; -+ obuf[1] = 0x86; -+ obuf[2] = 1; -+ -+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) -+ err("command 0x0e transfer failed."); -+ -+ obuf[0] = 0xe; -+ obuf[1] = 0x80; -+ obuf[2] = 0; -+ -+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) -+ err("command 0x0e transfer failed."); -+ -+ msleep(50); -+ -+ obuf[0] = 0xe; -+ obuf[1] = 0x80; -+ obuf[2] = 1; -+ -+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) -+ err("command 0x0e transfer failed."); -+ -+ obuf[0] = 0x51; -+ -+ if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) -+ err("command 0x51 transfer failed."); -+ -+ d->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config, -+ &d->dev->i2c_adap, NULL); -+ if (d->fe_adap[0].fe != NULL) { -+ if (dvb_attach(tda18273_attach, d->fe_adap[0].fe, -+ &d->dev->i2c_adap, 0x60)) { -+ info("Attached TDA18273/CXD2820R!\n"); -+ return 0; -+ } -+ } -+ -+ info("Failed to attach TDA18273/CXD2820R!\n"); -+ return -EIO; -+} -+ - static int m88rs2000_frontend_attach(struct dvb_usb_adapter *d) - { - u8 obuf[] = { 0x51 }; -@@ -1644,6 +1696,7 @@ enum dw2102_table_entry { - TERRATEC_CINERGY_S2_R4, - GOTVIEW_SAT_HD, - GENIATECH_T220, -+ GENIATECH_T220A, - TECHNOTREND_S2_4600, - TEVII_S482_1, - TEVII_S482_2, -@@ -1674,6 +1727,7 @@ static struct usb_device_id dw2102_table[] = { - [TERRATEC_CINERGY_S2_R4] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R4)}, - [GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)}, - [GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)}, -+ [GENIATECH_T220A] = {USB_DEVICE(0x0572, 0xC686)}, - [TECHNOTREND_S2_4600] = {USB_DEVICE(USB_VID_TECHNOTREND, - USB_PID_TECHNOTREND_CONNECT_S2_4600)}, - [TEVII_S482_1] = {USB_DEVICE(0x9022, 0xd483)}, -@@ -2164,6 +2218,55 @@ static struct dvb_usb_device_properties t220_properties = { - } - }; - -+static struct dvb_usb_device_properties t220a_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .size_of_priv = sizeof(struct dw2102_state), -+ .power_ctrl = su3000_power_ctrl, -+ .num_adapters = 1, -+ .identify_state = su3000_identify_state, -+ .i2c_algo = &su3000_i2c_algo, -+ -+ .rc.core = { -+ .rc_interval = 150, -+ .rc_codes = RC_MAP_SU3000, -+ .module_name = "dw2102", -+ .allowed_protos = RC_BIT_RC5, -+ .rc_query = su3000_rc_query, -+ }, -+ -+ .read_mac_address = su3000_read_mac_address, -+ -+ .generic_bulk_ctrl_endpoint = 0x01, -+ -+ .adapter = { -+ { -+ .num_frontends = 1, -+ .fe = { { -+ .streaming_ctrl = su3000_streaming_ctrl, -+ .frontend_attach = t220a_frontend_attach, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ } -+ } }, -+ } -+ }, -+ .num_device_descs = 1, -+ .devices = { -+ { "Geniatech T220A DVB-T/T2 USB2.0", -+ { &dw2102_table[GENIATECH_T220A], NULL }, -+ { NULL }, -+ }, -+ } -+}; -+ - static struct dvb_usb_device_properties tt_s2_4600_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - .usb_ctrl = DEVICE_SPECIFIC, -@@ -2304,6 +2407,8 @@ static int dw2102_probe(struct usb_interface *intf, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &t220_properties, - THIS_MODULE, NULL, adapter_nr) || -+ 0 == dvb_usb_device_init(intf, &t220a_properties, -+ THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &tt_s2_4600_properties, - THIS_MODULE, NULL, adapter_nr)) - return 0; -@@ -2346,9 +2451,10 @@ module_usb_driver(dw2102_driver); - MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); - MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," - " DVB-C 3101 USB2.0," -- " TeVii S421, S480, S482, S600, S630, S632, S650," -+ " TeVii S421, S480, S482, S600, S630, S632, S650, S660" - " TeVii S660, S662, Prof 1100, 7500 USB2.0," -- " Geniatech SU3000, T220," -+ " Prof 1100, 7500 USB2.0," -+ " Geniatech SU3000, T220, T220A," - " TechnoTrend S2-4600, Terratec Cinergy S2 devices"); - MODULE_VERSION("0.1"); - MODULE_LICENSE("GPL"); -diff --git a/drivers/media/usb/dvb-usb/tbs-qbox.c b/drivers/media/usb/dvb-usb/tbs-qbox.c -new file mode 100644 -index 0000000..89d665b ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs-qbox.c -@@ -0,0 +1,514 @@ -+/* DVB USB framework compliant Linux driver for the -+* TBS QBOX -+* -+* Copyright (C) 2008 Bob Liu (Bob@Turbosight.com) -+* Igor M. Liplianin (liplianin@me.by) -+* -+* Konstantin Dimitrov -+* June 2009 -+* Some fixes and improvements. -+* -+* This program is free software; you can redistribute it and/or modify it -+* under the terms of the GNU General Public License as published by the -+* Free Software Foundation, version 2. -+* -+* see Documentation/dvb/README.dvb-usb for more information -+*/ -+#include -+#include "tbs-qbox.h" -+#include "stv0299.h" -+#include "stv0288.h" -+#include "stb6000.h" -+ -+#define TBSQBOX_READ_MSG 0 -+#define TBSQBOX_WRITE_MSG 1 -+ -+/* on my own*/ -+#define TBSQBOX_VOLTAGE_CTRL (0x1800) -+#define TBSQBOX_RC_QUERY (0x1a00) -+#define TBSQBOX_LED_CTRL (0x1b00) -+ -+struct tbsqboxs1_state { -+ u32 last_key_pressed; -+}; -+struct tbsqboxs1_rc_keys { -+ u32 keycode; -+ u32 event; -+}; -+ -+/* debug */ -+static int dvb_usb_tbsqboxs1_debug; -+module_param_named(debug, dvb_usb_tbsqboxs1_debug, int, 0644); -+MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS); -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+static int tbsqboxs1_op_rw(struct usb_device *dev, u8 request, u16 value, -+ u16 index, u8 * data, u16 len, int flags) -+{ -+ int ret; -+ u8 u8buf[len]; -+ -+ unsigned int pipe = (flags == TBSQBOX_READ_MSG) ? -+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); -+ u8 request_type = (flags == TBSQBOX_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; -+ -+ if (flags == TBSQBOX_WRITE_MSG) -+ memcpy(u8buf, data, len); -+ ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, -+ value, index , u8buf, len, 2000); -+ -+ if (flags == TBSQBOX_READ_MSG) -+ memcpy(data, u8buf, len); -+ return ret; -+} -+ -+/* I2C */ -+static int tbsqboxs1_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], -+ int num) -+{ -+struct dvb_usb_device *d = i2c_get_adapdata(adap); -+ int i = 0; -+ u8 buf6[20]; -+ u8 inbuf[20]; -+ -+ if (!d) -+ return -ENODEV; -+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) -+ return -EAGAIN; -+ -+ switch (num) { -+ case 2: -+ -+ buf6[0]=msg[1].len;//lenth -+ buf6[1]=msg[0].addr<<1;//demod addr -+ buf6[2]=msg[0].buf[0];//register -+ -+ tbsqboxs1_op_rw(d->udev, 0x90, 0, 0, -+ buf6, 3, TBSQBOX_WRITE_MSG); -+ msleep(5); -+ tbsqboxs1_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, msg[1].len, TBSQBOX_READ_MSG); -+ memcpy(msg[1].buf, inbuf, msg[1].len); -+ break; -+ case 1: -+ switch (msg[0].addr) { -+ case 0x68: -+ /* write to stv0299 register */ -+ buf6[0] = msg[0].len+1;//lenth -+ buf6[1] = msg[0].addr<<1;//demod addr -+ for(i=0;iudev, 0x80, 0, 0, -+ buf6, msg[0].len+2, TBSQBOX_WRITE_MSG); -+ msleep(3); -+ break; -+ case 0x61: -+ case 0x60: -+ if (msg[0].flags == 0) { -+ /* write to tuner pll */ -+ buf6[0] = msg[0].len+1;//lenth -+ buf6[1] = msg[0].addr<<1;//tuner addr -+ for(i=0;iudev, 0x80, 0, 0, -+ buf6, msg[0].len+2, TBSQBOX_WRITE_MSG); -+ } -+ msleep(3); -+ break; -+ case (TBSQBOX_RC_QUERY): -+ tbsqboxs1_op_rw(d->udev, 0xb8, 0, 0, -+ buf6, 4, TBSQBOX_READ_MSG); -+ msg[0].buf[0] = buf6[2]; -+ msg[0].buf[1] = buf6[3]; -+ msleep(3); -+ //info("TBSQBOX_RC_QUERY %x %x %x %x\n",buf6[0],buf6[1],buf6[2],buf6[3]); -+ break; -+ case (TBSQBOX_VOLTAGE_CTRL): -+ buf6[0] = 3; -+ buf6[1] = msg[0].buf[0]; -+ tbsqboxs1_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBSQBOX_WRITE_MSG); -+ break; -+ case (TBSQBOX_LED_CTRL): -+ buf6[0] = 5; -+ buf6[1] = msg[0].buf[0]; -+ tbsqboxs1_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBSQBOX_WRITE_MSG); -+ break; -+ } -+ -+ break; -+ } -+ -+ mutex_unlock(&d->i2c_mutex); -+ return num; -+} -+ -+static u32 tbsqboxs1_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C; -+} -+ -+static void tbsqboxs1_led_ctrl(struct dvb_frontend *fe, int offon) -+{ -+ static u8 led_off[] = { 0 }; -+ static u8 led_on[] = { 1 }; -+ struct i2c_msg msg = { -+ .addr = TBSQBOX_LED_CTRL, -+ .flags = 0, -+ .buf = led_off, -+ .len = 1 -+ }; -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ -+ if (offon) -+ msg.buf = led_on; -+ i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); -+} -+ -+ -+static struct stv0288_config earda_config = { -+ .demod_address = 0x68, -+ .set_lock_led = tbsqboxs1_led_ctrl, -+}; -+ -+static struct i2c_algorithm tbsqboxs1_i2c_algo = { -+ .master_xfer = tbsqboxs1_i2c_transfer, -+ .functionality = tbsqboxs1_i2c_func, -+}; -+ -+static int tbsqboxs1_earda_tuner_attach(struct dvb_usb_adapter *adap) -+{ -+ if (!dvb_attach(stb6000_attach, adap->fe_adap->fe, 0x61, -+ &adap->dev->i2c_adap)) -+ return -EIO; -+ -+ return 0; -+} -+static int tbsqboxs1_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -+{ -+ int i,ret; -+ u8 ibuf[3] = {0, 0,0}; -+ u8 eeprom[256], eepromline[16]; -+ -+ for (i = 0; i < 256; i++) { -+ ibuf[0]=1;//lenth -+ ibuf[1]=0xa0;//eeprom addr -+ ibuf[2]=i;//register -+ ret = tbsqboxs1_op_rw(d->udev, 0x90, 0, 0, -+ ibuf, 3, TBSQBOX_WRITE_MSG); -+ ret = tbsqboxs1_op_rw(d->udev, 0x91, 0, 0, -+ ibuf, 1, TBSQBOX_READ_MSG); -+ if (ret < 0) { -+ err("read eeprom failed."); -+ return -1; -+ } else { -+ eepromline[i%16] = ibuf[0]; -+ eeprom[i] = ibuf[0]; -+ } -+ -+ if ((i % 16) == 15) { -+ deb_xfer("%02x: ", i - 15); -+ debug_dump(eepromline, 16, deb_xfer); -+ } -+ } -+ memcpy(mac, eeprom + 16, 6); -+ return 0; -+}; -+ -+static int tbsqboxs1_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) -+{ -+ static u8 command_13v[1] = {0x00}; -+ static u8 command_18v[1] = {0x01}; -+ struct i2c_msg msg[] = { -+ {.addr = TBSQBOX_VOLTAGE_CTRL, .flags = 0, -+ .buf = command_13v, .len = 1}, -+ }; -+ -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ if (voltage == SEC_VOLTAGE_18) -+ msg[0].buf = command_18v; -+ //info("tbsqboxs1_set_voltage %d",voltage); -+ i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1); -+ return 0; -+} -+ -+static struct dvb_usb_device_properties tbsqboxs1_properties; -+ -+static int tbsqboxs1_frontend_attach(struct dvb_usb_adapter *d) -+{ -+ struct dvb_usb_device *u = d->dev; -+ u8 buf[20]; -+ -+ if (tbsqboxs1_properties.adapter->fe->tuner_attach == &tbsqboxs1_earda_tuner_attach) { -+ d->fe_adap->fe = dvb_attach(stv0288_attach, &earda_config, -+ &u->i2c_adap); -+ if (d->fe_adap->fe != NULL) { -+ d->fe_adap->fe->ops.set_voltage = tbsqboxs1_set_voltage; -+ -+ buf[0] = 7; -+ buf[1] = 1; -+ tbsqboxs1_op_rw(u->udev, 0x8a, 0, 0, -+ buf, 2, TBSQBOX_WRITE_MSG); -+ -+ strlcpy(d->fe_adap->fe->ops.info.name,u->props.devices[0].name,52); -+ return 0; -+ } -+ } -+ -+ return -EIO; -+} -+ -+ -+ -+static struct rc_map_table tbsqboxs1_rc_keys[] = { -+ { 0xff84, KEY_POWER2}, /* power */ -+ { 0xff94, KEY_MUTE}, /* mute */ -+ { 0xff87, KEY_1}, -+ { 0xff86, KEY_2}, -+ { 0xff85, KEY_3}, -+ { 0xff8b, KEY_4}, -+ { 0xff8a, KEY_5}, -+ { 0xff89, KEY_6}, -+ { 0xff8f, KEY_7}, -+ { 0xff8e, KEY_8}, -+ { 0xff8d, KEY_9}, -+ { 0xff92, KEY_0}, -+ { 0xff96, KEY_CHANNELUP}, /* ch+ */ -+ { 0xff91, KEY_CHANNELDOWN}, /* ch- */ -+ { 0xff93, KEY_VOLUMEUP}, /* vol+ */ -+ { 0xff8c, KEY_VOLUMEDOWN}, /* vol- */ -+ { 0xff83, KEY_RECORD}, /* rec */ -+ { 0xff98, KEY_PAUSE}, /* pause, yellow */ -+ { 0xff99, KEY_OK}, /* ok */ -+ { 0xff9a, KEY_CAMERA}, /* snapshot */ -+ { 0xff81, KEY_UP}, -+ { 0xff90, KEY_LEFT}, -+ { 0xff82, KEY_RIGHT}, -+ { 0xff88, KEY_DOWN}, -+ { 0xff95, KEY_FAVORITES}, /* blue */ -+ { 0xff97, KEY_SUBTITLE}, /* green */ -+ { 0xff9d, KEY_ZOOM}, -+ { 0xff9f, KEY_EXIT}, -+ { 0xff9e, KEY_MENU}, -+ { 0xff9c, KEY_EPG}, -+ { 0xff80, KEY_PREVIOUS}, /* red */ -+ { 0xff9b, KEY_MODE}, -+ { 0xffdd, KEY_TV }, -+ { 0xffde, KEY_PLAY }, -+ { 0xffdc, KEY_STOP }, -+ { 0xffdb, KEY_REWIND }, -+ { 0xffda, KEY_FASTFORWARD }, -+ { 0xffd9, KEY_PREVIOUS }, /* replay */ -+ { 0xffd8, KEY_NEXT }, /* skip */ -+ { 0xffd1, KEY_NUMERIC_STAR }, -+ { 0xffd2, KEY_NUMERIC_POUND }, -+ { 0xffd4, KEY_DELETE }, /* clear */ -+}; -+ -+ -+ -+static int tbsqboxs1_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -+{ -+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; -+ int keymap_size = d->props.rc.legacy.rc_map_size; -+ -+ struct tbsqboxs1_state *st = d->priv; -+ u8 key[2]; -+ struct i2c_msg msg[] = { -+ {.addr = TBSQBOX_RC_QUERY, .flags = I2C_M_RD, .buf = key, -+ .len = 2}, -+ }; -+ int i; -+ -+ *state = REMOTE_NO_KEY_PRESSED; -+ if (tbsqboxs1_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { -+ //info("key: %x %x\n",msg[0].buf[0],msg[0].buf[1]); -+ for (i = 0; i < keymap_size; i++) { -+ if (rc5_data(&keymap[i]) == msg[0].buf[1]) { -+ *state = REMOTE_KEY_PRESSED; -+ *event = keymap[i].keycode; -+ st->last_key_pressed = -+ keymap[i].keycode; -+ break; -+ } -+ st->last_key_pressed = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct usb_device_id tbsqboxs1_table[] = { -+ {USB_DEVICE(0x734c, 0x2601)}, -+ {USB_DEVICE(0x734c, 0x5910)}, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(usb, tbsqboxs1_table); -+ -+static int tbsqboxs1_load_firmware(struct usb_device *dev, -+ const struct firmware *frmwr) -+{ -+ u8 *b, *p; -+ int ret = 0, i; -+ u8 reset; -+ const struct firmware *fw; -+ const char *filename = "dvb-usb-tbsqbox-id2601.fw"; -+ switch (dev->descriptor.idProduct) { -+ case 0x2601: -+ ret = request_firmware(&fw, filename, &dev->dev); -+ if (ret != 0) { -+ err("did not find the firmware file. (%s) " -+ "Please see linux/Documentation/dvb/ for more details " -+ "on firmware-problems.", filename); -+ return ret; -+ } -+ break; -+ case 0x5910: -+ ret = request_firmware(&fw, tbsqboxs1_properties.firmware, &dev->dev); -+ if (ret != 0) { -+ err("did not find the firmware file. (%s) " -+ "Please see linux/Documentation/dvb/ for more details " -+ "on firmware-problems.", tbsqboxs1_properties.firmware); -+ return ret; -+ } -+ break; -+ default: -+ fw = frmwr; -+ break; -+ } -+ info("start downloading TBSQBOX firmware"); -+ p = kmalloc(fw->size, GFP_KERNEL); -+ reset = 1; -+ /*stop the CPU*/ -+ tbsqboxs1_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, TBSQBOX_WRITE_MSG); -+ tbsqboxs1_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, TBSQBOX_WRITE_MSG); -+ -+ if (p != NULL) { -+ memcpy(p, fw->data, fw->size); -+ for (i = 0; i < fw->size; i += 0x40) { -+ b = (u8 *) p + i; -+ if (tbsqboxs1_op_rw(dev, 0xa0, i, 0, b , 0x40, -+ TBSQBOX_WRITE_MSG) != 0x40) { -+ err("error while transferring firmware"); -+ ret = -EINVAL; -+ break; -+ } -+ } -+ /* restart the CPU */ -+ reset = 0; -+ if (ret || tbsqboxs1_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, -+ TBSQBOX_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ if (ret || tbsqboxs1_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, -+ TBSQBOX_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ -+ msleep(100); -+ kfree(p); -+ } -+ return ret; -+} -+ -+static struct dvb_usb_device_properties tbsqboxs1_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .firmware = "dvb-usb-tbsqbox-id5910.fw", -+ .size_of_priv = sizeof(struct tbsqboxs1_state), -+ .no_reconnect = 1, -+ -+ .i2c_algo = &tbsqboxs1_i2c_algo, -+ .rc.legacy = { -+ .rc_map_table = tbsqboxs1_rc_keys, -+ .rc_map_size = ARRAY_SIZE(tbsqboxs1_rc_keys), -+ .rc_interval = 150, -+ .rc_query = tbsqboxs1_rc_query, -+ }, -+ -+ .generic_bulk_ctrl_endpoint = 0x81, -+ /* parameter for the MPEG2-data transfer */ -+ .num_adapters = 1, -+ .download_firmware = tbsqboxs1_load_firmware, -+ .read_mac_address = tbsqboxs1_read_mac_address, -+ .adapter = {{ -+ .num_frontends = 1, -+ .fe = {{ -+ .frontend_attach = tbsqboxs1_frontend_attach, -+ .streaming_ctrl = NULL, -+ .tuner_attach = tbsqboxs1_earda_tuner_attach, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ }, -+ } }, -+ } }, -+ -+ .num_device_descs = 2, -+ .devices = { -+ {"TurboSight TBS QBOX DVB-S", -+ {&tbsqboxs1_table[0], NULL}, -+ {NULL}, -+ }, -+ {"TurboSight TBS QBOX DVB-S", -+ {&tbsqboxs1_table[1], NULL}, -+ {NULL}, -+ } -+ } -+}; -+ -+static int tbsqboxs1_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ if (0 == dvb_usb_device_init(intf, &tbsqboxs1_properties, -+ THIS_MODULE, NULL, adapter_nr)) { -+ return 0; -+ } -+ return -ENODEV; -+} -+ -+static struct usb_driver tbsqboxs1_driver = { -+ .name = "tbsqboxs1", -+ .probe = tbsqboxs1_probe, -+ .disconnect = dvb_usb_device_exit, -+ .id_table = tbsqboxs1_table, -+}; -+ -+static int __init tbsqboxs1_module_init(void) -+{ -+ int ret = usb_register(&tbsqboxs1_driver); -+ if (ret) -+ err("usb_register failed. Error number %d", ret); -+ -+ return ret; -+} -+ -+static void __exit tbsqboxs1_module_exit(void) -+{ -+ usb_deregister(&tbsqboxs1_driver); -+} -+ -+module_init(tbsqboxs1_module_init); -+module_exit(tbsqboxs1_module_exit); -+ -+MODULE_AUTHOR("Bob Liu "); -+MODULE_DESCRIPTION("Driver for TBS QBOX"); -+MODULE_VERSION("0.1"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/usb/dvb-usb/tbs-qbox.h b/drivers/media/usb/dvb-usb/tbs-qbox.h -new file mode 100644 -index 0000000..4c8cdcc ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs-qbox.h -@@ -0,0 +1,8 @@ -+#ifndef _TBSQBOX_H_ -+#define _TBSQBOX_H_ -+ -+#define DVB_USB_LOG_PREFIX "tbsqboxs1" -+#include "dvb-usb.h" -+ -+#define deb_xfer(args...) dprintk(dvb_usb_tbsqboxs1_debug, 0x02, args) -+#endif -diff --git a/drivers/media/usb/dvb-usb/tbs-qbox2.c b/drivers/media/usb/dvb-usb/tbs-qbox2.c -new file mode 100644 -index 0000000..fe46f02 ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs-qbox2.c -@@ -0,0 +1,519 @@ -+/* DVB USB framework compliant Linux driver for the -+* TBS QBOX -+* -+* Copyright (C) 2008 Bob Liu (Bob@Turbosight.com) -+* Igor M. Liplianin (liplianin@me.by) -+* -+* Konstantin Dimitrov -+* August 2009 -+* Add QBOX II STV0903 support -+* -+* This program is free software; you can redistribute it and/or modify it -+* under the terms of the GNU General Public License as published by the -+* Free Software Foundation, version 2. -+* -+* see Documentation/dvb/README.dvb-usb for more information -+*/ -+#include -+#include "tbs-qbox2.h" -+#include "stv6110x.h" -+#include "stv090x.h" -+#include "stb6100.h" -+#include "stb6100_cfg.h" -+ -+#define TBSQBOX_READ_MSG 0 -+#define TBSQBOX_WRITE_MSG 1 -+ -+/* on my own*/ -+#define TBSQBOX_VOLTAGE_CTRL (0x1800) -+#define TBSQBOX_RC_QUERY (0x1a00) -+#define TBSQBOX_LED_CTRL (0x1b00) -+ -+struct tbsqbox2_state { -+ u32 last_key_pressed; -+}; -+struct tbsqbox2_rc_keys { -+ u32 keycode; -+ u32 event; -+}; -+ -+/* debug */ -+static int dvb_usb_tbsqbox2_debug; -+module_param_named(debug, dvb_usb_tbsqbox2_debug, int, 0644); -+MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS); -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+static int tbsqbox2_op_rw(struct usb_device *dev, u8 request, u16 value, -+ u16 index, u8 * data, u16 len, int flags) -+{ -+ int ret; -+ u8 u8buf[len]; -+ -+ unsigned int pipe = (flags == TBSQBOX_READ_MSG) ? -+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); -+ u8 request_type = (flags == TBSQBOX_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; -+ -+ if (flags == TBSQBOX_WRITE_MSG) -+ memcpy(u8buf, data, len); -+ ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, -+ value, index , u8buf, len, 2000); -+ -+ if (flags == TBSQBOX_READ_MSG) -+ memcpy(data, u8buf, len); -+ return ret; -+} -+ -+/* I2C */ -+static int tbsqbox2_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], -+ int num) -+{ -+struct dvb_usb_device *d = i2c_get_adapdata(adap); -+ int i = 0; -+ u8 buf6[20]; -+ u8 inbuf[20]; -+ -+ if (!d) -+ return -ENODEV; -+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) -+ return -EAGAIN; -+ -+ switch (num) { -+ case 2: -+ buf6[0]=msg[1].len;//lenth -+ buf6[1]=msg[0].addr<<1;//demod addr -+ //register -+ buf6[2] = msg[0].buf[0]; -+ buf6[3] = msg[0].buf[1]; -+ -+ tbsqbox2_op_rw(d->udev, 0x92, 0, 0, -+ buf6, 4, TBSQBOX_WRITE_MSG); -+ //msleep(5); -+ tbsqbox2_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, msg[1].len, TBSQBOX_READ_MSG); -+ memcpy(msg[1].buf, inbuf, msg[1].len); -+ break; -+ case 1: -+ switch (msg[0].addr) { -+ case 0x6a: -+ case 0x61: -+ case 0x60: -+ if (msg[0].flags == 0) { -+ buf6[0] = msg[0].len+1;//lenth -+ buf6[1] = msg[0].addr<<1;//addr -+ for(i=0;iudev, 0x80, 0, 0, -+ buf6, msg[0].len+2, TBSQBOX_WRITE_MSG); -+ } else { -+ buf6[0] = msg[0].len;//length -+ buf6[1] = msg[0].addr<<1;//addr -+ buf6[2] = 0x00; -+ tbsqbox2_op_rw(d->udev, 0x90, 0, 0, -+ buf6, 3, TBSQBOX_WRITE_MSG); -+ //msleep(5); -+ tbsqbox2_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, buf6[0], TBSQBOX_READ_MSG); -+ memcpy(msg[0].buf, inbuf, msg[0].len); -+ } -+ //msleep(3); -+ break; -+ case (TBSQBOX_RC_QUERY): -+ tbsqbox2_op_rw(d->udev, 0xb8, 0, 0, -+ buf6, 4, TBSQBOX_READ_MSG); -+ msg[0].buf[0] = buf6[2]; -+ msg[0].buf[1] = buf6[3]; -+ msleep(3); -+ //info("TBSQBOX_RC_QUERY %x %x %x %x\n",buf6[0],buf6[1],buf6[2],buf6[3]); -+ break; -+ case (TBSQBOX_VOLTAGE_CTRL): -+ buf6[0] = 3; -+ buf6[1] = msg[0].buf[0]; -+ tbsqbox2_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBSQBOX_WRITE_MSG); -+ break; -+ case (TBSQBOX_LED_CTRL): -+ buf6[0] = 5; -+ buf6[1] = msg[0].buf[0]; -+ tbsqbox2_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBSQBOX_WRITE_MSG); -+ break; -+ } -+ -+ break; -+ } -+ -+ mutex_unlock(&d->i2c_mutex); -+ return num; -+} -+ -+static u32 tbsqbox2_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C; -+} -+ -+static void tbsqbox2_led_ctrl(struct dvb_frontend *fe, int offon) -+{ -+ static u8 led_off[] = { 0 }; -+ static u8 led_on[] = { 1 }; -+ struct i2c_msg msg = { -+ .addr = TBSQBOX_LED_CTRL, -+ .flags = 0, -+ .buf = led_off, -+ .len = 1 -+ }; -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ -+ if (offon) -+ msg.buf = led_on; -+ i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); -+} -+ -+static struct stv090x_config earda_config = { -+ .device = STV0903, -+ .demod_mode = STV090x_SINGLE, -+ .clk_mode = STV090x_CLK_EXT, -+ -+ .xtal = 27000000, -+ .address = 0x6a, -+ -+ .ts1_mode = STV090x_TSMODE_DVBCI, -+ .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, -+ -+ .repeater_level = STV090x_RPTLEVEL_16, -+ -+ .tuner_get_frequency = stb6100_get_frequency, -+ .tuner_set_frequency = stb6100_set_frequency, -+ .tuner_set_bandwidth = stb6100_set_bandwidth, -+ .tuner_get_bandwidth = stb6100_get_bandwidth, -+ -+ .set_lock_led = tbsqbox2_led_ctrl, -+}; -+ -+static struct stb6100_config qbox2_stb6100_config = { -+ .tuner_address = 0x60, -+ .refclock = 27000000, -+}; -+ -+static struct i2c_algorithm tbsqbox2_i2c_algo = { -+ .master_xfer = tbsqbox2_i2c_transfer, -+ .functionality = tbsqbox2_i2c_func, -+}; -+ -+static int tbsqbox2_earda_tuner_attach(struct dvb_usb_adapter *adap) -+{ -+ if (!dvb_attach(stb6100_attach, adap->fe_adap->fe, &qbox2_stb6100_config, -+ &adap->dev->i2c_adap)) -+ return -EIO; -+ -+ return 0; -+} -+static int tbsqbox2_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -+{ -+ int i,ret; -+ u8 ibuf[3] = {0, 0,0}; -+ u8 eeprom[256], eepromline[16]; -+ -+ for (i = 0; i < 256; i++) { -+ ibuf[0]=1;//lenth -+ ibuf[1]=0xa0;//eeprom addr -+ ibuf[2]=i;//register -+ ret = tbsqbox2_op_rw(d->udev, 0x90, 0, 0, -+ ibuf, 3, TBSQBOX_WRITE_MSG); -+ ret = tbsqbox2_op_rw(d->udev, 0x91, 0, 0, -+ ibuf, 1, TBSQBOX_READ_MSG); -+ if (ret < 0) { -+ err("read eeprom failed."); -+ return -1; -+ } else { -+ eepromline[i%16] = ibuf[0]; -+ eeprom[i] = ibuf[0]; -+ } -+ -+ if ((i % 16) == 15) { -+ deb_xfer("%02x: ", i - 15); -+ debug_dump(eepromline, 16, deb_xfer); -+ } -+ } -+ memcpy(mac, eeprom + 16, 6); -+ return 0; -+}; -+ -+static int tbsqbox2_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) -+{ -+ static u8 command_13v[1] = {0x00}; -+ static u8 command_18v[1] = {0x01}; -+ struct i2c_msg msg[] = { -+ {.addr = TBSQBOX_VOLTAGE_CTRL, .flags = 0, -+ .buf = command_13v, .len = 1}, -+ }; -+ -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ if (voltage == SEC_VOLTAGE_18) -+ msg[0].buf = command_18v; -+ //info("tbsqbox2_set_voltage %d",voltage); -+ i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1); -+ return 0; -+} -+ -+static struct dvb_usb_device_properties tbsqbox2_properties; -+ -+static int tbsqbox2_frontend_attach(struct dvb_usb_adapter *d) -+{ -+ struct dvb_usb_device *u = d->dev; -+ u8 buf[20]; -+ -+ if (tbsqbox2_properties.adapter->fe->tuner_attach == &tbsqbox2_earda_tuner_attach) { -+ d->fe_adap->fe = dvb_attach(stv090x_attach, &earda_config, -+ &u->i2c_adap, STV090x_DEMODULATOR_0); -+ if (d->fe_adap->fe != NULL) { -+ d->fe_adap->fe->ops.set_voltage = tbsqbox2_set_voltage; -+ -+ buf[0] = 7; -+ buf[1] = 1; -+ tbsqbox2_op_rw(u->udev, 0x8a, 0, 0, -+ buf, 2, TBSQBOX_WRITE_MSG); -+ -+ strlcpy(d->fe_adap->fe->ops.info.name,u->props.devices[0].name,52); -+ return 0; -+ } -+ } -+ -+ return -EIO; -+} -+ -+ -+ -+static struct rc_map_table tbsqbox2_rc_keys[] = { -+ { 0xff84, KEY_POWER2}, /* power */ -+ { 0xff94, KEY_MUTE}, /* mute */ -+ { 0xff87, KEY_1}, -+ { 0xff86, KEY_2}, -+ { 0xff85, KEY_3}, -+ { 0xff8b, KEY_4}, -+ { 0xff8a, KEY_5}, -+ { 0xff89, KEY_6}, -+ { 0xff8f, KEY_7}, -+ { 0xff8e, KEY_8}, -+ { 0xff8d, KEY_9}, -+ { 0xff92, KEY_0}, -+ { 0xff96, KEY_CHANNELUP}, /* ch+ */ -+ { 0xff91, KEY_CHANNELDOWN}, /* ch- */ -+ { 0xff93, KEY_VOLUMEUP}, /* vol+ */ -+ { 0xff8c, KEY_VOLUMEDOWN}, /* vol- */ -+ { 0xff83, KEY_RECORD}, /* rec */ -+ { 0xff98, KEY_PAUSE}, /* pause, yellow */ -+ { 0xff99, KEY_OK}, /* ok */ -+ { 0xff9a, KEY_CAMERA}, /* snapshot */ -+ { 0xff81, KEY_UP}, -+ { 0xff90, KEY_LEFT}, -+ { 0xff82, KEY_RIGHT}, -+ { 0xff88, KEY_DOWN}, -+ { 0xff95, KEY_FAVORITES}, /* blue */ -+ { 0xff97, KEY_SUBTITLE}, /* green */ -+ { 0xff9d, KEY_ZOOM}, -+ { 0xff9f, KEY_EXIT}, -+ { 0xff9e, KEY_MENU}, -+ { 0xff9c, KEY_EPG}, -+ { 0xff80, KEY_PREVIOUS}, /* red */ -+ { 0xff9b, KEY_MODE}, -+ { 0xffdd, KEY_TV }, -+ { 0xffde, KEY_PLAY }, -+ { 0xffdc, KEY_STOP }, -+ { 0xffdb, KEY_REWIND }, -+ { 0xffda, KEY_FASTFORWARD }, -+ { 0xffd9, KEY_PREVIOUS }, /* replay */ -+ { 0xffd8, KEY_NEXT }, /* skip */ -+ { 0xffd1, KEY_NUMERIC_STAR }, -+ { 0xffd2, KEY_NUMERIC_POUND }, -+ { 0xffd4, KEY_DELETE }, /* clear */ -+}; -+ -+ -+ -+static int tbsqbox2_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -+{ -+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; -+ int keymap_size = d->props.rc.legacy.rc_map_size; -+ -+ struct tbsqbox2_state *st = d->priv; -+ u8 key[2]; -+ struct i2c_msg msg[] = { -+ {.addr = TBSQBOX_RC_QUERY, .flags = I2C_M_RD, .buf = key, -+ .len = 2}, -+ }; -+ int i; -+ -+ *state = REMOTE_NO_KEY_PRESSED; -+ if (tbsqbox2_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { -+ //info("key: %x %x\n",msg[0].buf[0],msg[0].buf[1]); -+ for (i = 0; i < keymap_size; i++) { -+ if (rc5_data(&keymap[i]) == msg[0].buf[1]) { -+ *state = REMOTE_KEY_PRESSED; -+ *event = keymap[i].keycode; -+ st->last_key_pressed = -+ keymap[i].keycode; -+ break; -+ } -+ st->last_key_pressed = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct usb_device_id tbsqbox2_table[] = { -+ {USB_DEVICE(0x734c, 0x2601)}, -+ {USB_DEVICE(0x734c, 0x5920)}, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(usb, tbsqbox2_table); -+ -+static int tbsqbox2_load_firmware(struct usb_device *dev, -+ const struct firmware *frmwr) -+{ -+ u8 *b, *p; -+ int ret = 0, i; -+ u8 reset; -+ const struct firmware *fw; -+ switch (dev->descriptor.idProduct) { -+ case 0x5920: -+ ret = request_firmware(&fw, tbsqbox2_properties.firmware, &dev->dev); -+ if (ret != 0) { -+ err("did not find the firmware file. (%s) " -+ "Please see linux/Documentation/dvb/ for more details " -+ "on firmware-problems.", tbsqbox2_properties.firmware); -+ return ret; -+ } -+ break; -+ default: -+ fw = frmwr; -+ break; -+ } -+ info("start downloading TBSQBOX2 firmware"); -+ p = kmalloc(fw->size, GFP_KERNEL); -+ reset = 1; -+ /*stop the CPU*/ -+ tbsqbox2_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, TBSQBOX_WRITE_MSG); -+ tbsqbox2_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, TBSQBOX_WRITE_MSG); -+ -+ if (p != NULL) { -+ memcpy(p, fw->data, fw->size); -+ for (i = 0; i < fw->size; i += 0x40) { -+ b = (u8 *) p + i; -+ if (tbsqbox2_op_rw(dev, 0xa0, i, 0, b , 0x40, -+ TBSQBOX_WRITE_MSG) != 0x40) { -+ err("error while transferring firmware"); -+ ret = -EINVAL; -+ break; -+ } -+ } -+ /* restart the CPU */ -+ reset = 0; -+ if (ret || tbsqbox2_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, -+ TBSQBOX_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ if (ret || tbsqbox2_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, -+ TBSQBOX_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ -+ msleep(100); -+ kfree(p); -+ } -+ return ret; -+} -+ -+static struct dvb_usb_device_properties tbsqbox2_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .firmware = "dvb-usb-tbsqbox-id5920.fw", -+ .size_of_priv = sizeof(struct tbsqbox2_state), -+ .no_reconnect = 1, -+ -+ .i2c_algo = &tbsqbox2_i2c_algo, -+ .rc.legacy = { -+ .rc_map_table = tbsqbox2_rc_keys, -+ .rc_map_size = ARRAY_SIZE(tbsqbox2_rc_keys), -+ .rc_interval = 150, -+ .rc_query = tbsqbox2_rc_query, -+ }, -+ -+ .generic_bulk_ctrl_endpoint = 0x81, -+ /* parameter for the MPEG2-data transfer */ -+ .num_adapters = 1, -+ .download_firmware = tbsqbox2_load_firmware, -+ .read_mac_address = tbsqbox2_read_mac_address, -+ .adapter = {{ -+ .num_frontends = 1, -+ .fe = {{ -+ .frontend_attach = tbsqbox2_frontend_attach, -+ .streaming_ctrl = NULL, -+ .tuner_attach = tbsqbox2_earda_tuner_attach, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ }, -+ } }, -+ } }, -+ -+ .num_device_descs = 1, -+ .devices = { -+ {"TurboSight TBS QBOX2 DVB-S/S2", -+ {&tbsqbox2_table[1], NULL}, -+ {NULL}, -+ } -+ } -+}; -+ -+static int tbsqbox2_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ if (0 == dvb_usb_device_init(intf, &tbsqbox2_properties, -+ THIS_MODULE, NULL, adapter_nr)) { -+ return 0; -+ } -+ return -ENODEV; -+} -+ -+static struct usb_driver tbsqbox2_driver = { -+ .name = "tbsqbox2", -+ .probe = tbsqbox2_probe, -+ .disconnect = dvb_usb_device_exit, -+ .id_table = tbsqbox2_table, -+}; -+ -+static int __init tbsqbox2_module_init(void) -+{ -+ int ret = usb_register(&tbsqbox2_driver); -+ if (ret) -+ err("usb_register failed. Error number %d", ret); -+ -+ return ret; -+} -+ -+static void __exit tbsqbox2_module_exit(void) -+{ -+ usb_deregister(&tbsqbox2_driver); -+} -+ -+module_init(tbsqbox2_module_init); -+module_exit(tbsqbox2_module_exit); -+ -+MODULE_AUTHOR("Bob Liu "); -+MODULE_DESCRIPTION("Driver for TBS QBOX2 STV0903"); -+MODULE_VERSION("0.3"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/usb/dvb-usb/tbs-qbox2.h b/drivers/media/usb/dvb-usb/tbs-qbox2.h -new file mode 100644 -index 0000000..adac50e ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs-qbox2.h -@@ -0,0 +1,8 @@ -+#ifndef _TBSQBOX2_H_ -+#define _TBSQBOX2_H_ -+ -+#define DVB_USB_LOG_PREFIX "tbsqbox2" -+#include "dvb-usb.h" -+ -+#define deb_xfer(args...) dprintk(dvb_usb_tbsqbox2_debug, 0x02, args) -+#endif -diff --git a/drivers/media/usb/dvb-usb/tbs-qbox22.c b/drivers/media/usb/dvb-usb/tbs-qbox22.c -new file mode 100644 -index 0000000..9fa1786 ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs-qbox22.c -@@ -0,0 +1,463 @@ -+/* DVB USB framework compliant Linux driver for the -+* TBS QBOX -+* -+* Copyright (C) 2008 Bob Liu (Bob@Turbosight.com) -+* Igor M. Liplianin (liplianin@me.by) -+* -+* This program is free software; you can redistribute it and/or modify it -+* under the terms of the GNU General Public License as published by the -+* Free Software Foundation, version 2. -+* -+* see Documentation/dvb/README.dvb-usb for more information -+*/ -+ -+/* -+* History: -+* -+* December 2011 Konstantin Dimitrov -+* remove QBOXS3 support -+* add QBOX22 support -+*/ -+ -+#include -+#include "tbs-qbox22.h" -+#include "tas2101.h" -+#include "av201x.h" -+ -+#ifndef USB_PID_TBSQBOX_1 -+#define USB_PID_TBSQBOX_1 0x5922 -+#endif -+ -+#define TBSQBOX_READ_MSG 0 -+#define TBSQBOX_WRITE_MSG 1 -+ -+/* on my own*/ -+#define TBSQBOX_VOLTAGE_CTRL (0x1800) -+#define TBSQBOX_RC_QUERY (0x1a00) -+ -+struct tbsqbox22_state { -+ u32 last_key_pressed; -+}; -+struct tbsqbox22_rc_keys { -+ u32 keycode; -+ u32 event; -+}; -+ -+/* debug */ -+static int dvb_usb_tbsqbox22_debug; -+module_param_named(debug, dvb_usb_tbsqbox22_debug, int, 0644); -+MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS); -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+static int tbsqbox22_op_rw(struct usb_device *dev, u8 request, u16 value, -+ u16 index, u8 * data, u16 len, int flags) -+{ -+ int ret; -+ u8 u8buf[len]; -+ -+ unsigned int pipe = (flags == TBSQBOX_READ_MSG) ? -+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); -+ u8 request_type = (flags == TBSQBOX_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; -+ -+ if (flags == TBSQBOX_WRITE_MSG) -+ memcpy(u8buf, data, len); -+ ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, -+ value, index, u8buf, len, 2000); -+ -+ if (flags == TBSQBOX_READ_MSG) -+ memcpy(data, u8buf, len); -+ return ret; -+} -+ -+/* I2C */ -+static int tbsqbox22_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], -+ int num) -+{ -+ struct dvb_usb_device *d = i2c_get_adapdata(adap); -+ int i = 0; -+ u8 buf[20]; -+ -+ if (!d) -+ return -ENODEV; -+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) -+ return -EAGAIN; -+ -+ switch (num) { -+ case 2: -+ /* read */ -+ buf[0] = msg[1].len; -+ buf[1] = msg[0].addr << 1; -+ buf[2] = msg[0].buf[0]; -+ -+ tbsqbox22_op_rw(d->udev, 0x90, 0, 0, -+ buf, 3, TBSQBOX_WRITE_MSG); -+ msleep(5); -+ tbsqbox22_op_rw(d->udev, 0x91, 0, 0, -+ buf, msg[1].len, TBSQBOX_READ_MSG); -+ memcpy(msg[1].buf, buf, msg[1].len); -+ break; -+ case 1: -+ switch (msg[0].addr) { -+ case 0x68: -+ case 0x63: -+ /* write to register */ -+ buf[0] = msg[0].len + 1; //lenth -+ buf[1] = msg[0].addr << 1; //demod addr -+ for(i=0; i < msg[0].len; i++) -+ buf[2+i] = msg[0].buf[i]; //register -+ tbsqbox22_op_rw(d->udev, 0x80, 0, 0, -+ buf, msg[0].len+2, TBSQBOX_WRITE_MSG); -+ //msleep(3); -+ break; -+ case (TBSQBOX_RC_QUERY): -+ tbsqbox22_op_rw(d->udev, 0xb8, 0, 0, -+ buf, 4, TBSQBOX_READ_MSG); -+ msg[0].buf[0] = buf[2]; -+ msg[0].buf[1] = buf[3]; -+ msleep(3); -+ //info("TBSQBOX_RC_QUERY %x %x %x %x\n",buf6[0],buf6[1],buf6[2],buf6[3]); -+ break; -+ case (TBSQBOX_VOLTAGE_CTRL): -+ break; -+ default: -+ break; -+ } -+ -+ break; -+ default: -+ break; -+ } -+ -+ mutex_unlock(&d->i2c_mutex); -+ return num; -+} -+ -+static u32 tbsqbox22_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C; -+} -+ -+ -+static struct i2c_algorithm tbsqbox22_i2c_algo = { -+ .master_xfer = tbsqbox22_i2c_transfer, -+ .functionality = tbsqbox22_i2c_func, -+}; -+ -+ -+static int tbsqbox22_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -+{ -+ int i,ret; -+ u8 buf[3]; -+ u8 eeprom[256], eepromline[16]; -+ -+ for (i = 0; i < 256; i++) { -+ buf[0] = 1; //lenth -+ buf[1] = 0xa0; //eeprom addr -+ buf[2] = i; //register -+ ret = tbsqbox22_op_rw(d->udev, 0x90, 0, 0, -+ buf, 3, TBSQBOX_WRITE_MSG); -+ ret = tbsqbox22_op_rw(d->udev, 0x91, 0, 0, -+ buf, 1, TBSQBOX_READ_MSG); -+ if (ret < 0) { -+ err("read eeprom failed"); -+ return -1; -+ } else { -+ eepromline[i % 16] = buf[0]; -+ eeprom[i] = buf[0]; -+ } -+ -+ if ((i % 16) == 15) { -+ deb_xfer("%02x: ", i - 15); -+ debug_dump(eepromline, 16, deb_xfer); -+ } -+ } -+ memcpy(mac, eeprom + 16, 6); -+ return 0; -+}; -+ -+static struct dvb_usb_device_properties tbsqbox22_properties; -+ -+ -+static struct tas2101_config tbs5922_cfg = { -+ .i2c_address = 0x68, -+ .id = ID_TAS2100, -+ .reset_demod = NULL, -+ .lnb_power = NULL, -+ .init = {0xb8, 0x67, 0x45, 0x23, 0x01, 0x9a, 0x33}, -+ .init2 = 0, -+}; -+ -+static struct av201x_config tbs5922_av201x_cfg = { -+ .i2c_address = 0x63, -+ .id = ID_AV2012, -+ .xtal_freq = 27000, /* kHz */ -+}; -+ -+static int tbsqbox22_frontend_attach(struct dvb_usb_adapter *d) -+{ -+ struct dvb_usb_device *u = d->dev; -+ u8 buf[20]; -+ -+ d->fe_adap->fe = dvb_attach(tas2101_attach, &tbs5922_cfg, -+ &u->i2c_adap); -+ if (d->fe_adap->fe == NULL) -+ goto err; -+ -+ if (dvb_attach(av201x_attach, d->fe_adap->fe, &tbs5922_av201x_cfg, -+ tas2101_get_i2c_adapter(d->fe_adap->fe, 2)) == NULL) { -+ dvb_frontend_detach(d->fe_adap->fe); -+ d->fe_adap->fe = NULL; -+ goto err; -+ } -+ -+ buf[0] = 7; -+ buf[1] = 1; -+ tbsqbox22_op_rw(u->udev, 0x8a, 0, 0, buf, 2, TBSQBOX_WRITE_MSG); -+ -+ buf[0] = 1; -+ buf[1] = 1; -+ tbsqbox22_op_rw(u->udev, 0x8a, 0, 0, buf, 2, TBSQBOX_WRITE_MSG); -+ -+ buf[0] = 6; -+ buf[1] = 1; -+ tbsqbox22_op_rw(u->udev, 0x8a, 0, 0, buf, 2, TBSQBOX_WRITE_MSG); -+ -+ strlcpy(d->fe_adap->fe->ops.info.name,u->props.devices[0].name,52); -+ -+ return 0; -+err: -+ return -ENODEV; -+} -+ -+ -+ -+static struct rc_map_table tbsqbox22_rc_keys[] = { -+ { 0xff84, KEY_POWER2}, /* power */ -+ { 0xff94, KEY_MUTE}, /* mute */ -+ { 0xff87, KEY_1}, -+ { 0xff86, KEY_2}, -+ { 0xff85, KEY_3}, -+ { 0xff8b, KEY_4}, -+ { 0xff8a, KEY_5}, -+ { 0xff89, KEY_6}, -+ { 0xff8f, KEY_7}, -+ { 0xff8e, KEY_8}, -+ { 0xff8d, KEY_9}, -+ { 0xff92, KEY_0}, -+ { 0xff96, KEY_CHANNELUP}, /* ch+ */ -+ { 0xff91, KEY_CHANNELDOWN}, /* ch- */ -+ { 0xff93, KEY_VOLUMEUP}, /* vol+ */ -+ { 0xff8c, KEY_VOLUMEDOWN}, /* vol- */ -+ { 0xff83, KEY_RECORD}, /* rec */ -+ { 0xff98, KEY_PAUSE}, /* pause, yellow */ -+ { 0xff99, KEY_OK}, /* ok */ -+ { 0xff9a, KEY_CAMERA}, /* snapshot */ -+ { 0xff81, KEY_UP}, -+ { 0xff90, KEY_LEFT}, -+ { 0xff82, KEY_RIGHT}, -+ { 0xff88, KEY_DOWN}, -+ { 0xff95, KEY_FAVORITES}, /* blue */ -+ { 0xff97, KEY_SUBTITLE}, /* green */ -+ { 0xff9d, KEY_ZOOM}, -+ { 0xff9f, KEY_EXIT}, -+ { 0xff9e, KEY_MENU}, -+ { 0xff9c, KEY_EPG}, -+ { 0xff80, KEY_PREVIOUS}, /* red */ -+ { 0xff9b, KEY_MODE}, -+ { 0xffdd, KEY_TV }, -+ { 0xffde, KEY_PLAY }, -+ { 0xffdc, KEY_STOP }, -+ { 0xffdb, KEY_REWIND }, -+ { 0xffda, KEY_FASTFORWARD }, -+ { 0xffd9, KEY_PREVIOUS }, /* replay */ -+ { 0xffd8, KEY_NEXT }, /* skip */ -+ { 0xffd1, KEY_NUMERIC_STAR }, -+ { 0xffd2, KEY_NUMERIC_POUND }, -+ { 0xffd4, KEY_DELETE }, /* clear */ -+}; -+ -+ -+ -+static int tbsqbox22_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -+{ -+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; -+ int keymap_size = d->props.rc.legacy.rc_map_size; -+ -+ struct tbsqbox22_state *st = d->priv; -+ u8 key[2]; -+ struct i2c_msg msg[] = { -+ {.addr = TBSQBOX_RC_QUERY, .flags = I2C_M_RD, .buf = key, -+ .len = 2}, -+ }; -+ int i; -+ -+ *state = REMOTE_NO_KEY_PRESSED; -+ if (tbsqbox22_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { -+ //info("key: %x %x\n",msg[0].buf[0],msg[0].buf[1]); -+ for (i = 0; i < keymap_size; i++) { -+ if (rc5_data(&keymap[i]) == msg[0].buf[1]) { -+ *state = REMOTE_KEY_PRESSED; -+ *event = keymap[i].keycode; -+ st->last_key_pressed = -+ keymap[i].keycode; -+ break; -+ } -+ st->last_key_pressed = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct usb_device_id tbsqbox22_table[] = { -+ {USB_DEVICE(0x734c, 0x5922)}, -+ {USB_DEVICE(USB_VID_CYPRESS, USB_PID_TBSQBOX_1)}, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(usb, tbsqbox22_table); -+ -+static int tbsqbox22_load_firmware(struct usb_device *dev, -+ const struct firmware *frmwr) -+{ -+ u8 *b, *p; -+ int ret = 0, i; -+ u8 reset; -+ const struct firmware *fw; -+ const char *filename = "dvb-usb-tbsqbox-id5922.fw"; -+ switch (dev->descriptor.idProduct) { -+ case 0x5922: -+ ret = request_firmware(&fw, filename, &dev->dev); -+ if (ret != 0) { -+ err("did not find the firmware file. (%s) " -+ "Please see linux/Documentation/dvb/ for more details " -+ "on firmware-problems.", filename); -+ return ret; -+ } -+ break; -+ default: -+ fw = frmwr; -+ break; -+ } -+ info("start downloading TBSQBOX firmware"); -+ p = kmalloc(fw->size, GFP_KERNEL); -+ reset = 1; -+ /*stop the CPU*/ -+ tbsqbox22_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, TBSQBOX_WRITE_MSG); -+ tbsqbox22_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, TBSQBOX_WRITE_MSG); -+ -+ if (p != NULL) { -+ memcpy(p, fw->data, fw->size); -+ for (i = 0; i < fw->size; i += 0x40) { -+ b = (u8 *) p + i; -+ if (tbsqbox22_op_rw(dev, 0xa0, i, 0, b , 0x40, -+ TBSQBOX_WRITE_MSG) != 0x40) { -+ err("error while transferring firmware"); -+ ret = -EINVAL; -+ break; -+ } -+ } -+ /* restart the CPU */ -+ reset = 0; -+ if (ret || tbsqbox22_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, -+ TBSQBOX_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ if (ret || tbsqbox22_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, -+ TBSQBOX_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ -+ msleep(100); -+ kfree(p); -+ } -+ return ret; -+} -+ -+static struct dvb_usb_device_properties tbsqbox22_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .firmware = "dvb-usb-tbsqbox-id5922.fw", -+ .size_of_priv = sizeof(struct tbsqbox22_state), -+ .no_reconnect = 1, -+ -+ .i2c_algo = &tbsqbox22_i2c_algo, -+ .rc.legacy = { -+ .rc_map_table = tbsqbox22_rc_keys, -+ .rc_map_size = ARRAY_SIZE(tbsqbox22_rc_keys), -+ .rc_interval = 150, -+ .rc_query = tbsqbox22_rc_query, -+ }, -+ -+ .generic_bulk_ctrl_endpoint = 0x81, -+ /* parameter for the MPEG2-data transfer */ -+ .num_adapters = 1, -+ .download_firmware = tbsqbox22_load_firmware, -+ .read_mac_address = tbsqbox22_read_mac_address, -+ .adapter = {{ -+ .num_frontends = 1, -+ .fe = {{ -+ .frontend_attach = tbsqbox22_frontend_attach, -+ .streaming_ctrl = NULL, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ }, -+ }}, -+ }}, -+ .num_device_descs = 1, -+ .devices = { -+ {"TurboSight QBOX3 DVB-S/S2", -+ {&tbsqbox22_table[0], NULL}, -+ {NULL}, -+ } -+ } -+}; -+ -+static int tbsqbox22_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ if (0 == dvb_usb_device_init(intf, &tbsqbox22_properties, -+ THIS_MODULE, NULL, adapter_nr)) { -+ return 0; -+ } -+ return -ENODEV; -+} -+ -+static struct usb_driver tbsqbox22_driver = { -+ .name = "tbsqbox22", -+ .probe = tbsqbox22_probe, -+ .disconnect = dvb_usb_device_exit, -+ .id_table = tbsqbox22_table, -+}; -+ -+static int __init tbsqbox22_module_init(void) -+{ -+ int ret = usb_register(&tbsqbox22_driver); -+ if (ret) -+ err("usb_register failed. Error number %d", ret); -+ -+ return ret; -+} -+ -+static void __exit tbsqbox22_module_exit(void) -+{ -+ usb_deregister(&tbsqbox22_driver); -+} -+ -+module_init(tbsqbox22_module_init); -+module_exit(tbsqbox22_module_exit); -+ -+MODULE_AUTHOR("Bob Liu "); -+MODULE_DESCRIPTION("Driver for TBS QBOX22"); -+MODULE_VERSION("0.2"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/usb/dvb-usb/tbs-qbox22.h b/drivers/media/usb/dvb-usb/tbs-qbox22.h -new file mode 100644 -index 0000000..f05ea3c ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs-qbox22.h -@@ -0,0 +1,8 @@ -+#ifndef _TBSQBOX22_H_ -+#define _TBSQBOX22_H_ -+ -+#define DVB_USB_LOG_PREFIX "tbsqbox22" -+#include "dvb-usb.h" -+ -+#define deb_xfer(args...) dprintk(dvb_usb_tbsqbox22_debug, 0x02, args) -+#endif -diff --git a/drivers/media/usb/dvb-usb/tbs-qbox2ci.c b/drivers/media/usb/dvb-usb/tbs-qbox2ci.c -new file mode 100644 -index 0000000..5b008b9 ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs-qbox2ci.c -@@ -0,0 +1,849 @@ -+/* -+ * TurboSight (TBS) Qbox DVB-S2 CI driver -+ * -+ * Copyright (c) 2010 Konstantin Dimitrov -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, version 2. -+ * -+ */ -+ -+#include -+#include "tbs-qbox2ci.h" -+#include "stv6110x.h" -+#include "stv090x.h" -+#include "stb6100.h" -+#include "stb6100_cfg.h" -+ -+#include "dvb_ca_en50221.h" -+ -+#define TBSQBOX_READ_MSG 0 -+#define TBSQBOX_WRITE_MSG 1 -+#define TBSQBOX_LED_CTRL (0x1b00) -+ -+/* on my own*/ -+#define TBSQBOX_VOLTAGE_CTRL (0x1800) -+#define TBSQBOX_RC_QUERY (0x1a00) -+ -+struct tbsqbox2ci_state { -+ struct dvb_ca_en50221 ca; -+ struct mutex ca_mutex; -+ -+ u32 last_key_pressed; -+}; -+ -+/*struct tbsqbox2ci_rc_keys { -+ u32 keycode; -+ u32 event; -+};*/ -+ -+/* debug */ -+static int dvb_usb_tbsqbox2ci_debug; -+module_param_named(debug, dvb_usb_tbsqbox2ci_debug, int, 0644); -+MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." -+ DVB_USB_DEBUG_STATUS); -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+static int tbsqbox2ci_op_rw(struct usb_device *dev, u8 request, u16 value, -+ u16 index, u8 * data, u16 len, int flags) -+{ -+ int ret; -+ u8 u8buf[len]; -+ -+ unsigned int pipe = (flags == TBSQBOX_READ_MSG) ? -+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); -+ u8 request_type = (flags == TBSQBOX_READ_MSG) ? USB_DIR_IN : -+ USB_DIR_OUT; -+ -+ if (flags == TBSQBOX_WRITE_MSG) -+ memcpy(u8buf, data, len); -+ ret = usb_control_msg(dev, pipe, request, request_type | -+ USB_TYPE_VENDOR, value, index , u8buf, len, 2000); -+ -+ if (flags == TBSQBOX_READ_MSG) -+ memcpy(data, u8buf, len); -+ return ret; -+} -+ -+static int tbsqbox2ci_read_attribute_mem(struct dvb_ca_en50221 *ca, -+ int slot, int address) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbsqbox2ci_state *state = (struct tbsqbox2ci_state *)d->priv; -+ u8 buf[4], rbuf[3]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 1; -+ buf[1] = 0; -+ buf[2] = (address >> 8) & 0x0f; -+ buf[3] = address; -+ -+ //msleep(10); -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbsqbox2ci_op_rw(d->udev, 0xa4, 0, 0, -+ buf, 4, TBSQBOX_WRITE_MSG); -+ -+ //msleep(1); -+ -+ ret = tbsqbox2ci_op_rw(d->udev, 0xa5, 0, 0, -+ rbuf, 1, TBSQBOX_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return rbuf[0]; -+} -+ -+static int tbsqbox2ci_write_attribute_mem(struct dvb_ca_en50221 *ca, -+ int slot, int address, u8 value) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbsqbox2ci_state *state = (struct tbsqbox2ci_state *)d->priv; -+ u8 buf[5];//, rbuf[1]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 1; -+ buf[1] = 0; -+ buf[2] = (address >> 8) & 0x0f; -+ buf[3] = address; -+ buf[4] = value; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbsqbox2ci_op_rw(d->udev, 0xa2, 0, 0, -+ buf, 5, TBSQBOX_WRITE_MSG); -+ -+ //msleep(1); -+ -+ //ret = tbsqbox2ci_op_rw(d->udev, 0xa5, 0, 0, -+ // rbuf, 1, TBSQBOX_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int tbsqbox2ci_read_cam_control(struct dvb_ca_en50221 *ca, int slot, -+ u8 address) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbsqbox2ci_state *state = (struct tbsqbox2ci_state *)d->priv; -+ u8 buf[4], rbuf[1]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 1; -+ buf[1] = 1; -+ buf[2] = (address >> 8) & 0x0f; -+ buf[3] = address; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbsqbox2ci_op_rw(d->udev, 0xa4, 0, 0, -+ buf, 4, TBSQBOX_WRITE_MSG); -+ -+ //msleep(10); -+ -+ ret = tbsqbox2ci_op_rw(d->udev, 0xa5, 0, 0, -+ rbuf, 1, TBSQBOX_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return rbuf[0]; -+} -+ -+static int tbsqbox2ci_write_cam_control(struct dvb_ca_en50221 *ca, int slot, -+ u8 address, u8 value) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbsqbox2ci_state *state = (struct tbsqbox2ci_state *)d->priv; -+ u8 buf[5];//, rbuf[1]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 1; -+ buf[1] = 1; -+ buf[2] = (address >> 8) & 0x0f; -+ buf[3] = address; -+ buf[4] = value; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbsqbox2ci_op_rw(d->udev, 0xa2, 0, 0, -+ buf, 5, TBSQBOX_WRITE_MSG); -+ -+ //msleep(1); -+ -+ //ret = tbsqbox2ci_op_rw(d->udev, 0xa5, 0, 0, -+ // rbuf, 1, TBSQBOX_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int tbsqbox2ci_set_video_port(struct dvb_ca_en50221 *ca, -+ int slot, int enable) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbsqbox2ci_state *state = (struct tbsqbox2ci_state *)d->priv; -+ u8 buf[2]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 2; -+ buf[1] = enable; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbsqbox2ci_op_rw(d->udev, 0xa6, 0, 0, -+ buf, 2, TBSQBOX_WRITE_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ if (enable != buf[1]) { -+ err("CI not %sabled.", enable ? "en" : "dis"); -+ return -EIO; -+ } -+ -+ info("CI %sabled.", enable ? "en" : "dis"); -+ return 0; -+} -+ -+static int tbsqbox2ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) -+{ -+ return tbsqbox2ci_set_video_port(ca, slot, /* enable */ 0); -+} -+ -+static int tbsqbox2ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) -+{ -+ return tbsqbox2ci_set_video_port(ca, slot, /* enable */ 1); -+} -+ -+static int tbsqbox2ci_slot_reset(struct dvb_ca_en50221 *ca, int slot) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbsqbox2ci_state *state = (struct tbsqbox2ci_state *)d->priv; -+ u8 buf[2]; -+ int ret; -+ -+ if (0 != slot) { -+ return -EINVAL; -+ } -+ -+ buf[0] = 1; -+ buf[1] = 0; -+ -+ mutex_lock (&state->ca_mutex); -+ -+ ret = tbsqbox2ci_op_rw(d->udev, 0xa6, 0, 0, -+ buf, 2, TBSQBOX_WRITE_MSG); -+ -+ msleep (5); -+ -+ buf[1] = 1; -+ -+ ret = tbsqbox2ci_op_rw(d->udev, 0xa6, 0, 0, -+ buf, 2, TBSQBOX_WRITE_MSG); -+ -+ msleep (1400); -+ -+ mutex_unlock (&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int tbsqbox2ci_poll_slot_status(struct dvb_ca_en50221 *ca, -+ int slot, int open) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbsqbox2ci_state *state = (struct tbsqbox2ci_state *)d->priv; -+ u8 buf[3]; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ tbsqbox2ci_op_rw(d->udev, 0xa8, 0, 0, -+ buf, 3, TBSQBOX_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if ((1 == buf[2]) && (1 == buf[1]) && (0xa9 == buf[0])) { -+ return (DVB_CA_EN50221_POLL_CAM_PRESENT | -+ DVB_CA_EN50221_POLL_CAM_READY); -+ } else { -+ return 0; -+ } -+} -+ -+static void tbsqbox2ci_uninit(struct dvb_usb_device *d) -+{ -+ struct tbsqbox2ci_state *state; -+ -+ if (NULL == d) -+ return; -+ -+ state = (struct tbsqbox2ci_state *)d->priv; -+ if (NULL == state) -+ return; -+ -+ if (NULL == state->ca.data) -+ return; -+ -+ /* Error ignored. */ -+ tbsqbox2ci_set_video_port(&state->ca, /* slot */ 0, /* enable */ 0); -+ -+ dvb_ca_en50221_release(&state->ca); -+ -+ memset(&state->ca, 0, sizeof(state->ca)); -+} -+ -+static int tbsqbox2ci_init(struct dvb_usb_adapter *a) -+{ -+ -+ struct dvb_usb_device *d = a->dev; -+ struct tbsqbox2ci_state *state = (struct tbsqbox2ci_state *)d->priv; -+ int ret; -+ -+ state->ca.owner = THIS_MODULE; -+ state->ca.read_attribute_mem = tbsqbox2ci_read_attribute_mem; -+ state->ca.write_attribute_mem = tbsqbox2ci_write_attribute_mem; -+ state->ca.read_cam_control = tbsqbox2ci_read_cam_control; -+ state->ca.write_cam_control = tbsqbox2ci_write_cam_control; -+ state->ca.slot_reset = tbsqbox2ci_slot_reset; -+ state->ca.slot_shutdown = tbsqbox2ci_slot_shutdown; -+ state->ca.slot_ts_enable = tbsqbox2ci_slot_ts_enable; -+ state->ca.poll_slot_status = tbsqbox2ci_poll_slot_status; -+ state->ca.data = d; -+ -+ ret = dvb_ca_en50221_init (&a->dvb_adap, &state->ca, -+ /* flags */ 0, /* n_slots */ 1); -+ -+ if (0 != ret) { -+ err ("Cannot initialize CI: Error %d.", ret); -+ memset (&state->ca, 0, sizeof (state->ca)); -+ return ret; -+ } -+ -+ info ("CI initialized."); -+ -+ ret = tbsqbox2ci_poll_slot_status(&state->ca, 0, 0); -+ if (0 == ret) -+ tbsqbox2ci_set_video_port(&state->ca, /* slot */ 0, /* enable */ 0); -+ -+ return 0; -+} -+ -+/* I2C */ -+static int tbsqbox2ci_i2c_transfer(struct i2c_adapter *adap, -+ struct i2c_msg msg[], int num) -+{ -+ struct dvb_usb_device *d = i2c_get_adapdata(adap); -+ struct tbsqbox2ci_state *state = (struct tbsqbox2ci_state *)d->priv; -+ int i = 0; -+ u8 buf6[20]; -+ u8 inbuf[20]; -+ -+ if (!d) -+ return -ENODEV; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) -+ return -EAGAIN; -+ -+ switch (num) { -+ case 2: -+ buf6[0]=msg[1].len;//lenth -+ buf6[1]=msg[0].addr<<1;//demod addr -+ //register -+ buf6[2] = msg[0].buf[0]; -+ buf6[3] = msg[0].buf[1]; -+ -+ tbsqbox2ci_op_rw(d->udev, 0x92, 0, 0, -+ buf6, 4, TBSQBOX_WRITE_MSG); -+ //msleep(5); -+ tbsqbox2ci_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, msg[1].len, TBSQBOX_READ_MSG); -+ memcpy(msg[1].buf, inbuf, msg[1].len); -+ break; -+ case 1: -+ switch (msg[0].addr) { -+ case 0x6a: -+ case 0x61: -+ case 0x60: -+ if (msg[0].flags == 0) { -+ buf6[0] = msg[0].len+1;//lenth -+ buf6[1] = msg[0].addr<<1;//addr -+ for(i=0;iudev, 0x80, 0, 0, -+ buf6, msg[0].len+2, TBSQBOX_WRITE_MSG); -+ } else { -+ buf6[0] = msg[0].len;//length -+ buf6[1] = msg[0].addr<<1;//addr -+ buf6[2] = 0x00; -+ tbsqbox2ci_op_rw(d->udev, 0x90, 0, 0, -+ buf6, 3, TBSQBOX_WRITE_MSG); -+ //msleep(5); -+ tbsqbox2ci_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, buf6[0], TBSQBOX_READ_MSG); -+ memcpy(msg[0].buf, inbuf, msg[0].len); -+ } -+ //msleep(3); -+ break; -+ case (TBSQBOX_RC_QUERY): -+ tbsqbox2ci_op_rw(d->udev, 0xb8, 0, 0, -+ buf6, 4, TBSQBOX_READ_MSG); -+ msg[0].buf[0] = buf6[2]; -+ msg[0].buf[1] = buf6[3]; -+ //msleep(3); -+ //info("TBSQBOX_RC_QUERY %x %x %x %x\n", -+ // buf6[0],buf6[1],buf6[2],buf6[3]); -+ break; -+ case (TBSQBOX_VOLTAGE_CTRL): -+ buf6[0] = 3; -+ buf6[1] = msg[0].buf[0]; -+ tbsqbox2ci_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBSQBOX_WRITE_MSG); -+ break; -+ case (TBSQBOX_LED_CTRL): -+ buf6[0] = 5; -+ buf6[1] = msg[0].buf[0]; -+ tbsqbox2ci_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBSQBOX_WRITE_MSG); -+ break; -+ } -+ -+ break; -+ } -+ -+ mutex_unlock(&d->i2c_mutex); -+ mutex_unlock(&state->ca_mutex); -+ return num; -+} -+ -+static u32 tbsqbox2ci_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C; -+} -+ -+static void tbsqbox2ci_led_ctrl(struct dvb_frontend *fe, int offon) -+{ -+ static u8 led_off[] = { 0 }; -+ static u8 led_on[] = { 1 }; -+ struct i2c_msg msg = { -+ .addr = TBSQBOX_LED_CTRL, -+ .flags = 0, -+ .buf = led_off, -+ .len = 1 -+ }; -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ -+ if (offon) -+ msg.buf = led_on; -+ i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); -+} -+ -+static struct stv090x_config earda_config = { -+ .device = STV0903, -+ .demod_mode = STV090x_SINGLE, -+ .clk_mode = STV090x_CLK_EXT, -+ -+ .xtal = 27000000, -+ .address = 0x6a, -+ -+ .ts1_mode = STV090x_TSMODE_DVBCI, -+ .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, -+ -+ .repeater_level = STV090x_RPTLEVEL_16, -+ -+ .tuner_get_frequency = stb6100_get_frequency, -+ .tuner_set_frequency = stb6100_set_frequency, -+ .tuner_set_bandwidth = stb6100_set_bandwidth, -+ .tuner_get_bandwidth = stb6100_get_bandwidth, -+ -+ .set_lock_led = tbsqbox2ci_led_ctrl, -+}; -+ -+static struct stb6100_config qbox2_stb6100_config = { -+ .tuner_address = 0x60, -+ .refclock = 27000000, -+}; -+ -+static struct i2c_algorithm tbsqbox2ci_i2c_algo = { -+ .master_xfer = tbsqbox2ci_i2c_transfer, -+ .functionality = tbsqbox2ci_i2c_func, -+}; -+ -+static int tbsqbox2ci_earda_tuner_attach(struct dvb_usb_adapter *adap) -+{ -+ if (!dvb_attach(stb6100_attach, adap->fe_adap->fe, &qbox2_stb6100_config, -+ &adap->dev->i2c_adap)) -+ return -EIO; -+ -+ return 0; -+} -+static int tbsqbox2ci_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -+{ -+ int i,ret; -+ u8 ibuf[3] = {0, 0,0}; -+ u8 eeprom[256], eepromline[16]; -+ -+ for (i = 0; i < 256; i++) { -+ ibuf[0]=1;//lenth -+ ibuf[1]=0xa0;//eeprom addr -+ ibuf[2]=i;//register -+ ret = tbsqbox2ci_op_rw(d->udev, 0x90, 0, 0, -+ ibuf, 3, TBSQBOX_WRITE_MSG); -+ ret = tbsqbox2ci_op_rw(d->udev, 0x91, 0, 0, -+ ibuf, 1, TBSQBOX_READ_MSG); -+ if (ret < 0) { -+ err("read eeprom failed."); -+ return -1; -+ } else { -+ eepromline[i%16] = ibuf[0]; -+ eeprom[i] = ibuf[0]; -+ } -+ -+ if ((i % 16) == 15) { -+ deb_xfer("%02x: ", i - 15); -+ debug_dump(eepromline, 16, deb_xfer); -+ } -+ } -+ memcpy(mac, eeprom + 16, 6); -+ return 0; -+}; -+ -+static int tbsqbox2ci_set_voltage(struct dvb_frontend *fe, -+ enum fe_sec_voltage voltage) -+{ -+ static u8 command_13v[1] = {0x00}; -+ static u8 command_18v[1] = {0x01}; -+ struct i2c_msg msg[] = { -+ {.addr = TBSQBOX_VOLTAGE_CTRL, .flags = 0, -+ .buf = command_13v, .len = 1}, -+ }; -+ -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ if (voltage == SEC_VOLTAGE_18) -+ msg[0].buf = command_18v; -+ //info("tbsqbox2ci_set_voltage %d",voltage); -+ i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1); -+ return 0; -+} -+ -+static struct dvb_usb_device_properties tbsqbox2ci_properties; -+ -+static int tbsqbox2ci_frontend_attach(struct dvb_usb_adapter *d) -+{ -+ struct dvb_usb_device *u = d->dev; -+ struct tbsqbox2ci_state *state = (struct tbsqbox2ci_state *)u->priv; -+ u8 buf[20]; -+ -+ mutex_init(&state->ca_mutex); -+ -+ if (tbsqbox2ci_properties.adapter->fe->tuner_attach == &tbsqbox2ci_earda_tuner_attach) { -+ d->fe_adap->fe = dvb_attach(stv090x_attach, &earda_config, -+ &u->i2c_adap, STV090x_DEMODULATOR_0); -+ if (d->fe_adap->fe != NULL) { -+ d->fe_adap->fe->ops.set_voltage = tbsqbox2ci_set_voltage; -+ -+ buf[0] = 7; -+ buf[1] = 1; -+ tbsqbox2ci_op_rw(u->udev, 0x8a, 0, 0, -+ buf, 2, TBSQBOX_WRITE_MSG); -+ -+ buf[0] = 1; -+ buf[1] = 1; -+ tbsqbox2ci_op_rw(u->udev, 0x8a, 0, 0, -+ buf, 2, TBSQBOX_WRITE_MSG); -+ -+ buf[0] = 6; -+ buf[1] = 1; -+ tbsqbox2ci_op_rw(u->udev, 0x8a, 0, 0, -+ buf, 2, TBSQBOX_WRITE_MSG); -+ -+ tbsqbox2ci_init(d); -+ -+ strlcpy(d->fe_adap->fe->ops.info.name,u->props.devices[0].name,52); -+ return 0; -+ } -+ } -+ -+ return -EIO; -+} -+ -+static void tbsqbox2ci2_usb_disconnect (struct usb_interface * intf) -+{ -+ struct dvb_usb_device *d = usb_get_intfdata (intf); -+ -+ tbsqbox2ci_uninit (d); -+ dvb_usb_device_exit (intf); -+} -+ -+static struct rc_map_table tbsqbox2ci_rc_keys[] = { -+ { 0xff84, KEY_POWER2}, /* power */ -+ { 0xff94, KEY_MUTE}, /* mute */ -+ { 0xff87, KEY_1}, -+ { 0xff86, KEY_2}, -+ { 0xff85, KEY_3}, -+ { 0xff8b, KEY_4}, -+ { 0xff8a, KEY_5}, -+ { 0xff89, KEY_6}, -+ { 0xff8f, KEY_7}, -+ { 0xff8e, KEY_8}, -+ { 0xff8d, KEY_9}, -+ { 0xff92, KEY_0}, -+ { 0xff96, KEY_CHANNELUP}, /* ch+ */ -+ { 0xff91, KEY_CHANNELDOWN}, /* ch- */ -+ { 0xff93, KEY_VOLUMEUP}, /* vol+ */ -+ { 0xff8c, KEY_VOLUMEDOWN}, /* vol- */ -+ { 0xff83, KEY_RECORD}, /* rec */ -+ { 0xff98, KEY_PAUSE}, /* pause, yellow */ -+ { 0xff99, KEY_OK}, /* ok */ -+ { 0xff9a, KEY_CAMERA}, /* snapshot */ -+ { 0xff81, KEY_UP}, -+ { 0xff90, KEY_LEFT}, -+ { 0xff82, KEY_RIGHT}, -+ { 0xff88, KEY_DOWN}, -+ { 0xff95, KEY_FAVORITES}, /* blue */ -+ { 0xff97, KEY_SUBTITLE}, /* green */ -+ { 0xff9d, KEY_ZOOM}, -+ { 0xff9f, KEY_EXIT}, -+ { 0xff9e, KEY_MENU}, -+ { 0xff9c, KEY_EPG}, -+ { 0xff80, KEY_PREVIOUS}, /* red */ -+ { 0xff9b, KEY_MODE}, -+ { 0xffdd, KEY_TV }, -+ { 0xffde, KEY_PLAY }, -+ { 0xffdc, KEY_STOP }, -+ { 0xffdb, KEY_REWIND }, -+ { 0xffda, KEY_FASTFORWARD }, -+ { 0xffd9, KEY_PREVIOUS }, /* replay */ -+ { 0xffd8, KEY_NEXT }, /* skip */ -+ { 0xffd1, KEY_NUMERIC_STAR }, -+ { 0xffd2, KEY_NUMERIC_POUND }, -+ { 0xffd4, KEY_DELETE }, /* clear */ -+}; -+ -+static int tbsqbox2ci_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -+{ -+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; -+ int keymap_size = d->props.rc.legacy.rc_map_size; -+ -+ struct tbsqbox2ci_state *st = d->priv; -+ u8 key[2]; -+ struct i2c_msg msg[] = { -+ {.addr = TBSQBOX_RC_QUERY, .flags = I2C_M_RD, .buf = key, -+ .len = 2}, -+ }; -+ int i; -+ -+ *state = REMOTE_NO_KEY_PRESSED; -+ if (tbsqbox2ci_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { -+ //info("key: %x %x\n",msg[0].buf[0],msg[0].buf[1]); -+ for (i = 0; i < keymap_size; i++) { -+ if (rc5_data(&keymap[i]) == msg[0].buf[1]) { -+ *state = REMOTE_KEY_PRESSED; -+ *event = keymap[i].keycode; -+ st->last_key_pressed = -+ keymap[i].keycode; -+ break; -+ } -+ st->last_key_pressed = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct usb_device_id tbsqbox2ci_table[] = { -+ {USB_DEVICE(0x734c, 0x5980)}, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(usb, tbsqbox2ci_table); -+ -+static int tbsqbox2ci_load_firmware(struct usb_device *dev, -+ const struct firmware *frmwr) -+{ -+ u8 *b, *p; -+ int ret = 0, i; -+ u8 reset; -+ const struct firmware *fw; -+ switch (dev->descriptor.idProduct) { -+ case 0x5980: -+ ret = request_firmware(&fw, tbsqbox2ci_properties.firmware, &dev->dev); -+ if (ret != 0) { -+ err("did not find the firmware file. (%s) " -+ "Please see linux/Documentation/dvb/ for more details " -+ "on firmware-problems.", tbsqbox2ci_properties.firmware); -+ return ret; -+ } -+ break; -+ default: -+ fw = frmwr; -+ break; -+ } -+ info("start downloading TBSQBOX2CI firmware"); -+ p = kmalloc(fw->size, GFP_KERNEL); -+ reset = 1; -+ /*stop the CPU*/ -+ tbsqbox2ci_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, TBSQBOX_WRITE_MSG); -+ tbsqbox2ci_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, TBSQBOX_WRITE_MSG); -+ -+ if (p != NULL) { -+ memcpy(p, fw->data, fw->size); -+ for (i = 0; i < fw->size; i += 0x40) { -+ b = (u8 *) p + i; -+ if (tbsqbox2ci_op_rw(dev, 0xa0, i, 0, b , 0x40, -+ TBSQBOX_WRITE_MSG) != 0x40) { -+ err("error while transferring firmware"); -+ ret = -EINVAL; -+ break; -+ } -+ } -+ /* restart the CPU */ -+ reset = 0; -+ if (ret || tbsqbox2ci_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, -+ TBSQBOX_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ if (ret || tbsqbox2ci_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, -+ TBSQBOX_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ -+ msleep(100); -+ kfree(p); -+ } -+ return ret; -+} -+ -+static struct dvb_usb_device_properties tbsqbox2ci_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .firmware = "dvb-usb-tbsqbox-id5980.fw", -+ .size_of_priv = sizeof(struct tbsqbox2ci_state), -+ .no_reconnect = 1, -+ -+ .i2c_algo = &tbsqbox2ci_i2c_algo, -+ .rc.legacy = { -+ .rc_map_table = tbsqbox2ci_rc_keys, -+ .rc_map_size = ARRAY_SIZE(tbsqbox2ci_rc_keys), -+ .rc_interval = 450, -+ .rc_query = tbsqbox2ci_rc_query, -+ }, -+ -+ .generic_bulk_ctrl_endpoint = 0x81, -+ /* parameter for the MPEG2-data transfer */ -+ .num_adapters = 1, -+ .download_firmware = tbsqbox2ci_load_firmware, -+ .read_mac_address = tbsqbox2ci_read_mac_address, -+ .adapter = {{ -+ .num_frontends = 1, -+ .fe = {{ -+ .frontend_attach = tbsqbox2ci_frontend_attach, -+ .streaming_ctrl = NULL, -+ .tuner_attach = tbsqbox2ci_earda_tuner_attach, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ }, -+ } }, -+ } }, -+ -+ .num_device_descs = 1, -+ .devices = { -+ {"TurboSight TBS QBOX2-CI DVB-S/S2", -+ {&tbsqbox2ci_table[0], NULL}, -+ {NULL}, -+ } -+ } -+}; -+ -+static int tbsqbox2ci_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ if (0 == dvb_usb_device_init(intf, &tbsqbox2ci_properties, -+ THIS_MODULE, NULL, adapter_nr)) { -+ return 0; -+ } -+ return -ENODEV; -+} -+ -+static struct usb_driver tbsqbox2ci_driver = { -+ .name = "tbsqbox2ci", -+ .probe = tbsqbox2ci_probe, -+ .disconnect = tbsqbox2ci2_usb_disconnect, -+ .id_table = tbsqbox2ci_table, -+}; -+ -+static int __init tbsqbox2ci_module_init(void) -+{ -+ int ret = usb_register(&tbsqbox2ci_driver); -+ if (ret) -+ err("usb_register failed. Error number %d", ret); -+ -+ return ret; -+} -+ -+static void __exit tbsqbox2ci_module_exit(void) -+{ -+ usb_deregister(&tbsqbox2ci_driver); -+} -+ -+module_init(tbsqbox2ci_module_init); -+module_exit(tbsqbox2ci_module_exit); -+ -+MODULE_AUTHOR("Konstantin Dimitrov "); -+MODULE_DESCRIPTION("TurboSight (TBS) Qbox DVB-S2 CI driver"); -+MODULE_VERSION("1.0"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/usb/dvb-usb/tbs-qbox2ci.h b/drivers/media/usb/dvb-usb/tbs-qbox2ci.h -new file mode 100644 -index 0000000..152849f ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs-qbox2ci.h -@@ -0,0 +1,8 @@ -+#ifndef _TBSQBOX2CI_H_ -+#define _TBSQBOX2CI_H_ -+ -+#define DVB_USB_LOG_PREFIX "tbsqbox2ci" -+#include "dvb-usb.h" -+ -+#define deb_xfer(args...) dprintk(dvb_usb_tbsqbox2ci_debug, 0x02, args) -+#endif -diff --git a/drivers/media/usb/dvb-usb/tbs-qboxs2.c b/drivers/media/usb/dvb-usb/tbs-qboxs2.c -new file mode 100644 -index 0000000..d3b03a2 ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs-qboxs2.c -@@ -0,0 +1,508 @@ -+/* DVB USB framework compliant Linux driver for the -+* TBS QBOX -+* -+* Copyright (C) 2008 Bob Liu (Bob@Turbosight.com) -+* Igor M. Liplianin (liplianin@me.by) -+* -+* This program is free software; you can redistribute it and/or modify it -+* under the terms of the GNU General Public License as published by the -+* Free Software Foundation, version 2. -+* -+* see Documentation/dvb/README.dvb-usb for more information -+*/ -+ -+/* -+* History: -+* -+* July 2009 Konstantin Dimitrov -+* remove QBOX2-DS3000 support -+* add QBOXS2-CX24116 support -+*/ -+ -+#include -+#include "tbs-qboxs2.h" -+#include "cx24116.h" -+ -+#define TBSQBOX_READ_MSG 0 -+#define TBSQBOX_WRITE_MSG 1 -+ -+/* on my own*/ -+#define TBSQBOX_VOLTAGE_CTRL (0x1800) -+#define TBSQBOX_RC_QUERY (0x1a00) -+#define TBSQBOX_LED_CTRL (0x1b00) -+ -+struct tbsqboxs2_state { -+ u32 last_key_pressed; -+}; -+struct tbsqboxs2_rc_keys { -+ u32 keycode; -+ u32 event; -+}; -+ -+/* debug */ -+static int dvb_usb_tbsqboxs2_debug; -+module_param_named(debug, dvb_usb_tbsqboxs2_debug, int, 0644); -+MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS); -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+static int tbsqboxs2_op_rw(struct usb_device *dev, u8 request, u16 value, -+ u16 index, u8 * data, u16 len, int flags) -+{ -+ int ret; -+ u8 u8buf[len]; -+ -+ unsigned int pipe = (flags == TBSQBOX_READ_MSG) ? -+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); -+ u8 request_type = (flags == TBSQBOX_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; -+ -+ if (flags == TBSQBOX_WRITE_MSG) -+ memcpy(u8buf, data, len); -+ ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, -+ value, index, u8buf, len, 2000); -+ -+ if (flags == TBSQBOX_READ_MSG) -+ memcpy(data, u8buf, len); -+ return ret; -+} -+ -+/* I2C */ -+static int tbsqboxs2_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], -+ int num) -+{ -+struct dvb_usb_device *d = i2c_get_adapdata(adap); -+ int i = 0, len; -+ u8 ibuf[1], obuf[3]; -+ u8 buf6[20]; -+ -+ if (!d) -+ return -ENODEV; -+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) -+ return -EAGAIN; -+ -+ switch (num) { -+ case 2: { -+ /* read */ -+ obuf[0] = msg[0].len; -+ obuf[1] = msg[0].addr<<1; -+ obuf[2] = msg[0].buf[0]; -+ -+ tbsqboxs2_op_rw(d->udev, 0x90, 0, 0, -+ obuf, 3, TBSQBOX_WRITE_MSG); -+ msleep(5); -+ tbsqboxs2_op_rw(d->udev, 0x91, 0, 0, -+ ibuf, msg[1].len, TBSQBOX_READ_MSG); -+ memcpy(msg[1].buf, ibuf, msg[1].len); -+ break; -+ } -+ case 1: -+ switch (msg[0].addr) { -+ case 0x55: { -+ if (msg[0].buf[0] == 0xf7) { -+ /* firmware */ -+ /* Write in small blocks */ -+ u8 iobuf[19]; -+ iobuf[0] = 0x12; -+ iobuf[1] = 0xaa; -+ iobuf[2] = 0xf7; -+ len = msg[0].len - 1; -+ i = 1; -+ do { -+ memcpy(iobuf + 3, msg[0].buf + i, (len > 16 ? 16 : len)); -+ tbsqboxs2_op_rw(d->udev, 0x80, 0, 0, -+ iobuf, (len > 16 ? 16 : len) + 3, TBSQBOX_WRITE_MSG); -+ i += 16; -+ len -= 16; -+ } while (len > 0); -+ } else { -+ /* write to register */ -+ buf6[0] = msg[0].len+1;//lenth -+ buf6[1] = msg[0].addr<<1;//demod addr -+ for(i=0;iudev, 0x80, 0, 0, -+ buf6, msg[0].len+2, TBSQBOX_WRITE_MSG); -+ //msleep(3); -+ } -+ break; -+ } -+ case 0x60: { -+ /* write to register */ -+ buf6[0] = msg[0].len+1;//lenth -+ buf6[1] = msg[0].addr<<1;//demod addr -+ for(i=0;iudev, 0x80, 0, 0, -+ buf6, msg[0].len+2, TBSQBOX_WRITE_MSG); -+ msleep(3); -+ -+ break; -+ } -+ case (TBSQBOX_RC_QUERY): { -+ tbsqboxs2_op_rw(d->udev, 0xb8, 0, 0, -+ buf6, 4, TBSQBOX_READ_MSG); -+ msg[0].buf[0] = buf6[2]; -+ msg[0].buf[1] = buf6[3]; -+ msleep(3); -+ //info("TBSQBOX_RC_QUERY %x %x %x %x\n",buf6[0],buf6[1],buf6[2],buf6[3]); -+ break; -+ } -+ case (TBSQBOX_VOLTAGE_CTRL): { -+ buf6[0] = 3; -+ buf6[1] = msg[0].buf[0]; -+ tbsqboxs2_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBSQBOX_WRITE_MSG); -+ break; -+ } -+ case (TBSQBOX_LED_CTRL): { -+ buf6[0] = 5; -+ buf6[1] = msg[0].buf[0]; -+ tbsqboxs2_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBSQBOX_WRITE_MSG); -+ break; -+ } -+ } -+ -+ break; -+ } -+ -+ mutex_unlock(&d->i2c_mutex); -+ return num; -+} -+ -+static u32 tbsqboxs2_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C; -+} -+ -+static struct i2c_algorithm tbsqboxs2_i2c_algo = { -+ .master_xfer = tbsqboxs2_i2c_transfer, -+ .functionality = tbsqboxs2_i2c_func, -+}; -+ -+static void tbsqboxs2_led_ctrl(struct dvb_frontend *fe, int offon) -+{ -+ static u8 led_off[] = { 0 }; -+ static u8 led_on[] = { 1 }; -+ struct i2c_msg msg = { -+ .addr = TBSQBOX_LED_CTRL, -+ .flags = 0, -+ .buf = led_off, -+ .len = 1 -+ }; -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ -+ if (offon) -+ msg.buf = led_on; -+ i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); -+} -+ -+static const struct cx24116_config qbox2_cx24116_config = { -+ .demod_address = 0x55, -+ .mpg_clk_pos_pol = 0x01, -+ .set_lock_led = tbsqboxs2_led_ctrl, -+}; -+ -+static int tbsqboxs2_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -+{ -+ int i,ret; -+ u8 ibuf[3] = {0, 0,0}; -+ u8 eeprom[256], eepromline[16]; -+ -+ for (i = 0; i < 256; i++) { -+ ibuf[0]=1;//lenth -+ ibuf[1]=0xa0;//eeprom addr -+ ibuf[2]=i;//register -+ ret = tbsqboxs2_op_rw(d->udev, 0x90, 0, 0, -+ ibuf, 3, TBSQBOX_WRITE_MSG); -+ ret = tbsqboxs2_op_rw(d->udev, 0x91, 0, 0, -+ ibuf, 1, TBSQBOX_READ_MSG); -+ if (ret < 0) { -+ err("read eeprom failed"); -+ return -1; -+ } else { -+ eepromline[i%16] = ibuf[0]; -+ eeprom[i] = ibuf[0]; -+ } -+ -+ if ((i % 16) == 15) { -+ deb_xfer("%02x: ", i - 15); -+ debug_dump(eepromline, 16, deb_xfer); -+ } -+ } -+ memcpy(mac, eeprom + 16, 6); -+ return 0; -+}; -+ -+static int tbsqboxs2_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) -+{ -+ static u8 command_13v[1] = {0x00}; -+ static u8 command_18v[1] = {0x01}; -+ struct i2c_msg msg[] = { -+ {.addr = TBSQBOX_VOLTAGE_CTRL, .flags = 0, -+ .buf = command_13v, .len = 1}, -+ }; -+ -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ if (voltage == SEC_VOLTAGE_18) -+ msg[0].buf = command_18v; -+ info("tbsqboxs2_set_voltage %d",voltage); -+ i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1); -+ return 0; -+} -+ -+static struct dvb_usb_device_properties tbsqboxs2_properties; -+ -+static int tbsqboxs2_frontend_attach(struct dvb_usb_adapter *d) -+{ -+ struct dvb_usb_device *u = d->dev; -+ u8 buf[20]; -+ -+ if ((d->fe_adap->fe = dvb_attach(cx24116_attach, &qbox2_cx24116_config, -+ &u->i2c_adap)) != NULL) { -+ d->fe_adap->fe->ops.set_voltage = tbsqboxs2_set_voltage; -+ -+ buf[0] = 7; -+ buf[1] = 1; -+ tbsqboxs2_op_rw(u->udev, 0x8a, 0, 0, -+ buf, 2, TBSQBOX_WRITE_MSG); -+ -+ strlcpy(d->fe_adap->fe->ops.info.name,u->props.devices[0].name,52); -+ return 0; -+ } -+ -+ return -EIO; -+} -+ -+static struct rc_map_table tbsqboxs2_rc_keys[] = { -+ { 0xff84, KEY_POWER2}, /* power */ -+ { 0xff94, KEY_MUTE}, /* mute */ -+ { 0xff87, KEY_1}, -+ { 0xff86, KEY_2}, -+ { 0xff85, KEY_3}, -+ { 0xff8b, KEY_4}, -+ { 0xff8a, KEY_5}, -+ { 0xff89, KEY_6}, -+ { 0xff8f, KEY_7}, -+ { 0xff8e, KEY_8}, -+ { 0xff8d, KEY_9}, -+ { 0xff92, KEY_0}, -+ { 0xff96, KEY_CHANNELUP}, /* ch+ */ -+ { 0xff91, KEY_CHANNELDOWN}, /* ch- */ -+ { 0xff93, KEY_VOLUMEUP}, /* vol+ */ -+ { 0xff8c, KEY_VOLUMEDOWN}, /* vol- */ -+ { 0xff83, KEY_RECORD}, /* rec */ -+ { 0xff98, KEY_PAUSE}, /* pause, yellow */ -+ { 0xff99, KEY_OK}, /* ok */ -+ { 0xff9a, KEY_CAMERA}, /* snapshot */ -+ { 0xff81, KEY_UP}, -+ { 0xff90, KEY_LEFT}, -+ { 0xff82, KEY_RIGHT}, -+ { 0xff88, KEY_DOWN}, -+ { 0xff95, KEY_FAVORITES}, /* blue */ -+ { 0xff97, KEY_SUBTITLE}, /* green */ -+ { 0xff9d, KEY_ZOOM}, -+ { 0xff9f, KEY_EXIT}, -+ { 0xff9e, KEY_MENU}, -+ { 0xff9c, KEY_EPG}, -+ { 0xff80, KEY_PREVIOUS}, /* red */ -+ { 0xff9b, KEY_MODE}, -+ { 0xffdd, KEY_TV }, -+ { 0xffde, KEY_PLAY }, -+ { 0xffdc, KEY_STOP }, -+ { 0xffdb, KEY_REWIND }, -+ { 0xffda, KEY_FASTFORWARD }, -+ { 0xffd9, KEY_PREVIOUS }, /* replay */ -+ { 0xffd8, KEY_NEXT }, /* skip */ -+ { 0xffd1, KEY_NUMERIC_STAR }, -+ { 0xffd2, KEY_NUMERIC_POUND }, -+ { 0xffd4, KEY_DELETE }, /* clear */ -+}; -+ -+ -+ -+static int tbsqboxs2_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -+{ -+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; -+ int keymap_size = d->props.rc.legacy.rc_map_size; -+ -+ struct tbsqboxs2_state *st = d->priv; -+ u8 key[2]; -+ struct i2c_msg msg[] = { -+ {.addr = TBSQBOX_RC_QUERY, .flags = I2C_M_RD, .buf = key, -+ .len = 2}, -+ }; -+ int i; -+ -+ *state = REMOTE_NO_KEY_PRESSED; -+ if (tbsqboxs2_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { -+ //info("key: %x %x\n",msg[0].buf[0],msg[0].buf[1]); -+ for (i = 0; i < keymap_size; i++) { -+ if (rc5_data(&keymap[i]) == msg[0].buf[1]) { -+ *state = REMOTE_KEY_PRESSED; -+ *event = keymap[i].keycode; -+ st->last_key_pressed = -+ keymap[i].keycode; -+ break; -+ } -+ st->last_key_pressed = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct usb_device_id tbsqboxs2_table[] = { -+ {USB_DEVICE(0x734c, 0x5928)}, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(usb, tbsqboxs2_table); -+ -+static int tbsqboxs2_load_firmware(struct usb_device *dev, -+ const struct firmware *frmwr) -+{ -+ u8 *b, *p; -+ int ret = 0, i; -+ u8 reset; -+ const struct firmware *fw; -+ switch (dev->descriptor.idProduct) { -+ case 0x5928: -+ ret = request_firmware(&fw, tbsqboxs2_properties.firmware, &dev->dev); -+ if (ret != 0) { -+ err("did not find the firmware file. (%s) " -+ "Please see linux/Documentation/dvb/ for more details " -+ "on firmware-problems.", tbsqboxs2_properties.firmware); -+ return ret; -+ } -+ break; -+ default: -+ fw = frmwr; -+ break; -+ } -+ info("start downloading TBSQBOX firmware"); -+ p = kmalloc(fw->size, GFP_KERNEL); -+ reset = 1; -+ /*stop the CPU*/ -+ tbsqboxs2_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, TBSQBOX_WRITE_MSG); -+ tbsqboxs2_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, TBSQBOX_WRITE_MSG); -+ -+ if (p != NULL) { -+ memcpy(p, fw->data, fw->size); -+ for (i = 0; i < fw->size; i += 0x40) { -+ b = (u8 *) p + i; -+ if (tbsqboxs2_op_rw(dev, 0xa0, i, 0, b , 0x40, -+ TBSQBOX_WRITE_MSG) != 0x40) { -+ err("error while transferring firmware"); -+ ret = -EINVAL; -+ break; -+ } -+ } -+ /* restart the CPU */ -+ reset = 0; -+ if (ret || tbsqboxs2_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, -+ TBSQBOX_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ if (ret || tbsqboxs2_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, -+ TBSQBOX_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ -+ msleep(100); -+ kfree(p); -+ } -+ return ret; -+} -+ -+static struct dvb_usb_device_properties tbsqboxs2_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .firmware = "dvb-usb-tbsqbox-id5928.fw", -+ .size_of_priv = sizeof(struct tbsqboxs2_state), -+ .no_reconnect = 1, -+ -+ .i2c_algo = &tbsqboxs2_i2c_algo, -+ .rc.legacy = { -+ .rc_map_table = tbsqboxs2_rc_keys, -+ .rc_map_size = ARRAY_SIZE(tbsqboxs2_rc_keys), -+ .rc_interval = 150, -+ .rc_query = tbsqboxs2_rc_query, -+ }, -+ -+ .generic_bulk_ctrl_endpoint = 0x81, -+ /* parameter for the MPEG2-data transfer */ -+ .num_adapters = 1, -+ .download_firmware = tbsqboxs2_load_firmware, -+ .read_mac_address = tbsqboxs2_read_mac_address, -+ .adapter = {{ -+ .num_frontends = 1, -+ .fe = {{ -+ .frontend_attach = tbsqboxs2_frontend_attach, -+ .streaming_ctrl = NULL, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ }, -+ } }, -+ } }, -+ -+ .num_device_descs = 1, -+ .devices = { -+ {"TurboSight TBS QBOX-S2 DVB-S/S2", -+ {&tbsqboxs2_table[0], NULL}, -+ {NULL}, -+ } -+ } -+}; -+ -+static int tbsqboxs2_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ if (0 == dvb_usb_device_init(intf, &tbsqboxs2_properties, -+ THIS_MODULE, NULL, adapter_nr)) { -+ return 0; -+ } -+ return -ENODEV; -+} -+ -+static struct usb_driver tbsqboxs2_driver = { -+ .name = "tbsqboxs2", -+ .probe = tbsqboxs2_probe, -+ .disconnect = dvb_usb_device_exit, -+ .id_table = tbsqboxs2_table, -+}; -+ -+static int __init tbsqboxs2_module_init(void) -+{ -+ int ret = usb_register(&tbsqboxs2_driver); -+ if (ret) -+ err("usb_register failed. Error number %d", ret); -+ -+ return ret; -+} -+ -+static void __exit tbsqboxs2_module_exit(void) -+{ -+ usb_deregister(&tbsqboxs2_driver); -+} -+ -+module_init(tbsqboxs2_module_init); -+module_exit(tbsqboxs2_module_exit); -+ -+MODULE_AUTHOR("Bob Liu "); -+MODULE_DESCRIPTION("Driver for TBS QBOXS2-CX24116"); -+MODULE_VERSION("0.2"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/usb/dvb-usb/tbs-qboxs2.h b/drivers/media/usb/dvb-usb/tbs-qboxs2.h -new file mode 100644 -index 0000000..fb7fd04 ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs-qboxs2.h -@@ -0,0 +1,8 @@ -+#ifndef _TBSQBOXS2_H_ -+#define _TBSQBOXS2_H_ -+ -+#define DVB_USB_LOG_PREFIX "tbsqboxs2" -+#include "dvb-usb.h" -+ -+#define deb_xfer(args...) dprintk(dvb_usb_tbsqboxs2_debug, 0x02, args) -+#endif -diff --git a/drivers/media/usb/dvb-usb/tbs5220.c b/drivers/media/usb/dvb-usb/tbs5220.c -new file mode 100644 -index 0000000..7bf7dea ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5220.c -@@ -0,0 +1,500 @@ -+/* -+ * TurboSight TBS 5220 driver -+ * -+ * Copyright (c) 2013 Konstantin Dimitrov -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, version 2. -+ * -+ */ -+ -+#include -+#include "tbs5220.h" -+#include "si2168.h" -+#include "si2157.h" -+ -+#define TBS5220_READ_MSG 0 -+#define TBS5220_WRITE_MSG 1 -+ -+#define TBS5220_RC_QUERY (0x1a00) -+ -+struct tbs5220_state { -+ struct i2c_client *i2c_client_demod; -+ struct i2c_client *i2c_client_tuner; -+ u32 last_key_pressed; -+}; -+ -+/* debug */ -+static int dvb_usb_tbs5220_debug; -+module_param_named(debug, dvb_usb_tbs5220_debug, int, 0644); -+MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." -+ DVB_USB_DEBUG_STATUS); -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+static int tbs5220_op_rw(struct usb_device *dev, u8 request, u16 value, -+ u16 index, u8 * data, u16 len, int flags) -+{ -+ int ret; -+ u8 u8buf[len]; -+ -+ unsigned int pipe = (flags == TBS5220_READ_MSG) ? -+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); -+ u8 request_type = (flags == TBS5220_READ_MSG) ? USB_DIR_IN : -+ USB_DIR_OUT; -+ -+ if (flags == TBS5220_WRITE_MSG) -+ memcpy(u8buf, data, len); -+ ret = usb_control_msg(dev, pipe, request, request_type | -+ USB_TYPE_VENDOR, value, index , u8buf, len, 2000); -+ -+ if (flags == TBS5220_READ_MSG) -+ memcpy(data, u8buf, len); -+ return ret; -+} -+ -+/* I2C */ -+static int tbs5220_i2c_transfer(struct i2c_adapter *adap, -+ struct i2c_msg msg[], int num) -+{ -+ struct dvb_usb_device *d = i2c_get_adapdata(adap); -+ int i = 0; -+ u8 buf6[20]; -+ u8 inbuf[20]; -+ -+ if (!d) -+ return -ENODEV; -+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) -+ return -EAGAIN; -+ -+ switch (num) { -+ case 2: -+ buf6[0]=msg[1].len;//lenth -+ buf6[1]=msg[0].addr<<1;//demod addr -+ //register -+ buf6[2] = msg[0].buf[0]; -+ -+ tbs5220_op_rw(d->udev, 0x90, 0, 0, -+ buf6, 3, TBS5220_WRITE_MSG); -+ //msleep(5); -+ tbs5220_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, buf6[0], TBS5220_READ_MSG); -+ memcpy(msg[1].buf, inbuf, msg[1].len); -+ break; -+ case 1: -+ switch (msg[0].addr) { -+ case 0x64: -+ case 0x60: -+ if (msg[0].flags == 0) { -+ buf6[0] = msg[0].len+1;//lenth -+ buf6[1] = msg[0].addr<<1;//addr -+ for(i=0;iudev, 0x80, 0, 0, -+ buf6, msg[0].len+2, TBS5220_WRITE_MSG); -+ } else { -+ buf6[0] = msg[0].len;//length -+ buf6[1] = (msg[0].addr<<1) | 0x01;//addr -+ tbs5220_op_rw(d->udev, 0x93, 0, 0, -+ buf6, 2, TBS5220_WRITE_MSG); -+ //msleep(5); -+ tbs5220_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, buf6[0], TBS5220_READ_MSG); -+ memcpy(msg[0].buf, inbuf, msg[0].len); -+ } -+ //msleep(3); -+ break; -+ case (TBS5220_RC_QUERY): -+ tbs5220_op_rw(d->udev, 0xb8, 0, 0, -+ buf6, 4, TBS5220_READ_MSG); -+ msg[0].buf[0] = buf6[2]; -+ msg[0].buf[1] = buf6[3]; -+ //msleep(3); -+ //info("TBS5220_RC_QUERY %x %x %x %x\n", -+ // buf6[0],buf6[1],buf6[2],buf6[3]); -+ break; -+ } -+ -+ break; -+ } -+ -+ mutex_unlock(&d->i2c_mutex); -+ return num; -+} -+ -+static u32 tbs5220_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C; -+} -+ -+static struct i2c_algorithm tbs5220_i2c_algo = { -+ .master_xfer = tbs5220_i2c_transfer, -+ .functionality = tbs5220_i2c_func, -+}; -+ -+static int tbs5220_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -+{ -+ int i,ret; -+ u8 ibuf[3] = {0, 0,0}; -+ u8 eeprom[256], eepromline[16]; -+ -+ for (i = 0; i < 256; i++) { -+ ibuf[0]=1;//lenth -+ ibuf[1]=0xa0;//eeprom addr -+ ibuf[2]=i;//register -+ ret = tbs5220_op_rw(d->udev, 0x90, 0, 0, -+ ibuf, 3, TBS5220_WRITE_MSG); -+ ret = tbs5220_op_rw(d->udev, 0x91, 0, 0, -+ ibuf, 1, TBS5220_READ_MSG); -+ if (ret < 0) { -+ err("read eeprom failed."); -+ return -1; -+ } else { -+ eepromline[i%16] = ibuf[0]; -+ eeprom[i] = ibuf[0]; -+ } -+ -+ if ((i % 16) == 15) { -+ deb_xfer("%02x: ", i - 15); -+ debug_dump(eepromline, 16, deb_xfer); -+ } -+ } -+ memcpy(mac, eeprom + 16, 6); -+ return 0; -+}; -+ -+static struct dvb_usb_device_properties tbs5220_properties; -+ -+static int tbs5220_frontend_attach(struct dvb_usb_adapter *adap) -+{ -+ struct dvb_usb_device *d = adap->dev; -+ struct tbs5220_state *st = d->priv; -+ struct i2c_adapter *adapter; -+ struct i2c_client *client_demod; -+ struct i2c_client *client_tuner; -+ struct i2c_board_info info; -+ struct si2168_config si2168_config; -+ struct si2157_config si2157_config; -+ u8 buf[20]; -+ -+ /* attach frontend */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.i2c_adapter = &adapter; -+ si2168_config.fe = &adap->fe_adap[0].fe; -+ si2168_config.ts_mode = SI2168_TS_PARALLEL; -+ si2168_config.ts_clock_gapped = true; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2168", I2C_NAME_SIZE); -+ info.addr = 0x64; -+ info.platform_data = &si2168_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(&d->i2c_adap, &info); -+ if (client_demod == NULL || client_demod->dev.driver == NULL) -+ return -ENODEV; -+ -+ if (!try_module_get(client_demod->dev.driver->owner)) { -+ i2c_unregister_device(client_demod); -+ return -ENODEV; -+ } -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = adap->fe_adap[0].fe; -+ si2157_config.if_port = 1; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client_tuner = i2c_new_device(adapter, &info); -+ if (client_tuner == NULL || client_tuner->dev.driver == NULL) { -+ module_put(client_demod->dev.driver->owner); -+ i2c_unregister_device(client_demod); -+ return -ENODEV; -+ } -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ module_put(client_demod->dev.driver->owner); -+ i2c_unregister_device(client_demod); -+ return -ENODEV; -+ } -+ -+ st->i2c_client_demod = client_demod; -+ st->i2c_client_tuner = client_tuner; -+ -+ buf[0] = 0; -+ buf[1] = 0; -+ tbs5220_op_rw(d->udev, 0xb7, 0, 0, -+ buf, 2, TBS5220_WRITE_MSG); -+ buf[0] = 8; -+ buf[1] = 1; -+ tbs5220_op_rw(d->udev, 0x8a, 0, 0, -+ buf, 2, TBS5220_WRITE_MSG); -+ -+ buf[0] = 7; -+ buf[1] = 1; -+ tbs5220_op_rw(d->udev, 0x8a, 0, 0, -+ buf, 2, TBS5220_WRITE_MSG); -+ -+ buf[0] = 6; -+ buf[1] = 1; -+ tbs5220_op_rw(d->udev, 0x8a, 0, 0, -+ buf, 2, TBS5220_WRITE_MSG); -+ -+ strlcpy(adap->fe_adap->fe->ops.info.name,d->props.devices[0].name,52); -+ -+ return 0; -+} -+ -+static struct rc_map_table tbs5220_rc_keys[] = { -+ { 0xff84, KEY_POWER2}, /* power */ -+ { 0xff94, KEY_MUTE}, /* mute */ -+ { 0xff87, KEY_1}, -+ { 0xff86, KEY_2}, -+ { 0xff85, KEY_3}, -+ { 0xff8b, KEY_4}, -+ { 0xff8a, KEY_5}, -+ { 0xff89, KEY_6}, -+ { 0xff8f, KEY_7}, -+ { 0xff8e, KEY_8}, -+ { 0xff8d, KEY_9}, -+ { 0xff92, KEY_0}, -+ { 0xff96, KEY_CHANNELUP}, /* ch+ */ -+ { 0xff91, KEY_CHANNELDOWN}, /* ch- */ -+ { 0xff93, KEY_VOLUMEUP}, /* vol+ */ -+ { 0xff8c, KEY_VOLUMEDOWN}, /* vol- */ -+ { 0xff83, KEY_RECORD}, /* rec */ -+ { 0xff98, KEY_PAUSE}, /* pause, yellow */ -+ { 0xff99, KEY_OK}, /* ok */ -+ { 0xff9a, KEY_CAMERA}, /* snapshot */ -+ { 0xff81, KEY_UP}, -+ { 0xff90, KEY_LEFT}, -+ { 0xff82, KEY_RIGHT}, -+ { 0xff88, KEY_DOWN}, -+ { 0xff95, KEY_FAVORITES}, /* blue */ -+ { 0xff97, KEY_SUBTITLE}, /* green */ -+ { 0xff9d, KEY_ZOOM}, -+ { 0xff9f, KEY_EXIT}, -+ { 0xff9e, KEY_MENU}, -+ { 0xff9c, KEY_EPG}, -+ { 0xff80, KEY_PREVIOUS}, /* red */ -+ { 0xff9b, KEY_MODE}, -+ { 0xffdd, KEY_TV }, -+ { 0xffde, KEY_PLAY }, -+ { 0xffdc, KEY_STOP }, -+ { 0xffdb, KEY_REWIND }, -+ { 0xffda, KEY_FASTFORWARD }, -+ { 0xffd9, KEY_PREVIOUS }, /* replay */ -+ { 0xffd8, KEY_NEXT }, /* skip */ -+ { 0xffd1, KEY_NUMERIC_STAR }, -+ { 0xffd2, KEY_NUMERIC_POUND }, -+ { 0xffd4, KEY_DELETE }, /* clear */ -+}; -+ -+static int tbs5220_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -+{ -+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; -+ int keymap_size = d->props.rc.legacy.rc_map_size; -+ -+ struct tbs5220_state *st = d->priv; -+ u8 key[2]; -+ struct i2c_msg msg[] = { -+ {.addr = TBS5220_RC_QUERY, .flags = I2C_M_RD, .buf = key, -+ .len = 2}, -+ }; -+ int i; -+ -+ *state = REMOTE_NO_KEY_PRESSED; -+ if (tbs5220_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { -+ //info("key: %x %x\n",msg[0].buf[0],msg[0].buf[1]); -+ for (i = 0; i < keymap_size; i++) { -+ if (rc5_data(&keymap[i]) == msg[0].buf[1]) { -+ *state = REMOTE_KEY_PRESSED; -+ *event = keymap[i].keycode; -+ st->last_key_pressed = -+ keymap[i].keycode; -+ break; -+ } -+ st->last_key_pressed = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct usb_device_id tbs5220_table[] = { -+ {USB_DEVICE(0x734c, 0x5220)}, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(usb, tbs5220_table); -+ -+static int tbs5220_load_firmware(struct usb_device *dev, -+ const struct firmware *frmwr) -+{ -+ u8 *b, *p; -+ int ret = 0, i; -+ u8 reset; -+ const struct firmware *fw; -+ switch (dev->descriptor.idProduct) { -+ case 0x5220: -+ ret = request_firmware(&fw, tbs5220_properties.firmware, &dev->dev); -+ if (ret != 0) { -+ err("did not find the firmware file. (%s) " -+ "Please see linux/Documentation/dvb/ for more details " -+ "on firmware-problems.", tbs5220_properties.firmware); -+ return ret; -+ } -+ break; -+ default: -+ fw = frmwr; -+ break; -+ } -+ info("start downloading TBS5220 firmware"); -+ p = kmalloc(fw->size, GFP_KERNEL); -+ reset = 1; -+ /*stop the CPU*/ -+ tbs5220_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, TBS5220_WRITE_MSG); -+ tbs5220_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, TBS5220_WRITE_MSG); -+ -+ if (p != NULL) { -+ memcpy(p, fw->data, fw->size); -+ for (i = 0; i < fw->size; i += 0x40) { -+ b = (u8 *) p + i; -+ if (tbs5220_op_rw(dev, 0xa0, i, 0, b , 0x40, -+ TBS5220_WRITE_MSG) != 0x40) { -+ err("error while transferring firmware"); -+ ret = -EINVAL; -+ break; -+ } -+ } -+ /* restart the CPU */ -+ reset = 0; -+ if (ret || tbs5220_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, -+ TBS5220_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ if (ret || tbs5220_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, -+ TBS5220_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ -+ msleep(100); -+ kfree(p); -+ } -+ return ret; -+} -+ -+static struct dvb_usb_device_properties tbs5220_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .firmware = "dvb-usb-tbsqbox-id5220.fw", -+ .size_of_priv = sizeof(struct tbs5220_state), -+ .no_reconnect = 1, -+ -+ .i2c_algo = &tbs5220_i2c_algo, -+ .rc.legacy = { -+ .rc_map_table = tbs5220_rc_keys, -+ .rc_map_size = ARRAY_SIZE(tbs5220_rc_keys), -+ .rc_interval = 150, -+ .rc_query = tbs5220_rc_query, -+ }, -+ -+ .generic_bulk_ctrl_endpoint = 0x81, -+ /* parameter for the MPEG2-data transfer */ -+ .num_adapters = 1, -+ .download_firmware = tbs5220_load_firmware, -+ .read_mac_address = tbs5220_read_mac_address, -+ .adapter = {{ -+ .num_frontends = 1, -+ .fe = {{ -+ .frontend_attach = tbs5220_frontend_attach, -+ .streaming_ctrl = NULL, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ }, -+ }}, -+ }}, -+ -+ .num_device_descs = 1, -+ .devices = { -+ {"TurboSight TBS 5220 DVB-T/T2/C", -+ {&tbs5220_table[0], NULL}, -+ {NULL}, -+ } -+ } -+}; -+ -+static int tbs5220_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ if (0 == dvb_usb_device_init(intf, &tbs5220_properties, -+ THIS_MODULE, NULL, adapter_nr)) { -+ return 0; -+ } -+ return -ENODEV; -+} -+ -+static void tbs5220_disconnect(struct usb_interface *intf) -+{ -+#if 0 -+ struct dvb_usb_device *d = usb_get_intfdata(intf); -+ struct tbs5220_state *st = d->priv; -+ struct i2c_client *client; -+ -+ /* remove I2C client for tuner */ -+ client = st->i2c_client_tuner; -+ if (client) { -+ module_put(client->dev.driver->owner); -+ i2c_unregister_device(client); -+ } -+ -+ /* remove I2C client for demodulator */ -+ client = st->i2c_client_demod; -+ if (client) { -+ module_put(client->dev.driver->owner); -+ i2c_unregister_device(client); -+ } -+#endif -+ dvb_usb_device_exit(intf); -+} -+ -+static struct usb_driver tbs5220_driver = { -+ .name = "tbs5220", -+ .probe = tbs5220_probe, -+ .disconnect = tbs5220_disconnect, -+ .id_table = tbs5220_table, -+}; -+ -+static int __init tbs5220_module_init(void) -+{ -+ int ret = usb_register(&tbs5220_driver); -+ if (ret) -+ err("usb_register failed. Error number %d", ret); -+ -+ return ret; -+} -+ -+static void __exit tbs5220_module_exit(void) -+{ -+ usb_deregister(&tbs5220_driver); -+} -+ -+module_init(tbs5220_module_init); -+module_exit(tbs5220_module_exit); -+ -+MODULE_AUTHOR("Konstantin Dimitrov "); -+MODULE_DESCRIPTION("TurboSight TBS 5220 driver"); -+MODULE_VERSION("1.0"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/usb/dvb-usb/tbs5220.h b/drivers/media/usb/dvb-usb/tbs5220.h -new file mode 100644 -index 0000000..52595cf ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5220.h -@@ -0,0 +1,8 @@ -+#ifndef _TBS5220_H_ -+#define _TBS5220_H_ -+ -+#define DVB_USB_LOG_PREFIX "tbs5220" -+#include "dvb-usb.h" -+ -+#define deb_xfer(args...) dprintk(dvb_usb_tbs5220_debug, 0x02, args) -+#endif -diff --git a/drivers/media/usb/dvb-usb/tbs5520.c b/drivers/media/usb/dvb-usb/tbs5520.c -new file mode 100644 -index 0000000..37849bd ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5520.c -@@ -0,0 +1,518 @@ -+/* -+ * TurboSight TBS 5520 driver -+ * -+ * Copyright (c) 2013 Konstantin Dimitrov -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, version 2. -+ * -+ */ -+ -+#include -+#include "tbs5520.h" -+ -+#include "avl6882.h" -+#include "r848.h" -+ -+#ifndef USB_PID_tbs5520 -+#define USB_PID_tbs5520 0x5520 -+#endif -+ -+#define tbs5520_READ_MSG 0 -+#define tbs5520_WRITE_MSG 1 -+ -+#define tbs5520_RC_QUERY (0x1a00) -+ -+struct tbs5520_state { -+ u32 last_key_pressed; -+}; -+ -+/* debug */ -+static int dvb_usb_tbs5520_debug; -+module_param_named(debug, dvb_usb_tbs5520_debug, int, 0644); -+MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." -+ DVB_USB_DEBUG_STATUS); -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+static int tbs5520_op_rw(struct usb_device *dev, u8 request, u16 value, -+ u16 index, u8 *data, u16 len, int flags) -+{ -+ int ret; -+ u8 u8buf[len]; -+ -+ unsigned int pipe = (flags == tbs5520_READ_MSG) ? -+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); -+ u8 request_type = (flags == tbs5520_READ_MSG) ? USB_DIR_IN : -+ USB_DIR_OUT; -+ -+ if (flags == tbs5520_WRITE_MSG) -+ memcpy(u8buf, data, len); -+ ret = usb_control_msg(dev, pipe, request, request_type | -+ USB_TYPE_VENDOR, value, index , u8buf, len, 2000); -+ -+ if (flags == tbs5520_READ_MSG) -+ memcpy(data, u8buf, len); -+ return ret; -+} -+ -+/* I2C */ -+ -+#define MAX_I2C_LEN 62 -+ -+static int tbs5520_i2c_transfer(struct i2c_adapter *adap, -+ struct i2c_msg msg[], int num) -+{ -+ struct dvb_usb_device *d = i2c_get_adapdata(adap); -+ int i; -+ u8 txbuf[64]; -+ -+ if (msg[0].addr == tbs5520_RC_QUERY) -+ return -ENODEV; -+ -+ if (!d) -+ return -ENODEV; -+ -+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) -+ return -EAGAIN; -+ -+ for (i = 0; i < num; i++) { -+ if (msg[i].len > MAX_I2C_LEN) -+ break; -+ if (msg[i].buf == NULL) -+ break; -+ -+ if (msg[i].flags & I2C_M_RD) { -+ //printk("RD: saddr=%02x len=%d:", msg[i].addr, msg[i].len); -+ /* read */ -+ txbuf[0] = msg[i].len; -+ txbuf[1] = (msg[i].addr << 1) | 1; -+ tbs5520_op_rw(d->udev, 0x93, 0, 0, txbuf, 2, tbs5520_WRITE_MSG); -+ tbs5520_op_rw(d->udev, 0x91, 0, 0, msg[i].buf, msg[i].len, tbs5520_READ_MSG); -+ //for (j = 0; j < msg[i].len; j++) -+ // printk(" %02x", msg[i].buf[j]); -+ //printk("\n"); -+ } else { -+ //printk("WR: saddr=%02x len=%d:", msg[i].addr, msg[i].len); -+ //for (j = 0; j < msg[i].len; j++) -+ // printk(" %02x", msg[i].buf[j]); -+ //printk("\n"); -+ txbuf[0] = msg[i].len + 1; -+ txbuf[1] = msg[i].addr << 1; -+ memcpy(&txbuf[2], msg[i].buf, msg[i].len); -+ tbs5520_op_rw(d->udev, 0x80, 0, 0, txbuf, msg[i].len + 2, tbs5520_WRITE_MSG); -+ } -+ } -+ -+ //printk("msg=%d\n", i); -+#if 0 -+ -+ switch (num) { -+ case 2: -+ printk("wr-rd: adr=%02x rd_len=%02x", msg[0].addr, msg[1].len); -+ buf6[0] = msg[1].len; // lenth -+ buf6[1] = (msg[0].addr<<1)+1; // slave addr -+ -+ -+ //register -+ //buf6[2] = 0; -+ -+ /* wr,rd | 0x90 -> 0x91 -+ wr | 0x80 -+ rd | 0x90 -> 0x91 -+ */ -+ -+ /* request 0x80 = i2c write (data=[wr_len+1, slave_addr, buf...] len=wr_len+2) */ -+ /* request 0x82 = i2c write (data=buf, len=64) -- no i2c stop? -- */ -+ -+ /* request 0x90 = i2c read n bytes (data=[rd_len, slave_addr, x?]; len=2+x?) */ -+ /* request 0x91 = i2c grab received data (data=buf, len=rd_len) */ -+ -+ /* request 0x92 = i2c read n bytes 16bit reg? (data=[rd_len, slave_addr, r1, r2]; len=4) */ -+ /* request 0x93 = i2c read n bytes (data=[rd_len, slave_addr | 1]; len=2) */ -+ -+ /* tbs5520_op_rw(struct usb_device *dev, u8 request, u16 value, u16 index, u8 * data, u16 len, int flags) */ -+ -+ tbs5520_op_rw(d->udev, 0x93, 0, 0, buf6, 2, tbs5520_WRITE_MSG); -+ //msleep(5); -+ tbs5520_op_rw(d->udev, 0x91, 0, 0, inbuf, buf6[0], tbs5520_READ_MSG); -+ memcpy(msg[1].buf, inbuf, msg[1].len); -+ -+ for (i = 0; i < msg[1].len; i++) -+ printk(" %02x", inbuf[i]); -+ -+ printk("\n"); -+ break; -+ case 1: -+ switch (msg[0].addr) { -+ case 0x14: -+ case 0x7a: -+ if (msg[0].flags == 0) { -+ buf6[0] = msg[0].len+1;//lenth -+ buf6[1] = msg[0].addr<<1;//addr -+ for(i=0;iudev, 0x80, 0, 0, buf6, msg[0].len+2, tbs5520_WRITE_MSG); -+ } else { -+ printk("wr_1:"); -+ for (i = 0; i < msg[0].len; i++) -+ printk(" %02x", msg[0].buf[i]); -+ tbs5520_op_rw(d->udev, 0x82, 0, 0, msg[0].buf, 64, tbs5520_WRITE_MSG); -+ } -+ printk("\n"); -+ -+ //msleep(3); -+ break; -+ -+ case (tbs5520_RC_QUERY): -+ tbs5520_op_rw(d->udev, 0xb8, 0, 0, -+ buf6, 4, tbs5520_READ_MSG); -+ msg[0].buf[0] = buf6[2]; -+ msg[0].buf[1] = buf6[3]; -+ //msleep(3); -+ //info("tbs5520_RC_QUERY %x %x %x %x\n", -+ // buf6[0],buf6[1],buf6[2],buf6[3]); -+ break; -+ } -+ -+ break; -+ } -+ -+#endif -+ mutex_unlock(&d->i2c_mutex); -+ return i; -+} -+ -+static u32 tbs5520_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -+} -+ -+static struct r848_config r848_config = { -+ .i2c_address = 0x7a, -+ .xtal = 16000000, -+ -+ .R848_DetectTfType = 0, //R848_UL_USING_BEAD, -+ .R848_Xtal_Pwr = 3, //XTAL_SMALL_HIGHEST, -+ .R848_Xtal_Pwr_tmp = 4, //XTAL_LARGE_HIGHEST, -+ -+ /* dvb t/c */ -+ .R848_SetTfType = 1, //R848_TF_BEAD, -+}; -+ -+ -+static struct avl6882_config avl6882_config = { -+ .demod_address = 0x14, -+}; -+ -+static struct i2c_algorithm tbs5520_i2c_algo = { -+ .master_xfer = tbs5520_i2c_transfer, -+ .functionality = tbs5520_i2c_func, -+}; -+ -+static int tbs5520_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -+{ -+ -+ int i,ret; -+ -+ -+ u8 ibuf[3] = {0, 0,0}; -+ u8 eeprom[256], eepromline[16]; -+ -+return 0; -+ -+ for (i = 0; i < 256; i++) { -+ ibuf[0]=1;//lenth -+ ibuf[1]=0xa0;//eeprom addr -+ ibuf[2]=i;//register -+ ret = tbs5520_op_rw(d->udev, 0x90, 0, 0, -+ ibuf, 3, tbs5520_WRITE_MSG); -+ ret = tbs5520_op_rw(d->udev, 0x91, 0, 0, -+ ibuf, 1, tbs5520_READ_MSG); -+ if (ret < 0) { -+ err("read eeprom failed."); -+ return -1; -+ } else { -+ eepromline[i%16] = ibuf[0]; -+ eeprom[i] = ibuf[0]; -+ } -+ -+ if ((i % 16) == 15) { -+ deb_xfer("%02x: ", i - 15); -+ debug_dump(eepromline, 16, deb_xfer); -+ } -+ } -+ memcpy(mac, eeprom + 16, 6); -+ return 0; -+}; -+ -+static struct dvb_usb_device_properties tbs5520_properties; -+ -+static int tbs5520_frontend_attach(struct dvb_usb_adapter *d) -+{ -+ u8 buf[2]; -+ -+ d->fe_adap->fe = dvb_attach(avl6882_attach, &avl6882_config, -+ &d->dev->i2c_adap); -+ if (d->fe_adap->fe == NULL) -+ goto err; -+ -+ if (dvb_attach(r848_attach, d->fe_adap->fe, &r848_config, -+ &d->dev->i2c_adap) == NULL) { -+ dvb_frontend_detach(d->fe_adap->fe); -+ d->fe_adap->fe = NULL; -+ printk("TBS5520: tuner attach failed\n"); -+ goto err; -+ } -+ -+ info("TBS5520: frontend attached\n"); -+ buf[0] = 7; -+ buf[1] = 1; -+ tbs5520_op_rw(d->dev->udev, 0x8a, 0, 0, -+ buf, 2, tbs5520_WRITE_MSG); -+ -+ buf[0] = 6; -+ buf[1] = 1; -+ tbs5520_op_rw(d->dev->udev, 0x8a, 0, 0, -+ buf, 2, tbs5520_WRITE_MSG); -+ -+ return 0; -+err: -+ printk("TBS5520: frontend attach failed\n"); -+ return -ENODEV; -+} -+ -+static struct rc_map_table tbs5520_rc_keys[] = { -+ { 0xff84, KEY_POWER2}, /* power */ -+ { 0xff94, KEY_MUTE}, /* mute */ -+ { 0xff87, KEY_1}, -+ { 0xff86, KEY_2}, -+ { 0xff85, KEY_3}, -+ { 0xff8b, KEY_4}, -+ { 0xff8a, KEY_5}, -+ { 0xff89, KEY_6}, -+ { 0xff8f, KEY_7}, -+ { 0xff8e, KEY_8}, -+ { 0xff8d, KEY_9}, -+ { 0xff92, KEY_0}, -+ { 0xff96, KEY_CHANNELUP}, /* ch+ */ -+ { 0xff91, KEY_CHANNELDOWN}, /* ch- */ -+ { 0xff93, KEY_VOLUMEUP}, /* vol+ */ -+ { 0xff8c, KEY_VOLUMEDOWN}, /* vol- */ -+ { 0xff83, KEY_RECORD}, /* rec */ -+ { 0xff98, KEY_PAUSE}, /* pause, yellow */ -+ { 0xff99, KEY_OK}, /* ok */ -+ { 0xff9a, KEY_CAMERA}, /* snapshot */ -+ { 0xff81, KEY_UP}, -+ { 0xff90, KEY_LEFT}, -+ { 0xff82, KEY_RIGHT}, -+ { 0xff88, KEY_DOWN}, -+ { 0xff95, KEY_FAVORITES}, /* blue */ -+ { 0xff97, KEY_SUBTITLE}, /* green */ -+ { 0xff9d, KEY_ZOOM}, -+ { 0xff9f, KEY_EXIT}, -+ { 0xff9e, KEY_MENU}, -+ { 0xff9c, KEY_EPG}, -+ { 0xff80, KEY_PREVIOUS}, /* red */ -+ { 0xff9b, KEY_MODE}, -+ { 0xffdd, KEY_TV }, -+ { 0xffde, KEY_PLAY }, -+ { 0xffdc, KEY_STOP }, -+ { 0xffdb, KEY_REWIND }, -+ { 0xffda, KEY_FASTFORWARD }, -+ { 0xffd9, KEY_PREVIOUS }, /* replay */ -+ { 0xffd8, KEY_NEXT }, /* skip */ -+ { 0xffd1, KEY_NUMERIC_STAR }, -+ { 0xffd2, KEY_NUMERIC_POUND }, -+ { 0xffd4, KEY_DELETE }, /* clear */ -+}; -+ -+static int tbs5520_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -+{ -+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; -+ int keymap_size = d->props.rc.legacy.rc_map_size; -+ -+ struct tbs5520_state *st = d->priv; -+ u8 key[2]; -+ struct i2c_msg msg[] = { -+ {.addr = tbs5520_RC_QUERY, .flags = I2C_M_RD, .buf = key, -+ .len = 2}, -+ }; -+ int i; -+ -+ *state = REMOTE_NO_KEY_PRESSED; -+ if (tbs5520_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { -+ //info("key: %x %x\n",msg[0].buf[0],msg[0].buf[1]); -+ for (i = 0; i < keymap_size; i++) { -+ if (rc5_data(&keymap[i]) == msg[0].buf[1]) { -+ *state = REMOTE_KEY_PRESSED; -+ *event = keymap[i].keycode; -+ st->last_key_pressed = -+ keymap[i].keycode; -+ break; -+ } -+ st->last_key_pressed = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct usb_device_id tbs5520_table[] = { -+ {USB_DEVICE(0x734c, 0x5520)}, -+ {USB_DEVICE(0x734c, 0x5922)}, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(usb, tbs5520_table); -+ -+static int tbs5520_load_firmware(struct usb_device *dev, -+ const struct firmware *frmwr) -+{ -+ u8 *b, *p; -+ int ret = 0, i; -+ u8 reset; -+ const struct firmware *fw; -+ const char *filename = "dvb-usb-tbs5520-01.fw"; -+ switch (dev->descriptor.idProduct) { -+ case 0xdc02: -+ ret = request_firmware(&fw, filename, &dev->dev); -+ if (ret != 0) { -+ err("did not find the firmware file. (%s) " -+ "Please see linux/Documentation/dvb/ for more details " -+ "on firmware-problems.", filename); -+ return ret; -+ } -+ break; -+ default: -+ fw = frmwr; -+ break; -+ } -+ info("start downloading tbs5520 firmware"); -+ p = kmalloc(fw->size, GFP_KERNEL); -+ reset = 1; -+ /*stop the CPU*/ -+ tbs5520_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, tbs5520_WRITE_MSG); -+ tbs5520_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, tbs5520_WRITE_MSG); -+ -+ if (p != NULL) { -+ memcpy(p, fw->data, fw->size); -+ for (i = 0; i < fw->size; i += 0x40) { -+ b = (u8 *) p + i; -+ if (tbs5520_op_rw(dev, 0xa0, i, 0, b , 0x40, -+ tbs5520_WRITE_MSG) != 0x40) { -+ err("error while transferring firmware"); -+ ret = -EINVAL; -+ break; -+ } -+ } -+ /* restart the CPU */ -+ reset = 0; -+ if (ret |= tbs5520_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, -+ tbs5520_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ if (ret |= tbs5520_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, -+ tbs5520_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ -+ msleep(100); -+ kfree(p); -+ } -+ info("end downloading tbs5520 firmware"); -+ return ret; -+} -+ -+static struct dvb_usb_device_properties tbs5520_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .firmware = "dvb-usb-tbs5520-01.fw", -+ .download_firmware = tbs5520_load_firmware, -+ .size_of_priv = sizeof(struct tbs5520_state), -+ .no_reconnect = 1, -+ -+ .i2c_algo = &tbs5520_i2c_algo, -+ -+ .rc.legacy = { -+ .rc_map_table = tbs5520_rc_keys, -+ .rc_map_size = ARRAY_SIZE(tbs5520_rc_keys), -+ .rc_interval = 150, -+ .rc_query = tbs5520_rc_query, -+ }, -+ -+ .generic_bulk_ctrl_endpoint = 0x81, -+ /* parameter for the MPEG2-data transfer */ -+ .num_adapters = 1, -+ -+ .read_mac_address = tbs5520_read_mac_address, -+ .adapter = {{ -+ .num_frontends = 1, -+ .fe = {{ -+ .frontend_attach = tbs5520_frontend_attach, -+ .streaming_ctrl = NULL, -+ .tuner_attach = NULL, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ }, -+ }}, -+ }}, -+ .num_device_descs = 1, -+ .devices = { -+ {"TBS 5520 USB2.0", {&tbs5520_table[0], NULL}, {NULL}, }, -+ } -+}; -+ -+ -+static int tbs5520_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ if (0 == dvb_usb_device_init(intf, &tbs5520_properties, -+ THIS_MODULE, NULL, adapter_nr)) { -+ return 0; -+ } -+ return -ENODEV; -+} -+ -+static struct usb_driver tbs5520_driver = { -+ .name = "tbs5520", -+ .probe = tbs5520_probe, -+ .disconnect = dvb_usb_device_exit, -+ .id_table = tbs5520_table, -+}; -+ -+static int __init tbs5520_module_init(void) -+{ -+ int ret = usb_register(&tbs5520_driver); -+ if (ret) -+ err("usb_register failed. Error number %d", ret); -+ -+ return ret; -+} -+ -+static void __exit tbs5520_module_exit(void) -+{ -+ usb_deregister(&tbs5520_driver); -+} -+ -+module_init(tbs5520_module_init); -+module_exit(tbs5520_module_exit); -+ -+MODULE_AUTHOR("Konstantin Dimitrov "); -+MODULE_DESCRIPTION("TurboSight TBS 5520 driver"); -+MODULE_VERSION("1.0"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/usb/dvb-usb/tbs5520.h b/drivers/media/usb/dvb-usb/tbs5520.h -new file mode 100644 -index 0000000..20796a7 ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5520.h -@@ -0,0 +1,8 @@ -+#ifndef _TBS5520_H_ -+#define _TBS5520_H_ -+ -+#define DVB_USB_LOG_PREFIX "tbs5520" -+#include "dvb-usb.h" -+ -+#define deb_xfer(args...) dprintk(dvb_usb_tbs5520_debug, 0x02, args) -+#endif -diff --git a/drivers/media/usb/dvb-usb/tbs5880.c b/drivers/media/usb/dvb-usb/tbs5880.c -new file mode 100644 -index 0000000..880f53a ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5880.c -@@ -0,0 +1,835 @@ -+/* -+ * TurboSight TBS 5880 CI driver -+ * -+ * Copyright (c) 2011 Konstantin Dimitrov -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, version 2. -+ * -+ */ -+ -+#include -+#include "tbs5880.h" -+#include "tda18212.h" -+#include "cxd2820r.h" -+ -+#include "dvb_ca_en50221.h" -+ -+#define TBS5880_READ_MSG 0 -+#define TBS5880_WRITE_MSG 1 -+ -+#define TBS5880_RC_QUERY (0x1a00) -+#define TBS5880_LED_CTRL (0x1b00) -+ -+struct tbs5880_state { -+ struct dvb_ca_en50221 ca; -+ struct mutex ca_mutex; -+ -+ u32 last_key_pressed; -+ -+ struct i2c_client *i2c_client_tuner; -+}; -+ -+/*struct tbs5880_rc_keys { -+ u32 keycode; -+ u32 event; -+};*/ -+ -+/* debug */ -+static int dvb_usb_tbs5880_debug; -+module_param_named(debug, dvb_usb_tbs5880_debug, int, 0644); -+MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." -+ DVB_USB_DEBUG_STATUS); -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+static int tbs5880_op_rw(struct usb_device *dev, u8 request, u16 value, -+ u16 index, u8 * data, u16 len, int flags) -+{ -+ int ret; -+ u8 u8buf[len]; -+ -+ unsigned int pipe = (flags == TBS5880_READ_MSG) ? -+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); -+ u8 request_type = (flags == TBS5880_READ_MSG) ? USB_DIR_IN : -+ USB_DIR_OUT; -+ -+ if (flags == TBS5880_WRITE_MSG) -+ memcpy(u8buf, data, len); -+ ret = usb_control_msg(dev, pipe, request, request_type | -+ USB_TYPE_VENDOR, value, index , u8buf, len, 2000); -+ -+ if (flags == TBS5880_READ_MSG) -+ memcpy(data, u8buf, len); -+ return ret; -+} -+ -+static int tbs5880_read_attribute_mem(struct dvb_ca_en50221 *ca, -+ int slot, int address) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5880_state *state = (struct tbs5880_state *)d->priv; -+ u8 buf[4], rbuf[3]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 1; -+ buf[1] = 0; -+ buf[2] = (address >> 8) & 0x0f; -+ buf[3] = address; -+ -+ //msleep(10); -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbs5880_op_rw(d->udev, 0xa4, 0, 0, -+ buf, 4, TBS5880_WRITE_MSG); -+ -+ //msleep(1); -+ -+ ret = tbs5880_op_rw(d->udev, 0xa5, 0, 0, -+ rbuf, 1, TBS5880_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return rbuf[0]; -+} -+ -+static int tbs5880_write_attribute_mem(struct dvb_ca_en50221 *ca, -+ int slot, int address, u8 value) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5880_state *state = (struct tbs5880_state *)d->priv; -+ u8 buf[5];//, rbuf[1]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 1; -+ buf[1] = 0; -+ buf[2] = (address >> 8) & 0x0f; -+ buf[3] = address; -+ buf[4] = value; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbs5880_op_rw(d->udev, 0xa2, 0, 0, -+ buf, 5, TBS5880_WRITE_MSG); -+ -+ //msleep(1); -+ -+ //ret = tbs5880_op_rw(d->udev, 0xa5, 0, 0, -+ // rbuf, 1, TBS5880_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int tbs5880_read_cam_control(struct dvb_ca_en50221 *ca, int slot, -+ u8 address) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5880_state *state = (struct tbs5880_state *)d->priv; -+ u8 buf[4], rbuf[1]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 1; -+ buf[1] = 1; -+ buf[2] = (address >> 8) & 0x0f; -+ buf[3] = address; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbs5880_op_rw(d->udev, 0xa4, 0, 0, -+ buf, 4, TBS5880_WRITE_MSG); -+ -+ //msleep(10); -+ -+ ret = tbs5880_op_rw(d->udev, 0xa5, 0, 0, -+ rbuf, 1, TBS5880_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return rbuf[0]; -+} -+ -+static int tbs5880_write_cam_control(struct dvb_ca_en50221 *ca, int slot, -+ u8 address, u8 value) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5880_state *state = (struct tbs5880_state *)d->priv; -+ u8 buf[5];//, rbuf[1]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 1; -+ buf[1] = 1; -+ buf[2] = (address >> 8) & 0x0f; -+ buf[3] = address; -+ buf[4] = value; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbs5880_op_rw(d->udev, 0xa2, 0, 0, -+ buf, 5, TBS5880_WRITE_MSG); -+ -+ //msleep(1); -+ -+ //ret = tbs5880_op_rw(d->udev, 0xa5, 0, 0, -+ // rbuf, 1, TBS5880_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int tbs5880_set_video_port(struct dvb_ca_en50221 *ca, -+ int slot, int enable) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5880_state *state = (struct tbs5880_state *)d->priv; -+ u8 buf[2]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 2; -+ buf[1] = enable; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbs5880_op_rw(d->udev, 0xa6, 0, 0, -+ buf, 2, TBS5880_WRITE_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ if (enable != buf[1]) { -+ err("CI not %sabled.", enable ? "en" : "dis"); -+ return -EIO; -+ } -+ -+ info("CI %sabled.", enable ? "en" : "dis"); -+ return 0; -+} -+ -+static int tbs5880_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) -+{ -+ return tbs5880_set_video_port(ca, slot, /* enable */ 0); -+} -+ -+static int tbs5880_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) -+{ -+ return tbs5880_set_video_port(ca, slot, /* enable */ 1); -+} -+ -+static int tbs5880_slot_reset(struct dvb_ca_en50221 *ca, int slot) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5880_state *state = (struct tbs5880_state *)d->priv; -+ u8 buf[2]; -+ int ret; -+ -+ if (0 != slot) { -+ return -EINVAL; -+ } -+ -+ buf[0] = 1; -+ buf[1] = 0; -+ -+ mutex_lock (&state->ca_mutex); -+ -+ ret = tbs5880_op_rw(d->udev, 0xa6, 0, 0, -+ buf, 2, TBS5880_WRITE_MSG); -+ -+ msleep (5); -+ -+ buf[1] = 1; -+ -+ ret = tbs5880_op_rw(d->udev, 0xa6, 0, 0, -+ buf, 2, TBS5880_WRITE_MSG); -+ -+ msleep (1400); -+ -+ mutex_unlock (&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int tbs5880_poll_slot_status(struct dvb_ca_en50221 *ca, -+ int slot, int open) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5880_state *state = (struct tbs5880_state *)d->priv; -+ u8 buf[3]; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ tbs5880_op_rw(d->udev, 0xa8, 0, 0, -+ buf, 3, TBS5880_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if ((1 == buf[2]) && (1 == buf[1]) && (0xa9 == buf[0])) { -+ return (DVB_CA_EN50221_POLL_CAM_PRESENT | -+ DVB_CA_EN50221_POLL_CAM_READY); -+ } else { -+ return 0; -+ } -+} -+ -+static void tbs5880_uninit(struct dvb_usb_device *d) -+{ -+ struct tbs5880_state *state; -+ struct i2c_client *client; -+ -+ if (NULL == d) -+ return; -+ -+ state = (struct tbs5880_state *)d->priv; -+ if (NULL == state) -+ return; -+ -+ if (NULL == state->ca.data) -+ return; -+ -+ /* remove I2C tuner */ -+ client = state->i2c_client_tuner; -+ if (client) { -+ module_put(client->dev.driver->owner); -+ i2c_unregister_device(client); -+ } -+ -+ /* Error ignored. */ -+ tbs5880_set_video_port(&state->ca, /* slot */ 0, /* enable */ 0); -+ -+ dvb_ca_en50221_release(&state->ca); -+ -+ memset(&state->ca, 0, sizeof(state->ca)); -+} -+ -+static int tbs5880_init(struct dvb_usb_adapter *a) -+{ -+ -+ struct dvb_usb_device *d = a->dev; -+ struct tbs5880_state *state = (struct tbs5880_state *)d->priv; -+ int ret; -+ -+ state->ca.owner = THIS_MODULE; -+ state->ca.read_attribute_mem = tbs5880_read_attribute_mem; -+ state->ca.write_attribute_mem = tbs5880_write_attribute_mem; -+ state->ca.read_cam_control = tbs5880_read_cam_control; -+ state->ca.write_cam_control = tbs5880_write_cam_control; -+ state->ca.slot_reset = tbs5880_slot_reset; -+ state->ca.slot_shutdown = tbs5880_slot_shutdown; -+ state->ca.slot_ts_enable = tbs5880_slot_ts_enable; -+ state->ca.poll_slot_status = tbs5880_poll_slot_status; -+ state->ca.data = d; -+ -+ ret = dvb_ca_en50221_init (&a->dvb_adap, &state->ca, -+ /* flags */ 0, /* n_slots */ 1); -+ -+ if (0 != ret) { -+ err ("Cannot initialize CI: Error %d.", ret); -+ memset (&state->ca, 0, sizeof (state->ca)); -+ return ret; -+ } -+ -+ info ("CI initialized."); -+ -+ ret = tbs5880_poll_slot_status(&state->ca, 0, 0); -+ if (0 == ret) -+ tbs5880_set_video_port(&state->ca, /* slot */ 0, /* enable */ 0); -+ -+ return 0; -+} -+ -+/* I2C */ -+static int tbs5880_i2c_transfer(struct i2c_adapter *adap, -+ struct i2c_msg msg[], int num) -+{ -+ struct dvb_usb_device *d = i2c_get_adapdata(adap); -+ struct tbs5880_state *state = (struct tbs5880_state *)d->priv; -+ int i = 0; -+ u8 buf6[20]; -+ u8 inbuf[20]; -+ -+ if (!d) -+ return -ENODEV; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) -+ return -EAGAIN; -+ -+ switch (num) { -+ case 2: -+ buf6[0]=msg[1].len;//lenth -+ buf6[1]=msg[0].addr<<1;//demod addr -+ //register -+ buf6[2] = msg[0].buf[0]; -+ -+ tbs5880_op_rw(d->udev, 0x90, 0, 0, -+ buf6, 3, TBS5880_WRITE_MSG); -+ //msleep(5); -+ tbs5880_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, msg[1].len, TBS5880_READ_MSG); -+ memcpy(msg[1].buf, inbuf, msg[1].len); -+ break; -+ case 1: -+ switch (msg[0].addr) { -+ case 0x6c: -+ case 0x6e: -+ case 0x61: -+ case 0x60: -+ if (msg[0].flags == 0) { -+ buf6[0] = msg[0].len+1;//lenth -+ buf6[1] = msg[0].addr<<1;//addr -+ for(i=0;iudev, 0x80, 0, 0, -+ buf6, msg[0].len+2, TBS5880_WRITE_MSG); -+ } else { -+ buf6[0] = msg[0].len;//length -+ buf6[1] = msg[0].addr<<1;//addr -+ buf6[2] = 0x00; -+ tbs5880_op_rw(d->udev, 0x90, 0, 0, -+ buf6, 3, TBS5880_WRITE_MSG); -+ //msleep(5); -+ tbs5880_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, buf6[0], TBS5880_READ_MSG); -+ memcpy(msg[0].buf, inbuf, msg[0].len); -+ } -+ //msleep(3); -+ break; -+ case (TBS5880_RC_QUERY): -+ tbs5880_op_rw(d->udev, 0xb8, 0, 0, -+ buf6, 4, TBS5880_READ_MSG); -+ msg[0].buf[0] = buf6[2]; -+ msg[0].buf[1] = buf6[3]; -+ //msleep(3); -+ //info("TBS5880_RC_QUERY %x %x %x %x\n", -+ // buf6[0],buf6[1],buf6[2],buf6[3]); -+ break; -+ case (TBS5880_LED_CTRL): -+ buf6[0] = 5; -+ buf6[1] = msg[0].buf[0]; -+ tbs5880_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBS5880_WRITE_MSG); -+ break; -+ } -+ -+ break; -+ } -+ -+ mutex_unlock(&d->i2c_mutex); -+ mutex_unlock(&state->ca_mutex); -+ return num; -+} -+ -+static u32 tbs5880_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C; -+} -+ -+static struct i2c_algorithm tbs5880_i2c_algo = { -+ .master_xfer = tbs5880_i2c_transfer, -+ .functionality = tbs5880_i2c_func, -+}; -+ -+static int tbs5880_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -+{ -+ int i,ret; -+ u8 ibuf[3] = {0, 0,0}; -+ u8 eeprom[256], eepromline[16]; -+ -+ for (i = 0; i < 256; i++) { -+ ibuf[0]=1;//lenth -+ ibuf[1]=0xa0;//eeprom addr -+ ibuf[2]=i;//register -+ ret = tbs5880_op_rw(d->udev, 0x90, 0, 0, -+ ibuf, 3, TBS5880_WRITE_MSG); -+ ret = tbs5880_op_rw(d->udev, 0x91, 0, 0, -+ ibuf, 1, TBS5880_READ_MSG); -+ if (ret < 0) { -+ err("read eeprom failed."); -+ return -1; -+ } else { -+ eepromline[i%16] = ibuf[0]; -+ eeprom[i] = ibuf[0]; -+ } -+ -+ if ((i % 16) == 15) { -+ deb_xfer("%02x: ", i - 15); -+ debug_dump(eepromline, 16, deb_xfer); -+ } -+ } -+ memcpy(mac, eeprom + 16, 6); -+ return 0; -+}; -+ -+static void tbs5880_led_ctrl(struct dvb_frontend *fe, int offon) -+{ -+ static u8 led_off[] = { 0 }; -+ static u8 led_on[] = { 1 }; -+ struct i2c_msg msg = { -+ .addr = TBS5880_LED_CTRL, -+ .flags = 0, -+ .buf = led_off, -+ .len = 1 -+ }; -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ -+ if (offon) -+ msg.buf = led_on; -+ i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); -+} -+ -+static struct dvb_usb_device_properties tbs5880_properties; -+ -+static struct cxd2820r_config cxd2820r_config = { -+ .i2c_address = 0x6c, /* (0xd8 >> 1) */ -+ .ts_mode = CXD2820R_TS_SERIAL, -+ .set_lock_led = tbs5880_led_ctrl, -+}; -+ -+static struct tda18212_config tda18212_config = { -+ //.i2c_address = 0x60 /* (0xc0 >> 1) */, -+ .if_dvbt_6 = 3550, -+ .if_dvbt_7 = 3700, -+ .if_dvbt_8 = 4150, -+ .if_dvbt2_6 = 3250, -+ .if_dvbt2_7 = 4000, -+ .if_dvbt2_8 = 4000, -+ .if_dvbc = 5000, -+}; -+ -+static int tbs5880_tuner_attach(struct dvb_usb_adapter *adap) -+{ -+ struct dvb_usb_device *d = adap->dev; -+ struct tbs5880_state *state = (struct tbs5880_state *)d->priv; -+ -+ struct i2c_adapter *adapter = &d->i2c_adap; -+ struct i2c_client *client; -+ struct i2c_board_info board_info = { -+ .type = "tda18212", -+ .addr = 0x60, -+ .platform_data = &tda18212_config, -+ }; -+ -+ /* attach tuner */ -+ tda18212_config.fe = adap->fe_adap->fe; -+ request_module("tda18212"); -+ client = i2c_new_device(adapter, &board_info); -+ if (client == NULL || client->dev.driver == NULL) { -+ dvb_frontend_detach(adap->fe_adap->fe); -+ goto err; -+ } -+ if (!try_module_get(client->dev.driver->owner)) { -+ i2c_unregister_device(client); -+ dvb_frontend_detach(adap->fe_adap->fe); -+ goto err; -+ } -+ state->i2c_client_tuner = client; -+ -+ return 0; -+ -+err: -+ return -ENODEV; -+} -+ -+static int tbs5880_frontend_attach(struct dvb_usb_adapter *d) -+{ -+ struct dvb_usb_device *u = d->dev; -+ struct tbs5880_state *state = (struct tbs5880_state *)u->priv; -+ u8 buf[20]; -+ -+ mutex_init(&state->ca_mutex); -+ -+ if (tbs5880_properties.adapter->fe->tuner_attach == &tbs5880_tuner_attach) { -+ d->fe_adap->fe = dvb_attach(cxd2820r_attach, &cxd2820r_config, -+ &d->dev->i2c_adap,NULL); -+ -+ if (d->fe_adap->fe != NULL) { -+ buf[0] = 7; -+ buf[1] = 1; -+ tbs5880_op_rw(u->udev, 0x8a, 0, 0, -+ buf, 2, TBS5880_WRITE_MSG); -+ -+ tbs5880_init(d); -+ strlcpy(d->fe_adap->fe->ops.info.name,u->props.devices[0].name,52); -+ return 0; -+ } -+ } -+ -+ return -EIO; -+} -+ -+static void tbs58802_usb_disconnect (struct usb_interface * intf) -+{ -+ struct dvb_usb_device *d = usb_get_intfdata (intf); -+ -+ tbs5880_uninit (d); -+ dvb_usb_device_exit (intf); -+} -+ -+static struct rc_map_table tbs5880_rc_keys[] = { -+ { 0xff84, KEY_POWER2}, /* power */ -+ { 0xff94, KEY_MUTE}, /* mute */ -+ { 0xff87, KEY_1}, -+ { 0xff86, KEY_2}, -+ { 0xff85, KEY_3}, -+ { 0xff8b, KEY_4}, -+ { 0xff8a, KEY_5}, -+ { 0xff89, KEY_6}, -+ { 0xff8f, KEY_7}, -+ { 0xff8e, KEY_8}, -+ { 0xff8d, KEY_9}, -+ { 0xff92, KEY_0}, -+ { 0xff96, KEY_CHANNELUP}, /* ch+ */ -+ { 0xff91, KEY_CHANNELDOWN}, /* ch- */ -+ { 0xff93, KEY_VOLUMEUP}, /* vol+ */ -+ { 0xff8c, KEY_VOLUMEDOWN}, /* vol- */ -+ { 0xff83, KEY_RECORD}, /* rec */ -+ { 0xff98, KEY_PAUSE}, /* pause, yellow */ -+ { 0xff99, KEY_OK}, /* ok */ -+ { 0xff9a, KEY_CAMERA}, /* snapshot */ -+ { 0xff81, KEY_UP}, -+ { 0xff90, KEY_LEFT}, -+ { 0xff82, KEY_RIGHT}, -+ { 0xff88, KEY_DOWN}, -+ { 0xff95, KEY_FAVORITES}, /* blue */ -+ { 0xff97, KEY_SUBTITLE}, /* green */ -+ { 0xff9d, KEY_ZOOM}, -+ { 0xff9f, KEY_EXIT}, -+ { 0xff9e, KEY_MENU}, -+ { 0xff9c, KEY_EPG}, -+ { 0xff80, KEY_PREVIOUS}, /* red */ -+ { 0xff9b, KEY_MODE}, -+ { 0xffdd, KEY_TV }, -+ { 0xffde, KEY_PLAY }, -+ { 0xffdc, KEY_STOP }, -+ { 0xffdb, KEY_REWIND }, -+ { 0xffda, KEY_FASTFORWARD }, -+ { 0xffd9, KEY_PREVIOUS }, /* replay */ -+ { 0xffd8, KEY_NEXT }, /* skip */ -+ { 0xffd1, KEY_NUMERIC_STAR }, -+ { 0xffd2, KEY_NUMERIC_POUND }, -+ { 0xffd4, KEY_DELETE }, /* clear */ -+}; -+ -+static int tbs5880_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -+{ -+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; -+ int keymap_size = d->props.rc.legacy.rc_map_size; -+ -+ struct tbs5880_state *st = d->priv; -+ u8 key[2]; -+ struct i2c_msg msg[] = { -+ {.addr = TBS5880_RC_QUERY, .flags = I2C_M_RD, .buf = key, -+ .len = 2}, -+ }; -+ int i; -+ -+ *state = REMOTE_NO_KEY_PRESSED; -+ if (tbs5880_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { -+ //info("key: %x %x\n",msg[0].buf[0],msg[0].buf[1]); -+ for (i = 0; i < keymap_size; i++) { -+ if (rc5_data(&keymap[i]) == msg[0].buf[1]) { -+ *state = REMOTE_KEY_PRESSED; -+ *event = keymap[i].keycode; -+ st->last_key_pressed = -+ keymap[i].keycode; -+ break; -+ } -+ st->last_key_pressed = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct usb_device_id tbs5880_table[] = { -+ {USB_DEVICE(0x734c, 0x5880)}, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(usb, tbs5880_table); -+ -+static int tbs5880_load_firmware(struct usb_device *dev, -+ const struct firmware *frmwr) -+{ -+ u8 *b, *p; -+ int ret = 0, i; -+ u8 reset; -+ const struct firmware *fw; -+ switch (dev->descriptor.idProduct) { -+ case 0x5880: -+ ret = request_firmware(&fw, tbs5880_properties.firmware, &dev->dev); -+ if (ret != 0) { -+ err("did not find the firmware file. (%s) " -+ "Please see linux/Documentation/dvb/ for more details " -+ "on firmware-problems.", tbs5880_properties.firmware); -+ return ret; -+ } -+ break; -+ default: -+ fw = frmwr; -+ break; -+ } -+ info("start downloading TBS5880 CI firmware"); -+ p = kmalloc(fw->size, GFP_KERNEL); -+ reset = 1; -+ /*stop the CPU*/ -+ tbs5880_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, TBS5880_WRITE_MSG); -+ tbs5880_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, TBS5880_WRITE_MSG); -+ -+ if (p != NULL) { -+ memcpy(p, fw->data, fw->size); -+ for (i = 0; i < fw->size; i += 0x40) { -+ b = (u8 *) p + i; -+ if (tbs5880_op_rw(dev, 0xa0, i, 0, b , 0x40, -+ TBS5880_WRITE_MSG) != 0x40) { -+ err("error while transferring firmware"); -+ ret = -EINVAL; -+ break; -+ } -+ } -+ /* restart the CPU */ -+ reset = 0; -+ if (ret || tbs5880_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, -+ TBS5880_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ if (ret || tbs5880_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, -+ TBS5880_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ -+ msleep(100); -+ kfree(p); -+ } -+ return ret; -+} -+ -+static struct dvb_usb_device_properties tbs5880_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .firmware = "dvb-usb-tbsqbox-id5880.fw", -+ .size_of_priv = sizeof(struct tbs5880_state), -+ .no_reconnect = 1, -+ -+ .i2c_algo = &tbs5880_i2c_algo, -+ .rc.legacy = { -+ .rc_map_table = tbs5880_rc_keys, -+ .rc_map_size = ARRAY_SIZE(tbs5880_rc_keys), -+ .rc_interval = 150, -+ .rc_query = tbs5880_rc_query, -+ }, -+ -+ .generic_bulk_ctrl_endpoint = 0x81, -+ /* parameter for the MPEG2-data transfer */ -+ .num_adapters = 1, -+ .download_firmware = tbs5880_load_firmware, -+ .read_mac_address = tbs5880_read_mac_address, -+ .adapter = {{ -+ .num_frontends = 1, -+ .fe = {{ -+ .frontend_attach = tbs5880_frontend_attach, -+ .streaming_ctrl = NULL, -+ .tuner_attach = tbs5880_tuner_attach, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ }, -+ } }, -+ } }, -+ -+ .num_device_descs = 1, -+ .devices = { -+ {"TurboSight TBS 5880 DVB-T/T2/C + CI", -+ {&tbs5880_table[0], NULL}, -+ {NULL}, -+ } -+ } -+}; -+ -+static int tbs5880_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ if (0 == dvb_usb_device_init(intf, &tbs5880_properties, -+ THIS_MODULE, NULL, adapter_nr)) { -+ return 0; -+ } -+ return -ENODEV; -+} -+ -+static struct usb_driver tbs5880_driver = { -+ .name = "tbs5880", -+ .probe = tbs5880_probe, -+ .disconnect = tbs58802_usb_disconnect, -+ .id_table = tbs5880_table, -+}; -+ -+static int __init tbs5880_module_init(void) -+{ -+ int ret = usb_register(&tbs5880_driver); -+ if (ret) -+ err("usb_register failed. Error number %d", ret); -+ -+ return ret; -+} -+ -+static void __exit tbs5880_module_exit(void) -+{ -+ usb_deregister(&tbs5880_driver); -+} -+ -+module_init(tbs5880_module_init); -+module_exit(tbs5880_module_exit); -+ -+MODULE_AUTHOR("Konstantin Dimitrov "); -+MODULE_DESCRIPTION("TurboSight TBS 5880 CI driver"); -+MODULE_VERSION("1.0"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/usb/dvb-usb/tbs5880.h b/drivers/media/usb/dvb-usb/tbs5880.h -new file mode 100644 -index 0000000..b0f9d9a ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5880.h -@@ -0,0 +1,8 @@ -+#ifndef _TBS5880_H_ -+#define _TBS5880_H_ -+ -+#define DVB_USB_LOG_PREFIX "tbs5880" -+#include "dvb-usb.h" -+ -+#define deb_xfer(args...) dprintk(dvb_usb_tbs5880_debug, 0x02, args) -+#endif -diff --git a/drivers/media/usb/dvb-usb/tbs5881.c b/drivers/media/usb/dvb-usb/tbs5881.c -new file mode 100644 -index 0000000..c6d0f47 ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5881.c -@@ -0,0 +1,818 @@ -+/* -+ * TurboSight TBS 5881 CI driver -+ * -+ * Copyright (c) 2013 Konstantin Dimitrov -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, version 2. -+ * -+ */ -+ -+#include -+#include "tbs5881.h" -+#include "si2168.h" -+#include "si2157.h" -+ -+#include "dvb_ca_en50221.h" -+ -+#define TBS5881_READ_MSG 0 -+#define TBS5881_WRITE_MSG 1 -+ -+#define TBS5881_RC_QUERY (0x1a00) -+ -+struct tbs5881_state { -+ struct i2c_client *i2c_client_demod; -+ struct i2c_client *i2c_client_tuner; -+ struct dvb_ca_en50221 ca; -+ struct mutex ca_mutex; -+ u32 last_key_pressed; -+}; -+ -+/*struct tbs5881_rc_keys { -+ u32 keycode; -+ u32 event; -+};*/ -+ -+/* debug */ -+static int dvb_usb_tbs5881_debug; -+module_param_named(debug, dvb_usb_tbs5881_debug, int, 0644); -+MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." -+ DVB_USB_DEBUG_STATUS); -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+static int tbs5881_op_rw(struct usb_device *dev, u8 request, u16 value, -+ u16 index, u8 * data, u16 len, int flags) -+{ -+ int ret; -+ u8 u8buf[len]; -+ -+ unsigned int pipe = (flags == TBS5881_READ_MSG) ? -+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); -+ u8 request_type = (flags == TBS5881_READ_MSG) ? USB_DIR_IN : -+ USB_DIR_OUT; -+ -+ if (flags == TBS5881_WRITE_MSG) -+ memcpy(u8buf, data, len); -+ ret = usb_control_msg(dev, pipe, request, request_type | -+ USB_TYPE_VENDOR, value, index , u8buf, len, 2000); -+ -+ if (flags == TBS5881_READ_MSG) -+ memcpy(data, u8buf, len); -+ return ret; -+} -+ -+static int tbs5881_read_attribute_mem(struct dvb_ca_en50221 *ca, -+ int slot, int address) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5881_state *state = (struct tbs5881_state *)d->priv; -+ u8 buf[4], rbuf[3]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 1; -+ buf[1] = 0; -+ buf[2] = (address >> 8) & 0x0f; -+ buf[3] = address; -+ -+ //msleep(10); -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbs5881_op_rw(d->udev, 0xa4, 0, 0, -+ buf, 4, TBS5881_WRITE_MSG); -+ -+ //msleep(1); -+ -+ ret = tbs5881_op_rw(d->udev, 0xa5, 0, 0, -+ rbuf, 1, TBS5881_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return rbuf[0]; -+} -+ -+static int tbs5881_write_attribute_mem(struct dvb_ca_en50221 *ca, -+ int slot, int address, u8 value) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5881_state *state = (struct tbs5881_state *)d->priv; -+ u8 buf[5];//, rbuf[1]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 1; -+ buf[1] = 0; -+ buf[2] = (address >> 8) & 0x0f; -+ buf[3] = address; -+ buf[4] = value; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbs5881_op_rw(d->udev, 0xa2, 0, 0, -+ buf, 5, TBS5881_WRITE_MSG); -+ -+ //msleep(1); -+ -+ //ret = tbs5881_op_rw(d->udev, 0xa5, 0, 0, -+ // rbuf, 1, TBS5881_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int tbs5881_read_cam_control(struct dvb_ca_en50221 *ca, int slot, -+ u8 address) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5881_state *state = (struct tbs5881_state *)d->priv; -+ u8 buf[4], rbuf[1]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 1; -+ buf[1] = 1; -+ buf[2] = (address >> 8) & 0x0f; -+ buf[3] = address; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbs5881_op_rw(d->udev, 0xa4, 0, 0, -+ buf, 4, TBS5881_WRITE_MSG); -+ -+ //msleep(10); -+ -+ ret = tbs5881_op_rw(d->udev, 0xa5, 0, 0, -+ rbuf, 1, TBS5881_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return rbuf[0]; -+} -+ -+static int tbs5881_write_cam_control(struct dvb_ca_en50221 *ca, int slot, -+ u8 address, u8 value) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5881_state *state = (struct tbs5881_state *)d->priv; -+ u8 buf[5];//, rbuf[1]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 1; -+ buf[1] = 1; -+ buf[2] = (address >> 8) & 0x0f; -+ buf[3] = address; -+ buf[4] = value; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbs5881_op_rw(d->udev, 0xa2, 0, 0, -+ buf, 5, TBS5881_WRITE_MSG); -+ -+ //msleep(1); -+ -+ //ret = tbs5881_op_rw(d->udev, 0xa5, 0, 0, -+ // rbuf, 1, TBS5881_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int tbs5881_set_video_port(struct dvb_ca_en50221 *ca, -+ int slot, int enable) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5881_state *state = (struct tbs5881_state *)d->priv; -+ u8 buf[2]; -+ int ret; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ buf[0] = 2; -+ buf[1] = enable; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ ret = tbs5881_op_rw(d->udev, 0xa6, 0, 0, -+ buf, 2, TBS5881_WRITE_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ if (enable != buf[1]) { -+ err("CI not %sabled.", enable ? "en" : "dis"); -+ return -EIO; -+ } -+ -+ info("CI %sabled.", enable ? "en" : "dis"); -+ return 0; -+} -+ -+static int tbs5881_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) -+{ -+ return tbs5881_set_video_port(ca, slot, /* enable */ 0); -+} -+ -+static int tbs5881_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) -+{ -+ return tbs5881_set_video_port(ca, slot, /* enable */ 1); -+} -+ -+static int tbs5881_slot_reset(struct dvb_ca_en50221 *ca, int slot) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5881_state *state = (struct tbs5881_state *)d->priv; -+ u8 buf[2]; -+ int ret; -+ -+ if (0 != slot) { -+ return -EINVAL; -+ } -+ -+ buf[0] = 1; -+ buf[1] = 0; -+ -+ mutex_lock (&state->ca_mutex); -+ -+ ret = tbs5881_op_rw(d->udev, 0xa6, 0, 0, -+ buf, 2, TBS5881_WRITE_MSG); -+ -+ msleep (5); -+ -+ buf[1] = 1; -+ -+ ret = tbs5881_op_rw(d->udev, 0xa6, 0, 0, -+ buf, 2, TBS5881_WRITE_MSG); -+ -+ msleep (1400); -+ -+ mutex_unlock (&state->ca_mutex); -+ -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int tbs5881_poll_slot_status(struct dvb_ca_en50221 *ca, -+ int slot, int open) -+{ -+ struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; -+ struct tbs5881_state *state = (struct tbs5881_state *)d->priv; -+ u8 buf[3]; -+ -+ if (0 != slot) -+ return -EINVAL; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ tbs5881_op_rw(d->udev, 0xa8, 0, 0, -+ buf, 3, TBS5881_READ_MSG); -+ -+ mutex_unlock(&state->ca_mutex); -+ -+ if ((1 == buf[2]) && (1 == buf[1]) && (0xa9 == buf[0])) { -+ return (DVB_CA_EN50221_POLL_CAM_PRESENT | -+ DVB_CA_EN50221_POLL_CAM_READY); -+ } else { -+ return 0; -+ } -+} -+ -+static void tbs5881_uninit(struct dvb_usb_device *d) -+{ -+ struct tbs5881_state *state; -+ -+ if (NULL == d) -+ return; -+ -+ state = (struct tbs5881_state *)d->priv; -+ if (NULL == state) -+ return; -+ -+ if (NULL == state->ca.data) -+ return; -+ -+ /* Error ignored. */ -+ tbs5881_set_video_port(&state->ca, /* slot */ 0, /* enable */ 0); -+ -+ dvb_ca_en50221_release(&state->ca); -+ -+ memset(&state->ca, 0, sizeof(state->ca)); -+} -+ -+static int tbs5881_init(struct dvb_usb_adapter *a) -+{ -+ -+ struct dvb_usb_device *d = a->dev; -+ struct tbs5881_state *state = (struct tbs5881_state *)d->priv; -+ int ret; -+ -+ state->ca.owner = THIS_MODULE; -+ state->ca.read_attribute_mem = tbs5881_read_attribute_mem; -+ state->ca.write_attribute_mem = tbs5881_write_attribute_mem; -+ state->ca.read_cam_control = tbs5881_read_cam_control; -+ state->ca.write_cam_control = tbs5881_write_cam_control; -+ state->ca.slot_reset = tbs5881_slot_reset; -+ state->ca.slot_shutdown = tbs5881_slot_shutdown; -+ state->ca.slot_ts_enable = tbs5881_slot_ts_enable; -+ state->ca.poll_slot_status = tbs5881_poll_slot_status; -+ state->ca.data = d; -+ -+ ret = dvb_ca_en50221_init (&a->dvb_adap, &state->ca, -+ /* flags */ 0, /* n_slots */ 1); -+ -+ if (0 != ret) { -+ err ("Cannot initialize CI: Error %d.", ret); -+ memset (&state->ca, 0, sizeof (state->ca)); -+ return ret; -+ } -+ -+ info ("CI initialized."); -+ -+ ret = tbs5881_poll_slot_status(&state->ca, 0, 0); -+ if (0 == ret) -+ tbs5881_set_video_port(&state->ca, /* slot */ 0, /* enable */ 0); -+ -+ return 0; -+} -+ -+/* I2C */ -+static int tbs5881_i2c_transfer(struct i2c_adapter *adap, -+ struct i2c_msg msg[], int num) -+{ -+ struct dvb_usb_device *d = i2c_get_adapdata(adap); -+ struct tbs5881_state *state = (struct tbs5881_state *)d->priv; -+ int i = 0; -+ u8 buf6[20]; -+ u8 inbuf[20]; -+ -+ if (!d) -+ return -ENODEV; -+ -+ mutex_lock(&state->ca_mutex); -+ -+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) -+ return -EAGAIN; -+ -+ switch (num) { -+ case 2: -+ buf6[0]=msg[1].len;//lenth -+ buf6[1]=msg[0].addr<<1;//demod addr -+ //register -+ buf6[2] = msg[0].buf[0]; -+ -+ tbs5881_op_rw(d->udev, 0x90, 0, 0, -+ buf6, 3, TBS5881_WRITE_MSG); -+ //msleep(5); -+ tbs5881_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, 1, TBS5881_READ_MSG); -+ memcpy(msg[1].buf, inbuf, msg[1].len); -+ break; -+ case 1: -+ switch (msg[0].addr) { -+ case 0x64: -+ case 0x60: -+ if (msg[0].flags == 0) { -+ buf6[0] = msg[0].len+1;//lenth -+ buf6[1] = msg[0].addr<<1;//addr -+ for(i=0;iudev, 0x80, 0, 0, -+ buf6, msg[0].len+2, TBS5881_WRITE_MSG); -+ } else { -+ buf6[0] = msg[0].len;//length -+ buf6[1] = (msg[0].addr<<1) | 0x01;//addr -+ tbs5881_op_rw(d->udev, 0x93, 0, 0, -+ buf6, 2, TBS5881_WRITE_MSG); -+ //msleep(5); -+ tbs5881_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, buf6[0], TBS5881_READ_MSG); -+ memcpy(msg[0].buf, inbuf, msg[0].len); -+ } -+ //msleep(3); -+ break; -+ case (TBS5881_RC_QUERY): -+ tbs5881_op_rw(d->udev, 0xb8, 0, 0, -+ buf6, 4, TBS5881_READ_MSG); -+ msg[0].buf[0] = buf6[2]; -+ msg[0].buf[1] = buf6[3]; -+ //msleep(3); -+ //info("TBS5881_RC_QUERY %x %x %x %x\n", -+ // buf6[0],buf6[1],buf6[2],buf6[3]); -+ break; -+ } -+ -+ break; -+ } -+ -+ mutex_unlock(&d->i2c_mutex); -+ mutex_unlock(&state->ca_mutex); -+ return num; -+} -+ -+static u32 tbs5881_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C; -+} -+ -+static struct i2c_algorithm tbs5881_i2c_algo = { -+ .master_xfer = tbs5881_i2c_transfer, -+ .functionality = tbs5881_i2c_func, -+}; -+ -+static int tbs5881_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -+{ -+ int i,ret; -+ u8 ibuf[3] = {0, 0,0}; -+ u8 eeprom[256], eepromline[16]; -+ -+ for (i = 0; i < 256; i++) { -+ ibuf[0]=1;//lenth -+ ibuf[1]=0xa0;//eeprom addr -+ ibuf[2]=i;//register -+ ret = tbs5881_op_rw(d->udev, 0x90, 0, 0, -+ ibuf, 3, TBS5881_WRITE_MSG); -+ ret = tbs5881_op_rw(d->udev, 0x91, 0, 0, -+ ibuf, 1, TBS5881_READ_MSG); -+ if (ret < 0) { -+ err("read eeprom failed."); -+ return -1; -+ } else { -+ eepromline[i%16] = ibuf[0]; -+ eeprom[i] = ibuf[0]; -+ } -+ -+ if ((i % 16) == 15) { -+ deb_xfer("%02x: ", i - 15); -+ debug_dump(eepromline, 16, deb_xfer); -+ } -+ } -+ memcpy(mac, eeprom + 16, 6); -+ return 0; -+}; -+ -+static struct dvb_usb_device_properties tbs5881_properties; -+ -+static int tbs5881_frontend_attach(struct dvb_usb_adapter *adap) -+{ -+ struct dvb_usb_device *d = adap->dev; -+ struct tbs5881_state *st = (struct tbs5881_state *)d->priv; -+ struct i2c_adapter *adapter; -+ struct i2c_client *client_demod; -+ struct i2c_client *client_tuner; -+ struct i2c_board_info info; -+ struct si2168_config si2168_config; -+ struct si2157_config si2157_config; -+ u8 buf[20]; -+ -+ mutex_init(&st->ca_mutex); -+ -+ /* attach frontend */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.i2c_adapter = &adapter; -+ si2168_config.fe = &adap->fe_adap[0].fe; -+ si2168_config.ts_mode = SI2168_TS_SERIAL; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2168", I2C_NAME_SIZE); -+ info.addr = 0x64; -+ info.platform_data = &si2168_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(&d->i2c_adap, &info); -+ if (client_demod == NULL || client_demod->dev.driver == NULL) -+ return -ENODEV; -+ -+ if (!try_module_get(client_demod->dev.driver->owner)) { -+ i2c_unregister_device(client_demod); -+ return -ENODEV; -+ } -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = adap->fe_adap[0].fe; -+ si2157_config.if_port = 1; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2157", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &si2157_config; -+ request_module(info.type); -+ client_tuner = i2c_new_device(adapter, &info); -+ if (client_tuner == NULL || client_tuner->dev.driver == NULL) { -+ module_put(client_demod->dev.driver->owner); -+ i2c_unregister_device(client_demod); -+ return -ENODEV; -+ } -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ module_put(client_demod->dev.driver->owner); -+ i2c_unregister_device(client_demod); -+ return -ENODEV; -+ } -+ -+ st->i2c_client_demod = client_demod; -+ st->i2c_client_tuner = client_tuner; -+ -+ buf[0] = 0; -+ buf[1] = 0; -+ tbs5881_op_rw(d->udev, 0xb7, 0, 0, -+ buf, 2, TBS5881_WRITE_MSG); -+ -+ buf[0] = 8; -+ buf[1] = 1; -+ tbs5881_op_rw(d->udev, 0x8a, 0, 0, -+ buf, 2, TBS5881_WRITE_MSG); -+ -+ buf[0] = 7; -+ buf[1] = 1; -+ tbs5881_op_rw(d->udev, 0x8a, 0, 0, -+ buf, 2, TBS5881_WRITE_MSG); -+ -+ buf[0] = 6; -+ buf[1] = 1; -+ tbs5881_op_rw(d->udev, 0x8a, 0, 0, -+ buf, 2, TBS5881_WRITE_MSG); -+ -+ tbs5881_init(adap); -+ strlcpy(adap->fe_adap->fe->ops.info.name,d->props.devices[0].name,52); -+ return 0; -+} -+ -+static void tbs5881_usb_disconnect (struct usb_interface * intf) -+{ -+ struct dvb_usb_device *d = usb_get_intfdata (intf); -+#if 0 -+ struct tbs5881_state *st = d->priv; -+ struct i2c_client *client; -+ -+ /* remove I2C client for tuner */ -+ client = st->i2c_client_tuner; -+ if (client) { -+ module_put(client->dev.driver->owner); -+ i2c_unregister_device(client); -+ } -+ -+ /* remove I2C client for demodulator */ -+ client = st->i2c_client_demod; -+ if (client) { -+ module_put(client->dev.driver->owner); -+ i2c_unregister_device(client); -+ } -+#endif -+ tbs5881_uninit (d); -+ dvb_usb_device_exit (intf); -+} -+ -+static struct rc_map_table tbs5881_rc_keys[] = { -+ { 0xff84, KEY_POWER2}, /* power */ -+ { 0xff94, KEY_MUTE}, /* mute */ -+ { 0xff87, KEY_1}, -+ { 0xff86, KEY_2}, -+ { 0xff85, KEY_3}, -+ { 0xff8b, KEY_4}, -+ { 0xff8a, KEY_5}, -+ { 0xff89, KEY_6}, -+ { 0xff8f, KEY_7}, -+ { 0xff8e, KEY_8}, -+ { 0xff8d, KEY_9}, -+ { 0xff92, KEY_0}, -+ { 0xff96, KEY_CHANNELUP}, /* ch+ */ -+ { 0xff91, KEY_CHANNELDOWN}, /* ch- */ -+ { 0xff93, KEY_VOLUMEUP}, /* vol+ */ -+ { 0xff8c, KEY_VOLUMEDOWN}, /* vol- */ -+ { 0xff83, KEY_RECORD}, /* rec */ -+ { 0xff98, KEY_PAUSE}, /* pause, yellow */ -+ { 0xff99, KEY_OK}, /* ok */ -+ { 0xff9a, KEY_CAMERA}, /* snapshot */ -+ { 0xff81, KEY_UP}, -+ { 0xff90, KEY_LEFT}, -+ { 0xff82, KEY_RIGHT}, -+ { 0xff88, KEY_DOWN}, -+ { 0xff95, KEY_FAVORITES}, /* blue */ -+ { 0xff97, KEY_SUBTITLE}, /* green */ -+ { 0xff9d, KEY_ZOOM}, -+ { 0xff9f, KEY_EXIT}, -+ { 0xff9e, KEY_MENU}, -+ { 0xff9c, KEY_EPG}, -+ { 0xff80, KEY_PREVIOUS}, /* red */ -+ { 0xff9b, KEY_MODE}, -+ { 0xffdd, KEY_TV }, -+ { 0xffde, KEY_PLAY }, -+ { 0xffdc, KEY_STOP }, -+ { 0xffdb, KEY_REWIND }, -+ { 0xffda, KEY_FASTFORWARD }, -+ { 0xffd9, KEY_PREVIOUS }, /* replay */ -+ { 0xffd8, KEY_NEXT }, /* skip */ -+ { 0xffd1, KEY_NUMERIC_STAR }, -+ { 0xffd2, KEY_NUMERIC_POUND }, -+ { 0xffd4, KEY_DELETE }, /* clear */ -+}; -+ -+static int tbs5881_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -+{ -+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; -+ int keymap_size = d->props.rc.legacy.rc_map_size; -+ -+ struct tbs5881_state *st = d->priv; -+ u8 key[2]; -+ struct i2c_msg msg[] = { -+ {.addr = TBS5881_RC_QUERY, .flags = I2C_M_RD, .buf = key, -+ .len = 2}, -+ }; -+ int i; -+ -+ *state = REMOTE_NO_KEY_PRESSED; -+ if (tbs5881_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { -+ //info("key: %x %x\n",msg[0].buf[0],msg[0].buf[1]); -+ for (i = 0; i < keymap_size; i++) { -+ if (rc5_data(&keymap[i]) == msg[0].buf[1]) { -+ *state = REMOTE_KEY_PRESSED; -+ *event = keymap[i].keycode; -+ st->last_key_pressed = -+ keymap[i].keycode; -+ break; -+ } -+ st->last_key_pressed = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct usb_device_id tbs5881_table[] = { -+ {USB_DEVICE(0x734c, 0x5881)}, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(usb, tbs5881_table); -+ -+static int tbs5881_load_firmware(struct usb_device *dev, -+ const struct firmware *frmwr) -+{ -+ u8 *b, *p; -+ int ret = 0, i; -+ u8 reset; -+ const struct firmware *fw; -+ switch (dev->descriptor.idProduct) { -+ case 0x5881: -+ ret = request_firmware(&fw, tbs5881_properties.firmware, &dev->dev); -+ if (ret != 0) { -+ err("did not find the firmware file. (%s) " -+ "Please see linux/Documentation/dvb/ for more details " -+ "on firmware-problems.", tbs5881_properties.firmware); -+ return ret; -+ } -+ break; -+ default: -+ fw = frmwr; -+ break; -+ } -+ info("start downloading TBS5881 CI firmware"); -+ p = kmalloc(fw->size, GFP_KERNEL); -+ reset = 1; -+ /*stop the CPU*/ -+ tbs5881_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, TBS5881_WRITE_MSG); -+ tbs5881_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, TBS5881_WRITE_MSG); -+ -+ if (p != NULL) { -+ memcpy(p, fw->data, fw->size); -+ for (i = 0; i < fw->size; i += 0x40) { -+ b = (u8 *) p + i; -+ if (tbs5881_op_rw(dev, 0xa0, i, 0, b , 0x40, -+ TBS5881_WRITE_MSG) != 0x40) { -+ err("error while transferring firmware"); -+ ret = -EINVAL; -+ break; -+ } -+ } -+ /* restart the CPU */ -+ reset = 0; -+ if (ret || tbs5881_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, -+ TBS5881_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ if (ret || tbs5881_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, -+ TBS5881_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ -+ msleep(100); -+ kfree(p); -+ } -+ return ret; -+} -+ -+static struct dvb_usb_device_properties tbs5881_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .firmware = "dvb-usb-tbsqbox-id5881.fw", -+ .size_of_priv = sizeof(struct tbs5881_state), -+ .no_reconnect = 1, -+ -+ .i2c_algo = &tbs5881_i2c_algo, -+ .rc.legacy = { -+ .rc_map_table = tbs5881_rc_keys, -+ .rc_map_size = ARRAY_SIZE(tbs5881_rc_keys), -+ .rc_interval = 150, -+ .rc_query = tbs5881_rc_query, -+ }, -+ -+ .generic_bulk_ctrl_endpoint = 0x81, -+ /* parameter for the MPEG2-data transfer */ -+ .num_adapters = 1, -+ .download_firmware = tbs5881_load_firmware, -+ .read_mac_address = tbs5881_read_mac_address, -+ .adapter = {{ -+ .num_frontends = 1, -+ .fe = {{ -+ .frontend_attach = tbs5881_frontend_attach, -+ .streaming_ctrl = NULL, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ }, -+ }}, -+ }}, -+ .num_device_descs = 1, -+ .devices = { -+ {"TurboSight TBS 5881 DVB-T/T2/C + CI", -+ {&tbs5881_table[0], NULL}, -+ {NULL}, -+ } -+ } -+}; -+ -+static int tbs5881_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ if (0 == dvb_usb_device_init(intf, &tbs5881_properties, -+ THIS_MODULE, NULL, adapter_nr)) { -+ return 0; -+ } -+ return -ENODEV; -+} -+ -+static struct usb_driver tbs5881_driver = { -+ .name = "tbs5881", -+ .probe = tbs5881_probe, -+ .disconnect = tbs5881_usb_disconnect, -+ .id_table = tbs5881_table, -+}; -+ -+static int __init tbs5881_module_init(void) -+{ -+ int ret = usb_register(&tbs5881_driver); -+ if (ret) -+ err("usb_register failed. Error number %d", ret); -+ -+ return ret; -+} -+ -+static void __exit tbs5881_module_exit(void) -+{ -+ usb_deregister(&tbs5881_driver); -+} -+ -+module_init(tbs5881_module_init); -+module_exit(tbs5881_module_exit); -+ -+MODULE_AUTHOR("Konstantin Dimitrov "); -+MODULE_DESCRIPTION("TurboSight TBS 5881 CI driver"); -+MODULE_VERSION("1.0"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/usb/dvb-usb/tbs5881.h b/drivers/media/usb/dvb-usb/tbs5881.h -new file mode 100644 -index 0000000..827073b ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5881.h -@@ -0,0 +1,8 @@ -+#ifndef _TBS5881_H_ -+#define _TBS5881_H_ -+ -+#define DVB_USB_LOG_PREFIX "tbs5881" -+#include "dvb-usb.h" -+ -+#define deb_xfer(args...) dprintk(dvb_usb_tbs5881_debug, 0x02, args) -+#endif -diff --git a/drivers/media/usb/dvb-usb/tbs5922se.c b/drivers/media/usb/dvb-usb/tbs5922se.c -new file mode 100644 -index 0000000..5ce8398 ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5922se.c -@@ -0,0 +1,463 @@ -+/* DVB USB framework compliant Linux driver for the -+* TBS 5922SE -+* -+* Copyright (C) 2008 Bob Liu (Bob@Turbosight.com) -+* Igor M. Liplianin (liplianin@me.by) -+* -+* This program is free software; you can redistribute it and/or modify it -+* under the terms of the GNU General Public License as published by the -+* Free Software Foundation, version 2. -+* -+* see Documentation/dvb/README.dvb-usb for more information -+*/ -+ -+/* -+* History: -+* -+* December 2011 Konstantin Dimitrov -+* remove QBOXS3 support -+* add QBOX22 support -+*/ -+ -+#include -+#include "tbs5922se.h" -+#include "tas2101.h" -+#include "av201x.h" -+ -+#ifndef USB_PID_TBS5922SE_1 -+#define USB_PID_TBS5922SE_1 0x5923 -+#endif -+ -+#define TBS5922SE_READ_MSG 0 -+#define TBS5922SE_WRITE_MSG 1 -+ -+/* on my own*/ -+#define TBS5922SE_VOLTAGE_CTRL (0x1800) -+#define TBS5922SE_RC_QUERY (0x1a00) -+ -+struct tbs5922se_state { -+ u32 last_key_pressed; -+}; -+struct tbs5922se_rc_keys { -+ u32 keycode; -+ u32 event; -+}; -+ -+/* debug */ -+static int dvb_usb_tbs5922se_debug; -+module_param_named(debug, dvb_usb_tbs5922se_debug, int, 0644); -+MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS); -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+static int tbs5922se_op_rw(struct usb_device *dev, u8 request, u16 value, -+ u16 index, u8 * data, u16 len, int flags) -+{ -+ int ret; -+ u8 u8buf[len]; -+ -+ unsigned int pipe = (flags == TBS5922SE_READ_MSG) ? -+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); -+ u8 request_type = (flags == TBS5922SE_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; -+ -+ if (flags == TBS5922SE_WRITE_MSG) -+ memcpy(u8buf, data, len); -+ ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, -+ value, index, u8buf, len, 2000); -+ -+ if (flags == TBS5922SE_READ_MSG) -+ memcpy(data, u8buf, len); -+ return ret; -+} -+ -+/* I2C */ -+static int tbs5922se_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], -+ int num) -+{ -+ struct dvb_usb_device *d = i2c_get_adapdata(adap); -+ int i = 0; -+ u8 buf[20]; -+ -+ if (!d) -+ return -ENODEV; -+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) -+ return -EAGAIN; -+ -+ switch (num) { -+ case 2: -+ /* read */ -+ buf[0] = msg[1].len; -+ buf[1] = msg[0].addr << 1; -+ buf[2] = msg[0].buf[0]; -+ -+ tbs5922se_op_rw(d->udev, 0x90, 0, 0, -+ buf, 3, TBS5922SE_WRITE_MSG); -+ msleep(5); -+ tbs5922se_op_rw(d->udev, 0x91, 0, 0, -+ buf, msg[1].len, TBS5922SE_READ_MSG); -+ memcpy(msg[1].buf, buf, msg[1].len); -+ break; -+ case 1: -+ switch (msg[0].addr) { -+ case 0x68: -+ case 0x63: -+ /* write to register */ -+ buf[0] = msg[0].len + 1; //lenth -+ buf[1] = msg[0].addr << 1; //demod addr -+ for(i=0; i < msg[0].len; i++) -+ buf[2+i] = msg[0].buf[i]; //register -+ tbs5922se_op_rw(d->udev, 0x80, 0, 0, -+ buf, msg[0].len+2, TBS5922SE_WRITE_MSG); -+ //msleep(3); -+ break; -+ case (TBS5922SE_RC_QUERY): -+ tbs5922se_op_rw(d->udev, 0xb8, 0, 0, -+ buf, 4, TBS5922SE_READ_MSG); -+ msg[0].buf[0] = buf[2]; -+ msg[0].buf[1] = buf[3]; -+ msleep(3); -+ //info("TBS5922SE_RC_QUERY %x %x %x %x\n",buf6[0],buf6[1],buf6[2],buf6[3]); -+ break; -+ case (TBS5922SE_VOLTAGE_CTRL): -+ break; -+ default: -+ break; -+ } -+ -+ break; -+ default: -+ break; -+ } -+ -+ mutex_unlock(&d->i2c_mutex); -+ return num; -+} -+ -+static u32 tbs5922se_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C; -+} -+ -+ -+static struct i2c_algorithm tbs5922se_i2c_algo = { -+ .master_xfer = tbs5922se_i2c_transfer, -+ .functionality = tbs5922se_i2c_func, -+}; -+ -+ -+static int tbs5922se_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -+{ -+ int i,ret; -+ u8 buf[3]; -+ u8 eeprom[256], eepromline[16]; -+ -+ for (i = 0; i < 256; i++) { -+ buf[0] = 1; //lenth -+ buf[1] = 0xa0; //eeprom addr -+ buf[2] = i; //register -+ ret = tbs5922se_op_rw(d->udev, 0x90, 0, 0, -+ buf, 3, TBS5922SE_WRITE_MSG); -+ ret = tbs5922se_op_rw(d->udev, 0x91, 0, 0, -+ buf, 1, TBS5922SE_READ_MSG); -+ if (ret < 0) { -+ err("read eeprom failed"); -+ return -1; -+ } else { -+ eepromline[i % 16] = buf[0]; -+ eeprom[i] = buf[0]; -+ } -+ -+ if ((i % 16) == 15) { -+ deb_xfer("%02x: ", i - 15); -+ debug_dump(eepromline, 16, deb_xfer); -+ } -+ } -+ memcpy(mac, eeprom + 16, 6); -+ return 0; -+}; -+ -+static struct dvb_usb_device_properties tbs5922se_properties; -+ -+ -+static struct tas2101_config tbs5922_cfg = { -+ .i2c_address = 0x68, -+ .id = ID_TAS2101, -+ .reset_demod = NULL, -+ .lnb_power = NULL, -+ .init = {0x67, 0x45, 0xba, 0x23, 0x01, 0x98, 0x33}, -+ .init2 = 1, -+}; -+ -+static struct av201x_config tbs5922_av201x_cfg = { -+ .i2c_address = 0x63, -+ .id = ID_AV2012, -+ .xtal_freq = 27000, /* kHz */ -+}; -+ -+static int tbs5922se_frontend_attach(struct dvb_usb_adapter *d) -+{ -+ struct dvb_usb_device *u = d->dev; -+ u8 buf[20]; -+ -+ d->fe_adap->fe = dvb_attach(tas2101_attach, &tbs5922_cfg, -+ &u->i2c_adap); -+ if (d->fe_adap->fe == NULL) -+ goto err; -+ -+ if (dvb_attach(av201x_attach, d->fe_adap->fe, &tbs5922_av201x_cfg, -+ tas2101_get_i2c_adapter(d->fe_adap->fe, 2)) == NULL) { -+ dvb_frontend_detach(d->fe_adap->fe); -+ d->fe_adap->fe = NULL; -+ goto err; -+ } -+ -+ buf[0] = 7; -+ buf[1] = 1; -+ tbs5922se_op_rw(u->udev, 0x8a, 0, 0, buf, 2, TBS5922SE_WRITE_MSG); -+ -+ buf[0] = 1; -+ buf[1] = 1; -+ tbs5922se_op_rw(u->udev, 0x8a, 0, 0, buf, 2, TBS5922SE_WRITE_MSG); -+ -+ buf[0] = 6; -+ buf[1] = 1; -+ tbs5922se_op_rw(u->udev, 0x8a, 0, 0, buf, 2, TBS5922SE_WRITE_MSG); -+ -+ strlcpy(d->fe_adap->fe->ops.info.name,u->props.devices[0].name,52); -+ -+ return 0; -+err: -+ return -ENODEV; -+} -+ -+ -+ -+static struct rc_map_table tbs5922se_rc_keys[] = { -+ { 0xff84, KEY_POWER2}, /* power */ -+ { 0xff94, KEY_MUTE}, /* mute */ -+ { 0xff87, KEY_1}, -+ { 0xff86, KEY_2}, -+ { 0xff85, KEY_3}, -+ { 0xff8b, KEY_4}, -+ { 0xff8a, KEY_5}, -+ { 0xff89, KEY_6}, -+ { 0xff8f, KEY_7}, -+ { 0xff8e, KEY_8}, -+ { 0xff8d, KEY_9}, -+ { 0xff92, KEY_0}, -+ { 0xff96, KEY_CHANNELUP}, /* ch+ */ -+ { 0xff91, KEY_CHANNELDOWN}, /* ch- */ -+ { 0xff93, KEY_VOLUMEUP}, /* vol+ */ -+ { 0xff8c, KEY_VOLUMEDOWN}, /* vol- */ -+ { 0xff83, KEY_RECORD}, /* rec */ -+ { 0xff98, KEY_PAUSE}, /* pause, yellow */ -+ { 0xff99, KEY_OK}, /* ok */ -+ { 0xff9a, KEY_CAMERA}, /* snapshot */ -+ { 0xff81, KEY_UP}, -+ { 0xff90, KEY_LEFT}, -+ { 0xff82, KEY_RIGHT}, -+ { 0xff88, KEY_DOWN}, -+ { 0xff95, KEY_FAVORITES}, /* blue */ -+ { 0xff97, KEY_SUBTITLE}, /* green */ -+ { 0xff9d, KEY_ZOOM}, -+ { 0xff9f, KEY_EXIT}, -+ { 0xff9e, KEY_MENU}, -+ { 0xff9c, KEY_EPG}, -+ { 0xff80, KEY_PREVIOUS}, /* red */ -+ { 0xff9b, KEY_MODE}, -+ { 0xffdd, KEY_TV }, -+ { 0xffde, KEY_PLAY }, -+ { 0xffdc, KEY_STOP }, -+ { 0xffdb, KEY_REWIND }, -+ { 0xffda, KEY_FASTFORWARD }, -+ { 0xffd9, KEY_PREVIOUS }, /* replay */ -+ { 0xffd8, KEY_NEXT }, /* skip */ -+ { 0xffd1, KEY_NUMERIC_STAR }, -+ { 0xffd2, KEY_NUMERIC_POUND }, -+ { 0xffd4, KEY_DELETE }, /* clear */ -+}; -+ -+ -+ -+static int tbs5922se_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -+{ -+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; -+ int keymap_size = d->props.rc.legacy.rc_map_size; -+ -+ struct tbs5922se_state *st = d->priv; -+ u8 key[2]; -+ struct i2c_msg msg[] = { -+ {.addr = TBS5922SE_RC_QUERY, .flags = I2C_M_RD, .buf = key, -+ .len = 2}, -+ }; -+ int i; -+ -+ *state = REMOTE_NO_KEY_PRESSED; -+ if (tbs5922se_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { -+ //info("key: %x %x\n",msg[0].buf[0],msg[0].buf[1]); -+ for (i = 0; i < keymap_size; i++) { -+ if (rc5_data(&keymap[i]) == msg[0].buf[1]) { -+ *state = REMOTE_KEY_PRESSED; -+ *event = keymap[i].keycode; -+ st->last_key_pressed = -+ keymap[i].keycode; -+ break; -+ } -+ st->last_key_pressed = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct usb_device_id tbs5922se_table[] = { -+ {USB_DEVICE(0x734c, 0x5923)}, -+ {USB_DEVICE(USB_VID_CYPRESS, USB_PID_TBS5922SE_1)}, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(usb, tbs5922se_table); -+ -+static int tbs5922se_load_firmware(struct usb_device *dev, -+ const struct firmware *frmwr) -+{ -+ u8 *b, *p; -+ int ret = 0, i; -+ u8 reset; -+ const struct firmware *fw; -+ const char *filename = "dvb-usb-tbsqbox-id5923.fw"; -+ switch (dev->descriptor.idProduct) { -+ case 0x5923: -+ ret = request_firmware(&fw, filename, &dev->dev); -+ if (ret != 0) { -+ err("did not find the firmware file. (%s) " -+ "Please see linux/Documentation/dvb/ for more details " -+ "on firmware-problems.", filename); -+ return ret; -+ } -+ break; -+ default: -+ fw = frmwr; -+ break; -+ } -+ info("start downloading TBS5922SE firmware"); -+ p = kmalloc(fw->size, GFP_KERNEL); -+ reset = 1; -+ /*stop the CPU*/ -+ tbs5922se_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, TBS5922SE_WRITE_MSG); -+ tbs5922se_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, TBS5922SE_WRITE_MSG); -+ -+ if (p != NULL) { -+ memcpy(p, fw->data, fw->size); -+ for (i = 0; i < fw->size; i += 0x40) { -+ b = (u8 *) p + i; -+ if (tbs5922se_op_rw(dev, 0xa0, i, 0, b , 0x40, -+ TBS5922SE_WRITE_MSG) != 0x40) { -+ err("error while transferring firmware"); -+ ret = -EINVAL; -+ break; -+ } -+ } -+ /* restart the CPU */ -+ reset = 0; -+ if (ret || tbs5922se_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, -+ TBS5922SE_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ if (ret || tbs5922se_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, -+ TBS5922SE_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ -+ msleep(100); -+ kfree(p); -+ } -+ return ret; -+} -+ -+static struct dvb_usb_device_properties tbs5922se_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .firmware = "dvb-usb-tbsqbox-id5923.fw", -+ .size_of_priv = sizeof(struct tbs5922se_state), -+ .no_reconnect = 1, -+ -+ .i2c_algo = &tbs5922se_i2c_algo, -+ .rc.legacy = { -+ .rc_map_table = tbs5922se_rc_keys, -+ .rc_map_size = ARRAY_SIZE(tbs5922se_rc_keys), -+ .rc_interval = 150, -+ .rc_query = tbs5922se_rc_query, -+ }, -+ -+ .generic_bulk_ctrl_endpoint = 0x81, -+ /* parameter for the MPEG2-data transfer */ -+ .num_adapters = 1, -+ .download_firmware = tbs5922se_load_firmware, -+ .read_mac_address = tbs5922se_read_mac_address, -+ .adapter = {{ -+ .num_frontends = 1, -+ .fe = {{ -+ .frontend_attach = tbs5922se_frontend_attach, -+ .streaming_ctrl = NULL, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ }, -+ }}, -+ }}, -+ .num_device_descs = 1, -+ .devices = { -+ {"TurboSight TBS 5922SE DVB-S/S2", -+ {&tbs5922se_table[0], NULL}, -+ {NULL}, -+ } -+ } -+}; -+ -+static int tbs5922se_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ if (0 == dvb_usb_device_init(intf, &tbs5922se_properties, -+ THIS_MODULE, NULL, adapter_nr)) { -+ return 0; -+ } -+ return -ENODEV; -+} -+ -+static struct usb_driver tbs5922se_driver = { -+ .name = "tbs5922se", -+ .probe = tbs5922se_probe, -+ .disconnect = dvb_usb_device_exit, -+ .id_table = tbs5922se_table, -+}; -+ -+static int __init tbs5922se_module_init(void) -+{ -+ int ret = usb_register(&tbs5922se_driver); -+ if (ret) -+ err("usb_register failed. Error number %d", ret); -+ -+ return ret; -+} -+ -+static void __exit tbs5922se_module_exit(void) -+{ -+ usb_deregister(&tbs5922se_driver); -+} -+ -+module_init(tbs5922se_module_init); -+module_exit(tbs5922se_module_exit); -+ -+MODULE_AUTHOR("Bob Liu "); -+MODULE_DESCRIPTION("Driver for TBS 5922SE"); -+MODULE_VERSION("0.1"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/usb/dvb-usb/tbs5922se.h b/drivers/media/usb/dvb-usb/tbs5922se.h -new file mode 100644 -index 0000000..36f02b7 ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5922se.h -@@ -0,0 +1,8 @@ -+#ifndef _TBS5922SE_H_ -+#define _TBS5922SE_H_ -+ -+#define DVB_USB_LOG_PREFIX "tbs5922se" -+#include "dvb-usb.h" -+ -+#define deb_xfer(args...) dprintk(dvb_usb_tbs5922se_debug, 0x02, args) -+#endif -diff --git a/drivers/media/usb/dvb-usb/tbs5925.c b/drivers/media/usb/dvb-usb/tbs5925.c -new file mode 100644 -index 0000000..47e8bf2 ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5925.c -@@ -0,0 +1,523 @@ -+/* -+ * TurboSight TBS 5925 DVB-S2 driver -+ * -+ * Copyright (c) 2012 Konstantin Dimitrov -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, version 2. -+ * -+ */ -+ -+#include -+#include "tbs5925.h" -+#include "stv6110x.h" -+#include "stv090x.h" -+#include "stb6100.h" -+#include "stb6100_cfg.h" -+ -+#define TBS5925_READ_MSG 0 -+#define TBS5925_WRITE_MSG 1 -+#define TBS5925_LED_CTRL (0x1b00) -+ -+/* on my own*/ -+#define TBS5925_RC_QUERY (0x1a00) -+#define TBS5925_VOLTAGE_CTRL (0x1800) -+ -+struct tbs5925_state { -+ u32 last_key_pressed; -+}; -+ -+/* struct tbs5925_rc_keys { -+ u32 keycode; -+ u32 event; -+}; */ -+ -+/* debug */ -+static int dvb_usb_tbs5925_debug; -+module_param_named(debug, dvb_usb_tbs5925_debug, int, 0644); -+MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." -+ DVB_USB_DEBUG_STATUS); -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+static int tbs5925_op_rw(struct usb_device *dev, u8 request, u16 value, -+ u16 index, u8 * data, u16 len, int flags) -+{ -+ int ret; -+ u8 u8buf[len]; -+ -+ unsigned int pipe = (flags == TBS5925_READ_MSG) ? -+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); -+ u8 request_type = (flags == TBS5925_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; -+ -+ if (flags == TBS5925_WRITE_MSG) -+ memcpy(u8buf, data, len); -+ ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, -+ value, index , u8buf, len, 2000); -+ -+ if (flags == TBS5925_READ_MSG) -+ memcpy(data, u8buf, len); -+ return ret; -+} -+ -+/* I2C */ -+static int tbs5925_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], -+ int num) -+{ -+struct dvb_usb_device *d = i2c_get_adapdata(adap); -+ int i = 0; -+ u8 buf6[20]; -+ u8 inbuf[20]; -+ -+ if (!d) -+ return -ENODEV; -+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) -+ return -EAGAIN; -+ -+ switch (num) { -+ case 2: -+ buf6[0]=msg[1].len;//lenth -+ buf6[1]=msg[0].addr<<1;//demod addr -+ //register -+ buf6[2] = msg[0].buf[0]; -+ buf6[3] = msg[0].buf[1]; -+ -+ tbs5925_op_rw(d->udev, 0x92, 0, 0, -+ buf6, 4, TBS5925_WRITE_MSG); -+ //msleep(5); -+ tbs5925_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, msg[1].len, TBS5925_READ_MSG); -+ memcpy(msg[1].buf, inbuf, msg[1].len); -+ break; -+ case 1: -+ switch (msg[0].addr) { -+ case 0x68: -+ case 0x61: -+ case 0x60: -+ if (msg[0].flags == 0) { -+ buf6[0] = msg[0].len+1;//lenth -+ buf6[1] = msg[0].addr<<1;//addr -+ for(i=0;iudev, 0x80, 0, 0, -+ buf6, msg[0].len+2, TBS5925_WRITE_MSG); -+ } else { -+ buf6[0] = msg[0].len;//length -+ buf6[1] = msg[0].addr<<1;//addr -+ buf6[2] = 0x00; -+ tbs5925_op_rw(d->udev, 0x90, 0, 0, -+ buf6, 3, TBS5925_WRITE_MSG); -+ //msleep(5); -+ tbs5925_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, buf6[0], TBS5925_READ_MSG); -+ memcpy(msg[0].buf, inbuf, msg[0].len); -+ } -+ //msleep(3); -+ break; -+ case (TBS5925_RC_QUERY): -+ tbs5925_op_rw(d->udev, 0xb8, 0, 0, -+ buf6, 4, TBS5925_READ_MSG); -+ msg[0].buf[0] = buf6[2]; -+ msg[0].buf[1] = buf6[3]; -+ msleep(3); -+ //info("TBS5925_RC_QUERY %x %x %x %x\n",buf6[0],buf6[1],buf6[2],buf6[3]); -+ break; -+ case (TBS5925_VOLTAGE_CTRL): -+ buf6[0] = 3; -+ buf6[1] = msg[0].buf[0]; -+ tbs5925_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBS5925_WRITE_MSG); -+ break; -+ case (TBS5925_LED_CTRL): -+ buf6[0] = 5; -+ buf6[1] = msg[0].buf[0]; -+ tbs5925_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBS5925_WRITE_MSG); -+ break; -+ } -+ -+ break; -+ } -+ -+ mutex_unlock(&d->i2c_mutex); -+ return num; -+} -+ -+static u32 tbs5925_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C; -+} -+ -+static void tbs5925_led_ctrl(struct dvb_frontend *fe, int offon) -+{ -+ static u8 led_off[] = { 0 }; -+ static u8 led_on[] = { 1 }; -+ struct i2c_msg msg = { -+ .addr = TBS5925_LED_CTRL, -+ .flags = 0, -+ .buf = led_off, -+ .len = 1 -+ }; -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ -+ if (offon) -+ msg.buf = led_on; -+ i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); -+} -+ -+static struct stv090x_config stv0900_config = { -+ .device = STV0900, -+ .demod_mode = STV090x_SINGLE, -+ .clk_mode = STV090x_CLK_EXT, -+ -+ .xtal = 27000000, -+ .address = 0x68, -+ -+ .ts1_mode = STV090x_TSMODE_DVBCI, -+ .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, -+ -+ .repeater_level = STV090x_RPTLEVEL_16, -+ -+ .tuner_get_frequency = stb6100_get_frequency, -+ .tuner_set_frequency = stb6100_set_frequency, -+ .tuner_set_bandwidth = stb6100_set_bandwidth, -+ .tuner_get_bandwidth = stb6100_get_bandwidth, -+ -+ .set_lock_led = tbs5925_led_ctrl, -+}; -+ -+static struct stb6100_config stb6100_config = { -+ .tuner_address = 0x60, -+ .refclock = 27000000, -+}; -+ -+static struct i2c_algorithm tbs5925_i2c_algo = { -+ .master_xfer = tbs5925_i2c_transfer, -+ .functionality = tbs5925_i2c_func, -+}; -+ -+static int tbs5925_tuner_attach(struct dvb_usb_adapter *adap) -+{ -+ if (!dvb_attach(stb6100_attach, adap->fe_adap->fe, &stb6100_config, -+ &adap->dev->i2c_adap)) -+ return -EIO; -+ -+ return 0; -+} -+static int tbs5925_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -+{ -+ int i,ret; -+ u8 ibuf[3] = {0, 0,0}; -+ u8 eeprom[256], eepromline[16]; -+ -+ for (i = 0; i < 256; i++) { -+ ibuf[0]=1;//lenth -+ ibuf[1]=0xa0;//eeprom addr -+ ibuf[2]=i;//register -+ ret = tbs5925_op_rw(d->udev, 0x90, 0, 0, -+ ibuf, 3, TBS5925_WRITE_MSG); -+ ret = tbs5925_op_rw(d->udev, 0x91, 0, 0, -+ ibuf, 1, TBS5925_READ_MSG); -+ if (ret < 0) { -+ err("read eeprom failed."); -+ return -1; -+ } else { -+ eepromline[i%16] = ibuf[0]; -+ eeprom[i] = ibuf[0]; -+ } -+ -+ if ((i % 16) == 15) { -+ deb_xfer("%02x: ", i - 15); -+ debug_dump(eepromline, 16, deb_xfer); -+ } -+ } -+ memcpy(mac, eeprom + 16, 6); -+ return 0; -+}; -+ -+static int tbs5925_set_voltage(struct dvb_frontend *fe, -+ enum fe_sec_voltage voltage) -+{ -+ static u8 command_13v[1] = {0x00}; -+ static u8 command_18v[1] = {0x01}; -+ struct i2c_msg msg[] = { -+ {.addr = TBS5925_VOLTAGE_CTRL, .flags = 0, -+ .buf = command_13v, .len = 1}, -+ }; -+ -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ if (voltage == SEC_VOLTAGE_18) -+ msg[0].buf = command_18v; -+ //info("tbs5925_set_voltage %d",voltage); -+ i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1); -+ return 0; -+} -+ -+static struct dvb_usb_device_properties tbs5925_properties; -+ -+static int tbs5925_frontend_attach(struct dvb_usb_adapter *d) -+{ -+ struct dvb_usb_device *u = d->dev; -+ u8 buf[20]; -+ -+ if (tbs5925_properties.adapter->fe->tuner_attach == &tbs5925_tuner_attach) { -+ d->fe_adap->fe = dvb_attach(stv090x_attach, &stv0900_config, -+ &u->i2c_adap, STV090x_DEMODULATOR_0); -+ if (d->fe_adap->fe != NULL) { -+ d->fe_adap->fe->ops.set_voltage = tbs5925_set_voltage; -+ -+ buf[0] = 6; -+ buf[1] = 1; -+ tbs5925_op_rw(u->udev, 0x8a, 0, 0, -+ buf, 2, TBS5925_WRITE_MSG); -+ -+ buf[0] = 1; -+ buf[1] = 1; -+ tbs5925_op_rw(u->udev, 0x8a, 0, 0, -+ buf, 2, TBS5925_WRITE_MSG); -+ -+ buf[0] = 7; -+ buf[1] = 1; -+ tbs5925_op_rw(u->udev, 0x8a, 0, 0, -+ buf, 2, TBS5925_WRITE_MSG); -+ -+ strlcpy(d->fe_adap->fe->ops.info.name,u->props.devices[0].name,52); -+ -+ return 0; -+ } -+ } -+ -+ return -EIO; -+} -+ -+static struct rc_map_table tbs5925_rc_keys[] = { -+ { 0xff84, KEY_POWER2}, /* power */ -+ { 0xff94, KEY_MUTE}, /* mute */ -+ { 0xff87, KEY_1}, -+ { 0xff86, KEY_2}, -+ { 0xff85, KEY_3}, -+ { 0xff8b, KEY_4}, -+ { 0xff8a, KEY_5}, -+ { 0xff89, KEY_6}, -+ { 0xff8f, KEY_7}, -+ { 0xff8e, KEY_8}, -+ { 0xff8d, KEY_9}, -+ { 0xff92, KEY_0}, -+ { 0xff96, KEY_CHANNELUP}, /* ch+ */ -+ { 0xff91, KEY_CHANNELDOWN}, /* ch- */ -+ { 0xff93, KEY_VOLUMEUP}, /* vol+ */ -+ { 0xff8c, KEY_VOLUMEDOWN}, /* vol- */ -+ { 0xff83, KEY_RECORD}, /* rec */ -+ { 0xff98, KEY_PAUSE}, /* pause, yellow */ -+ { 0xff99, KEY_OK}, /* ok */ -+ { 0xff9a, KEY_CAMERA}, /* snapshot */ -+ { 0xff81, KEY_UP}, -+ { 0xff90, KEY_LEFT}, -+ { 0xff82, KEY_RIGHT}, -+ { 0xff88, KEY_DOWN}, -+ { 0xff95, KEY_FAVORITES}, /* blue */ -+ { 0xff97, KEY_SUBTITLE}, /* green */ -+ { 0xff9d, KEY_ZOOM}, -+ { 0xff9f, KEY_EXIT}, -+ { 0xff9e, KEY_MENU}, -+ { 0xff9c, KEY_EPG}, -+ { 0xff80, KEY_PREVIOUS}, /* red */ -+ { 0xff9b, KEY_MODE}, -+ { 0xffdd, KEY_TV }, -+ { 0xffde, KEY_PLAY }, -+ { 0xffdc, KEY_STOP }, -+ { 0xffdb, KEY_REWIND }, -+ { 0xffda, KEY_FASTFORWARD }, -+ { 0xffd9, KEY_PREVIOUS }, /* replay */ -+ { 0xffd8, KEY_NEXT }, /* skip */ -+ { 0xffd1, KEY_NUMERIC_STAR }, -+ { 0xffd2, KEY_NUMERIC_POUND }, -+ { 0xffd4, KEY_DELETE }, /* clear */ -+}; -+ -+static int tbs5925_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -+{ -+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; -+ int keymap_size = d->props.rc.legacy.rc_map_size; -+ -+ struct tbs5925_state *st = d->priv; -+ u8 key[2]; -+ struct i2c_msg msg[] = { -+ {.addr = TBS5925_RC_QUERY, .flags = I2C_M_RD, .buf = key, -+ .len = 2}, -+ }; -+ int i; -+ -+ *state = REMOTE_NO_KEY_PRESSED; -+ if (tbs5925_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { -+ //info("key: %x %x\n",msg[0].buf[0],msg[0].buf[1]); -+ for (i = 0; i < keymap_size; i++) { -+ if (rc5_data(&keymap[i]) == msg[0].buf[1]) { -+ *state = REMOTE_KEY_PRESSED; -+ *event = keymap[i].keycode; -+ st->last_key_pressed = -+ keymap[i].keycode; -+ break; -+ } -+ st->last_key_pressed = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct usb_device_id tbs5925_table[] = { -+ {USB_DEVICE(0x734c, 0x5925)}, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(usb, tbs5925_table); -+ -+static int tbs5925_load_firmware(struct usb_device *dev, -+ const struct firmware *frmwr) -+{ -+ u8 *b, *p; -+ int ret = 0, i; -+ u8 reset; -+ const struct firmware *fw; -+ switch (dev->descriptor.idProduct) { -+ case 0x5925: -+ ret = request_firmware(&fw, tbs5925_properties.firmware, &dev->dev); -+ if (ret != 0) { -+ err("did not find the firmware file. (%s) " -+ "Please see linux/Documentation/dvb/ for more details " -+ "on firmware-problems.", tbs5925_properties.firmware); -+ return ret; -+ } -+ break; -+ default: -+ fw = frmwr; -+ break; -+ } -+ info("start downloading TBS5925 firmware"); -+ p = kmalloc(fw->size, GFP_KERNEL); -+ reset = 1; -+ /*stop the CPU*/ -+ tbs5925_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, TBS5925_WRITE_MSG); -+ tbs5925_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, TBS5925_WRITE_MSG); -+ -+ if (p != NULL) { -+ memcpy(p, fw->data, fw->size); -+ for (i = 0; i < fw->size; i += 0x40) { -+ b = (u8 *) p + i; -+ if (tbs5925_op_rw(dev, 0xa0, i, 0, b , 0x40, -+ TBS5925_WRITE_MSG) != 0x40) { -+ err("error while transferring firmware"); -+ ret = -EINVAL; -+ break; -+ } -+ } -+ /* restart the CPU */ -+ reset = 0; -+ if (ret || tbs5925_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, -+ TBS5925_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ if (ret || tbs5925_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, -+ TBS5925_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ -+ msleep(100); -+ kfree(p); -+ } -+ return ret; -+} -+ -+static struct dvb_usb_device_properties tbs5925_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .firmware = "dvb-usb-tbsqbox-id5925.fw", -+ .size_of_priv = sizeof(struct tbs5925_state), -+ .no_reconnect = 1, -+ -+ .i2c_algo = &tbs5925_i2c_algo, -+ .rc.legacy = { -+ .rc_map_table = tbs5925_rc_keys, -+ .rc_map_size = ARRAY_SIZE(tbs5925_rc_keys), -+ .rc_interval = 250, -+ .rc_query = tbs5925_rc_query, -+ }, -+ -+ .generic_bulk_ctrl_endpoint = 0x81, -+ /* parameter for the MPEG2-data transfer */ -+ .num_adapters = 1, -+ .download_firmware = tbs5925_load_firmware, -+ .read_mac_address = tbs5925_read_mac_address, -+ .adapter = {{ -+ .num_frontends = 1, -+ .fe = {{ -+ .frontend_attach = tbs5925_frontend_attach, -+ .streaming_ctrl = NULL, -+ .tuner_attach = tbs5925_tuner_attach, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ }, -+ } }, -+ } }, -+ -+ .num_device_descs = 1, -+ .devices = { -+ {"TurboSight TBS 5925 DVB-S/S2", -+ {&tbs5925_table[0], NULL}, -+ {NULL}, -+ } -+ } -+}; -+ -+static int tbs5925_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ if (0 == dvb_usb_device_init(intf, &tbs5925_properties, -+ THIS_MODULE, NULL, adapter_nr)) { -+ return 0; -+ } -+ return -ENODEV; -+} -+ -+static struct usb_driver tbs5925_driver = { -+ .name = "tbs5925", -+ .probe = tbs5925_probe, -+ .disconnect = dvb_usb_device_exit, -+ .id_table = tbs5925_table, -+}; -+ -+static int __init tbs5925_module_init(void) -+{ -+ int ret = usb_register(&tbs5925_driver); -+ if (ret) -+ err("usb_register failed. Error number %d", ret); -+ -+ return ret; -+} -+ -+static void __exit tbs5925_module_exit(void) -+{ -+ usb_deregister(&tbs5925_driver); -+} -+ -+module_init(tbs5925_module_init); -+module_exit(tbs5925_module_exit); -+ -+MODULE_AUTHOR("Konstantin Dimitrov "); -+MODULE_DESCRIPTION("TurboSight TBS 5925 DVB-S2 driver"); -+MODULE_VERSION("1.0"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/usb/dvb-usb/tbs5925.h b/drivers/media/usb/dvb-usb/tbs5925.h -new file mode 100644 -index 0000000..83278f5 ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5925.h -@@ -0,0 +1,8 @@ -+#ifndef _TBS5925_H_ -+#define _TBS5925_H_ -+ -+#define DVB_USB_LOG_PREFIX "tbs5925" -+#include "dvb-usb.h" -+ -+#define deb_xfer(args...) dprintk(dvb_usb_tbs5925_debug, 0x02, args) -+#endif -diff --git a/drivers/media/usb/dvb-usb/tbs5927.c b/drivers/media/usb/dvb-usb/tbs5927.c -new file mode 100644 -index 0000000..672234d ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5927.c -@@ -0,0 +1,529 @@ -+/* -+ * TurboSight TBS 5927 DVB-S2 driver -+ * -+ * Copyright (c) 2016 TBSDTV -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, version 2. -+ * -+ */ -+ -+#include -+#include "tbs5927.h" -+#include "stv6120.h" -+#include "stv0910.h" -+ -+#define TBS5927_READ_MSG 0 -+#define TBS5927_WRITE_MSG 1 -+#define TBS5927_LED_CTRL (0x1b00) -+ -+/* on my own*/ -+#define TBS5927_RC_QUERY (0x1a00) -+#define TBS5927_VOLTAGE_CTRL (0x1800) -+ -+struct tbs5927_state { -+ u32 last_key_pressed; -+}; -+ -+/* struct tbs5927_rc_keys { -+ u32 keycode; -+ u32 event; -+}; */ -+ -+/* debug */ -+static int dvb_usb_tbs5927_debug; -+module_param_named(debug, dvb_usb_tbs5927_debug, int, 0644); -+MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." -+ DVB_USB_DEBUG_STATUS); -+ -+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -+ -+static int tbs5927_op_rw(struct usb_device *dev, u8 request, u16 value, -+ u16 index, u8 * data, u16 len, int flags) -+{ -+ int ret; -+ u8 u8buf[len]; -+ -+ unsigned int pipe = (flags == TBS5927_READ_MSG) ? -+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); -+ u8 request_type = (flags == TBS5927_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; -+ -+ if (flags == TBS5927_WRITE_MSG) -+ memcpy(u8buf, data, len); -+ ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, -+ value, index , u8buf, len, 2000); -+ -+ if (flags == TBS5927_READ_MSG) -+ memcpy(data, u8buf, len); -+ return ret; -+} -+ -+/* I2C */ -+static int tbs5927_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], -+ int num) -+{ -+struct dvb_usb_device *d = i2c_get_adapdata(adap); -+ int i = 0; -+ u8 buf6[32]; -+ u8 inbuf[32]; -+ -+ if (!d) -+ return -ENODEV; -+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0) -+ return -EAGAIN; -+ -+ switch (num) { -+ case 2: -+ buf6[0]=msg[1].len;//lenth -+ buf6[1]=msg[0].addr<<1;//demod addr -+ //register -+ memcpy(buf6+2,msg[0].buf,msg[0].len); -+ -+ tbs5927_op_rw(d->udev, msg[0].addr < 0x68 ? 0x90 : 0x92, 0, 0, -+ buf6, msg[0].len+2, TBS5927_WRITE_MSG); -+ //msleep(5); -+ tbs5927_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, msg[1].len, TBS5927_READ_MSG); -+ memcpy(msg[1].buf, inbuf, msg[1].len); -+ break; -+ case 1: -+ switch (msg[0].addr) { -+ case 0x68: -+ case 0x61: -+ case 0x60: -+ if (msg[0].flags == 0) { -+ buf6[0] = msg[0].len+1;//lenth -+ buf6[1] = msg[0].addr<<1;//addr -+ for(i=0;iudev, 0x80, 0, 0, -+ buf6, msg[0].len+2, TBS5927_WRITE_MSG); -+ } else { -+ buf6[0] = msg[0].len;//length -+ buf6[1] = msg[0].addr<<1;//addr -+ buf6[2] = 0x00; -+ tbs5927_op_rw(d->udev, 0x90, 0, 0, -+ buf6, 3, TBS5927_WRITE_MSG); -+ //msleep(5); -+ tbs5927_op_rw(d->udev, 0x91, 0, 0, -+ inbuf, buf6[0], TBS5927_READ_MSG); -+ memcpy(msg[0].buf, inbuf, msg[0].len); -+ } -+ //msleep(3); -+ break; -+ case (TBS5927_RC_QUERY): -+ tbs5927_op_rw(d->udev, 0xb8, 0, 0, -+ buf6, 4, TBS5927_READ_MSG); -+ msg[0].buf[0] = buf6[2]; -+ msg[0].buf[1] = buf6[3]; -+ msleep(3); -+ /* info("TBS5927_RC_QUERY %x %x %x %x\n",buf6[0],buf6[1],buf6[2],buf6[3]); */ -+ break; -+ case (TBS5927_VOLTAGE_CTRL): -+ buf6[0] = 1; -+ buf6[1] = msg[0].buf[0] < 2; -+ tbs5927_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBS5927_WRITE_MSG); -+ msleep(5); -+ if (msg[0].buf[0] < 2) { -+ buf6[0] = 3; -+ buf6[1] = msg[0].buf[0]; -+ tbs5927_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBS5927_WRITE_MSG); -+ } -+ break; -+ case (TBS5927_LED_CTRL): -+ buf6[0] = 5; -+ buf6[1] = msg[0].buf[0]; -+ tbs5927_op_rw(d->udev, 0x8a, 0, 0, -+ buf6, 2, TBS5927_WRITE_MSG); -+ break; -+ } -+ -+ break; -+ } -+ -+ mutex_unlock(&d->i2c_mutex); -+ return num; -+} -+ -+static u32 tbs5927_i2c_func(struct i2c_adapter *adapter) -+{ -+ return I2C_FUNC_I2C; -+} -+ -+static void tbs5927_led_ctrl(struct dvb_frontend *fe, int offon) -+{ -+ static u8 led_off[] = { 0 }; -+ static u8 led_on[] = { 1 }; -+ struct i2c_msg msg = { -+ .addr = TBS5927_LED_CTRL, -+ .flags = 0, -+ .buf = led_off, -+ .len = 1 -+ }; -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ -+ if (offon) -+ msg.buf = led_on; -+ -+ /* info("tbs5927_led_ctrl %d", msg.buf[0]); */ -+ i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); -+} -+ -+static struct stv0910_cfg tbs5927_stv0910_cfg = { -+ .adr = 0x68, -+ .parallel = 1, -+ .rptlvl = 3, -+ .clk = 30000000, -+ .dual_tuner = 1, -+ .set_lock_led = tbs5927_led_ctrl, -+}; -+ -+static struct stv6120_cfg tbs5927_stv6120_cfg = { -+ .adr = 0x60, -+ .xtal = 30000, -+ .Rdiv = 2, -+}; -+ -+static struct i2c_algorithm tbs5927_i2c_algo = { -+ .master_xfer = tbs5927_i2c_transfer, -+ .functionality = tbs5927_i2c_func, -+}; -+ -+static int tbs5927_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -+{ -+ int i,ret; -+ u8 ibuf[3] = {0, 0,0}; -+ u8 eeprom[256], eepromline[16]; -+ -+ for (i = 0; i < 256; i++) { -+ ibuf[0]=1;//lenth -+ ibuf[1]=0xa0;//eeprom addr -+ ibuf[2]=i;//register -+ ret = tbs5927_op_rw(d->udev, 0x90, 0, 0, -+ ibuf, 3, TBS5927_WRITE_MSG); -+ ret = tbs5927_op_rw(d->udev, 0x91, 0, 0, -+ ibuf, 1, TBS5927_READ_MSG); -+ if (ret < 0) { -+ err("read eeprom failed."); -+ return -1; -+ } else { -+ eepromline[i%16] = ibuf[0]; -+ eeprom[i] = ibuf[0]; -+ } -+ -+ if ((i % 16) == 15) { -+ deb_xfer("%02x: ", i - 15); -+ debug_dump(eepromline, 16, deb_xfer); -+ } -+ } -+ memcpy(mac, eeprom + 16, 6); -+ return 0; -+}; -+ -+static int tbs5927_set_voltage(struct dvb_frontend *fe, -+ enum fe_sec_voltage voltage) -+{ -+ static u8 cmd[1] = {0x00}; -+ -+ struct i2c_msg msg[] = { -+ {.addr = TBS5927_VOLTAGE_CTRL, .flags = 0, -+ .buf = cmd, .len = 1}, -+ }; -+ -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ switch (voltage) { -+ case SEC_VOLTAGE_13: -+ cmd[0] = 0; -+ break; -+ case SEC_VOLTAGE_18: -+ cmd[0] = 1; -+ break; -+ case SEC_VOLTAGE_OFF: -+ cmd[0] = 2; -+ break; -+ } -+ -+ /*info("tbs5927_set_voltage %d", voltage);*/ -+ i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1); -+ return 0; -+} -+ -+static int tbs5927_tuner_attach(struct dvb_usb_adapter *adap) -+{ -+ if (!dvb_attach(stv6120_attach, adap->fe_adap->fe, -+ &adap->dev->i2c_adap, &tbs5927_stv6120_cfg, 0)) -+ return -EIO; -+ -+ return 0; -+} -+ -+static struct dvb_usb_device_properties tbs5927_properties; -+ -+static int tbs5927_frontend_attach(struct dvb_usb_adapter *d) -+{ -+ struct dvb_usb_device *u = d->dev; -+ u8 buf[20]; -+ -+ buf[0] = 6; /* I2C speed */ -+ buf[1] = 0; /* 100KHz */ -+ tbs5927_op_rw(d->dev->udev, 0x8a, 0, 0, -+ buf, 2, TBS5927_WRITE_MSG); -+ -+ if (tbs5927_properties.adapter->fe->tuner_attach == &tbs5927_tuner_attach) { -+ d->fe_adap->fe = dvb_attach(stv0910_attach, &d->dev->i2c_adap, -+ &tbs5927_stv0910_cfg, 1 ); -+ if (d->fe_adap->fe != NULL) { -+ d->fe_adap->fe->ops.set_voltage = tbs5927_set_voltage; -+ -+ buf[0] = 1; /* LNB power disable */ -+ buf[1] = 0; -+ tbs5927_op_rw(d->dev->udev, 0x8a, 0, 0, -+ buf, 2, TBS5927_WRITE_MSG); -+ -+ buf[0] = 7; /* IR RC enable */ -+ buf[1] = 1; -+ tbs5927_op_rw(d->dev->udev, 0x8a, 0, 0, -+ buf, 2, TBS5927_WRITE_MSG); -+ -+ strlcpy(d->fe_adap->fe->ops.info.name,u->props.devices[0].name,52); -+ -+ return 0; -+ } -+ } -+ -+ return -EIO; -+} -+ -+static struct rc_map_table tbs5927_rc_keys[] = { -+ { 0xff84, KEY_POWER2}, /* power */ -+ { 0xff94, KEY_MUTE}, /* mute */ -+ { 0xff87, KEY_1}, -+ { 0xff86, KEY_2}, -+ { 0xff85, KEY_3}, -+ { 0xff8b, KEY_4}, -+ { 0xff8a, KEY_5}, -+ { 0xff89, KEY_6}, -+ { 0xff8f, KEY_7}, -+ { 0xff8e, KEY_8}, -+ { 0xff8d, KEY_9}, -+ { 0xff92, KEY_0}, -+ { 0xff96, KEY_CHANNELUP}, /* ch+ */ -+ { 0xff91, KEY_CHANNELDOWN}, /* ch- */ -+ { 0xff93, KEY_VOLUMEUP}, /* vol+ */ -+ { 0xff8c, KEY_VOLUMEDOWN}, /* vol- */ -+ { 0xff83, KEY_RECORD}, /* rec */ -+ { 0xff98, KEY_PAUSE}, /* pause, yellow */ -+ { 0xff99, KEY_OK}, /* ok */ -+ { 0xff9a, KEY_CAMERA}, /* snapshot */ -+ { 0xff81, KEY_UP}, -+ { 0xff90, KEY_LEFT}, -+ { 0xff82, KEY_RIGHT}, -+ { 0xff88, KEY_DOWN}, -+ { 0xff95, KEY_FAVORITES}, /* blue */ -+ { 0xff97, KEY_SUBTITLE}, /* green */ -+ { 0xff9d, KEY_ZOOM}, -+ { 0xff9f, KEY_EXIT}, -+ { 0xff9e, KEY_MENU}, -+ { 0xff9c, KEY_EPG}, -+ { 0xff80, KEY_PREVIOUS}, /* red */ -+ { 0xff9b, KEY_MODE}, -+ { 0xffdd, KEY_TV }, -+ { 0xffde, KEY_PLAY }, -+ { 0xffdc, KEY_STOP }, -+ { 0xffdb, KEY_REWIND }, -+ { 0xffda, KEY_FASTFORWARD }, -+ { 0xffd9, KEY_PREVIOUS }, /* replay */ -+ { 0xffd8, KEY_NEXT }, /* skip */ -+ { 0xffd1, KEY_NUMERIC_STAR }, -+ { 0xffd2, KEY_NUMERIC_POUND }, -+ { 0xffd4, KEY_DELETE }, /* clear */ -+}; -+ -+static int tbs5927_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -+{ -+ struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; -+ int keymap_size = d->props.rc.legacy.rc_map_size; -+ -+ struct tbs5927_state *st = d->priv; -+ u8 key[2]; -+ struct i2c_msg msg[] = { -+ {.addr = TBS5927_RC_QUERY, .flags = I2C_M_RD, .buf = key, -+ .len = 2}, -+ }; -+ int i; -+ -+ *state = REMOTE_NO_KEY_PRESSED; -+ if (tbs5927_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { -+ //info("key: %x %x\n",msg[0].buf[0],msg[0].buf[1]); -+ for (i = 0; i < keymap_size; i++) { -+ if (rc5_data(&keymap[i]) == msg[0].buf[1]) { -+ *state = REMOTE_KEY_PRESSED; -+ *event = keymap[i].keycode; -+ st->last_key_pressed = -+ keymap[i].keycode; -+ break; -+ } -+ st->last_key_pressed = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct usb_device_id tbs5927_table[] = { -+ {USB_DEVICE(0x734c, 0x5927)}, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(usb, tbs5927_table); -+ -+static int tbs5927_load_firmware(struct usb_device *dev, -+ const struct firmware *frmwr) -+{ -+ u8 *b, *p; -+ int ret = 0, i; -+ u8 reset; -+ const struct firmware *fw; -+ switch (dev->descriptor.idProduct) { -+ case 0x5927: -+ ret = request_firmware(&fw, tbs5927_properties.firmware, &dev->dev); -+ if (ret != 0) { -+ err("did not find the firmware file. (%s) " -+ "Please see linux/Documentation/dvb/ for more details " -+ "on firmware-problems.", tbs5927_properties.firmware); -+ return ret; -+ } -+ break; -+ default: -+ fw = frmwr; -+ break; -+ } -+ info("start downloading TBS5927 firmware"); -+ p = kmalloc(fw->size, GFP_KERNEL); -+ reset = 1; -+ /*stop the CPU*/ -+ tbs5927_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, TBS5927_WRITE_MSG); -+ tbs5927_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, TBS5927_WRITE_MSG); -+ -+ if (p != NULL) { -+ memcpy(p, fw->data, fw->size); -+ for (i = 0; i < fw->size; i += 0x40) { -+ b = (u8 *) p + i; -+ if (tbs5927_op_rw(dev, 0xa0, i, 0, b , 0x40, -+ TBS5927_WRITE_MSG) != 0x40) { -+ err("error while transferring firmware"); -+ ret = -EINVAL; -+ break; -+ } -+ } -+ /* restart the CPU */ -+ reset = 0; -+ if (ret || tbs5927_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, -+ TBS5927_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ if (ret || tbs5927_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, -+ TBS5927_WRITE_MSG) != 1) { -+ err("could not restart the USB controller CPU."); -+ ret = -EINVAL; -+ } -+ -+ msleep(100); -+ kfree(p); -+ } -+ return ret; -+} -+ -+static struct dvb_usb_device_properties tbs5927_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .firmware = "dvb-usb-tbsqbox-id5927.fw", -+ .size_of_priv = sizeof(struct tbs5927_state), -+ .no_reconnect = 1, -+ -+ .i2c_algo = &tbs5927_i2c_algo, -+ .rc.legacy = { -+ .rc_map_table = tbs5927_rc_keys, -+ .rc_map_size = ARRAY_SIZE(tbs5927_rc_keys), -+ .rc_interval = 250, -+ .rc_query = tbs5927_rc_query, -+ }, -+ -+ .generic_bulk_ctrl_endpoint = 0x81, -+ /* parameter for the MPEG2-data transfer */ -+ .num_adapters = 1, -+ .download_firmware = tbs5927_load_firmware, -+ .read_mac_address = tbs5927_read_mac_address, -+ .adapter = {{ -+ .num_frontends = 1, -+ .fe = {{ -+ .frontend_attach = tbs5927_frontend_attach, -+ .streaming_ctrl = NULL, -+ .tuner_attach = tbs5927_tuner_attach, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ }, -+ } }, -+ } }, -+ -+ .num_device_descs = 1, -+ .devices = { -+ {"TurboSight TBS 5927 DVB-S/S2", -+ {&tbs5927_table[0], NULL}, -+ {NULL}, -+ } -+ } -+}; -+ -+static int tbs5927_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ if (0 == dvb_usb_device_init(intf, &tbs5927_properties, -+ THIS_MODULE, NULL, adapter_nr)) { -+ return 0; -+ } -+ return -ENODEV; -+} -+ -+static struct usb_driver tbs5927_driver = { -+ .name = "tbs5927", -+ .probe = tbs5927_probe, -+ .disconnect = dvb_usb_device_exit, -+ .id_table = tbs5927_table, -+}; -+ -+static int __init tbs5927_module_init(void) -+{ -+ int ret = usb_register(&tbs5927_driver); -+ if (ret) -+ err("usb_register failed. Error number %d", ret); -+ -+ return ret; -+} -+ -+static void __exit tbs5927_module_exit(void) -+{ -+ usb_deregister(&tbs5927_driver); -+} -+ -+module_init(tbs5927_module_init); -+module_exit(tbs5927_module_exit); -+ -+MODULE_AUTHOR("TBSDTV"); -+MODULE_DESCRIPTION("TurboSight TBS 5927 DVB-S2 driver"); -+MODULE_VERSION("1.0"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/usb/dvb-usb/tbs5927.h b/drivers/media/usb/dvb-usb/tbs5927.h -new file mode 100644 -index 0000000..9b5948c ---- /dev/null -+++ b/drivers/media/usb/dvb-usb/tbs5927.h -@@ -0,0 +1,8 @@ -+#ifndef _TBS5927_H_ -+#define _TBS5927_H_ -+ -+#define DVB_USB_LOG_PREFIX "tbs5927" -+#include "dvb-usb.h" -+ -+#define deb_xfer(args...) dprintk(dvb_usb_tbs5927_debug, 0x02, args) -+#endif -diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h -index 00a20cd..3157d38 100644 ---- a/include/uapi/linux/dvb/frontend.h -+++ b/include/uapi/linux/dvb/frontend.h -@@ -156,6 +156,8 @@ enum fe_code_rate { - FEC_3_5, - FEC_9_10, - FEC_2_5, -+ FEC_1_4, -+ FEC_1_3, - }; - - enum fe_modulation { -@@ -342,6 +344,7 @@ enum fe_delivery_system { - SYS_DVBT2, - SYS_TURBO, - SYS_DVBC_ANNEX_C, -+ SYS_DVBC2, - }; - - /* backward compatibility */ diff --git a/packages/linux/patches/default/linux-221-T230C-support.patch b/packages/linux/patches/default/linux-221-T230C-support.patch deleted file mode 100644 index 16ce2ecad1..0000000000 --- a/packages/linux/patches/default/linux-221-T230C-support.patch +++ /dev/null @@ -1,502 +0,0 @@ -From: https://github.com/crazycat69/linux_media/ -Date: Wed, 28 Sep 2016 01:29:23 +0300 -Subject: [PATCH] cxusb: Geniatech T230C support. - -diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c -index 20b4a65..28f3bbe 100644 ---- a/drivers/media/dvb-frontends/si2168.c -+++ b/drivers/media/dvb-frontends/si2168.c -@@ -674,6 +674,9 @@ static int si2168_probe(struct i2c_client *client, - case SI2168_CHIP_ID_B40: - dev->firmware_name = SI2168_B40_FIRMWARE; - break; -+ case SI2168_CHIP_ID_D60: -+ dev->firmware_name = SI2168_D60_FIRMWARE; -+ break; - default: - dev_dbg(&client->dev, "unknown chip version Si21%d-%c%c%c\n", - cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]); -@@ -761,3 +764,4 @@ static int si2168_remove(struct i2c_client *client) - MODULE_FIRMWARE(SI2168_A20_FIRMWARE); - MODULE_FIRMWARE(SI2168_A30_FIRMWARE); - MODULE_FIRMWARE(SI2168_B40_FIRMWARE); -+MODULE_FIRMWARE(SI2168_D60_FIRMWARE); -diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h -index 7843ccb..4baa95b 100644 ---- a/drivers/media/dvb-frontends/si2168_priv.h -+++ b/drivers/media/dvb-frontends/si2168_priv.h -@@ -25,6 +25,7 @@ - #define SI2168_A20_FIRMWARE "dvb-demod-si2168-a20-01.fw" - #define SI2168_A30_FIRMWARE "dvb-demod-si2168-a30-01.fw" - #define SI2168_B40_FIRMWARE "dvb-demod-si2168-b40-01.fw" -+#define SI2168_D60_FIRMWARE "dvb-demod-si2168-d60-01.fw" - #define SI2168_B40_FIRMWARE_FALLBACK "dvb-demod-si2168-02.fw" - - /* state struct */ -@@ -37,6 +38,7 @@ struct si2168_dev { - #define SI2168_CHIP_ID_A20 ('A' << 24 | 68 << 16 | '2' << 8 | '0' << 0) - #define SI2168_CHIP_ID_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0) - #define SI2168_CHIP_ID_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0) -+ #define SI2168_CHIP_ID_D60 ('D' << 24 | 68 << 16 | '6' << 8 | '0' << 0) - unsigned int chip_id; - unsigned int version; - const char *firmware_name; -diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c -index 57b2508..69fd21e 100644 ---- a/drivers/media/tuners/si2157.c -+++ b/drivers/media/tuners/si2157.c -@@ -1,5 +1,5 @@ - /* -- * Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver -+ * Silicon Labs Si2141/2146/2147/2148/2151/2157/2158 silicon tuner driver - * - * Copyright (C) 2014 Antti Palosaari - * -@@ -84,7 +84,7 @@ static int si2157_init(struct dvb_frontend *fe) - struct si2157_cmd cmd; - const struct firmware *fw; - const char *fw_name; -- unsigned int uitmp, chip_id; -+ unsigned int uitmp, chip_id, count; - - dev_dbg(&client->dev, "\n"); - -@@ -102,14 +102,46 @@ static int si2157_init(struct dvb_frontend *fe) - if (uitmp == dev->if_frequency / 1000) - goto warm; - -+ if (dev->chiptype == SI2157_CHIPTYPE_SI2141) { -+ count = 0; -+ do { -+ if (count > 10) -+ goto err; -+ -+ /* reset */ -+ memcpy(cmd.args, "\xc0\x05\x00\x00", 4); -+ cmd.wlen = 4; -+ cmd.rlen = 1; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ -+ memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 10); -+ cmd.wlen = 10; -+ cmd.rlen = 1; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ count++; -+ } while (cmd.args[0] == 0xfe); -+ dev_info(&client->dev, "Si2141/2151 reset attempts %d\n", count); -+ } -+ - /* power up */ -- if (dev->chiptype == SI2157_CHIPTYPE_SI2146) { -+ switch (dev->chiptype) { -+ case SI2157_CHIPTYPE_SI2146: - memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9); - cmd.wlen = 9; -- } else { -+ break; -+ case SI2157_CHIPTYPE_SI2141: -+ memcpy(cmd.args, "\xc0\x08\x01\x02\x00\x08\x01", 7); -+ cmd.wlen = 7; -+ break; -+ default: - memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15); - cmd.wlen = 15; - } -+ - cmd.rlen = 1; - ret = si2157_cmd_execute(client, &cmd); - if (ret) -@@ -131,6 +163,8 @@ static int si2157_init(struct dvb_frontend *fe) - #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0) - #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0) - #define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0) -+ #define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0) -+ #define SI2151_A10 ('A' << 24 | 51 << 16 | '1' << 8 | '0' << 0) - - switch (chip_id) { - case SI2158_A20: -@@ -142,6 +176,10 @@ static int si2157_init(struct dvb_frontend *fe) - case SI2146_A10: - fw_name = NULL; - break; -+ case SI2141_A10: -+ case SI2151_A10: -+ fw_name = SI2141_A10_FIRMWARE; -+ break; - default: - dev_err(&client->dev, "unknown chip version Si21%d-%c%c%c\n", - cmd.args[2], cmd.args[1], -@@ -214,6 +252,23 @@ static int si2157_init(struct dvb_frontend *fe) - - dev_info(&client->dev, "firmware version: %c.%c.%d\n", - cmd.args[6], cmd.args[7], cmd.args[8]); -+ -+ if (dev->chiptype == SI2157_CHIPTYPE_SI2141) { -+ /* set clock */ -+ memcpy(cmd.args, "\xc0\x00\x0d", 3); -+ cmd.wlen = 3; -+ cmd.rlen = 1; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ /* setup PIN */ -+ memcpy(cmd.args, "\x12\x80\x80\x85\x00\x81\x00", 7); -+ cmd.wlen = 7; -+ cmd.rlen = 7; -+ ret = si2157_cmd_execute(client, &cmd); -+ if (ret) -+ goto err; -+ } - warm: - /* init statistics in order signal app which are supported */ - c->strength.len = 1; -@@ -471,7 +526,8 @@ static int si2157_probe(struct i2c_client *client, - #endif - - dev_info(&client->dev, "Silicon Labs %s successfully attached\n", -- dev->chiptype == SI2157_CHIPTYPE_SI2146 ? -+ dev->chiptype == SI2157_CHIPTYPE_SI2141 ? -+ "Si2141/2151" : dev->chiptype == SI2157_CHIPTYPE_SI2146 ? - "Si2146" : "Si2147/2148/2157/2158"); - - return 0; -@@ -508,6 +564,8 @@ static int si2157_remove(struct i2c_client *client) - static const struct i2c_device_id si2157_id_table[] = { - {"si2157", SI2157_CHIPTYPE_SI2157}, - {"si2146", SI2157_CHIPTYPE_SI2146}, -+ {"si2141", SI2157_CHIPTYPE_SI2141}, -+ {"si2151", SI2157_CHIPTYPE_SI2141}, - {} - }; - MODULE_DEVICE_TABLE(i2c, si2157_id_table); -@@ -524,7 +582,8 @@ static int si2157_remove(struct i2c_client *client) - - module_i2c_driver(si2157_driver); - --MODULE_DESCRIPTION("Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver"); -+MODULE_DESCRIPTION("Silicon Labs Si2141/2146/2147/2148/2151/2157/2158 silicon tuner driver"); - MODULE_AUTHOR("Antti Palosaari "); - MODULE_LICENSE("GPL"); - MODULE_FIRMWARE(SI2158_A20_FIRMWARE); -+MODULE_FIRMWARE(SI2141_A10_FIRMWARE); -diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h -index d6b2c7b..e6436f7 100644 ---- a/drivers/media/tuners/si2157_priv.h -+++ b/drivers/media/tuners/si2157_priv.h -@@ -42,6 +42,7 @@ struct si2157_dev { - - #define SI2157_CHIPTYPE_SI2157 0 - #define SI2157_CHIPTYPE_SI2146 1 -+#define SI2157_CHIPTYPE_SI2141 2 - - /* firmware command struct */ - #define SI2157_ARGLEN 30 -@@ -52,5 +53,6 @@ struct si2157_cmd { - }; - - #define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw" -+#define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw" - - #endif -diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c -index 0f6ace4..4bf4c68 100644 ---- a/drivers/media/usb/dvb-usb/cxusb.c -+++ b/drivers/media/usb/dvb-usb/cxusb.c -@@ -369,6 +369,26 @@ static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) - return 0; - } - -+static int cxusb_read_status(struct dvb_frontend *fe, -+ enum fe_status *status) -+{ -+ struct dvb_usb_adapter *adap = (struct dvb_usb_adapter *)fe->dvb->priv; -+ struct cxusb_state *state = (struct cxusb_state *)adap->dev->priv; -+ int ret; -+ -+ ret = state->fe_read_status(fe, status); -+ -+ /* it need resync slave fifo when signal change from unlock to lock.*/ -+ if ((*status & FE_HAS_LOCK) && (!state->last_lock)) { -+ mutex_lock(&state->stream_mutex); -+ cxusb_streaming_ctrl(adap, 1); -+ mutex_unlock(&state->stream_mutex); -+ } -+ -+ state->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0; -+ return ret; -+} -+ - static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d) - { - int ep = d->props.generic_bulk_ctrl_endpoint; -@@ -633,6 +653,44 @@ static struct rc_map_table rc_map_d680_dmb_table[] = { - { 0x0025, KEY_POWER }, - }; - -+static struct rc_map_table rc_map_t230_table[] = { -+ { 0x0000, KEY_0 }, -+ { 0x0001, KEY_1 }, -+ { 0x0002, KEY_2 }, -+ { 0x0003, KEY_3 }, -+ { 0x0004, KEY_4 }, -+ { 0x0005, KEY_5 }, -+ { 0x0006, KEY_6 }, -+ { 0x0007, KEY_7 }, -+ { 0x0008, KEY_8 }, -+ { 0x0009, KEY_9 }, -+ { 0x000a, KEY_MUTE }, -+ { 0x000b, KEY_STOP }, /* Stop */ -+ { 0x000c, KEY_POWER2 }, /* Turn on/off application */ -+ { 0x000d, KEY_OK }, /* OK */ -+ { 0x000e, KEY_CAMERA }, /* Snapshot */ -+ { 0x000f, KEY_ZOOM }, /* Full Screen/Restore */ -+ { 0x0010, KEY_RIGHT }, /* Right arrow */ -+ { 0x0011, KEY_LEFT }, /* Left arrow */ -+ { 0x0012, KEY_CHANNELUP }, -+ { 0x0013, KEY_CHANNELDOWN }, -+ { 0x0014, KEY_SHUFFLE }, -+ { 0x0016, KEY_PAUSE }, -+ { 0x0017, KEY_PLAY }, /* Play */ -+ { 0x001e, KEY_TIME }, /* Time Shift */ -+ { 0x001f, KEY_RECORD }, -+ { 0x0020, KEY_UP }, -+ { 0x0021, KEY_DOWN }, -+ { 0x0025, KEY_POWER }, /* Turn off computer */ -+ { 0x0026, KEY_REWIND }, /* FR << */ -+ { 0x0027, KEY_FASTFORWARD }, /* FF >> */ -+ { 0x0029, KEY_ESC }, -+ { 0x002b, KEY_VOLUMEUP }, -+ { 0x002c, KEY_VOLUMEDOWN }, -+ { 0x002d, KEY_CHANNEL }, /* CH Surfing */ -+ { 0x0038, KEY_VIDEO }, /* TV/AV/S-Video/YPbPr */ -+}; -+ - static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) - { - static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; -@@ -1346,6 +1404,8 @@ static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) - return -ENODEV; - } - -+ st->i2c_client_demod = client_demod; -+ - /* attach tuner */ - memset(&si2157_config, 0, sizeof(si2157_config)); - si2157_config.fe = adap->fe_adap[0].fe; -@@ -1368,9 +1428,90 @@ static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) - return -ENODEV; - } - -+ st->i2c_client_tuner = client_tuner; -+ -+ /* hook fe: need to resync the slave fifo when signal locks. */ -+ mutex_init(&st->stream_mutex); -+ st->last_lock = 0; -+ st->fe_read_status = adap->fe_adap[0].fe->ops.read_status; -+ adap->fe_adap[0].fe->ops.read_status = cxusb_read_status; -+ -+ return 0; -+} -+ -+static int cxusb_mygica_t230c_frontend_attach(struct dvb_usb_adapter *adap) -+{ -+ struct dvb_usb_device *d = adap->dev; -+ struct cxusb_state *st = d->priv; -+ struct i2c_adapter *adapter; -+ struct i2c_client *client_demod; -+ struct i2c_client *client_tuner; -+ struct i2c_board_info info; -+ struct si2168_config si2168_config; -+ struct si2157_config si2157_config; -+ -+ /* Select required USB configuration */ -+ if (usb_set_interface(d->udev, 0, 0) < 0) -+ err("set interface failed"); -+ -+ /* Unblock all USB pipes */ -+ usb_clear_halt(d->udev, -+ usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); -+ usb_clear_halt(d->udev, -+ usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); -+ usb_clear_halt(d->udev, -+ usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); -+ -+ /* attach frontend */ -+ memset(&si2168_config, 0, sizeof(si2168_config)); -+ si2168_config.i2c_adapter = &adapter; -+ si2168_config.fe = &adap->fe_adap[0].fe; -+ si2168_config.ts_mode = SI2168_TS_PARALLEL; -+ si2168_config.ts_clock_inv = 1; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2168", I2C_NAME_SIZE); -+ info.addr = 0x64; -+ info.platform_data = &si2168_config; -+ request_module(info.type); -+ client_demod = i2c_new_device(&d->i2c_adap, &info); -+ if (client_demod == NULL || client_demod->dev.driver == NULL) -+ return -ENODEV; -+ -+ if (!try_module_get(client_demod->dev.driver->owner)) { -+ i2c_unregister_device(client_demod); -+ return -ENODEV; -+ } -+ -+ /* attach tuner */ -+ memset(&si2157_config, 0, sizeof(si2157_config)); -+ si2157_config.fe = adap->fe_adap[0].fe; -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "si2141", I2C_NAME_SIZE); -+ info.addr = 0x60; -+ info.platform_data = &si2157_config; -+ request_module("si2157"); -+ client_tuner = i2c_new_device(adapter, &info); -+ if (client_tuner == NULL || client_tuner->dev.driver == NULL) { -+ module_put(client_demod->dev.driver->owner); -+ i2c_unregister_device(client_demod); -+ return -ENODEV; -+ } -+ if (!try_module_get(client_tuner->dev.driver->owner)) { -+ i2c_unregister_device(client_tuner); -+ module_put(client_demod->dev.driver->owner); -+ i2c_unregister_device(client_demod); -+ return -ENODEV; -+ } -+ - st->i2c_client_demod = client_demod; - st->i2c_client_tuner = client_tuner; - -+ /* hook fe: need to resync the slave fifo when signal locks. */ -+ mutex_init(&st->stream_mutex); -+ st->last_lock = 0; -+ st->fe_read_status = adap->fe_adap[0].fe->ops.read_status; -+ adap->fe_adap[0].fe->ops.read_status = cxusb_read_status; -+ - return 0; - } - -@@ -1456,6 +1597,7 @@ static struct dvb_usb_device_properties cxusb_aver_a868r_properties; - static struct dvb_usb_device_properties cxusb_d680_dmb_properties; - static struct dvb_usb_device_properties cxusb_mygica_d689_properties; - static struct dvb_usb_device_properties cxusb_mygica_t230_properties; -+static struct dvb_usb_device_properties cxusb_mygica_t230c_properties; - - static int cxusb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -@@ -1488,6 +1630,8 @@ static int cxusb_probe(struct usb_interface *intf, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, - THIS_MODULE, NULL, adapter_nr) || -+ 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230c_properties, -+ THIS_MODULE, NULL, adapter_nr) || - 0) - return 0; - -@@ -1539,6 +1683,7 @@ enum cxusb_table_index { - CONEXANT_D680_DMB, - MYGICA_D689, - MYGICA_T230, -+ MYGICA_T230C, - NR__cxusb_table_index - }; - -@@ -1606,6 +1751,9 @@ static struct usb_device_id cxusb_table[NR__cxusb_table_index + 1] = { - [MYGICA_T230] = { - USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) - }, -+ [MYGICA_T230C] = { -+ USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230+1) -+ }, - {} /* Terminating entry */ - }; - MODULE_DEVICE_TABLE (usb, cxusb_table); -@@ -2290,8 +2438,8 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { - - .rc.legacy = { - .rc_interval = 100, -- .rc_map_table = rc_map_d680_dmb_table, -- .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table), -+ .rc_map_table = rc_map_t230_table, -+ .rc_map_size = ARRAY_SIZE(rc_map_t230_table), - .rc_query = cxusb_d680_dmb_rc_query, - }, - -@@ -2305,6 +2453,59 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { - } - }; - -+static struct dvb_usb_device_properties cxusb_mygica_t230c_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ -+ .usb_ctrl = CYPRESS_FX2, -+ -+ .size_of_priv = sizeof(struct cxusb_state), -+ -+ .num_adapters = 1, -+ .adapter = { -+ { -+ .num_frontends = 1, -+ .fe = {{ -+ .streaming_ctrl = cxusb_streaming_ctrl, -+ .frontend_attach = cxusb_mygica_t230c_frontend_attach, -+ -+ /* parameter for the MPEG2-data transfer */ -+ .stream = { -+ .type = USB_BULK, -+ .count = 5, -+ .endpoint = 0x02, -+ .u = { -+ .bulk = { -+ .buffersize = 8192, -+ } -+ } -+ }, -+ } }, -+ }, -+ }, -+ -+ .power_ctrl = cxusb_d680_dmb_power_ctrl, -+ -+ .i2c_algo = &cxusb_i2c_algo, -+ -+ .generic_bulk_ctrl_endpoint = 0x01, -+ -+ .rc.legacy = { -+ .rc_interval = 100, -+ .rc_map_table = rc_map_t230_table, -+ .rc_map_size = ARRAY_SIZE(rc_map_t230_table), -+ .rc_query = cxusb_d680_dmb_rc_query, -+ }, -+ -+ .num_device_descs = 1, -+ .devices = { -+ { -+ "Mygica T230C DVB-T/T2/C", -+ { NULL }, -+ { &cxusb_table[MYGICA_T230C], NULL }, -+ }, -+ } -+}; -+ - static struct usb_driver cxusb_driver = { - .name = "dvb_usb_cxusb", - .probe = cxusb_probe, -diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h -index 18acda1..66429d7 100644 ---- a/drivers/media/usb/dvb-usb/cxusb.h -+++ b/drivers/media/usb/dvb-usb/cxusb.h -@@ -37,6 +37,11 @@ struct cxusb_state { - struct i2c_client *i2c_client_tuner; - - unsigned char data[MAX_XFER_SIZE]; -+ -+ struct mutex stream_mutex; -+ u8 last_lock; -+ int (*fe_read_status)(struct dvb_frontend *fe, -+ enum fe_status *status); - }; - - #endif