From c7bdcd0f541efcb92c407c601ff7819a4a551f6f Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sat, 17 Jan 2009 10:16:36 -0300 Subject: V4L/DVB (10268): Proper implement set_voltage in cx24116. Now there is a card, which uses cx24116 to control LNB DC voltage. It is DVBWorld DVBS2 PCI-e 2005. The patch is nedded to add support for that card. 1. Rename CMD_SET_TONEPRE to CMD_LNBDCLEVEL. 2. Fill set_voltage with actually control voltage code. 3. Correct set_tone to not affect voltage. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/cx24116.c | 51 ++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 19 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c index 28ad609e73f4..a146c352df59 100644 --- a/drivers/media/dvb/frontends/cx24116.c +++ b/drivers/media/dvb/frontends/cx24116.c @@ -15,6 +15,9 @@ September, 9th 2008 Fixed locking on high symbol rates (>30000). Implement MPEG initialization parameter. + January, 17th 2009 + Fill set_voltage with actually control voltage code. + Correct set tone to not affect voltage. 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 @@ -146,7 +149,7 @@ enum cmds { CMD_GETAGC = 0x19, CMD_LNBCONFIG = 0x20, CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */ - CMD_SET_TONEPRE = 0x22, + CMD_LNBDCLEVEL = 0x22, CMD_SET_TONE = 0x23, CMD_UPDFWVERS = 0x35, CMD_TUNERSLEEP = 0x36, @@ -667,16 +670,6 @@ static int cx24116_load_firmware(struct dvb_frontend *fe, return 0; } -static int cx24116_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) -{ - /* The isl6421 module will override this function in the fops. */ - dprintk("%s() This should never appear if the isl6421 module " - "is loaded correctly\n", __func__); - - return -EOPNOTSUPP; -} - static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct cx24116_state *state = fe->demodulator_priv; @@ -837,6 +830,34 @@ static int cx24116_wait_for_lnb(struct dvb_frontend *fe) return -ETIMEDOUT; /* -EBUSY ? */ } +static int cx24116_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) +{ + struct cx24116_cmd cmd; + int ret; + + dprintk("%s: %s\n", __func__, + voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : + voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); + + /* Wait for LNB ready */ + ret = cx24116_wait_for_lnb(fe); + if (ret != 0) + return ret; + + /* Wait for voltage/min repeat delay */ + msleep(100); + + cmd.args[0x00] = CMD_LNBDCLEVEL; + cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00); + cmd.len = 0x02; + + /* Min delay time before DiSEqC send */ + msleep(15); + + return cx24116_cmd_execute(fe, &cmd); +} + static int cx24116_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) { @@ -857,14 +878,6 @@ static int cx24116_set_tone(struct dvb_frontend *fe, /* Min delay time after DiSEqC send */ msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ - /* This is always done before the tone is set */ - cmd.args[0x00] = CMD_SET_TONEPRE; - cmd.args[0x01] = 0x00; - cmd.len = 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - /* Now we set the tone */ cmd.args[0x00] = CMD_SET_TONE; cmd.args[0x01] = 0x00; -- cgit v1.2.1 From 9a909447d3af6917bf2f7eaae08af0c9e1c3593e Mon Sep 17 00:00:00 2001 From: Hans Werner Date: Wed, 14 Jan 2009 13:17:59 -0300 Subject: V4L/DVB (10392): lnbp21: documentation about the system register Here is a patch which adds some documentation about meanings of the the lnbp21 system register bits. Signed-off-by: Hans Werner Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/lnbp21.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h index 8fe094bd9689..b8745887492c 100644 --- a/drivers/media/dvb/frontends/lnbp21.h +++ b/drivers/media/dvb/frontends/lnbp21.h @@ -28,14 +28,14 @@ #define _LNBP21_H /* system register bits */ -#define LNBP21_OLF 0x01 -#define LNBP21_OTF 0x02 -#define LNBP21_EN 0x04 -#define LNBP21_VSEL 0x08 -#define LNBP21_LLC 0x10 -#define LNBP21_TEN 0x20 -#define LNBP21_ISEL 0x40 -#define LNBP21_PCL 0x80 +#define LNBP21_OLF 0x01 /* [R-only] 0=OK; 1=over current limit flag*/ +#define LNBP21_OTF 0x02 /* [R-only] 0=OK; 1=over temperature flag (150degC typ) */ +#define LNBP21_EN 0x04 /* [RW] 0=disable LNB power, enable loopthrough; 1=enable LNB power, disable loopthrough*/ +#define LNBP21_VSEL 0x08 /* [RW] 0=low voltage (13/14V, vert pol); 1=high voltage (18/19V,horiz pol) */ +#define LNBP21_LLC 0x10 /* [RW] increase LNB voltage by 1V: 0=13/18V; 1=14/19V */ +#define LNBP21_TEN 0x20 /* [RW] 0=tone controlled by DSQIN pin; 1=tone enable, disable DSQIN */ +#define LNBP21_ISEL 0x40 /* [RW] current limit select 0:Iout=500-650mA,Isc=300mA ; 1:Iout=400-550mA,Isc=200mA*/ +#define LNBP21_PCL 0x80 /* [RW] short-circuit prot: 0=pulsed (dynamic) curr limiting; 1=static curr limiting*/ #include -- cgit v1.2.1 From 8afe6ad6176205b9612110b8f64dbf3325a1c236 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Thu, 29 Jan 2009 21:57:07 -0300 Subject: V4L/DVB (10413): Bug fix: Restore HVR-4000 tuning. Some cards uses cx24116 LNB_DC pin for LNB power control, some not uses, some uses it different way, like HVR-4000. Tested-by : Edgar Hucek Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/cx24116.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c index a146c352df59..ba1e24c82272 100644 --- a/drivers/media/dvb/frontends/cx24116.c +++ b/drivers/media/dvb/frontends/cx24116.c @@ -1167,7 +1167,12 @@ static int cx24116_initfe(struct dvb_frontend *fe) if (ret != 0) return ret; - return cx24116_diseqc_init(fe); + ret = cx24116_diseqc_init(fe); + if (ret != 0) + return ret; + + /* HVR-4000 needs this */ + return cx24116_set_voltage(fe, SEC_VOLTAGE_13); } /* -- cgit v1.2.1 From 517efa89acef3ac440e6e1ca10252d407ba51abf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 9 Feb 2009 13:12:41 -0300 Subject: V4L/DVB (10512): tda1004x: Fix eeprom firmware load on boards with 16MHz Xtal For i2c normal work, we need to slow down the bus speed. However, the slow down breaks the eeprom firmware load. So, use normal speed for eeprom booting and then restore the i2c speed after that. It should also be noticed that no other I2C transfer should be in course while booting from eeprom, otherwise, tda10046 goes into an instable state. So, proper locking are needed at the i2c bus master. Tested with saa7134 MSI TV @nyware A/D board, that comes with an eeprom with firmware version 29. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda1004x.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index 1465ff77b0cb..4981cef8b444 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c @@ -162,7 +162,7 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg) if (ret != 2) { dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret); - return -1; + return -EINVAL; } dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__, @@ -481,16 +481,18 @@ static void tda10046_init_plls(struct dvb_frontend* fe) static int tda10046_fwupload(struct dvb_frontend* fe) { struct tda1004x_state* state = fe->demodulator_priv; - int ret; + int ret, confc4; const struct firmware *fw; /* reset + wake up chip */ if (state->config->xtal_freq == TDA10046_XTAL_4M) { - tda1004x_write_byteI(state, TDA1004X_CONFC4, 0); + confc4 = 0; } else { dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__); - tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); + confc4 = 0x80; } + tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4); + tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); /* set GPIO 1 and 3 */ if (state->config->gpio_config != TDA10046_GPTRI) { @@ -508,13 +510,29 @@ static int tda10046_fwupload(struct dvb_frontend* fe) if (tda1004x_check_upload_ok(state) == 0) return 0; + /* + For i2c normal work, we need to slow down the bus speed. + However, the slow down breaks the eeprom firmware load. + So, use normal speed for eeprom booting and then restore the + i2c speed after that. Tested with MSI TV @nyware A/D board, + that comes with firmware version 29 inside their eeprom. + + It should also be noticed that no other I2C transfer should + be in course while booting from eeprom, otherwise, tda10046 + goes into an instable state. So, proper locking are needed + at the i2c bus master. + */ printk(KERN_INFO "tda1004x: trying to boot from eeprom\n"); - tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); + tda1004x_write_byteI(state, TDA1004X_CONFC4, 4); msleep(300); - /* don't re-upload unless necessary */ + tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4); + + /* Checks if eeprom firmware went without troubles */ if (tda1004x_check_upload_ok(state) == 0) return 0; + /* eeprom firmware didn't work. Load one manually. */ + if (state->config->request_firmware != NULL) { /* request the firmware, this will block until someone uploads it */ printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); -- cgit v1.2.1 From 8420fa7ee22c1d681549ff7ab0466ceda5a911c2 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Mon, 23 Feb 2009 12:26:38 -0300 Subject: V4L/DVB (10662): remove redundant memset after kzalloc Hi there! While having a look at the allocation of struct dvb_frontend in *_attach functions, I found some cases calling memset after kzalloc. This is redundant, and the attached patch removes these calls. I also changed one case calling kmalloc and memset to kzalloc. Regards Matthias Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/cx24113.c | 2 +- drivers/media/dvb/frontends/cx24116.c | 5 +---- drivers/media/dvb/frontends/cx24123.c | 4 ++-- drivers/media/dvb/frontends/lgdt3304.c | 1 - drivers/media/dvb/frontends/s921_module.c | 1 - 5 files changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c index f6e7b0380a5a..e4fd533a427c 100644 --- a/drivers/media/dvb/frontends/cx24113.c +++ b/drivers/media/dvb/frontends/cx24113.c @@ -559,7 +559,7 @@ struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, kzalloc(sizeof(struct cx24113_state), GFP_KERNEL); int rc; if (state == NULL) { - err("Unable to kmalloc\n"); + err("Unable to kzalloc\n"); goto error; } diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c index ba1e24c82272..9b9f57264cef 100644 --- a/drivers/media/dvb/frontends/cx24116.c +++ b/drivers/media/dvb/frontends/cx24116.c @@ -1112,13 +1112,10 @@ struct dvb_frontend *cx24116_attach(const struct cx24116_config *config, dprintk("%s\n", __func__); /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL); + state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL); if (state == NULL) goto error1; - /* setup the state */ - memset(state, 0, sizeof(struct cx24116_state)); - state->config = config; state->i2c = i2c; diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c index 1a8c36f76061..0592f043ea64 100644 --- a/drivers/media/dvb/frontends/cx24123.c +++ b/drivers/media/dvb/frontends/cx24123.c @@ -1069,13 +1069,13 @@ static struct dvb_frontend_ops cx24123_ops; struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, struct i2c_adapter *i2c) { + /* allocate memory for the internal state */ struct cx24123_state *state = kzalloc(sizeof(struct cx24123_state), GFP_KERNEL); dprintk("\n"); - /* allocate memory for the internal state */ if (state == NULL) { - err("Unable to kmalloc\n"); + err("Unable to kzalloc\n"); goto error; } diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c index 3bb0c4394f8a..eb72a9866c93 100644 --- a/drivers/media/dvb/frontends/lgdt3304.c +++ b/drivers/media/dvb/frontends/lgdt3304.c @@ -363,7 +363,6 @@ struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, struct lgdt3304_state *state; state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL); - memset(state, 0x0, sizeof(struct lgdt3304_state)); state->addr = config->i2c_address; state->i2c = i2c; diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c index 892af8c9ed57..3f5a0e1dfdf5 100644 --- a/drivers/media/dvb/frontends/s921_module.c +++ b/drivers/media/dvb/frontends/s921_module.c @@ -169,7 +169,6 @@ struct dvb_frontend* s921_attach(const struct s921_config *config, struct s921_state *state; state = kzalloc(sizeof(struct s921_state), GFP_KERNEL); - memset(state, 0x0, sizeof(struct s921_state)); state->addr = config->i2c_address; state->i2c = i2c; -- cgit v1.2.1 From 47220bc11f5bb4bc21ae7227278452ae82fefe18 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Tue, 3 Mar 2009 11:16:40 -0300 Subject: V4L/DVB (10799): Add support for ST STV6110 silicon tuner. The tuner is used in NetUP Dual DVB-S2 CI card. http://linuxtv.org/wiki/index.php/NetUP_Dual_DVB_S2_CI Signed-off-by: Igor M. Liplianin [mchehab@redhat.com: removed a wrong header: "cx23885.h"] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 7 + drivers/media/dvb/frontends/Makefile | 1 + drivers/media/dvb/frontends/stv6110.c | 456 ++++++++++++++++++++++++++++++++++ drivers/media/dvb/frontends/stv6110.h | 62 +++++ 4 files changed, 526 insertions(+) create mode 100644 drivers/media/dvb/frontends/stv6110.c create mode 100644 drivers/media/dvb/frontends/stv6110.h (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 00269560793a..649ac75aaefa 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -83,6 +83,13 @@ config DVB_STV0299 help A DVB-S tuner module. Say Y when you want to support this frontend. +config DVB_STV6110 + tristate "ST STV6110 silicon tuner" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A DVB-S silicon tuner module. Say Y when you want to support this tuner. + config DVB_TDA8083 tristate "Philips TDA8083 based" depends on DVB_CORE && I2C diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index af7bdf0ad4c7..1d180fc71023 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -64,4 +64,5 @@ obj-$(CONFIG_DVB_SI21XX) += si21xx.o obj-$(CONFIG_DVB_STV0288) += stv0288.o obj-$(CONFIG_DVB_STB6000) += stb6000.o obj-$(CONFIG_DVB_S921) += s921.o +obj-$(CONFIG_DVB_STV6110) += stv6110.o diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c new file mode 100644 index 000000000000..70efac869d28 --- /dev/null +++ b/drivers/media/dvb/frontends/stv6110.c @@ -0,0 +1,456 @@ +/* + * stv6110.c + * + * Driver for ST STV6110 satellite tuner IC. + * + * Copyright (C) 2009 NetUP Inc. + * Copyright (C) 2009 Igor M. Liplianin + * + * 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 "stv6110.h" + +static int debug; + +struct stv6110_priv { + int i2c_address; + struct i2c_adapter *i2c; + + u32 mclk; + u8 regs[8]; +}; + +#define dprintk(args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG args); \ + } while (0) + +static s32 abssub(s32 a, s32 b) +{ + if (a > b) + return a - b; + else + return b - a; +}; + +static int stv6110_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; + return 0; +} + +static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[], + int start, int len) +{ + struct stv6110_priv *priv = fe->tuner_priv; + int rc; + u8 cmdbuf[len + 1]; + struct i2c_msg msg = { + .addr = priv->i2c_address, + .flags = 0, + .buf = cmdbuf, + .len = len + 1 + }; + + dprintk("%s\n", __func__); + + if (start + len > 8) + return -EINVAL; + + memcpy(&cmdbuf[1], buf, len); + cmdbuf[0] = start; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + rc = i2c_transfer(priv->i2c, &msg, 1); + if (rc != 1) + dprintk("%s: i2c error\n", __func__); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + return 0; +} + +static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[], + int start, int len) +{ + struct stv6110_priv *priv = fe->tuner_priv; + int rc; + u8 reg[] = { start }; + struct i2c_msg msg_wr = { + .addr = priv->i2c_address, + .flags = 0, + .buf = reg, + .len = 1, + }; + + struct i2c_msg msg_rd = { + .addr = priv->i2c_address, + .flags = I2C_M_RD, + .buf = regs, + .len = len, + }; + /* write subaddr */ + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + rc = i2c_transfer(priv->i2c, &msg_wr, 1); + if (rc != 1) + dprintk("%s: i2c error\n", __func__); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + /* read registers */ + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + rc = i2c_transfer(priv->i2c, &msg_rd, 1); + if (rc != 1) + dprintk("%s: i2c error\n", __func__); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + memcpy(&priv->regs[start], regs, len); + + return 0; +} + +static int stv6110_read_reg(struct dvb_frontend *fe, int start) +{ + u8 buf[] = { 0 }; + stv6110_read_regs(fe, buf, start, 1); + + return buf[0]; +} + +static int stv6110_sleep(struct dvb_frontend *fe) +{ + u8 reg[] = { 0 }; + stv6110_write_regs(fe, reg, 0, 1); + + return 0; +} + +static u32 carrier_width(u32 symbol_rate, fe_rolloff_t rolloff) +{ + u32 rlf; + + switch (rolloff) { + case ROLLOFF_20: + rlf = 20; + break; + case ROLLOFF_25: + rlf = 25; + break; + default: + rlf = 35; + break; + } + + return symbol_rate + ((symbol_rate * rlf) / 100); +} + +static int stv6110_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) +{ + struct stv6110_priv *priv = fe->tuner_priv; + u8 r8, ret = 0x04; + int i; + + if ((bandwidth / 2) > 36000000) /*BW/2 max=31+5=36 mhz for r8=31*/ + r8 = 31; + else if ((bandwidth / 2) < 5000000) /* BW/2 min=5Mhz for F=0 */ + r8 = 0; + else /*if 5 < BW/2 < 36*/ + r8 = (bandwidth / 2) / 1000000 - 5; + + /* ctrl3, RCCLKOFF = 0 Activate the calibration Clock */ + /* ctrl3, CF = r8 Set the LPF value */ + priv->regs[RSTV6110_CTRL3] &= ~((1 << 6) | 0x1f); + priv->regs[RSTV6110_CTRL3] |= (r8 & 0x1f); + stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1); + /* stat1, CALRCSTRT = 1 Start LPF auto calibration*/ + priv->regs[RSTV6110_STAT1] |= 0x02; + stv6110_write_regs(fe, &priv->regs[RSTV6110_STAT1], RSTV6110_STAT1, 1); + + i = 0; + /* Wait for CALRCSTRT == 0 */ + while ((i < 10) && (ret != 0)) { + ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x02); + mdelay(1); /* wait for LPF auto calibration */ + i++; + } + + /* RCCLKOFF = 1 calibration done, desactivate the calibration Clock */ + priv->regs[RSTV6110_CTRL3] |= (1 << 6); + stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1); + return 0; +} + +static int stv6110_init(struct dvb_frontend *fe) +{ + struct stv6110_priv *priv = fe->tuner_priv; + u8 buf0[] = { 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e }; + + memcpy(priv->regs, buf0, 8); + /* K = (Reference / 1000000) - 16 */ + priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3); + priv->regs[RSTV6110_CTRL1] |= + ((((priv->mclk / 1000000) - 16) & 0x1f) << 3); + + stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8); + msleep(1); + stv6110_set_bandwidth(fe, 72000000); + + return 0; +} + +static int stv6110_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct stv6110_priv *priv = fe->tuner_priv; + u32 nbsteps, divider, psd2, freq; + u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + stv6110_read_regs(fe, regs, 0, 8); + /*N*/ + divider = (priv->regs[RSTV6110_TUNING2] & 0x0f) << 8; + divider += priv->regs[RSTV6110_TUNING1]; + + /*R*/ + nbsteps = (priv->regs[RSTV6110_TUNING2] >> 6) & 3; + /*p*/ + psd2 = (priv->regs[RSTV6110_TUNING2] >> 4) & 1; + + freq = divider * (priv->mclk / 1000); + freq /= (1 << (nbsteps + psd2)); + freq /= 4; + + *frequency = freq; + + return 0; +} + +static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency) +{ + struct stv6110_priv *priv = fe->tuner_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u8 ret = 0x04; + u32 divider, ref, p, presc, i, result_freq, vco_freq; + s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val; + s32 srate; u8 gain; + + dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__, + frequency, priv->mclk); + + /* K = (Reference / 1000000) - 16 */ + priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3); + priv->regs[RSTV6110_CTRL1] |= + ((((priv->mclk / 1000000) - 16) & 0x1f) << 3); + + /* BB_GAIN = db/2 */ + if (fe->ops.set_property && fe->ops.get_property) { + srate = c->symbol_rate; + dprintk("%s: Get Frontend parameters: srate=%d\n", + __func__, srate); + } else + srate = 15000000; + + if (srate >= 15000000) + gain = 3; /* +6 dB */ + else if (srate >= 5000000) + gain = 3; /* +6 dB */ + else + gain = 3; /* +6 dB */ + + priv->regs[RSTV6110_CTRL2] &= ~0x0f; + priv->regs[RSTV6110_CTRL2] |= (gain & 0x0f); + + if (frequency <= 1023000) { + p = 1; + presc = 0; + } else if (frequency <= 1300000) { + p = 1; + presc = 1; + } else if (frequency <= 2046000) { + p = 0; + presc = 0; + } else { + p = 0; + presc = 1; + } + /* DIV4SEL = p*/ + priv->regs[RSTV6110_TUNING2] &= ~(1 << 4); + priv->regs[RSTV6110_TUNING2] |= (p << 4); + + /* PRESC32ON = presc */ + priv->regs[RSTV6110_TUNING2] &= ~(1 << 5); + priv->regs[RSTV6110_TUNING2] |= (presc << 5); + + p_val = (int)(1 << (p + 1)) * 10;/* P = 2 or P = 4 */ + for (r_div = 0; r_div <= 3; r_div++) { + p_calc = (priv->mclk / 100000); + p_calc /= (1 << (r_div + 1)); + if ((abssub(p_calc, p_val)) < (abssub(p_calc_opt, p_val))) + r_div_opt = r_div; + + p_calc_opt = (priv->mclk / 100000); + p_calc_opt /= (1 << (r_div_opt + 1)); + } + + ref = priv->mclk / ((1 << (r_div_opt + 1)) * (1 << (p + 1))); + divider = (((frequency * 1000) + (ref >> 1)) / ref); + + /* RDIV = r_div_opt */ + priv->regs[RSTV6110_TUNING2] &= ~(3 << 6); + priv->regs[RSTV6110_TUNING2] |= (((r_div_opt) & 3) << 6); + + /* NDIV_MSB = MSB(divider) */ + priv->regs[RSTV6110_TUNING2] &= ~0x0f; + priv->regs[RSTV6110_TUNING2] |= (((divider) >> 8) & 0x0f); + + /* NDIV_LSB, LSB(divider) */ + priv->regs[RSTV6110_TUNING1] = (divider & 0xff); + + /* CALVCOSTRT = 1 VCO Auto Calibration */ + priv->regs[RSTV6110_STAT1] |= 0x04; + stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], + RSTV6110_CTRL1, 8); + + i = 0; + /* Wait for CALVCOSTRT == 0 */ + while ((i < 10) && (ret != 0)) { + ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x04); + msleep(1); /* wait for VCO auto calibration */ + i++; + } + + ret = stv6110_read_reg(fe, RSTV6110_STAT1); + stv6110_get_frequency(fe, &result_freq); + + vco_freq = divider * ((priv->mclk / 1000) / ((1 << (r_div_opt + 1)))); + dprintk("%s, stat1=%x, lo_freq=%d kHz, vco_frec=%d kHz\n", __func__, + ret, result_freq, vco_freq); + + return 0; +} + +static int stv6110_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u32 bandwidth = carrier_width(c->symbol_rate, c->rolloff); + + stv6110_set_frequency(fe, c->frequency); + stv6110_set_bandwidth(fe, bandwidth); + + return 0; +} + +static int stv6110_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) +{ + struct stv6110_priv *priv = fe->tuner_priv; + u8 r8 = 0; + u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + stv6110_read_regs(fe, regs, 0, 8); + + /* CF */ + r8 = priv->regs[RSTV6110_CTRL3] & 0x1f; + *bandwidth = (r8 + 5) * 2000000;/* x2 for ZIF tuner BW/2 = F+5 Mhz */ + + return 0; +} + +static struct dvb_tuner_ops stv6110_tuner_ops = { + .info = { + .name = "ST STV6110", + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_step = 1000, + }, + .init = stv6110_init, + .release = stv6110_release, + .sleep = stv6110_sleep, + .set_params = stv6110_set_params, + .get_frequency = stv6110_get_frequency, + .set_frequency = stv6110_set_frequency, + .get_bandwidth = stv6110_get_bandwidth, + .set_bandwidth = stv6110_set_bandwidth, + +}; + +struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe, + const struct stv6110_config *config, + struct i2c_adapter *i2c) +{ + struct stv6110_priv *priv = NULL; + u8 reg0[] = { 0x00, 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e }; + + struct i2c_msg msg[] = { + { + .addr = config->i2c_address, + .flags = 0, + .buf = reg0, + .len = 9 + } + }; + int ret; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = i2c_transfer(i2c, msg, 1); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + if (ret != 1) + return NULL; + + priv = kzalloc(sizeof(struct stv6110_priv), GFP_KERNEL); + if (priv == NULL) + return NULL; + + priv->i2c_address = config->i2c_address; + priv->i2c = i2c; + priv->mclk = config->mclk; + + memcpy(&priv->regs, ®0[1], 8); + + memcpy(&fe->ops.tuner_ops, &stv6110_tuner_ops, + sizeof(struct dvb_tuner_ops)); + fe->tuner_priv = priv; + printk(KERN_INFO "STV6110 attached on addr=%x!\n", priv->i2c_address); + + return fe; +} +EXPORT_SYMBOL(stv6110_attach); + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); + +MODULE_DESCRIPTION("ST STV6110 driver"); +MODULE_AUTHOR("Igor M. Liplianin"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/stv6110.h b/drivers/media/dvb/frontends/stv6110.h new file mode 100644 index 000000000000..1c0314d6aa55 --- /dev/null +++ b/drivers/media/dvb/frontends/stv6110.h @@ -0,0 +1,62 @@ +/* + * stv6110.h + * + * Driver for ST STV6110 satellite tuner IC. + * + * Copyright (C) 2009 NetUP Inc. + * Copyright (C) 2009 Igor M. Liplianin + * + * 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 __DVB_STV6110_H__ +#define __DVB_STV6110_H__ + +#include +#include "dvb_frontend.h" + +/* registers */ +#define RSTV6110_CTRL1 0 +#define RSTV6110_CTRL2 1 +#define RSTV6110_TUNING1 2 +#define RSTV6110_TUNING2 3 +#define RSTV6110_CTRL3 4 +#define RSTV6110_STAT1 5 +#define RSTV6110_STAT2 6 +#define RSTV6110_STAT3 7 + +struct stv6110_config { + u8 i2c_address; + u32 mclk; + int iq_wiring; +}; + +#if defined(CONFIG_DVB_STV6110) || (defined(CONFIG_DVB_STV6110_MODULE) \ + && defined(MODULE)) +extern struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe, + const struct stv6110_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe, + const struct stv6110_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif -- cgit v1.2.1 From 8c1a23312b120194a415be354808f58ace582d10 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Tue, 3 Mar 2009 11:24:18 -0300 Subject: V4L/DVB (10800): Add support for ST LNBH24 LNB power controller. The controller consist of two independent parts. Every part is similar to LNBP21, but has configurable i2c address. It is used in NetUP Dual DVB-S2 CI card. http://linuxtv.org/wiki/index.php/NetUP_Dual_DVB_S2_CI Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 4 +-- drivers/media/dvb/frontends/lnbh24.h | 55 ++++++++++++++++++++++++++++++++++++ drivers/media/dvb/frontends/lnbp21.c | 41 +++++++++++++++++++++------ drivers/media/dvb/frontends/lnbp21.h | 50 +++++++++++++++++++++++--------- 4 files changed, 126 insertions(+), 24 deletions(-) create mode 100644 drivers/media/dvb/frontends/lnbh24.h (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 649ac75aaefa..d3cfced2ce23 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -453,11 +453,11 @@ comment "SEC control devices for DVB-S" depends on DVB_CORE config DVB_LNBP21 - tristate "LNBP21 SEC controller" + tristate "LNBP21/LNBH24 SEC controllers" depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help - An SEC control chip. + An SEC control chips. config DVB_ISL6405 tristate "ISL6405 SEC controller" diff --git a/drivers/media/dvb/frontends/lnbh24.h b/drivers/media/dvb/frontends/lnbh24.h new file mode 100644 index 000000000000..c059b165318f --- /dev/null +++ b/drivers/media/dvb/frontends/lnbh24.h @@ -0,0 +1,55 @@ +/* + * lnbh24.h - driver for lnb supply and control ic lnbh24 + * + * Copyright (C) 2009 NetUP Inc. + * Copyright (C) 2009 Igor M. Liplianin + * + * 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 _LNBH24_H +#define _LNBH24_H + +/* system register bits */ +#define LNBH24_OLF 0x01 +#define LNBH24_OTF 0x02 +#define LNBH24_EN 0x04 +#define LNBH24_VSEL 0x08 +#define LNBH24_LLC 0x10 +#define LNBH24_TEN 0x20 +#define LNBH24_TTX 0x40 +#define LNBH24_PCL 0x80 + +#include + +#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \ + && defined(MODULE)) +/* override_set and override_clear control which + system register bits (above) to always set & clear */ +extern struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 override_set, + u8 override_clear, u8 i2c_addr); +#else +static inline struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 override_set, + u8 override_clear, u8 i2c_addr) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c index 76f935d9755a..772a0bbb0dd8 100644 --- a/drivers/media/dvb/frontends/lnbp21.c +++ b/drivers/media/dvb/frontends/lnbp21.c @@ -1,7 +1,8 @@ /* - * lnbp21.h - driver for lnb supply and control ic lnbp21 + * lnbp21.c - driver for lnb supply and control ic lnbp21 * * Copyright (C) 2006 Oliver Endriss + * Copyright (C) 2009 Igor M. Liplianin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -33,18 +34,21 @@ #include "dvb_frontend.h" #include "lnbp21.h" +#include "lnbh24.h" struct lnbp21 { u8 config; u8 override_or; u8 override_and; struct i2c_adapter *i2c; + u8 i2c_addr; }; -static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +static int lnbp21_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) { struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv; - struct i2c_msg msg = { .addr = 0x08, .flags = 0, + struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0, .buf = &lnbp21->config, .len = sizeof(lnbp21->config) }; @@ -72,7 +76,7 @@ static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) { struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv; - struct i2c_msg msg = { .addr = 0x08, .flags = 0, + struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0, .buf = &lnbp21->config, .len = sizeof(lnbp21->config) }; @@ -97,15 +101,18 @@ static void lnbp21_release(struct dvb_frontend *fe) fe->sec_priv = NULL; } -struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) +static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 override_set, + u8 override_clear, u8 i2c_addr, u8 config) { struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); if (!lnbp21) return NULL; /* default configuration */ - lnbp21->config = LNBP21_ISEL; + lnbp21->config = config; lnbp21->i2c = i2c; + lnbp21->i2c_addr = i2c_addr; fe->sec_priv = lnbp21; /* bits which should be forced to '1' */ @@ -126,11 +133,29 @@ struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter * /* override frontend ops */ fe->ops.set_voltage = lnbp21_set_voltage; fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; + printk(KERN_INFO "LNBx2x attached on addr=%x", lnbp21->i2c_addr); return fe; } + +struct dvb_frontend *lnbp24_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 override_set, + u8 override_clear, u8 i2c_addr) +{ + return lnbx2x_attach(fe, i2c, override_set, override_clear, + i2c_addr, LNBH24_TTX); +} +EXPORT_SYMBOL(lnbh24_attach); + +struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 override_set, + u8 override_clear) +{ + return lnbx2x_attach(fe, i2c, override_set, override_clear, + 0x08, LNBP21_ISEL); +} EXPORT_SYMBOL(lnbp21_attach); -MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21"); -MODULE_AUTHOR("Oliver Endriss"); +MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24"); +MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h index b8745887492c..fcdf1c650dde 100644 --- a/drivers/media/dvb/frontends/lnbp21.h +++ b/drivers/media/dvb/frontends/lnbp21.h @@ -28,26 +28,48 @@ #define _LNBP21_H /* system register bits */ -#define LNBP21_OLF 0x01 /* [R-only] 0=OK; 1=over current limit flag*/ -#define LNBP21_OTF 0x02 /* [R-only] 0=OK; 1=over temperature flag (150degC typ) */ -#define LNBP21_EN 0x04 /* [RW] 0=disable LNB power, enable loopthrough; 1=enable LNB power, disable loopthrough*/ -#define LNBP21_VSEL 0x08 /* [RW] 0=low voltage (13/14V, vert pol); 1=high voltage (18/19V,horiz pol) */ -#define LNBP21_LLC 0x10 /* [RW] increase LNB voltage by 1V: 0=13/18V; 1=14/19V */ -#define LNBP21_TEN 0x20 /* [RW] 0=tone controlled by DSQIN pin; 1=tone enable, disable DSQIN */ -#define LNBP21_ISEL 0x40 /* [RW] current limit select 0:Iout=500-650mA,Isc=300mA ; 1:Iout=400-550mA,Isc=200mA*/ -#define LNBP21_PCL 0x80 /* [RW] short-circuit prot: 0=pulsed (dynamic) curr limiting; 1=static curr limiting*/ +/* [RO] 0=OK; 1=over current limit flag */ +#define LNBP21_OLF 0x01 +/* [RO] 0=OK; 1=over temperature flag (150 C) */ +#define LNBP21_OTF 0x02 +/* [RW] 0=disable LNB power, enable loopthrough + 1=enable LNB power, disable loopthrough */ +#define LNBP21_EN 0x04 +/* [RW] 0=low voltage (13/14V, vert pol) + 1=high voltage (18/19V,horiz pol) */ +#define LNBP21_VSEL 0x08 +/* [RW] increase LNB voltage by 1V: + 0=13/18V; 1=14/19V */ +#define LNBP21_LLC 0x10 +/* [RW] 0=tone controlled by DSQIN pin + 1=tone enable, disable DSQIN */ +#define LNBP21_TEN 0x20 +/* [RW] current limit select: + 0:Iout=500-650mA Isc=300mA + 1:Iout=400-550mA Isc=200mA */ +#define LNBP21_ISEL 0x40 +/* [RW] short-circuit protect: + 0=pulsed (dynamic) curr limiting + 1=static curr limiting */ +#define LNBP21_PCL 0x80 #include -#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) && defined(MODULE)) -/* override_set and override_clear control which system register bits (above) to always set & clear */ -extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear); +#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \ + && defined(MODULE)) +/* override_set and override_clear control which + system register bits (above) to always set & clear */ +extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 override_set, + u8 override_clear); #else -static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) +static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 override_set, + u8 override_clear) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -#endif // CONFIG_DVB_LNBP21 +#endif -#endif // _LNBP21_H +#endif -- cgit v1.2.1 From e2bc99bac5415d4e6d252322c408b5008b0f3485 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Tue, 3 Mar 2009 11:35:25 -0300 Subject: V4L/DVB (10801): Add headers for ST STV0900 dual demodulator. The IC consist of two dependent parts. It may use single or dual mode. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900.h | 62 + drivers/media/dvb/frontends/stv0900_reg.h | 3787 +++++++++++++++++++++++++++++ 2 files changed, 3849 insertions(+) create mode 100644 drivers/media/dvb/frontends/stv0900.h create mode 100644 drivers/media/dvb/frontends/stv0900_reg.h (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h new file mode 100644 index 000000000000..8a1332c2031d --- /dev/null +++ b/drivers/media/dvb/frontends/stv0900.h @@ -0,0 +1,62 @@ +/* + * stv0900.h + * + * Driver for ST STV0900 satellite demodulator IC. + * + * Copyright (C) ST Microelectronics. + * Copyright (C) 2009 NetUP Inc. + * Copyright (C) 2009 Igor M. Liplianin + * + * 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 STV0900_H +#define STV0900_H + +#include +#include "dvb_frontend.h" + +struct stv0900_config { + u8 demod_address; + u32 xtal; + u8 clkmode;/* 0 for CLKI, 2 for XTALI */ + + u8 diseqc_mode; + + u8 path1_mode; + u8 path2_mode; + + u8 tun1_maddress;/* 0, 1, 2, 3 for 0xc0, 0xc2, 0xc4, 0xc6 */ + u8 tun2_maddress; + u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */ + u8 tun2_adc; +}; + +#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \ + && defined(MODULE)) +extern struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, + struct i2c_adapter *i2c, int demod); +#else +static inline struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, + struct i2c_adapter *i2c, int demod) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif + diff --git a/drivers/media/dvb/frontends/stv0900_reg.h b/drivers/media/dvb/frontends/stv0900_reg.h new file mode 100644 index 000000000000..264f9cf9a17e --- /dev/null +++ b/drivers/media/dvb/frontends/stv0900_reg.h @@ -0,0 +1,3787 @@ +/* + * stv0900_reg.h + * + * Driver for ST STV0900 satellite demodulator IC. + * + * Copyright (C) ST Microelectronics. + * Copyright (C) 2009 NetUP Inc. + * Copyright (C) 2009 Igor M. Liplianin + * + * 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 STV0900_REG_H +#define STV0900_REG_H + +/*MID*/ +#define R0900_MID 0xf100 +#define F0900_MCHIP_IDENT 0xf10000f0 +#define F0900_MRELEASE 0xf100000f + +/*DACR1*/ +#define R0900_DACR1 0xf113 +#define F0900_DAC_MODE 0xf11300e0 +#define F0900_DAC_VALUE1 0xf113000f + +/*DACR2*/ +#define R0900_DACR2 0xf114 +#define F0900_DAC_VALUE0 0xf11400ff + +/*OUTCFG*/ +#define R0900_OUTCFG 0xf11c +#define F0900_INV_DATA6 0xf11c0080 +#define F0900_OUTSERRS1_HZ 0xf11c0040 +#define F0900_OUTSERRS2_HZ 0xf11c0020 +#define F0900_OUTSERRS3_HZ 0xf11c0010 +#define F0900_OUTPARRS3_HZ 0xf11c0008 +#define F0900_OUTHZ3_CONTROL 0xf11c0007 + +/*MODECFG*/ +#define R0900_MODECFG 0xf11d +#define F0900_FECSPY_SEL_2 0xf11d0020 +#define F0900_HWARE_SEL_2 0xf11d0010 +#define F0900_PKTDEL_SEL_2 0xf11d0008 +#define F0900_DISEQC_SEL_2 0xf11d0004 +#define F0900_VIT_SEL_2 0xf11d0002 +#define F0900_DEMOD_SEL_2 0xf11d0001 + +/*IRQSTATUS3*/ +#define R0900_IRQSTATUS3 0xf120 +#define F0900_SPLL_LOCK 0xf1200020 +#define F0900_SSTREAM_LCK_3 0xf1200010 +#define F0900_SSTREAM_LCK_2 0xf1200008 +#define F0900_SSTREAM_LCK_1 0xf1200004 +#define F0900_SDVBS1_PRF_2 0xf1200002 +#define F0900_SDVBS1_PRF_1 0xf1200001 + +/*IRQSTATUS2*/ +#define R0900_IRQSTATUS2 0xf121 +#define F0900_SSPY_ENDSIM_3 0xf1210080 +#define F0900_SSPY_ENDSIM_2 0xf1210040 +#define F0900_SSPY_ENDSIM_1 0xf1210020 +#define F0900_SPKTDEL_ERROR_2 0xf1210010 +#define F0900_SPKTDEL_LOCKB_2 0xf1210008 +#define F0900_SPKTDEL_LOCK_2 0xf1210004 +#define F0900_SPKTDEL_ERROR_1 0xf1210002 +#define F0900_SPKTDEL_LOCKB_1 0xf1210001 + +/*IRQSTATUS1*/ +#define R0900_IRQSTATUS1 0xf122 +#define F0900_SPKTDEL_LOCK_1 0xf1220080 +#define F0900_SEXTPINB2 0xf1220040 +#define F0900_SEXTPIN2 0xf1220020 +#define F0900_SEXTPINB1 0xf1220010 +#define F0900_SEXTPIN1 0xf1220008 +#define F0900_SDEMOD_LOCKB_2 0xf1220004 +#define F0900_SDEMOD_LOCK_2 0xf1220002 +#define F0900_SDEMOD_IRQ_2 0xf1220001 + +/*IRQSTATUS0*/ +#define R0900_IRQSTATUS0 0xf123 +#define F0900_SDEMOD_LOCKB_1 0xf1230080 +#define F0900_SDEMOD_LOCK_1 0xf1230040 +#define F0900_SDEMOD_IRQ_1 0xf1230020 +#define F0900_SBCH_ERRFLAG 0xf1230010 +#define F0900_SDISEQC2RX_IRQ 0xf1230008 +#define F0900_SDISEQC2TX_IRQ 0xf1230004 +#define F0900_SDISEQC1RX_IRQ 0xf1230002 +#define F0900_SDISEQC1TX_IRQ 0xf1230001 + +/*IRQMASK3*/ +#define R0900_IRQMASK3 0xf124 +#define F0900_MPLL_LOCK 0xf1240020 +#define F0900_MSTREAM_LCK_3 0xf1240010 +#define F0900_MSTREAM_LCK_2 0xf1240008 +#define F0900_MSTREAM_LCK_1 0xf1240004 +#define F0900_MDVBS1_PRF_2 0xf1240002 +#define F0900_MDVBS1_PRF_1 0xf1240001 + +/*IRQMASK2*/ +#define R0900_IRQMASK2 0xf125 +#define F0900_MSPY_ENDSIM_3 0xf1250080 +#define F0900_MSPY_ENDSIM_2 0xf1250040 +#define F0900_MSPY_ENDSIM_1 0xf1250020 +#define F0900_MPKTDEL_ERROR_2 0xf1250010 +#define F0900_MPKTDEL_LOCKB_2 0xf1250008 +#define F0900_MPKTDEL_LOCK_2 0xf1250004 +#define F0900_MPKTDEL_ERROR_1 0xf1250002 +#define F0900_MPKTDEL_LOCKB_1 0xf1250001 + +/*IRQMASK1*/ +#define R0900_IRQMASK1 0xf126 +#define F0900_MPKTDEL_LOCK_1 0xf1260080 +#define F0900_MEXTPINB2 0xf1260040 +#define F0900_MEXTPIN2 0xf1260020 +#define F0900_MEXTPINB1 0xf1260010 +#define F0900_MEXTPIN1 0xf1260008 +#define F0900_MDEMOD_LOCKB_2 0xf1260004 +#define F0900_MDEMOD_LOCK_2 0xf1260002 +#define F0900_MDEMOD_IRQ_2 0xf1260001 + +/*IRQMASK0*/ +#define R0900_IRQMASK0 0xf127 +#define F0900_MDEMOD_LOCKB_1 0xf1270080 +#define F0900_MDEMOD_LOCK_1 0xf1270040 +#define F0900_MDEMOD_IRQ_1 0xf1270020 +#define F0900_MBCH_ERRFLAG 0xf1270010 +#define F0900_MDISEQC2RX_IRQ 0xf1270008 +#define F0900_MDISEQC2TX_IRQ 0xf1270004 +#define F0900_MDISEQC1RX_IRQ 0xf1270002 +#define F0900_MDISEQC1TX_IRQ 0xf1270001 + +/*I2CCFG*/ +#define R0900_I2CCFG 0xf129 +#define F0900_I2C2_FASTMODE 0xf1290080 +#define F0900_STATUS_WR2 0xf1290040 +#define F0900_I2C2ADDR_INC 0xf1290030 +#define F0900_I2C_FASTMODE 0xf1290008 +#define F0900_STATUS_WR 0xf1290004 +#define F0900_I2CADDR_INC 0xf1290003 + +/*P1_I2CRPT*/ +#define R0900_P1_I2CRPT 0xf12a +#define F0900_P1_I2CT_ON 0xf12a0080 +#define F0900_P1_ENARPT_LEVEL 0xf12a0070 +#define F0900_P1_SCLT_DELAY 0xf12a0008 +#define F0900_P1_STOP_ENABLE 0xf12a0004 +#define F0900_P1_STOP_SDAT2SDA 0xf12a0002 + +/*P2_I2CRPT*/ +#define R0900_P2_I2CRPT 0xf12b +#define F0900_P2_I2CT_ON 0xf12b0080 +#define F0900_P2_ENARPT_LEVEL 0xf12b0070 +#define F0900_P2_SCLT_DELAY 0xf12b0008 +#define F0900_P2_STOP_ENABLE 0xf12b0004 +#define F0900_P2_STOP_SDAT2SDA 0xf12b0002 + +/*CLKI2CFG*/ +#define R0900_CLKI2CFG 0xf140 +#define F0900_CLKI2_OPD 0xf1400080 +#define F0900_CLKI2_CONFIG 0xf140007e +#define F0900_CLKI2_XOR 0xf1400001 + +/*GPIO1CFG*/ +#define R0900_GPIO1CFG 0xf141 +#define F0900_GPIO1_OPD 0xf1410080 +#define F0900_GPIO1_CONFIG 0xf141007e +#define F0900_GPIO1_XOR 0xf1410001 + +/*GPIO2CFG*/ +#define R0900_GPIO2CFG 0xf142 +#define F0900_GPIO2_OPD 0xf1420080 +#define F0900_GPIO2_CONFIG 0xf142007e +#define F0900_GPIO2_XOR 0xf1420001 + +/*GPIO3CFG*/ +#define R0900_GPIO3CFG 0xf143 +#define F0900_GPIO3_OPD 0xf1430080 +#define F0900_GPIO3_CONFIG 0xf143007e +#define F0900_GPIO3_XOR 0xf1430001 + +/*GPIO4CFG*/ +#define R0900_GPIO4CFG 0xf144 +#define F0900_GPIO4_OPD 0xf1440080 +#define F0900_GPIO4_CONFIG 0xf144007e +#define F0900_GPIO4_XOR 0xf1440001 + +/*GPIO5CFG*/ +#define R0900_GPIO5CFG 0xf145 +#define F0900_GPIO5_OPD 0xf1450080 +#define F0900_GPIO5_CONFIG 0xf145007e +#define F0900_GPIO5_XOR 0xf1450001 + +/*GPIO6CFG*/ +#define R0900_GPIO6CFG 0xf146 +#define F0900_GPIO6_OPD 0xf1460080 +#define F0900_GPIO6_CONFIG 0xf146007e +#define F0900_GPIO6_XOR 0xf1460001 + +/*GPIO7CFG*/ +#define R0900_GPIO7CFG 0xf147 +#define F0900_GPIO7_OPD 0xf1470080 +#define F0900_GPIO7_CONFIG 0xf147007e +#define F0900_GPIO7_XOR 0xf1470001 + +/*GPIO8CFG*/ +#define R0900_GPIO8CFG 0xf148 +#define F0900_GPIO8_OPD 0xf1480080 +#define F0900_GPIO8_CONFIG 0xf148007e +#define F0900_GPIO8_XOR 0xf1480001 + +/*GPIO9CFG*/ +#define R0900_GPIO9CFG 0xf149 +#define F0900_GPIO9_OPD 0xf1490080 +#define F0900_GPIO9_CONFIG 0xf149007e +#define F0900_GPIO9_XOR 0xf1490001 + +/*GPIO10CFG*/ +#define R0900_GPIO10CFG 0xf14a +#define F0900_GPIO10_OPD 0xf14a0080 +#define F0900_GPIO10_CONFIG 0xf14a007e +#define F0900_GPIO10_XOR 0xf14a0001 + +/*GPIO11CFG*/ +#define R0900_GPIO11CFG 0xf14b +#define F0900_GPIO11_OPD 0xf14b0080 +#define F0900_GPIO11_CONFIG 0xf14b007e +#define F0900_GPIO11_XOR 0xf14b0001 + +/*GPIO12CFG*/ +#define R0900_GPIO12CFG 0xf14c +#define F0900_GPIO12_OPD 0xf14c0080 +#define F0900_GPIO12_CONFIG 0xf14c007e +#define F0900_GPIO12_XOR 0xf14c0001 + +/*GPIO13CFG*/ +#define R0900_GPIO13CFG 0xf14d +#define F0900_GPIO13_OPD 0xf14d0080 +#define F0900_GPIO13_CONFIG 0xf14d007e +#define F0900_GPIO13_XOR 0xf14d0001 + +/*CS0CFG*/ +#define R0900_CS0CFG 0xf14e +#define F0900_CS0_OPD 0xf14e0080 +#define F0900_CS0_CONFIG 0xf14e007e +#define F0900_CS0_XOR 0xf14e0001 + +/*CS1CFG*/ +#define R0900_CS1CFG 0xf14f +#define F0900_CS1_OPD 0xf14f0080 +#define F0900_CS1_CONFIG 0xf14f007e +#define F0900_CS1_XOR 0xf14f0001 + +/*STDBYCFG*/ +#define R0900_STDBYCFG 0xf150 +#define F0900_STDBY_OPD 0xf1500080 +#define F0900_STDBY_CONFIG 0xf150007e +#define F0900_STBDY_XOR 0xf1500001 + +/*DIRCLKCFG*/ +#define R0900_DIRCLKCFG 0xf151 +#define F0900_DIRCLK_OPD 0xf1510080 +#define F0900_DIRCLK_CONFIG 0xf151007e +#define F0900_DIRCLK_XOR 0xf1510001 + +/*AGCRF1CFG*/ +#define R0900_AGCRF1CFG 0xf152 +#define F0900_AGCRF1_OPD 0xf1520080 +#define F0900_AGCRF1_CONFIG 0xf152007e +#define F0900_AGCRF1_XOR 0xf1520001 + +/*SDAT1CFG*/ +#define R0900_SDAT1CFG 0xf153 +#define F0900_SDAT1_OPD 0xf1530080 +#define F0900_SDAT1_CONFIG 0xf153007e +#define F0900_SDAT1_XOR 0xf1530001 + +/*SCLT1CFG*/ +#define R0900_SCLT1CFG 0xf154 +#define F0900_SCLT1_OPD 0xf1540080 +#define F0900_SCLT1_CONFIG 0xf154007e +#define F0900_SCLT1_XOR 0xf1540001 + +/*DISEQCO1CFG*/ +#define R0900_DISEQCO1CFG 0xf155 +#define F0900_DISEQCO1_OPD 0xf1550080 +#define F0900_DISEQCO1_CONFIG 0xf155007e +#define F0900_DISEQC1_XOR 0xf1550001 + +/*AGCRF2CFG*/ +#define R0900_AGCRF2CFG 0xf156 +#define F0900_AGCRF2_OPD 0xf1560080 +#define F0900_AGCRF2_CONFIG 0xf156007e +#define F0900_AGCRF2_XOR 0xf1560001 + +/*SDAT2CFG*/ +#define R0900_SDAT2CFG 0xf157 +#define F0900_SDAT2_OPD 0xf1570080 +#define F0900_SDAT2_CONFIG 0xf157007e +#define F0900_SDAT2_XOR 0xf1570001 + +/*SCLT2CFG*/ +#define R0900_SCLT2CFG 0xf158 +#define F0900_SCLT2_OPD 0xf1580080 +#define F0900_SCLT2_CONFIG 0xf158007e +#define F0900_SCLT2_XOR 0xf1580001 + +/*DISEQCO2CFG*/ +#define R0900_DISEQCO2CFG 0xf159 +#define F0900_DISEQCO2_OPD 0xf1590080 +#define F0900_DISEQCO2_CONFIG 0xf159007e +#define F0900_DISEQC2_XOR 0xf1590001 + +/*CLKOUT27CFG*/ +#define R0900_CLKOUT27CFG 0xf15a +#define F0900_CLKOUT27_OPD 0xf15a0080 +#define F0900_CLKOUT27_CONFIG 0xf15a007e +#define F0900_CLKOUT27_XOR 0xf15a0001 + +/*ERROR1CFG*/ +#define R0900_ERROR1CFG 0xf15b +#define F0900_ERROR1_OPD 0xf15b0080 +#define F0900_ERROR1_CONFIG 0xf15b007e +#define F0900_ERROR1_XOR 0xf15b0001 + +/*DPN1CFG*/ +#define R0900_DPN1CFG 0xf15c +#define F0900_DPN1_OPD 0xf15c0080 +#define F0900_DPN1_CONFIG 0xf15c007e +#define F0900_DPN1_XOR 0xf15c0001 + +/*STROUT1CFG*/ +#define R0900_STROUT1CFG 0xf15d +#define F0900_STROUT1_OPD 0xf15d0080 +#define F0900_STROUT1_CONFIG 0xf15d007e +#define F0900_STROUT1_XOR 0xf15d0001 + +/*CLKOUT1CFG*/ +#define R0900_CLKOUT1CFG 0xf15e +#define F0900_CLKOUT1_OPD 0xf15e0080 +#define F0900_CLKOUT1_CONFIG 0xf15e007e +#define F0900_CLKOUT1_XOR 0xf15e0001 + +/*DATA71CFG*/ +#define R0900_DATA71CFG 0xf15f +#define F0900_DATA71_OPD 0xf15f0080 +#define F0900_DATA71_CONFIG 0xf15f007e +#define F0900_DATA71_XOR 0xf15f0001 + +/*ERROR2CFG*/ +#define R0900_ERROR2CFG 0xf160 +#define F0900_ERROR2_OPD 0xf1600080 +#define F0900_ERROR2_CONFIG 0xf160007e +#define F0900_ERROR2_XOR 0xf1600001 + +/*DPN2CFG*/ +#define R0900_DPN2CFG 0xf161 +#define F0900_DPN2_OPD 0xf1610080 +#define F0900_DPN2_CONFIG 0xf161007e +#define F0900_DPN2_XOR 0xf1610001 + +/*STROUT2CFG*/ +#define R0900_STROUT2CFG 0xf162 +#define F0900_STROUT2_OPD 0xf1620080 +#define F0900_STROUT2_CONFIG 0xf162007e +#define F0900_STROUT2_XOR 0xf1620001 + +/*CLKOUT2CFG*/ +#define R0900_CLKOUT2CFG 0xf163 +#define F0900_CLKOUT2_OPD 0xf1630080 +#define F0900_CLKOUT2_CONFIG 0xf163007e +#define F0900_CLKOUT2_XOR 0xf1630001 + +/*DATA72CFG*/ +#define R0900_DATA72CFG 0xf164 +#define F0900_DATA72_OPD 0xf1640080 +#define F0900_DATA72_CONFIG 0xf164007e +#define F0900_DATA72_XOR 0xf1640001 + +/*ERROR3CFG*/ +#define R0900_ERROR3CFG 0xf165 +#define F0900_ERROR3_OPD 0xf1650080 +#define F0900_ERROR3_CONFIG 0xf165007e +#define F0900_ERROR3_XOR 0xf1650001 + +/*DPN3CFG*/ +#define R0900_DPN3CFG 0xf166 +#define F0900_DPN3_OPD 0xf1660080 +#define F0900_DPN3_CONFIG 0xf166007e +#define F0900_DPN3_XOR 0xf1660001 + +/*STROUT3CFG*/ +#define R0900_STROUT3CFG 0xf167 +#define F0900_STROUT3_OPD 0xf1670080 +#define F0900_STROUT3_CONFIG 0xf167007e +#define F0900_STROUT3_XOR 0xf1670001 + +/*CLKOUT3CFG*/ +#define R0900_CLKOUT3CFG 0xf168 +#define F0900_CLKOUT3_OPD 0xf1680080 +#define F0900_CLKOUT3_CONFIG 0xf168007e +#define F0900_CLKOUT3_XOR 0xf1680001 + +/*DATA73CFG*/ +#define R0900_DATA73CFG 0xf169 +#define F0900_DATA73_OPD 0xf1690080 +#define F0900_DATA73_CONFIG 0xf169007e +#define F0900_DATA73_XOR 0xf1690001 + +/*FSKTFC2*/ +#define R0900_FSKTFC2 0xf170 +#define F0900_FSKT_KMOD 0xf17000fc +#define F0900_FSKT_CAR2 0xf1700003 + +/*FSKTFC1*/ +#define R0900_FSKTFC1 0xf171 +#define F0900_FSKT_CAR1 0xf17100ff + +/*FSKTFC0*/ +#define R0900_FSKTFC0 0xf172 +#define F0900_FSKT_CAR0 0xf17200ff + +/*FSKTDELTAF1*/ +#define R0900_FSKTDELTAF1 0xf173 +#define F0900_FSKT_DELTAF1 0xf173000f + +/*FSKTDELTAF0*/ +#define R0900_FSKTDELTAF0 0xf174 +#define F0900_FSKT_DELTAF0 0xf17400ff + +/*FSKTCTRL*/ +#define R0900_FSKTCTRL 0xf175 +#define F0900_FSKT_EN_SGN 0xf1750040 +#define F0900_FSKT_MOD_SGN 0xf1750020 +#define F0900_FSKT_MOD_EN 0xf175001c +#define F0900_FSKT_DACMODE 0xf1750003 + +/*FSKRFC2*/ +#define R0900_FSKRFC2 0xf176 +#define F0900_FSKR_DETSGN 0xf1760040 +#define F0900_FSKR_OUTSGN 0xf1760020 +#define F0900_FSKR_KAGC 0xf176001c +#define F0900_FSKR_CAR2 0xf1760003 + +/*FSKRFC1*/ +#define R0900_FSKRFC1 0xf177 +#define F0900_FSKR_CAR1 0xf17700ff + +/*FSKRFC0*/ +#define R0900_FSKRFC0 0xf178 +#define F0900_FSKR_CAR0 0xf17800ff + +/*FSKRK1*/ +#define R0900_FSKRK1 0xf179 +#define F0900_FSKR_K1_EXP 0xf17900e0 +#define F0900_FSKR_K1_MANT 0xf179001f + +/*FSKRK2*/ +#define R0900_FSKRK2 0xf17a +#define F0900_FSKR_K2_EXP 0xf17a00e0 +#define F0900_FSKR_K2_MANT 0xf17a001f + +/*FSKRAGCR*/ +#define R0900_FSKRAGCR 0xf17b +#define F0900_FSKR_OUTCTL 0xf17b00c0 +#define F0900_FSKR_AGC_REF 0xf17b003f + +/*FSKRAGC*/ +#define R0900_FSKRAGC 0xf17c +#define F0900_FSKR_AGC_ACCU 0xf17c00ff + +/*FSKRALPHA*/ +#define R0900_FSKRALPHA 0xf17d +#define F0900_FSKR_ALPHA_EXP 0xf17d001c +#define F0900_FSKR_ALPHA_M 0xf17d0003 + +/*FSKRPLTH1*/ +#define R0900_FSKRPLTH1 0xf17e +#define F0900_FSKR_BETA 0xf17e00f0 +#define F0900_FSKR_PLL_TRESH1 0xf17e000f + +/*FSKRPLTH0*/ +#define R0900_FSKRPLTH0 0xf17f +#define F0900_FSKR_PLL_TRESH0 0xf17f00ff + +/*FSKRDF1*/ +#define R0900_FSKRDF1 0xf180 +#define F0900_FSKR_OUT 0xf1800080 +#define F0900_FSKR_DELTAF1 0xf180001f + +/*FSKRDF0*/ +#define R0900_FSKRDF0 0xf181 +#define F0900_FSKR_DELTAF0 0xf18100ff + +/*FSKRSTEPP*/ +#define R0900_FSKRSTEPP 0xf182 +#define F0900_FSKR_STEP_PLUS 0xf18200ff + +/*FSKRSTEPM*/ +#define R0900_FSKRSTEPM 0xf183 +#define F0900_FSKR_STEP_MINUS 0xf18300ff + +/*FSKRDET1*/ +#define R0900_FSKRDET1 0xf184 +#define F0900_FSKR_DETECT 0xf1840080 +#define F0900_FSKR_CARDET_ACCU1 0xf184000f + +/*FSKRDET0*/ +#define R0900_FSKRDET0 0xf185 +#define F0900_FSKR_CARDET_ACCU0 0xf18500ff + +/*FSKRDTH1*/ +#define R0900_FSKRDTH1 0xf186 +#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0 +#define F0900_FSKR_CARDET_THRESH1 0xf186000f + +/*FSKRDTH0*/ +#define R0900_FSKRDTH0 0xf187 +#define F0900_FSKR_CARDET_THRESH0 0xf18700ff + +/*FSKRLOSS*/ +#define R0900_FSKRLOSS 0xf188 +#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff + +/*P2_DISTXCTL*/ +#define R0900_P2_DISTXCTL 0xf190 +#define F0900_P2_TIM_OFF 0xf1900080 +#define F0900_P2_DISEQC_RESET 0xf1900040 +#define F0900_P2_TIM_CMD 0xf1900030 +#define F0900_P2_DIS_PRECHARGE 0xf1900008 +#define F0900_P2_DISTX_MODE 0xf1900007 + +/*P2_DISRXCTL*/ +#define R0900_P2_DISRXCTL 0xf191 +#define F0900_P2_RECEIVER_ON 0xf1910080 +#define F0900_P2_IGNO_SHORT22K 0xf1910040 +#define F0900_P2_ONECHIP_TRX 0xf1910020 +#define F0900_P2_EXT_ENVELOP 0xf1910010 +#define F0900_P2_PIN_SELECT 0xf191000c +#define F0900_P2_IRQ_RXEND 0xf1910002 +#define F0900_P2_IRQ_4NBYTES 0xf1910001 + +/*P2_DISRX_ST0*/ +#define R0900_P2_DISRX_ST0 0xf194 +#define F0900_P2_RX_END 0xf1940080 +#define F0900_P2_RX_ACTIVE 0xf1940040 +#define F0900_P2_SHORT_22KHZ 0xf1940020 +#define F0900_P2_CONT_TONE 0xf1940010 +#define F0900_P2_FIFO_4BREADY 0xf1940008 +#define F0900_P2_FIFO_EMPTY 0xf1940004 +#define F0900_P2_ABORT_DISRX 0xf1940001 + +/*P2_DISRX_ST1*/ +#define R0900_P2_DISRX_ST1 0xf195 +#define F0900_P2_RX_FAIL 0xf1950080 +#define F0900_P2_FIFO_PARITYFAIL 0xf1950040 +#define F0900_P2_RX_NONBYTE 0xf1950020 +#define F0900_P2_FIFO_OVERFLOW 0xf1950010 +#define F0900_P2_FIFO_BYTENBR 0xf195000f + +/*P2_DISRXDATA*/ +#define R0900_P2_DISRXDATA 0xf196 +#define F0900_P2_DISRX_DATA 0xf19600ff + +/*P2_DISTXDATA*/ +#define R0900_P2_DISTXDATA 0xf197 +#define F0900_P2_DISEQC_FIFO 0xf19700ff + +/*P2_DISTXSTATUS*/ +#define R0900_P2_DISTXSTATUS 0xf198 +#define F0900_P2_TX_FAIL 0xf1980080 +#define F0900_P2_FIFO_FULL 0xf1980040 +#define F0900_P2_TX_IDLE 0xf1980020 +#define F0900_P2_GAP_BURST 0xf1980010 +#define F0900_P2_TXFIFO_BYTES 0xf198000f + +/*P2_F22TX*/ +#define R0900_P2_F22TX 0xf199 +#define F0900_P2_F22_REG 0xf19900ff + +/*P2_F22RX*/ +#define R0900_P2_F22RX 0xf19a +#define F0900_P2_F22RX_REG 0xf19a00ff + +/*P2_ACRPRESC*/ +#define R0900_P2_ACRPRESC 0xf19c +#define F0900_P2_ACR_CODFRDY 0xf19c0008 +#define F0900_P2_ACR_PRESC 0xf19c0007 + +/*P2_ACRDIV*/ +#define R0900_P2_ACRDIV 0xf19d +#define F0900_P2_ACR_DIV 0xf19d00ff + +/*P1_DISTXCTL*/ +#define R0900_P1_DISTXCTL 0xf1a0 +#define F0900_P1_TIM_OFF 0xf1a00080 +#define F0900_P1_DISEQC_RESET 0xf1a00040 +#define F0900_P1_TIM_CMD 0xf1a00030 +#define F0900_P1_DIS_PRECHARGE 0xf1a00008 +#define F0900_P1_DISTX_MODE 0xf1a00007 + +/*P1_DISRXCTL*/ +#define R0900_P1_DISRXCTL 0xf1a1 +#define F0900_P1_RECEIVER_ON 0xf1a10080 +#define F0900_P1_IGNO_SHORT22K 0xf1a10040 +#define F0900_P1_ONECHIP_TRX 0xf1a10020 +#define F0900_P1_EXT_ENVELOP 0xf1a10010 +#define F0900_P1_PIN_SELECT 0xf1a1000c +#define F0900_P1_IRQ_RXEND 0xf1a10002 +#define F0900_P1_IRQ_4NBYTES 0xf1a10001 + +/*P1_DISRX_ST0*/ +#define R0900_P1_DISRX_ST0 0xf1a4 +#define F0900_P1_RX_END 0xf1a40080 +#define F0900_P1_RX_ACTIVE 0xf1a40040 +#define F0900_P1_SHORT_22KHZ 0xf1a40020 +#define F0900_P1_CONT_TONE 0xf1a40010 +#define F0900_P1_FIFO_4BREADY 0xf1a40008 +#define F0900_P1_FIFO_EMPTY 0xf1a40004 +#define F0900_P1_ABORT_DISRX 0xf1a40001 + +/*P1_DISRX_ST1*/ +#define R0900_P1_DISRX_ST1 0xf1a5 +#define F0900_P1_RX_FAIL 0xf1a50080 +#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040 +#define F0900_P1_RX_NONBYTE 0xf1a50020 +#define F0900_P1_FIFO_OVERFLOW 0xf1a50010 +#define F0900_P1_FIFO_BYTENBR 0xf1a5000f + +/*P1_DISRXDATA*/ +#define R0900_P1_DISRXDATA 0xf1a6 +#define F0900_P1_DISRX_DATA 0xf1a600ff + +/*P1_DISTXDATA*/ +#define R0900_P1_DISTXDATA 0xf1a7 +#define F0900_P1_DISEQC_FIFO 0xf1a700ff + +/*P1_DISTXSTATUS*/ +#define R0900_P1_DISTXSTATUS 0xf1a8 +#define F0900_P1_TX_FAIL 0xf1a80080 +#define F0900_P1_FIFO_FULL 0xf1a80040 +#define F0900_P1_TX_IDLE 0xf1a80020 +#define F0900_P1_GAP_BURST 0xf1a80010 +#define F0900_P1_TXFIFO_BYTES 0xf1a8000f + +/*P1_F22TX*/ +#define R0900_P1_F22TX 0xf1a9 +#define F0900_P1_F22_REG 0xf1a900ff + +/*P1_F22RX*/ +#define R0900_P1_F22RX 0xf1aa +#define F0900_P1_F22RX_REG 0xf1aa00ff + +/*P1_ACRPRESC*/ +#define R0900_P1_ACRPRESC 0xf1ac +#define F0900_P1_ACR_CODFRDY 0xf1ac0008 +#define F0900_P1_ACR_PRESC 0xf1ac0007 + +/*P1_ACRDIV*/ +#define R0900_P1_ACRDIV 0xf1ad +#define F0900_P1_ACR_DIV 0xf1ad00ff + +/*NCOARSE*/ +#define R0900_NCOARSE 0xf1b3 +#define F0900_M_DIV 0xf1b300ff + +/*SYNTCTRL*/ +#define R0900_SYNTCTRL 0xf1b6 +#define F0900_STANDBY 0xf1b60080 +#define F0900_BYPASSPLLCORE 0xf1b60040 +#define F0900_SELX1RATIO 0xf1b60020 +#define F0900_I2C_TUD 0xf1b60010 +#define F0900_STOP_PLL 0xf1b60008 +#define F0900_BYPASSPLLFSK 0xf1b60004 +#define F0900_SELOSCI 0xf1b60002 +#define F0900_BYPASSPLLADC 0xf1b60001 + +/*FILTCTRL*/ +#define R0900_FILTCTRL 0xf1b7 +#define F0900_INV_CLK135 0xf1b70080 +#define F0900_PERM_BYPDIS 0xf1b70040 +#define F0900_SEL_FSKCKDIV 0xf1b70004 +#define F0900_INV_CLKFSK 0xf1b70002 +#define F0900_BYPASS_APPLI 0xf1b70001 + +/*PLLSTAT*/ +#define R0900_PLLSTAT 0xf1b8 +#define F0900_ACM_SEL 0xf1b80080 +#define F0900_DTV_SEL 0xf1b80040 +#define F0900_PLLLOCK 0xf1b80001 + +/*STOPCLK1*/ +#define R0900_STOPCLK1 0xf1c2 +#define F0900_STOP_CLKPKDT2 0xf1c20040 +#define F0900_STOP_CLKPKDT1 0xf1c20020 +#define F0900_STOP_CLKFEC 0xf1c20010 +#define F0900_STOP_CLKADCI2 0xf1c20008 +#define F0900_INV_CLKADCI2 0xf1c20004 +#define F0900_STOP_CLKADCI1 0xf1c20002 +#define F0900_INV_CLKADCI1 0xf1c20001 + +/*STOPCLK2*/ +#define R0900_STOPCLK2 0xf1c3 +#define F0900_STOP_CLKSAMP2 0xf1c30010 +#define F0900_STOP_CLKSAMP1 0xf1c30008 +#define F0900_STOP_CLKVIT2 0xf1c30004 +#define F0900_STOP_CLKVIT1 0xf1c30002 +#define F0900_STOP_CLKTS 0xf1c30001 + +/*TSTTNR0*/ +#define R0900_TSTTNR0 0xf1df +#define F0900_SEL_FSK 0xf1df0080 +#define F0900_FSK_PON 0xf1df0004 +#define F0900_FSK_OPENLOOP 0xf1df0002 + +/*TSTTNR1*/ +#define R0900_TSTTNR1 0xf1e0 +#define F0900_BYPASS_ADC1 0xf1e00080 +#define F0900_INVADC1_CKOUT 0xf1e00040 +#define F0900_SELIQSRC1 0xf1e00030 +#define F0900_ADC1_PON 0xf1e00002 +#define F0900_ADC1_INMODE 0xf1e00001 + +/*TSTTNR2*/ +#define R0900_TSTTNR2 0xf1e1 +#define F0900_DISEQC1_PON 0xf1e10020 +#define F0900_DISEQC1_TEST 0xf1e1001f + +/*TSTTNR3*/ +#define R0900_TSTTNR3 0xf1e2 +#define F0900_BYPASS_ADC2 0xf1e20080 +#define F0900_INVADC2_CKOUT 0xf1e20040 +#define F0900_SELIQSRC2 0xf1e20030 +#define F0900_ADC2_PON 0xf1e20002 +#define F0900_ADC2_INMODE 0xf1e20001 + +/*TSTTNR4*/ +#define R0900_TSTTNR4 0xf1e3 +#define F0900_DISEQC2_PON 0xf1e30020 +#define F0900_DISEQC2_TEST 0xf1e3001f + +/*P2_IQCONST*/ +#define R0900_P2_IQCONST 0xf200 +#define F0900_P2_CONSTEL_SELECT 0xf2000060 +#define F0900_P2_IQSYMB_SEL 0xf200001f + +/*P2_NOSCFG*/ +#define R0900_P2_NOSCFG 0xf201 +#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020 +#define F0900_P2_NOSPLH_BETA 0xf2010018 +#define F0900_P2_NOSDATA_BETA 0xf2010007 + +/*P2_ISYMB*/ +#define R0900_P2_ISYMB 0xf202 +#define F0900_P2_I_SYMBOL 0xf20201ff + +/*P2_QSYMB*/ +#define R0900_P2_QSYMB 0xf203 +#define F0900_P2_Q_SYMBOL 0xf20301ff + +/*P2_AGC1CFG*/ +#define R0900_P2_AGC1CFG 0xf204 +#define F0900_P2_DC_FROZEN 0xf2040080 +#define F0900_P2_DC_CORRECT 0xf2040040 +#define F0900_P2_AMM_FROZEN 0xf2040020 +#define F0900_P2_AMM_CORRECT 0xf2040010 +#define F0900_P2_QUAD_FROZEN 0xf2040008 +#define F0900_P2_QUAD_CORRECT 0xf2040004 +#define F0900_P2_DCCOMP_SLOW 0xf2040002 +#define F0900_P2_IQMISM_SLOW 0xf2040001 + +/*P2_AGC1CN*/ +#define R0900_P2_AGC1CN 0xf206 +#define F0900_P2_AGC1_LOCKED 0xf2060080 +#define F0900_P2_AGC1_OVERFLOW 0xf2060040 +#define F0900_P2_AGC1_NOSLOWLK 0xf2060020 +#define F0900_P2_AGC1_MINPOWER 0xf2060010 +#define F0900_P2_AGCOUT_FAST 0xf2060008 +#define F0900_P2_AGCIQ_BETA 0xf2060007 + +/*P2_AGC1REF*/ +#define R0900_P2_AGC1REF 0xf207 +#define F0900_P2_AGCIQ_REF 0xf20700ff + +/*P2_IDCCOMP*/ +#define R0900_P2_IDCCOMP 0xf208 +#define F0900_P2_IAVERAGE_ADJ 0xf20801ff + +/*P2_QDCCOMP*/ +#define R0900_P2_QDCCOMP 0xf209 +#define F0900_P2_QAVERAGE_ADJ 0xf20901ff + +/*P2_POWERI*/ +#define R0900_P2_POWERI 0xf20a +#define F0900_P2_POWER_I 0xf20a00ff + +/*P2_POWERQ*/ +#define R0900_P2_POWERQ 0xf20b +#define F0900_P2_POWER_Q 0xf20b00ff + +/*P2_AGC1AMM*/ +#define R0900_P2_AGC1AMM 0xf20c +#define F0900_P2_AMM_VALUE 0xf20c00ff + +/*P2_AGC1QUAD*/ +#define R0900_P2_AGC1QUAD 0xf20d +#define F0900_P2_QUAD_VALUE 0xf20d01ff + +/*P2_AGCIQIN1*/ +#define R0900_P2_AGCIQIN1 0xf20e +#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff + +/*P2_AGCIQIN0*/ +#define R0900_P2_AGCIQIN0 0xf20f +#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff + +/*P2_DEMOD*/ +#define R0900_P2_DEMOD 0xf210 +#define F0900_P2_DEMOD_STOP 0xf2100040 +#define F0900_P2_SPECINV_CONTROL 0xf2100030 +#define F0900_P2_FORCE_ENASAMP 0xf2100008 +#define F0900_P2_MANUAL_ROLLOFF 0xf2100004 +#define F0900_P2_ROLLOFF_CONTROL 0xf2100003 + +/*P2_DMDMODCOD*/ +#define R0900_P2_DMDMODCOD 0xf211 +#define F0900_P2_MANUAL_MODCOD 0xf2110080 +#define F0900_P2_DEMOD_MODCOD 0xf211007c +#define F0900_P2_DEMOD_TYPE 0xf2110003 + +/*P2_DSTATUS*/ +#define R0900_P2_DSTATUS 0xf212 +#define F0900_P2_CAR_LOCK 0xf2120080 +#define F0900_P2_TMGLOCK_QUALITY 0xf2120060 +#define F0900_P2_SDVBS1_ENABLE 0xf2120010 +#define F0900_P2_LOCK_DEFINITIF 0xf2120008 +#define F0900_P2_TIMING_IS_LOCKED 0xf2120004 +#define F0900_P2_COARSE_TMGLOCK 0xf2120002 +#define F0900_P2_COARSE_CARLOCK 0xf2120001 + +/*P2_DSTATUS2*/ +#define R0900_P2_DSTATUS2 0xf213 +#define F0900_P2_DEMOD_DELOCK 0xf2130080 +#define F0900_P2_DEMOD_TIMEOUT 0xf2130040 +#define F0900_P2_MODCODRQ_SYNCTAG 0xf2130020 +#define F0900_P2_POLYPH_SATEVENT 0xf2130010 +#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008 +#define F0900_P2_AGC2_OVERFLOW 0xf2130004 +#define F0900_P2_CFR_OVERFLOW 0xf2130002 +#define F0900_P2_GAMMA_OVERUNDER 0xf2130001 + +/*P2_DMDCFGMD*/ +#define R0900_P2_DMDCFGMD 0xf214 +#define F0900_P2_DVBS2_ENABLE 0xf2140080 +#define F0900_P2_DVBS1_ENABLE 0xf2140040 +#define F0900_P2_CFR_AUTOSCAN 0xf2140020 +#define F0900_P2_SCAN_ENABLE 0xf2140010 +#define F0900_P2_TUN_AUTOSCAN 0xf2140008 +#define F0900_P2_NOFORCE_RELOCK 0xf2140004 +#define F0900_P2_TUN_RNG 0xf2140003 + +/*P2_DMDCFG2*/ +#define R0900_P2_DMDCFG2 0xf215 +#define F0900_P2_AGC1_WAITLOCK 0xf2150080 +#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040 +#define F0900_P2_OVERFLOW_TIMEOUT 0xf2150020 +#define F0900_P2_SCANFAIL_TIMEOUT 0xf2150010 +#define F0900_P2_DMDTOUT_BACK 0xf2150008 +#define F0900_P2_CARLOCK_S1ENABLE 0xf2150004 +#define F0900_P2_COARSE_LK3MODE 0xf2150002 +#define F0900_P2_COARSE_LK2MODE 0xf2150001 + +/*P2_DMDISTATE*/ +#define R0900_P2_DMDISTATE 0xf216 +#define F0900_P2_I2C_NORESETDMODE 0xf2160080 +#define F0900_P2_FORCE_ETAPED 0xf2160040 +#define F0900_P2_SDMDRST_DIRCLK 0xf2160020 +#define F0900_P2_I2C_DEMOD_MODE 0xf216001f + +/*P2_DMDT0M*/ +#define R0900_P2_DMDT0M 0xf217 +#define F0900_P2_DMDT0_MIN 0xf21700ff + +/*P2_DMDSTATE*/ +#define R0900_P2_DMDSTATE 0xf21b +#define F0900_P2_DEMOD_LOCKED 0xf21b0080 +#define F0900_P2_HEADER_MODE 0xf21b0060 +#define F0900_P2_DEMOD_MODE 0xf21b001f + +/*P2_DMDFLYW*/ +#define R0900_P2_DMDFLYW 0xf21c +#define F0900_P2_I2C_IRQVAL 0xf21c00f0 +#define F0900_P2_FLYWHEEL_CPT 0xf21c000f + +/*P2_DSTATUS3*/ +#define R0900_P2_DSTATUS3 0xf21d +#define F0900_P2_CFR_ZIGZAG 0xf21d0080 +#define F0900_P2_DEMOD_CFGMODE 0xf21d0060 +#define F0900_P2_GAMMA_LOWBAUDRATE 0xf21d0010 +#define F0900_P2_RELOCK_MODE 0xf21d0008 +#define F0900_P2_DEMOD_FAIL 0xf21d0004 +#define F0900_P2_ETAPE1A_DVBXMEM 0xf21d0003 + +/*P2_DMDCFG3*/ +#define R0900_P2_DMDCFG3 0xf21e +#define F0900_P2_DVBS1_TMGWAIT 0xf21e0080 +#define F0900_P2_NO_BWCENTERING 0xf21e0040 +#define F0900_P2_INV_SEQSRCH 0xf21e0020 +#define F0900_P2_DIS_SFRUPLOW_TRK 0xf21e0010 +#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008 +#define F0900_P2_LOCKTIME_MODE 0xf21e0007 + +/*P2_DMDCFG4*/ +#define R0900_P2_DMDCFG4 0xf21f +#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008 +#define F0900_P2_DIS_CLKENABLE 0xf21f0004 +#define F0900_P2_DIS_HDRDIVLOCK 0xf21f0002 +#define F0900_P2_NO_TNRWBINIT 0xf21f0001 + +/*P2_CORRELMANT*/ +#define R0900_P2_CORRELMANT 0xf220 +#define F0900_P2_CORREL_MANT 0xf22000ff + +/*P2_CORRELABS*/ +#define R0900_P2_CORRELABS 0xf221 +#define F0900_P2_CORREL_ABS 0xf22100ff + +/*P2_CORRELEXP*/ +#define R0900_P2_CORRELEXP 0xf222 +#define F0900_P2_CORREL_ABSEXP 0xf22200f0 +#define F0900_P2_CORREL_EXP 0xf222000f + +/*P2_PLHMODCOD*/ +#define R0900_P2_PLHMODCOD 0xf224 +#define F0900_P2_SPECINV_DEMOD 0xf2240080 +#define F0900_P2_PLH_MODCOD 0xf224007c +#define F0900_P2_PLH_TYPE 0xf2240003 + +/*P2_AGCK32*/ +#define R0900_P2_AGCK32 0xf22b +#define F0900_P2_R3ADJOFF_32APSK 0xf22b0080 +#define F0900_P2_R2ADJOFF_32APSK 0xf22b0040 +#define F0900_P2_R1ADJOFF_32APSK 0xf22b0020 +#define F0900_P2_RADJ_32APSK 0xf22b001f + +/*P2_AGC2O*/ +#define R0900_P2_AGC2O 0xf22c +#define F0900_P2_AGC2REF_ADJUSTING 0xf22c0080 +#define F0900_P2_AGC2_COARSEFAST 0xf22c0040 +#define F0900_P2_AGC2_LKSQRT 0xf22c0020 +#define F0900_P2_AGC2_LKMODE 0xf22c0010 +#define F0900_P2_AGC2_LKEQUA 0xf22c0008 +#define F0900_P2_AGC2_COEF 0xf22c0007 + +/*P2_AGC2REF*/ +#define R0900_P2_AGC2REF 0xf22d +#define F0900_P2_AGC2_REF 0xf22d00ff + +/*P2_AGC1ADJ*/ +#define R0900_P2_AGC1ADJ 0xf22e +#define F0900_P2_AGC1ADJ_MANUAL 0xf22e0080 +#define F0900_P2_AGC1_ADJUSTED 0xf22e017f + +/*P2_AGC2I1*/ +#define R0900_P2_AGC2I1 0xf236 +#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff + +/*P2_AGC2I0*/ +#define R0900_P2_AGC2I0 0xf237 +#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff + +/*P2_CARCFG*/ +#define R0900_P2_CARCFG 0xf238 +#define F0900_P2_CFRUPLOW_AUTO 0xf2380080 +#define F0900_P2_CFRUPLOW_TEST 0xf2380040 +#define F0900_P2_EN_CAR2CENTER 0xf2380020 +#define F0900_P2_CARHDR_NODIV8 0xf2380010 +#define F0900_P2_I2C_ROTA 0xf2380008 +#define F0900_P2_ROTAON 0xf2380004 +#define F0900_P2_PH_DET_ALGO 0xf2380003 + +/*P2_ACLC*/ +#define R0900_P2_ACLC 0xf239 +#define F0900_P2_STOP_S2ALPHA 0xf23900c0 +#define F0900_P2_CAR_ALPHA_MANT 0xf2390030 +#define F0900_P2_CAR_ALPHA_EXP 0xf239000f + +/*P2_BCLC*/ +#define R0900_P2_BCLC 0xf23a +#define F0900_P2_STOP_S2BETA 0xf23a00c0 +#define F0900_P2_CAR_BETA_MANT 0xf23a0030 +#define F0900_P2_CAR_BETA_EXP 0xf23a000f + +/*P2_CARFREQ*/ +#define R0900_P2_CARFREQ 0xf23d +#define F0900_P2_KC_COARSE_EXP 0xf23d00f0 +#define F0900_P2_BETA_FREQ 0xf23d000f + +/*P2_CARHDR*/ +#define R0900_P2_CARHDR 0xf23e +#define F0900_P2_K_FREQ_HDR 0xf23e00ff + +/*P2_LDT*/ +#define R0900_P2_LDT 0xf23f +#define F0900_P2_CARLOCK_THRES 0xf23f01ff + +/*P2_LDT2*/ +#define R0900_P2_LDT2 0xf240 +#define F0900_P2_CARLOCK_THRES2 0xf24001ff + +/*P2_CFRICFG*/ +#define R0900_P2_CFRICFG 0xf241 +#define F0900_P2_CFRINIT_UNVALRNG 0xf2410080 +#define F0900_P2_CFRINIT_LUNVALCPT 0xf2410040 +#define F0900_P2_CFRINIT_ABORTDBL 0xf2410020 +#define F0900_P2_CFRINIT_ABORTPRED 0xf2410010 +#define F0900_P2_CFRINIT_UNVALSKIP 0xf2410008 +#define F0900_P2_CFRINIT_CSTINC 0xf2410004 +#define F0900_P2_NEG_CFRSTEP 0xf2410001 + +/*P2_CFRUP1*/ +#define R0900_P2_CFRUP1 0xf242 +#define F0900_P2_CFR_UP1 0xf24201ff + +/*P2_CFRUP0*/ +#define R0900_P2_CFRUP0 0xf243 +#define F0900_P2_CFR_UP0 0xf24300ff + +/*P2_CFRLOW1*/ +#define R0900_P2_CFRLOW1 0xf246 +#define F0900_P2_CFR_LOW1 0xf24601ff + +/*P2_CFRLOW0*/ +#define R0900_P2_CFRLOW0 0xf247 +#define F0900_P2_CFR_LOW0 0xf24700ff + +/*P2_CFRINIT1*/ +#define R0900_P2_CFRINIT1 0xf248 +#define F0900_P2_CFR_INIT1 0xf24801ff + +/*P2_CFRINIT0*/ +#define R0900_P2_CFRINIT0 0xf249 +#define F0900_P2_CFR_INIT0 0xf24900ff + +/*P2_CFRINC1*/ +#define R0900_P2_CFRINC1 0xf24a +#define F0900_P2_MANUAL_CFRINC 0xf24a0080 +#define F0900_P2_CFR_INC1 0xf24a017f + +/*P2_CFRINC0*/ +#define R0900_P2_CFRINC0 0xf24b +#define F0900_P2_CFR_INC0 0xf24b00f0 + +/*P2_CFR2*/ +#define R0900_P2_CFR2 0xf24c +#define F0900_P2_CAR_FREQ2 0xf24c01ff + +/*P2_CFR1*/ +#define R0900_P2_CFR1 0xf24d +#define F0900_P2_CAR_FREQ1 0xf24d00ff + +/*P2_CFR0*/ +#define R0900_P2_CFR0 0xf24e +#define F0900_P2_CAR_FREQ0 0xf24e00ff + +/*P2_LDI*/ +#define R0900_P2_LDI 0xf24f +#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff + +/*P2_TMGCFG*/ +#define R0900_P2_TMGCFG 0xf250 +#define F0900_P2_TMGLOCK_BETA 0xf25000c0 +#define F0900_P2_NOTMG_GROUPDELAY 0xf2500020 +#define F0900_P2_DO_TIMING_CORR 0xf2500010 +#define F0900_P2_MANUAL_SCAN 0xf250000c +#define F0900_P2_TMG_MINFREQ 0xf2500003 + +/*P2_RTC*/ +#define R0900_P2_RTC 0xf251 +#define F0900_P2_TMGALPHA_EXP 0xf25100f0 +#define F0900_P2_TMGBETA_EXP 0xf251000f + +/*P2_RTCS2*/ +#define R0900_P2_RTCS2 0xf252 +#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0 +#define F0900_P2_TMGBETAS2_EXP 0xf252000f + +/*P2_TMGTHRISE*/ +#define R0900_P2_TMGTHRISE 0xf253 +#define F0900_P2_TMGLOCK_THRISE 0xf25300ff + +/*P2_TMGTHFALL*/ +#define R0900_P2_TMGTHFALL 0xf254 +#define F0900_P2_TMGLOCK_THFALL 0xf25400ff + +/*P2_SFRUPRATIO*/ +#define R0900_P2_SFRUPRATIO 0xf255 +#define F0900_P2_SFR_UPRATIO 0xf25500ff + +/*P2_SFRLOWRATIO*/ +#define R0900_P2_SFRLOWRATIO 0xf256 +#define F0900_P2_SFR_LOWRATIO 0xf25600ff + +/*P2_KREFTMG*/ +#define R0900_P2_KREFTMG 0xf258 +#define F0900_P2_KREF_TMG 0xf25800ff + +/*P2_SFRSTEP*/ +#define R0900_P2_SFRSTEP 0xf259 +#define F0900_P2_SFR_SCANSTEP 0xf25900f0 +#define F0900_P2_SFR_CENTERSTEP 0xf259000f + +/*P2_TMGCFG2*/ +#define R0900_P2_TMGCFG2 0xf25a +#define F0900_P2_DIS_AUTOSAMP 0xf25a0008 +#define F0900_P2_SCANINIT_QUART 0xf25a0004 +#define F0900_P2_NOTMG_DVBS1DERAT 0xf25a0002 +#define F0900_P2_SFRRATIO_FINE 0xf25a0001 + +/*P2_SFRINIT1*/ +#define R0900_P2_SFRINIT1 0xf25e +#define F0900_P2_SFR_INIT1 0xf25e00ff + +/*P2_SFRINIT0*/ +#define R0900_P2_SFRINIT0 0xf25f +#define F0900_P2_SFR_INIT0 0xf25f00ff + +/*P2_SFRUP1*/ +#define R0900_P2_SFRUP1 0xf260 +#define F0900_P2_AUTO_GUP 0xf2600080 +#define F0900_P2_SYMB_FREQ_UP1 0xf260007f + +/*P2_SFRUP0*/ +#define R0900_P2_SFRUP0 0xf261 +#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff + +/*P2_SFRLOW1*/ +#define R0900_P2_SFRLOW1 0xf262 +#define F0900_P2_AUTO_GLOW 0xf2620080 +#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f + +/*P2_SFRLOW0*/ +#define R0900_P2_SFRLOW0 0xf263 +#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff + +/*P2_SFR3*/ +#define R0900_P2_SFR3 0xf264 +#define F0900_P2_SYMB_FREQ3 0xf26400ff + +/*P2_SFR2*/ +#define R0900_P2_SFR2 0xf265 +#define F0900_P2_SYMB_FREQ2 0xf26500ff + +/*P2_SFR1*/ +#define R0900_P2_SFR1 0xf266 +#define F0900_P2_SYMB_FREQ1 0xf26600ff + +/*P2_SFR0*/ +#define R0900_P2_SFR0 0xf267 +#define F0900_P2_SYMB_FREQ0 0xf26700ff + +/*P2_TMGREG2*/ +#define R0900_P2_TMGREG2 0xf268 +#define F0900_P2_TMGREG2 0xf26800ff + +/*P2_TMGREG1*/ +#define R0900_P2_TMGREG1 0xf269 +#define F0900_P2_TMGREG1 0xf26900ff + +/*P2_TMGREG0*/ +#define R0900_P2_TMGREG0 0xf26a +#define F0900_P2_TMGREG0 0xf26a00ff + +/*P2_TMGLOCK1*/ +#define R0900_P2_TMGLOCK1 0xf26b +#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff + +/*P2_TMGLOCK0*/ +#define R0900_P2_TMGLOCK0 0xf26c +#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff + +/*P2_TMGOBS*/ +#define R0900_P2_TMGOBS 0xf26d +#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0 +#define F0900_P2_SCAN_SIGN 0xf26d0030 +#define F0900_P2_TMG_SCANNING 0xf26d0008 +#define F0900_P2_CHCENTERING_MODE 0xf26d0004 +#define F0900_P2_TMG_SCANFAIL 0xf26d0002 + +/*P2_EQUALCFG*/ +#define R0900_P2_EQUALCFG 0xf26f +#define F0900_P2_NOTMG_NEGALWAIT 0xf26f0080 +#define F0900_P2_EQUAL_ON 0xf26f0040 +#define F0900_P2_SEL_EQUALCOR 0xf26f0038 +#define F0900_P2_MU_EQUALDFE 0xf26f0007 + +/*P2_EQUAI1*/ +#define R0900_P2_EQUAI1 0xf270 +#define F0900_P2_EQUA_ACCI1 0xf27001ff + +/*P2_EQUAQ1*/ +#define R0900_P2_EQUAQ1 0xf271 +#define F0900_P2_EQUA_ACCQ1 0xf27101ff + +/*P2_EQUAI2*/ +#define R0900_P2_EQUAI2 0xf272 +#define F0900_P2_EQUA_ACCI2 0xf27201ff + +/*P2_EQUAQ2*/ +#define R0900_P2_EQUAQ2 0xf273 +#define F0900_P2_EQUA_ACCQ2 0xf27301ff + +/*P2_EQUAI3*/ +#define R0900_P2_EQUAI3 0xf274 +#define F0900_P2_EQUA_ACCI3 0xf27401ff + +/*P2_EQUAQ3*/ +#define R0900_P2_EQUAQ3 0xf275 +#define F0900_P2_EQUA_ACCQ3 0xf27501ff + +/*P2_EQUAI4*/ +#define R0900_P2_EQUAI4 0xf276 +#define F0900_P2_EQUA_ACCI4 0xf27601ff + +/*P2_EQUAQ4*/ +#define R0900_P2_EQUAQ4 0xf277 +#define F0900_P2_EQUA_ACCQ4 0xf27701ff + +/*P2_EQUAI5*/ +#define R0900_P2_EQUAI5 0xf278 +#define F0900_P2_EQUA_ACCI5 0xf27801ff + +/*P2_EQUAQ5*/ +#define R0900_P2_EQUAQ5 0xf279 +#define F0900_P2_EQUA_ACCQ5 0xf27901ff + +/*P2_EQUAI6*/ +#define R0900_P2_EQUAI6 0xf27a +#define F0900_P2_EQUA_ACCI6 0xf27a01ff + +/*P2_EQUAQ6*/ +#define R0900_P2_EQUAQ6 0xf27b +#define F0900_P2_EQUA_ACCQ6 0xf27b01ff + +/*P2_EQUAI7*/ +#define R0900_P2_EQUAI7 0xf27c +#define F0900_P2_EQUA_ACCI7 0xf27c01ff + +/*P2_EQUAQ7*/ +#define R0900_P2_EQUAQ7 0xf27d +#define F0900_P2_EQUA_ACCQ7 0xf27d01ff + +/*P2_EQUAI8*/ +#define R0900_P2_EQUAI8 0xf27e +#define F0900_P2_EQUA_ACCI8 0xf27e01ff + +/*P2_EQUAQ8*/ +#define R0900_P2_EQUAQ8 0xf27f +#define F0900_P2_EQUA_ACCQ8 0xf27f01ff + +/*P2_NNOSDATAT1*/ +#define R0900_P2_NNOSDATAT1 0xf280 +#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff + +/*P2_NNOSDATAT0*/ +#define R0900_P2_NNOSDATAT0 0xf281 +#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff + +/*P2_NNOSDATA1*/ +#define R0900_P2_NNOSDATA1 0xf282 +#define F0900_P2_NOSDATA_NORMED1 0xf28200ff + +/*P2_NNOSDATA0*/ +#define R0900_P2_NNOSDATA0 0xf283 +#define F0900_P2_NOSDATA_NORMED0 0xf28300ff + +/*P2_NNOSPLHT1*/ +#define R0900_P2_NNOSPLHT1 0xf284 +#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff + +/*P2_NNOSPLHT0*/ +#define R0900_P2_NNOSPLHT0 0xf285 +#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff + +/*P2_NNOSPLH1*/ +#define R0900_P2_NNOSPLH1 0xf286 +#define F0900_P2_NOSPLH_NORMED1 0xf28600ff + +/*P2_NNOSPLH0*/ +#define R0900_P2_NNOSPLH0 0xf287 +#define F0900_P2_NOSPLH_NORMED0 0xf28700ff + +/*P2_NOSDATAT1*/ +#define R0900_P2_NOSDATAT1 0xf288 +#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff + +/*P2_NOSDATAT0*/ +#define R0900_P2_NOSDATAT0 0xf289 +#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff + +/*P2_NOSDATA1*/ +#define R0900_P2_NOSDATA1 0xf28a +#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff + +/*P2_NOSDATA0*/ +#define R0900_P2_NOSDATA0 0xf28b +#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff + +/*P2_NOSPLHT1*/ +#define R0900_P2_NOSPLHT1 0xf28c +#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff + +/*P2_NOSPLHT0*/ +#define R0900_P2_NOSPLHT0 0xf28d +#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff + +/*P2_NOSPLH1*/ +#define R0900_P2_NOSPLH1 0xf28e +#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff + +/*P2_NOSPLH0*/ +#define R0900_P2_NOSPLH0 0xf28f +#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff + +/*P2_CAR2CFG*/ +#define R0900_P2_CAR2CFG 0xf290 +#define F0900_P2_DESCRAMB_OFF 0xf2900080 +#define F0900_P2_PN4_SELECT 0xf2900040 +#define F0900_P2_CFR2_STOPDVBS1 0xf2900020 +#define F0900_P2_STOP_CFR2UPDATE 0xf2900010 +#define F0900_P2_STOP_NCO2UPDATE 0xf2900008 +#define F0900_P2_ROTA2ON 0xf2900004 +#define F0900_P2_PH_DET_ALGO2 0xf2900003 + +/*P2_ACLC2*/ +#define R0900_P2_ACLC2 0xf291 +#define F0900_P2_CAR2_PUNCT_ADERAT 0xf2910040 +#define F0900_P2_CAR2_ALPHA_MANT 0xf2910030 +#define F0900_P2_CAR2_ALPHA_EXP 0xf291000f + +/*P2_BCLC2*/ +#define R0900_P2_BCLC2 0xf292 +#define F0900_P2_DVBS2_NIP 0xf2920080 +#define F0900_P2_CAR2_PUNCT_BDERAT 0xf2920040 +#define F0900_P2_CAR2_BETA_MANT 0xf2920030 +#define F0900_P2_CAR2_BETA_EXP 0xf292000f + +/*P2_CFR22*/ +#define R0900_P2_CFR22 0xf293 +#define F0900_P2_CAR2_FREQ2 0xf29301ff + +/*P2_CFR21*/ +#define R0900_P2_CFR21 0xf294 +#define F0900_P2_CAR2_FREQ1 0xf29400ff + +/*P2_CFR20*/ +#define R0900_P2_CFR20 0xf295 +#define F0900_P2_CAR2_FREQ0 0xf29500ff + +/*P2_ACLC2S2Q*/ +#define R0900_P2_ACLC2S2Q 0xf297 +#define F0900_P2_ENAB_SPSKSYMB 0xf2970080 +#define F0900_P2_CAR2S2_QADERAT 0xf2970040 +#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030 +#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f + +/*P2_ACLC2S28*/ +#define R0900_P2_ACLC2S28 0xf298 +#define F0900_P2_OLDI3Q_MODE 0xf2980080 +#define F0900_P2_CAR2S2_8ADERAT 0xf2980040 +#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030 +#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f + +/*P2_ACLC2S216A*/ +#define R0900_P2_ACLC2S216A 0xf299 +#define F0900_P2_CAR2S2_16ADERAT 0xf2990040 +#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030 +#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f + +/*P2_ACLC2S232A*/ +#define R0900_P2_ACLC2S232A 0xf29a +#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040 +#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030 +#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f + +/*P2_BCLC2S2Q*/ +#define R0900_P2_BCLC2S2Q 0xf29c +#define F0900_P2_DVBS2S2Q_NIP 0xf29c0080 +#define F0900_P2_CAR2S2_QBDERAT 0xf29c0040 +#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030 +#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f + +/*P2_BCLC2S28*/ +#define R0900_P2_BCLC2S28 0xf29d +#define F0900_P2_DVBS2S28_NIP 0xf29d0080 +#define F0900_P2_CAR2S2_8BDERAT 0xf29d0040 +#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030 +#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f + +/*P2_BCLC2S216A*/ +#define R0900_P2_BCLC2S216A 0xf29e +#define F0900_P2_DVBS2S216A_NIP 0xf29e0080 +#define F0900_P2_CAR2S2_16BDERAT 0xf29e0040 +#define F0900_P2_CAR2S2_16A_BETA_M 0xf29e0030 +#define F0900_P2_CAR2S2_16A_BETA_E 0xf29e000f + +/*P2_BCLC2S232A*/ +#define R0900_P2_BCLC2S232A 0xf29f +#define F0900_P2_DVBS2S232A_NIP 0xf29f0080 +#define F0900_P2_CAR2S2_32BDERAT 0xf29f0040 +#define F0900_P2_CAR2S2_32A_BETA_M 0xf29f0030 +#define F0900_P2_CAR2S2_32A_BETA_E 0xf29f000f + +/*P2_PLROOT2*/ +#define R0900_P2_PLROOT2 0xf2ac +#define F0900_P2_SHORTFR_DISABLE 0xf2ac0080 +#define F0900_P2_LONGFR_DISABLE 0xf2ac0040 +#define F0900_P2_DUMMYPL_DISABLE 0xf2ac0020 +#define F0900_P2_SHORTFR_AVOID 0xf2ac0010 +#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c +#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003 + +/*P2_PLROOT1*/ +#define R0900_P2_PLROOT1 0xf2ad +#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff + +/*P2_PLROOT0*/ +#define R0900_P2_PLROOT0 0xf2ae +#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff + +/*P2_MODCODLST0*/ +#define R0900_P2_MODCODLST0 0xf2b0 +#define F0900_P2_EN_TOKEN31 0xf2b00080 +#define F0900_P2_SYNCTAG_SELECT 0xf2b00040 +#define F0900_P2_MODCODRQ_MODE 0xf2b00030 + +/*P2_MODCODLST1*/ +#define R0900_P2_MODCODLST1 0xf2b1 +#define F0900_P2_DIS_MODCOD29 0xf2b100f0 +#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f + +/*P2_MODCODLST2*/ +#define R0900_P2_MODCODLST2 0xf2b2 +#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0 +#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f + +/*P2_MODCODLST3*/ +#define R0900_P2_MODCODLST3 0xf2b3 +#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0 +#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f + +/*P2_MODCODLST4*/ +#define R0900_P2_MODCODLST4 0xf2b4 +#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0 +#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f + +/*P2_MODCODLST5*/ +#define R0900_P2_MODCODLST5 0xf2b5 +#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0 +#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f + +/*P2_MODCODLST6*/ +#define R0900_P2_MODCODLST6 0xf2b6 +#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0 +#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f + +/*P2_MODCODLST7*/ +#define R0900_P2_MODCODLST7 0xf2b7 +#define F0900_P2_DIS_8P_9_10 0xf2b700f0 +#define F0900_P2_DIS_8P_8_9 0xf2b7000f + +/*P2_MODCODLST8*/ +#define R0900_P2_MODCODLST8 0xf2b8 +#define F0900_P2_DIS_8P_5_6 0xf2b800f0 +#define F0900_P2_DIS_8P_3_4 0xf2b8000f + +/*P2_MODCODLST9*/ +#define R0900_P2_MODCODLST9 0xf2b9 +#define F0900_P2_DIS_8P_2_3 0xf2b900f0 +#define F0900_P2_DIS_8P_3_5 0xf2b9000f + +/*P2_MODCODLSTA*/ +#define R0900_P2_MODCODLSTA 0xf2ba +#define F0900_P2_DIS_QP_9_10 0xf2ba00f0 +#define F0900_P2_DIS_QP_8_9 0xf2ba000f + +/*P2_MODCODLSTB*/ +#define R0900_P2_MODCODLSTB 0xf2bb +#define F0900_P2_DIS_QP_5_6 0xf2bb00f0 +#define F0900_P2_DIS_QP_4_5 0xf2bb000f + +/*P2_MODCODLSTC*/ +#define R0900_P2_MODCODLSTC 0xf2bc +#define F0900_P2_DIS_QP_3_4 0xf2bc00f0 +#define F0900_P2_DIS_QP_2_3 0xf2bc000f + +/*P2_MODCODLSTD*/ +#define R0900_P2_MODCODLSTD 0xf2bd +#define F0900_P2_DIS_QP_3_5 0xf2bd00f0 +#define F0900_P2_DIS_QP_1_2 0xf2bd000f + +/*P2_MODCODLSTE*/ +#define R0900_P2_MODCODLSTE 0xf2be +#define F0900_P2_DIS_QP_2_5 0xf2be00f0 +#define F0900_P2_DIS_QP_1_3 0xf2be000f + +/*P2_MODCODLSTF*/ +#define R0900_P2_MODCODLSTF 0xf2bf +#define F0900_P2_DIS_QP_1_4 0xf2bf00f0 +#define F0900_P2_DDEMOD_SET 0xf2bf0002 +#define F0900_P2_DDEMOD_MASK 0xf2bf0001 + +/*P2_DMDRESCFG*/ +#define R0900_P2_DMDRESCFG 0xf2c6 +#define F0900_P2_DMDRES_RESET 0xf2c60080 +#define F0900_P2_DMDRES_NOISESQR 0xf2c60010 +#define F0900_P2_DMDRES_STRALL 0xf2c60008 +#define F0900_P2_DMDRES_NEWONLY 0xf2c60004 +#define F0900_P2_DMDRES_NOSTORE 0xf2c60002 +#define F0900_P2_DMDRES_AGC2MEM 0xf2c60001 + +/*P2_DMDRESADR*/ +#define R0900_P2_DMDRESADR 0xf2c7 +#define F0900_P2_SUSP_PREDCANAL 0xf2c70080 +#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040 +#define F0900_P2_DMDRES_MEMFULL 0xf2c70030 +#define F0900_P2_DMDRES_RESNBR 0xf2c7000f + +/*P2_DMDRESDATA7*/ +#define R0900_P2_DMDRESDATA7 0xf2c8 +#define F0900_P2_DMDRES_DATA7 0xf2c800ff + +/*P2_DMDRESDATA6*/ +#define R0900_P2_DMDRESDATA6 0xf2c9 +#define F0900_P2_DMDRES_DATA6 0xf2c900ff + +/*P2_DMDRESDATA5*/ +#define R0900_P2_DMDRESDATA5 0xf2ca +#define F0900_P2_DMDRES_DATA5 0xf2ca00ff + +/*P2_DMDRESDATA4*/ +#define R0900_P2_DMDRESDATA4 0xf2cb +#define F0900_P2_DMDRES_DATA4 0xf2cb00ff + +/*P2_DMDRESDATA3*/ +#define R0900_P2_DMDRESDATA3 0xf2cc +#define F0900_P2_DMDRES_DATA3 0xf2cc00ff + +/*P2_DMDRESDATA2*/ +#define R0900_P2_DMDRESDATA2 0xf2cd +#define F0900_P2_DMDRES_DATA2 0xf2cd00ff + +/*P2_DMDRESDATA1*/ +#define R0900_P2_DMDRESDATA1 0xf2ce +#define F0900_P2_DMDRES_DATA1 0xf2ce00ff + +/*P2_DMDRESDATA0*/ +#define R0900_P2_DMDRESDATA0 0xf2cf +#define F0900_P2_DMDRES_DATA0 0xf2cf00ff + +/*P2_FFEI1*/ +#define R0900_P2_FFEI1 0xf2d0 +#define F0900_P2_FFE_ACCI1 0xf2d001ff + +/*P2_FFEQ1*/ +#define R0900_P2_FFEQ1 0xf2d1 +#define F0900_P2_FFE_ACCQ1 0xf2d101ff + +/*P2_FFEI2*/ +#define R0900_P2_FFEI2 0xf2d2 +#define F0900_P2_FFE_ACCI2 0xf2d201ff + +/*P2_FFEQ2*/ +#define R0900_P2_FFEQ2 0xf2d3 +#define F0900_P2_FFE_ACCQ2 0xf2d301ff + +/*P2_FFEI3*/ +#define R0900_P2_FFEI3 0xf2d4 +#define F0900_P2_FFE_ACCI3 0xf2d401ff + +/*P2_FFEQ3*/ +#define R0900_P2_FFEQ3 0xf2d5 +#define F0900_P2_FFE_ACCQ3 0xf2d501ff + +/*P2_FFEI4*/ +#define R0900_P2_FFEI4 0xf2d6 +#define F0900_P2_FFE_ACCI4 0xf2d601ff + +/*P2_FFEQ4*/ +#define R0900_P2_FFEQ4 0xf2d7 +#define F0900_P2_FFE_ACCQ4 0xf2d701ff + +/*P2_FFECFG*/ +#define R0900_P2_FFECFG 0xf2d8 +#define F0900_P2_EQUALFFE_ON 0xf2d80040 +#define F0900_P2_EQUAL_USEDSYMB 0xf2d80030 +#define F0900_P2_MU_EQUALFFE 0xf2d80007 + +/*P2_TNRCFG*/ +#define R0900_P2_TNRCFG 0xf2e0 +#define F0900_P2_TUN_ACKFAIL 0xf2e00080 +#define F0900_P2_TUN_TYPE 0xf2e00070 +#define F0900_P2_TUN_SECSTOP 0xf2e00008 +#define F0900_P2_TUN_VCOSRCH 0xf2e00004 +#define F0900_P2_TUN_MADDRESS 0xf2e00003 + +/*P2_TNRCFG2*/ +#define R0900_P2_TNRCFG2 0xf2e1 +#define F0900_P2_TUN_IQSWAP 0xf2e10080 +#define F0900_P2_STB6110_STEP2MHZ 0xf2e10040 +#define F0900_P2_STB6120_DBLI2C 0xf2e10020 +#define F0900_P2_DIS_FCCK 0xf2e10010 +#define F0900_P2_DIS_LPEN 0xf2e10008 +#define F0900_P2_DIS_BWCALC 0xf2e10004 +#define F0900_P2_SHORT_WAITSTATES 0xf2e10002 +#define F0900_P2_DIS_2BWAGC1 0xf2e10001 + +/*P2_TNRXTAL*/ +#define R0900_P2_TNRXTAL 0xf2e4 +#define F0900_P2_TUN_MCLKDECIMAL 0xf2e400e0 +#define F0900_P2_TUN_XTALFREQ 0xf2e4001f + +/*P2_TNRSTEPS*/ +#define R0900_P2_TNRSTEPS 0xf2e7 +#define F0900_P2_TUNER_BW1P6 0xf2e70080 +#define F0900_P2_BWINC_OFFSET 0xf2e70070 +#define F0900_P2_SOFTSTEP_RNG 0xf2e70008 +#define F0900_P2_TUN_BWOFFSET 0xf2e70107 + +/*P2_TNRGAIN*/ +#define R0900_P2_TNRGAIN 0xf2e8 +#define F0900_P2_TUN_KDIVEN 0xf2e800c0 +#define F0900_P2_STB6X00_OCK 0xf2e80030 +#define F0900_P2_TUN_GAIN 0xf2e8000f + +/*P2_TNRRF1*/ +#define R0900_P2_TNRRF1 0xf2e9 +#define F0900_P2_TUN_RFFREQ2 0xf2e900ff + +/*P2_TNRRF0*/ +#define R0900_P2_TNRRF0 0xf2ea +#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff + +/*P2_TNRBW*/ +#define R0900_P2_TNRBW 0xf2eb +#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0 +#define F0900_P2_TUN_BW 0xf2eb003f + +/*P2_TNRADJ*/ +#define R0900_P2_TNRADJ 0xf2ec +#define F0900_P2_STB61X0_RCLK 0xf2ec0080 +#define F0900_P2_STB61X0_CALTIME 0xf2ec0040 +#define F0900_P2_STB6X00_DLB 0xf2ec0038 +#define F0900_P2_STB6000_FCL 0xf2ec0007 + +/*P2_TNRCTL2*/ +#define R0900_P2_TNRCTL2 0xf2ed +#define F0900_P2_STB61X0_LCP1_RCCKOFF 0xf2ed0080 +#define F0900_P2_STB61X0_LCP0 0xf2ed0040 +#define F0900_P2_STB61X0_XTOUT_RFOUTS 0xf2ed0020 +#define F0900_P2_STB61X0_XTON_MCKDV 0xf2ed0010 +#define F0900_P2_STB61X0_CALOFF_DCOFF 0xf2ed0008 +#define F0900_P2_STB6110_LPT 0xf2ed0004 +#define F0900_P2_STB6110_RX 0xf2ed0002 +#define F0900_P2_STB6110_SYN 0xf2ed0001 + +/*P2_TNRCFG3*/ +#define R0900_P2_TNRCFG3 0xf2ee +#define F0900_P2_STB6120_DISCTRL1 0xf2ee0080 +#define F0900_P2_STB6120_INVORDER 0xf2ee0040 +#define F0900_P2_STB6120_ENCTRL6 0xf2ee0020 +#define F0900_P2_TUN_PLLFREQ 0xf2ee001c +#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003 + +/*P2_TNRLAUNCH*/ +#define R0900_P2_TNRLAUNCH 0xf2f0 + +/*P2_TNRLD*/ +#define R0900_P2_TNRLD 0xf2f0 +#define F0900_P2_TUNLD_VCOING 0xf2f00080 +#define F0900_P2_TUN_REG1FAIL 0xf2f00040 +#define F0900_P2_TUN_REG2FAIL 0xf2f00020 +#define F0900_P2_TUN_REG3FAIL 0xf2f00010 +#define F0900_P2_TUN_REG4FAIL 0xf2f00008 +#define F0900_P2_TUN_REG5FAIL 0xf2f00004 +#define F0900_P2_TUN_BWING 0xf2f00002 +#define F0900_P2_TUN_LOCKED 0xf2f00001 + +/*P2_TNROBSL*/ +#define R0900_P2_TNROBSL 0xf2f6 +#define F0900_P2_TUN_I2CABORTED 0xf2f60080 +#define F0900_P2_TUN_LPEN 0xf2f60040 +#define F0900_P2_TUN_FCCK 0xf2f60020 +#define F0900_P2_TUN_I2CLOCKED 0xf2f60010 +#define F0900_P2_TUN_PROGDONE 0xf2f6000c +#define F0900_P2_TUN_RFRESTE1 0xf2f60003 + +/*P2_TNRRESTE*/ +#define R0900_P2_TNRRESTE 0xf2f7 +#define F0900_P2_TUN_RFRESTE0 0xf2f700ff + +/*P2_SMAPCOEF7*/ +#define R0900_P2_SMAPCOEF7 0xf300 +#define F0900_P2_DIS_QSCALE 0xf3000080 +#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f + +/*P2_SMAPCOEF6*/ +#define R0900_P2_SMAPCOEF6 0xf301 +#define F0900_P2_DIS_NEWSCALE 0xf3010008 +#define F0900_P2_ADJ_8PSKLLR1 0xf3010004 +#define F0900_P2_OLD_8PSKLLR1 0xf3010002 +#define F0900_P2_DIS_AB8PSK 0xf3010001 + +/*P2_SMAPCOEF5*/ +#define R0900_P2_SMAPCOEF5 0xf302 +#define F0900_P2_DIS_8SCALE 0xf3020080 +#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f + +/*P2_DMDPLHSTAT*/ +#define R0900_P2_DMDPLHSTAT 0xf320 +#define F0900_P2_PLH_STATISTIC 0xf32000ff + +/*P2_LOCKTIME3*/ +#define R0900_P2_LOCKTIME3 0xf322 +#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff + +/*P2_LOCKTIME2*/ +#define R0900_P2_LOCKTIME2 0xf323 +#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff + +/*P2_LOCKTIME1*/ +#define R0900_P2_LOCKTIME1 0xf324 +#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff + +/*P2_LOCKTIME0*/ +#define R0900_P2_LOCKTIME0 0xf325 +#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff + +/*P2_VITSCALE*/ +#define R0900_P2_VITSCALE 0xf332 +#define F0900_P2_NVTH_NOSRANGE 0xf3320080 +#define F0900_P2_VERROR_MAXMODE 0xf3320040 +#define F0900_P2_KDIV_MODE 0xf3320030 +#define F0900_P2_NSLOWSN_LOCKED 0xf3320008 +#define F0900_P2_DELOCK_PRFLOSS 0xf3320004 +#define F0900_P2_DIS_RSFLOCK 0xf3320002 + +/*P2_FECM*/ +#define R0900_P2_FECM 0xf333 +#define F0900_P2_DSS_DVB 0xf3330080 +#define F0900_P2_DEMOD_BYPASS 0xf3330040 +#define F0900_P2_CMP_SLOWMODE 0xf3330020 +#define F0900_P2_DSS_SRCH 0xf3330010 +#define F0900_P2_DIFF_MODEVIT 0xf3330004 +#define F0900_P2_SYNCVIT 0xf3330002 +#define F0900_P2_IQINV 0xf3330001 + +/*P2_VTH12*/ +#define R0900_P2_VTH12 0xf334 +#define F0900_P2_VTH12 0xf33400ff + +/*P2_VTH23*/ +#define R0900_P2_VTH23 0xf335 +#define F0900_P2_VTH23 0xf33500ff + +/*P2_VTH34*/ +#define R0900_P2_VTH34 0xf336 +#define F0900_P2_VTH34 0xf33600ff + +/*P2_VTH56*/ +#define R0900_P2_VTH56 0xf337 +#define F0900_P2_VTH56 0xf33700ff + +/*P2_VTH67*/ +#define R0900_P2_VTH67 0xf338 +#define F0900_P2_VTH67 0xf33800ff + +/*P2_VTH78*/ +#define R0900_P2_VTH78 0xf339 +#define F0900_P2_VTH78 0xf33900ff + +/*P2_VITCURPUN*/ +#define R0900_P2_VITCURPUN 0xf33a +#define F0900_P2_VIT_MAPPING 0xf33a00e0 +#define F0900_P2_VIT_CURPUN 0xf33a001f + +/*P2_VERROR*/ +#define R0900_P2_VERROR 0xf33b +#define F0900_P2_REGERR_VIT 0xf33b00ff + +/*P2_PRVIT*/ +#define R0900_P2_PRVIT 0xf33c +#define F0900_P2_DIS_VTHLOCK 0xf33c0040 +#define F0900_P2_E7_8VIT 0xf33c0020 +#define F0900_P2_E6_7VIT 0xf33c0010 +#define F0900_P2_E5_6VIT 0xf33c0008 +#define F0900_P2_E3_4VIT 0xf33c0004 +#define F0900_P2_E2_3VIT 0xf33c0002 +#define F0900_P2_E1_2VIT 0xf33c0001 + +/*P2_VAVSRVIT*/ +#define R0900_P2_VAVSRVIT 0xf33d +#define F0900_P2_AMVIT 0xf33d0080 +#define F0900_P2_FROZENVIT 0xf33d0040 +#define F0900_P2_SNVIT 0xf33d0030 +#define F0900_P2_TOVVIT 0xf33d000c +#define F0900_P2_HYPVIT 0xf33d0003 + +/*P2_VSTATUSVIT*/ +#define R0900_P2_VSTATUSVIT 0xf33e +#define F0900_P2_VITERBI_ON 0xf33e0080 +#define F0900_P2_END_LOOPVIT 0xf33e0040 +#define F0900_P2_VITERBI_DEPRF 0xf33e0020 +#define F0900_P2_PRFVIT 0xf33e0010 +#define F0900_P2_LOCKEDVIT 0xf33e0008 +#define F0900_P2_VITERBI_DELOCK 0xf33e0004 +#define F0900_P2_VIT_DEMODSEL 0xf33e0002 +#define F0900_P2_VITERBI_COMPOUT 0xf33e0001 + +/*P2_VTHINUSE*/ +#define R0900_P2_VTHINUSE 0xf33f +#define F0900_P2_VIT_INUSE 0xf33f00ff + +/*P2_KDIV12*/ +#define R0900_P2_KDIV12 0xf340 +#define F0900_P2_KDIV12_MANUAL 0xf3400080 +#define F0900_P2_K_DIVIDER_12 0xf340007f + +/*P2_KDIV23*/ +#define R0900_P2_KDIV23 0xf341 +#define F0900_P2_KDIV23_MANUAL 0xf3410080 +#define F0900_P2_K_DIVIDER_23 0xf341007f + +/*P2_KDIV34*/ +#define R0900_P2_KDIV34 0xf342 +#define F0900_P2_KDIV34_MANUAL 0xf3420080 +#define F0900_P2_K_DIVIDER_34 0xf342007f + +/*P2_KDIV56*/ +#define R0900_P2_KDIV56 0xf343 +#define F0900_P2_KDIV56_MANUAL 0xf3430080 +#define F0900_P2_K_DIVIDER_56 0xf343007f + +/*P2_KDIV67*/ +#define R0900_P2_KDIV67 0xf344 +#define F0900_P2_KDIV67_MANUAL 0xf3440080 +#define F0900_P2_K_DIVIDER_67 0xf344007f + +/*P2_KDIV78*/ +#define R0900_P2_KDIV78 0xf345 +#define F0900_P2_KDIV78_MANUAL 0xf3450080 +#define F0900_P2_K_DIVIDER_78 0xf345007f + +/*P2_PDELCTRL1*/ +#define R0900_P2_PDELCTRL1 0xf350 +#define F0900_P2_INV_MISMASK 0xf3500080 +#define F0900_P2_FORCE_ACCEPTED 0xf3500040 +#define F0900_P2_FILTER_EN 0xf3500020 +#define F0900_P2_FORCE_PKTDELINUSE 0xf3500010 +#define F0900_P2_HYSTEN 0xf3500008 +#define F0900_P2_HYSTSWRST 0xf3500004 +#define F0900_P2_EN_MIS00 0xf3500002 +#define F0900_P2_ALGOSWRST 0xf3500001 + +/*P2_PDELCTRL2*/ +#define R0900_P2_PDELCTRL2 0xf351 +#define F0900_P2_FORCE_CONTINUOUS 0xf3510080 +#define F0900_P2_RESET_UPKO_COUNT 0xf3510040 +#define F0900_P2_USER_PKTDELIN_NB 0xf3510020 +#define F0900_P2_FORCE_LOCKED 0xf3510010 +#define F0900_P2_DATA_UNBBSCRAM 0xf3510008 +#define F0900_P2_FORCE_LONGPKT 0xf3510004 +#define F0900_P2_FRAME_MODE 0xf3510002 + +/*P2_HYSTTHRESH*/ +#define R0900_P2_HYSTTHRESH 0xf354 +#define F0900_P2_UNLCK_THRESH 0xf35400f0 +#define F0900_P2_DELIN_LCK_THRESH 0xf354000f + +/*P2_ISIENTRY*/ +#define R0900_P2_ISIENTRY 0xf35e +#define F0900_P2_ISI_ENTRY 0xf35e00ff + +/*P2_ISIBITENA*/ +#define R0900_P2_ISIBITENA 0xf35f +#define F0900_P2_ISI_BIT_EN 0xf35f00ff + +/*P2_MATSTR1*/ +#define R0900_P2_MATSTR1 0xf360 +#define F0900_P2_MATYPE_CURRENT1 0xf36000ff + +/*P2_MATSTR0*/ +#define R0900_P2_MATSTR0 0xf361 +#define F0900_P2_MATYPE_CURRENT0 0xf36100ff + +/*P2_UPLSTR1*/ +#define R0900_P2_UPLSTR1 0xf362 +#define F0900_P2_UPL_CURRENT1 0xf36200ff + +/*P2_UPLSTR0*/ +#define R0900_P2_UPLSTR0 0xf363 +#define F0900_P2_UPL_CURRENT0 0xf36300ff + +/*P2_DFLSTR1*/ +#define R0900_P2_DFLSTR1 0xf364 +#define F0900_P2_DFL_CURRENT1 0xf36400ff + +/*P2_DFLSTR0*/ +#define R0900_P2_DFLSTR0 0xf365 +#define F0900_P2_DFL_CURRENT0 0xf36500ff + +/*P2_SYNCSTR*/ +#define R0900_P2_SYNCSTR 0xf366 +#define F0900_P2_SYNC_CURRENT 0xf36600ff + +/*P2_SYNCDSTR1*/ +#define R0900_P2_SYNCDSTR1 0xf367 +#define F0900_P2_SYNCD_CURRENT1 0xf36700ff + +/*P2_SYNCDSTR0*/ +#define R0900_P2_SYNCDSTR0 0xf368 +#define F0900_P2_SYNCD_CURRENT0 0xf36800ff + +/*P2_PDELSTATUS1*/ +#define R0900_P2_PDELSTATUS1 0xf369 +#define F0900_P2_PKTDELIN_DELOCK 0xf3690080 +#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040 +#define F0900_P2_CONTINUOUS_STREAM 0xf3690020 +#define F0900_P2_UNACCEPTED_STREAM 0xf3690010 +#define F0900_P2_BCH_ERROR_FLAG 0xf3690008 +#define F0900_P2_BBHCRCKO 0xf3690004 +#define F0900_P2_PKTDELIN_LOCK 0xf3690002 +#define F0900_P2_FIRST_LOCK 0xf3690001 + +/*P2_PDELSTATUS2*/ +#define R0900_P2_PDELSTATUS2 0xf36a +#define F0900_P2_PKTDEL_DEMODSEL 0xf36a0080 +#define F0900_P2_FRAME_MODCOD 0xf36a007c +#define F0900_P2_FRAME_TYPE 0xf36a0003 + +/*P2_BBFCRCKO1*/ +#define R0900_P2_BBFCRCKO1 0xf36b +#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff + +/*P2_BBFCRCKO0*/ +#define R0900_P2_BBFCRCKO0 0xf36c +#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff + +/*P2_UPCRCKO1*/ +#define R0900_P2_UPCRCKO1 0xf36d +#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff + +/*P2_UPCRCKO0*/ +#define R0900_P2_UPCRCKO0 0xf36e +#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff + +/*P2_TSSTATEM*/ +#define R0900_P2_TSSTATEM 0xf370 +#define F0900_P2_TSDIL_ON 0xf3700080 +#define F0900_P2_TSSKIPRS_ON 0xf3700040 +#define F0900_P2_TSRS_ON 0xf3700020 +#define F0900_P2_TSDESCRAMB_ON 0xf3700010 +#define F0900_P2_TSFRAME_MODE 0xf3700008 +#define F0900_P2_TS_DISABLE 0xf3700004 +#define F0900_P2_TSACM_MODE 0xf3700002 +#define F0900_P2_TSOUT_NOSYNC 0xf3700001 + +/*P2_TSCFGH*/ +#define R0900_P2_TSCFGH 0xf372 +#define F0900_P2_TSFIFO_DVBCI 0xf3720080 +#define F0900_P2_TSFIFO_SERIAL 0xf3720040 +#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020 +#define F0900_P2_TSFIFO_DUTY50 0xf3720010 +#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008 +#define F0900_P2_TSFIFO_ERRMODE 0xf3720006 +#define F0900_P2_RST_HWARE 0xf3720001 + +/*P2_TSCFGM*/ +#define R0900_P2_TSCFGM 0xf373 +#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0 +#define F0900_P2_TSFIFO_PERMDATA 0xf3730020 +#define F0900_P2_TSFIFO_NONEWSGNL 0xf3730010 +#define F0900_P2_TSFIFO_BITSPEED 0xf3730008 +#define F0900_P2_NPD_SPECDVBS2 0xf3730004 +#define F0900_P2_TSFIFO_STOPCKDIS 0xf3730002 +#define F0900_P2_TSFIFO_INVDATA 0xf3730001 + +/*P2_TSCFGL*/ +#define R0900_P2_TSCFGL 0xf374 +#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0 +#define F0900_P2_BCHERROR_MODE 0xf3740030 +#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008 +#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004 +#define F0900_P2_TSFIFO_DPUNACT 0xf3740002 +#define F0900_P2_TSFIFO_NPDOFF 0xf3740001 + +/*P2_TSINSDELH*/ +#define R0900_P2_TSINSDELH 0xf376 +#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080 +#define F0900_P2_TSDEL_XXHEADER 0xf3760040 +#define F0900_P2_TSDEL_BBHEADER 0xf3760020 +#define F0900_P2_TSDEL_DATAFIELD 0xf3760010 +#define F0900_P2_TSINSDEL_ISCR 0xf3760008 +#define F0900_P2_TSINSDEL_NPD 0xf3760004 +#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002 +#define F0900_P2_TSINSDEL_CRC8 0xf3760001 + +/*P2_TSSPEED*/ +#define R0900_P2_TSSPEED 0xf380 +#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff + +/*P2_TSSTATUS*/ +#define R0900_P2_TSSTATUS 0xf381 +#define F0900_P2_TSFIFO_LINEOK 0xf3810080 +#define F0900_P2_TSFIFO_ERROR 0xf3810040 +#define F0900_P2_TSFIFO_DATA7 0xf3810020 +#define F0900_P2_TSFIFO_NOSYNC 0xf3810010 +#define F0900_P2_ISCR_INITIALIZED 0xf3810008 +#define F0900_P2_ISCR_UPDATED 0xf3810004 +#define F0900_P2_SOFFIFO_UNREGUL 0xf3810002 +#define F0900_P2_DIL_READY 0xf3810001 + +/*P2_TSSTATUS2*/ +#define R0900_P2_TSSTATUS2 0xf382 +#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080 +#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040 +#define F0900_P2_DILXX_RESET 0xf3820020 +#define F0900_P2_TSSERIAL_IMPOS 0xf3820010 +#define F0900_P2_TSFIFO_LINENOK 0xf3820008 +#define F0900_P2_BITSPEED_EVENT 0xf3820004 +#define F0900_P2_SCRAMBDETECT 0xf3820002 +#define F0900_P2_ULDTV67_FALSELOCK 0xf3820001 + +/*P2_TSBITRATE1*/ +#define R0900_P2_TSBITRATE1 0xf383 +#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff + +/*P2_TSBITRATE0*/ +#define R0900_P2_TSBITRATE0 0xf384 +#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff + +/*P2_ERRCTRL1*/ +#define R0900_P2_ERRCTRL1 0xf398 +#define F0900_P2_ERR_SOURCE1 0xf39800f0 +#define F0900_P2_NUM_EVENT1 0xf3980007 + +/*P2_ERRCNT12*/ +#define R0900_P2_ERRCNT12 0xf399 +#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080 +#define F0900_P2_ERR_CNT12 0xf399007f + +/*P2_ERRCNT11*/ +#define R0900_P2_ERRCNT11 0xf39a +#define F0900_P2_ERR_CNT11 0xf39a00ff + +/*P2_ERRCNT10*/ +#define R0900_P2_ERRCNT10 0xf39b +#define F0900_P2_ERR_CNT10 0xf39b00ff + +/*P2_ERRCTRL2*/ +#define R0900_P2_ERRCTRL2 0xf39c +#define F0900_P2_ERR_SOURCE2 0xf39c00f0 +#define F0900_P2_NUM_EVENT2 0xf39c0007 + +/*P2_ERRCNT22*/ +#define R0900_P2_ERRCNT22 0xf39d +#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080 +#define F0900_P2_ERR_CNT22 0xf39d007f + +/*P2_ERRCNT21*/ +#define R0900_P2_ERRCNT21 0xf39e +#define F0900_P2_ERR_CNT21 0xf39e00ff + +/*P2_ERRCNT20*/ +#define R0900_P2_ERRCNT20 0xf39f +#define F0900_P2_ERR_CNT20 0xf39f00ff + +/*P2_FECSPY*/ +#define R0900_P2_FECSPY 0xf3a0 +#define F0900_P2_SPY_ENABLE 0xf3a00080 +#define F0900_P2_NO_SYNCBYTE 0xf3a00040 +#define F0900_P2_SERIAL_MODE 0xf3a00020 +#define F0900_P2_UNUSUAL_PACKET 0xf3a00010 +#define F0900_P2_BER_PACKMODE 0xf3a00008 +#define F0900_P2_BERMETER_LMODE 0xf3a00002 +#define F0900_P2_BERMETER_RESET 0xf3a00001 + +/*P2_FSPYCFG*/ +#define R0900_P2_FSPYCFG 0xf3a1 +#define F0900_P2_FECSPY_INPUT 0xf3a100c0 +#define F0900_P2_RST_ON_ERROR 0xf3a10020 +#define F0900_P2_ONE_SHOT 0xf3a10010 +#define F0900_P2_I2C_MODE 0xf3a1000c +#define F0900_P2_SPY_HYSTERESIS 0xf3a10003 + +/*P2_FSPYDATA*/ +#define R0900_P2_FSPYDATA 0xf3a2 +#define F0900_P2_SPY_STUFFING 0xf3a20080 +#define F0900_P2_NOERROR_PKTJITTER 0xf3a20040 +#define F0900_P2_SPY_CNULLPKT 0xf3a20020 +#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f + +/*P2_FSPYOUT*/ +#define R0900_P2_FSPYOUT 0xf3a3 +#define F0900_P2_FSPY_DIRECT 0xf3a30080 +#define F0900_P2_SPY_OUTDATA_BUS 0xf3a30038 +#define F0900_P2_STUFF_MODE 0xf3a30007 + +/*P2_FSTATUS*/ +#define R0900_P2_FSTATUS 0xf3a4 +#define F0900_P2_SPY_ENDSIM 0xf3a40080 +#define F0900_P2_VALID_SIM 0xf3a40040 +#define F0900_P2_FOUND_SIGNAL 0xf3a40020 +#define F0900_P2_DSS_SYNCBYTE 0xf3a40010 +#define F0900_P2_RESULT_STATE 0xf3a4000f + +/*P2_FBERCPT4*/ +#define R0900_P2_FBERCPT4 0xf3a8 +#define F0900_P2_FBERMETER_CPT4 0xf3a800ff + +/*P2_FBERCPT3*/ +#define R0900_P2_FBERCPT3 0xf3a9 +#define F0900_P2_FBERMETER_CPT3 0xf3a900ff + +/*P2_FBERCPT2*/ +#define R0900_P2_FBERCPT2 0xf3aa +#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff + +/*P2_FBERCPT1*/ +#define R0900_P2_FBERCPT1 0xf3ab +#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff + +/*P2_FBERCPT0*/ +#define R0900_P2_FBERCPT0 0xf3ac +#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff + +/*P2_FBERERR2*/ +#define R0900_P2_FBERERR2 0xf3ad +#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff + +/*P2_FBERERR1*/ +#define R0900_P2_FBERERR1 0xf3ae +#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff + +/*P2_FBERERR0*/ +#define R0900_P2_FBERERR0 0xf3af +#define F0900_P2_FBERMETER_ERR0 0xf3af00ff + +/*P2_FSPYBER*/ +#define R0900_P2_FSPYBER 0xf3b2 +#define F0900_P2_FSPYOBS_XORREAD 0xf3b20040 +#define F0900_P2_FSPYBER_OBSMODE 0xf3b20020 +#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010 +#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008 +#define F0900_P2_FSPYBER_CTIME 0xf3b20007 + +/*P1_IQCONST*/ +#define R0900_P1_IQCONST 0xf400 +#define F0900_P1_CONSTEL_SELECT 0xf4000060 +#define F0900_P1_IQSYMB_SEL 0xf400001f + +/*P1_NOSCFG*/ +#define R0900_P1_NOSCFG 0xf401 +#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020 +#define F0900_P1_NOSPLH_BETA 0xf4010018 +#define F0900_P1_NOSDATA_BETA 0xf4010007 + +/*P1_ISYMB*/ +#define R0900_P1_ISYMB 0xf402 +#define F0900_P1_I_SYMBOL 0xf40201ff + +/*P1_QSYMB*/ +#define R0900_P1_QSYMB 0xf403 +#define F0900_P1_Q_SYMBOL 0xf40301ff + +/*P1_AGC1CFG*/ +#define R0900_P1_AGC1CFG 0xf404 +#define F0900_P1_DC_FROZEN 0xf4040080 +#define F0900_P1_DC_CORRECT 0xf4040040 +#define F0900_P1_AMM_FROZEN 0xf4040020 +#define F0900_P1_AMM_CORRECT 0xf4040010 +#define F0900_P1_QUAD_FROZEN 0xf4040008 +#define F0900_P1_QUAD_CORRECT 0xf4040004 +#define F0900_P1_DCCOMP_SLOW 0xf4040002 +#define F0900_P1_IQMISM_SLOW 0xf4040001 + +/*P1_AGC1CN*/ +#define R0900_P1_AGC1CN 0xf406 +#define F0900_P1_AGC1_LOCKED 0xf4060080 +#define F0900_P1_AGC1_OVERFLOW 0xf4060040 +#define F0900_P1_AGC1_NOSLOWLK 0xf4060020 +#define F0900_P1_AGC1_MINPOWER 0xf4060010 +#define F0900_P1_AGCOUT_FAST 0xf4060008 +#define F0900_P1_AGCIQ_BETA 0xf4060007 + +/*P1_AGC1REF*/ +#define R0900_P1_AGC1REF 0xf407 +#define F0900_P1_AGCIQ_REF 0xf40700ff + +/*P1_IDCCOMP*/ +#define R0900_P1_IDCCOMP 0xf408 +#define F0900_P1_IAVERAGE_ADJ 0xf40801ff + +/*P1_QDCCOMP*/ +#define R0900_P1_QDCCOMP 0xf409 +#define F0900_P1_QAVERAGE_ADJ 0xf40901ff + +/*P1_POWERI*/ +#define R0900_P1_POWERI 0xf40a +#define F0900_P1_POWER_I 0xf40a00ff + +/*P1_POWERQ*/ +#define R0900_P1_POWERQ 0xf40b +#define F0900_P1_POWER_Q 0xf40b00ff + +/*P1_AGC1AMM*/ +#define R0900_P1_AGC1AMM 0xf40c +#define F0900_P1_AMM_VALUE 0xf40c00ff + +/*P1_AGC1QUAD*/ +#define R0900_P1_AGC1QUAD 0xf40d +#define F0900_P1_QUAD_VALUE 0xf40d01ff + +/*P1_AGCIQIN1*/ +#define R0900_P1_AGCIQIN1 0xf40e +#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff + +/*P1_AGCIQIN0*/ +#define R0900_P1_AGCIQIN0 0xf40f +#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff + +/*P1_DEMOD*/ +#define R0900_P1_DEMOD 0xf410 +#define F0900_P1_DEMOD_STOP 0xf4100040 +#define F0900_P1_SPECINV_CONTROL 0xf4100030 +#define F0900_P1_FORCE_ENASAMP 0xf4100008 +#define F0900_P1_MANUAL_ROLLOFF 0xf4100004 +#define F0900_P1_ROLLOFF_CONTROL 0xf4100003 + +/*P1_DMDMODCOD*/ +#define R0900_P1_DMDMODCOD 0xf411 +#define F0900_P1_MANUAL_MODCOD 0xf4110080 +#define F0900_P1_DEMOD_MODCOD 0xf411007c +#define F0900_P1_DEMOD_TYPE 0xf4110003 + +/*P1_DSTATUS*/ +#define R0900_P1_DSTATUS 0xf412 +#define F0900_P1_CAR_LOCK 0xf4120080 +#define F0900_P1_TMGLOCK_QUALITY 0xf4120060 +#define F0900_P1_SDVBS1_ENABLE 0xf4120010 +#define F0900_P1_LOCK_DEFINITIF 0xf4120008 +#define F0900_P1_TIMING_IS_LOCKED 0xf4120004 +#define F0900_P1_COARSE_TMGLOCK 0xf4120002 +#define F0900_P1_COARSE_CARLOCK 0xf4120001 + +/*P1_DSTATUS2*/ +#define R0900_P1_DSTATUS2 0xf413 +#define F0900_P1_DEMOD_DELOCK 0xf4130080 +#define F0900_P1_DEMOD_TIMEOUT 0xf4130040 +#define F0900_P1_MODCODRQ_SYNCTAG 0xf4130020 +#define F0900_P1_POLYPH_SATEVENT 0xf4130010 +#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008 +#define F0900_P1_AGC2_OVERFLOW 0xf4130004 +#define F0900_P1_CFR_OVERFLOW 0xf4130002 +#define F0900_P1_GAMMA_OVERUNDER 0xf4130001 + +/*P1_DMDCFGMD*/ +#define R0900_P1_DMDCFGMD 0xf414 +#define F0900_P1_DVBS2_ENABLE 0xf4140080 +#define F0900_P1_DVBS1_ENABLE 0xf4140040 +#define F0900_P1_CFR_AUTOSCAN 0xf4140020 +#define F0900_P1_SCAN_ENABLE 0xf4140010 +#define F0900_P1_TUN_AUTOSCAN 0xf4140008 +#define F0900_P1_NOFORCE_RELOCK 0xf4140004 +#define F0900_P1_TUN_RNG 0xf4140003 + +/*P1_DMDCFG2*/ +#define R0900_P1_DMDCFG2 0xf415 +#define F0900_P1_AGC1_WAITLOCK 0xf4150080 +#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040 +#define F0900_P1_OVERFLOW_TIMEOUT 0xf4150020 +#define F0900_P1_SCANFAIL_TIMEOUT 0xf4150010 +#define F0900_P1_DMDTOUT_BACK 0xf4150008 +#define F0900_P1_CARLOCK_S1ENABLE 0xf4150004 +#define F0900_P1_COARSE_LK3MODE 0xf4150002 +#define F0900_P1_COARSE_LK2MODE 0xf4150001 + +/*P1_DMDISTATE*/ +#define R0900_P1_DMDISTATE 0xf416 +#define F0900_P1_I2C_NORESETDMODE 0xf4160080 +#define F0900_P1_FORCE_ETAPED 0xf4160040 +#define F0900_P1_SDMDRST_DIRCLK 0xf4160020 +#define F0900_P1_I2C_DEMOD_MODE 0xf416001f + +/*P1_DMDT0M*/ +#define R0900_P1_DMDT0M 0xf417 +#define F0900_P1_DMDT0_MIN 0xf41700ff + +/*P1_DMDSTATE*/ +#define R0900_P1_DMDSTATE 0xf41b +#define F0900_P1_DEMOD_LOCKED 0xf41b0080 +#define F0900_P1_HEADER_MODE 0xf41b0060 +#define F0900_P1_DEMOD_MODE 0xf41b001f + +/*P1_DMDFLYW*/ +#define R0900_P1_DMDFLYW 0xf41c +#define F0900_P1_I2C_IRQVAL 0xf41c00f0 +#define F0900_P1_FLYWHEEL_CPT 0xf41c000f + +/*P1_DSTATUS3*/ +#define R0900_P1_DSTATUS3 0xf41d +#define F0900_P1_CFR_ZIGZAG 0xf41d0080 +#define F0900_P1_DEMOD_CFGMODE 0xf41d0060 +#define F0900_P1_GAMMA_LOWBAUDRATE 0xf41d0010 +#define F0900_P1_RELOCK_MODE 0xf41d0008 +#define F0900_P1_DEMOD_FAIL 0xf41d0004 +#define F0900_P1_ETAPE1A_DVBXMEM 0xf41d0003 + +/*P1_DMDCFG3*/ +#define R0900_P1_DMDCFG3 0xf41e +#define F0900_P1_DVBS1_TMGWAIT 0xf41e0080 +#define F0900_P1_NO_BWCENTERING 0xf41e0040 +#define F0900_P1_INV_SEQSRCH 0xf41e0020 +#define F0900_P1_DIS_SFRUPLOW_TRK 0xf41e0010 +#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008 +#define F0900_P1_LOCKTIME_MODE 0xf41e0007 + +/*P1_DMDCFG4*/ +#define R0900_P1_DMDCFG4 0xf41f +#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008 +#define F0900_P1_DIS_CLKENABLE 0xf41f0004 +#define F0900_P1_DIS_HDRDIVLOCK 0xf41f0002 +#define F0900_P1_NO_TNRWBINIT 0xf41f0001 + +/*P1_CORRELMANT*/ +#define R0900_P1_CORRELMANT 0xf420 +#define F0900_P1_CORREL_MANT 0xf42000ff + +/*P1_CORRELABS*/ +#define R0900_P1_CORRELABS 0xf421 +#define F0900_P1_CORREL_ABS 0xf42100ff + +/*P1_CORRELEXP*/ +#define R0900_P1_CORRELEXP 0xf422 +#define F0900_P1_CORREL_ABSEXP 0xf42200f0 +#define F0900_P1_CORREL_EXP 0xf422000f + +/*P1_PLHMODCOD*/ +#define R0900_P1_PLHMODCOD 0xf424 +#define F0900_P1_SPECINV_DEMOD 0xf4240080 +#define F0900_P1_PLH_MODCOD 0xf424007c +#define F0900_P1_PLH_TYPE 0xf4240003 + +/*P1_AGCK32*/ +#define R0900_P1_AGCK32 0xf42b +#define F0900_P1_R3ADJOFF_32APSK 0xf42b0080 +#define F0900_P1_R2ADJOFF_32APSK 0xf42b0040 +#define F0900_P1_R1ADJOFF_32APSK 0xf42b0020 +#define F0900_P1_RADJ_32APSK 0xf42b001f + +/*P1_AGC2O*/ +#define R0900_P1_AGC2O 0xf42c +#define F0900_P1_AGC2REF_ADJUSTING 0xf42c0080 +#define F0900_P1_AGC2_COARSEFAST 0xf42c0040 +#define F0900_P1_AGC2_LKSQRT 0xf42c0020 +#define F0900_P1_AGC2_LKMODE 0xf42c0010 +#define F0900_P1_AGC2_LKEQUA 0xf42c0008 +#define F0900_P1_AGC2_COEF 0xf42c0007 + +/*P1_AGC2REF*/ +#define R0900_P1_AGC2REF 0xf42d +#define F0900_P1_AGC2_REF 0xf42d00ff + +/*P1_AGC1ADJ*/ +#define R0900_P1_AGC1ADJ 0xf42e +#define F0900_P1_AGC1ADJ_MANUAL 0xf42e0080 +#define F0900_P1_AGC1_ADJUSTED 0xf42e017f + +/*P1_AGC2I1*/ +#define R0900_P1_AGC2I1 0xf436 +#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff + +/*P1_AGC2I0*/ +#define R0900_P1_AGC2I0 0xf437 +#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff + +/*P1_CARCFG*/ +#define R0900_P1_CARCFG 0xf438 +#define F0900_P1_CFRUPLOW_AUTO 0xf4380080 +#define F0900_P1_CFRUPLOW_TEST 0xf4380040 +#define F0900_P1_EN_CAR2CENTER 0xf4380020 +#define F0900_P1_CARHDR_NODIV8 0xf4380010 +#define F0900_P1_I2C_ROTA 0xf4380008 +#define F0900_P1_ROTAON 0xf4380004 +#define F0900_P1_PH_DET_ALGO 0xf4380003 + +/*P1_ACLC*/ +#define R0900_P1_ACLC 0xf439 +#define F0900_P1_STOP_S2ALPHA 0xf43900c0 +#define F0900_P1_CAR_ALPHA_MANT 0xf4390030 +#define F0900_P1_CAR_ALPHA_EXP 0xf439000f + +/*P1_BCLC*/ +#define R0900_P1_BCLC 0xf43a +#define F0900_P1_STOP_S2BETA 0xf43a00c0 +#define F0900_P1_CAR_BETA_MANT 0xf43a0030 +#define F0900_P1_CAR_BETA_EXP 0xf43a000f + +/*P1_CARFREQ*/ +#define R0900_P1_CARFREQ 0xf43d +#define F0900_P1_KC_COARSE_EXP 0xf43d00f0 +#define F0900_P1_BETA_FREQ 0xf43d000f + +/*P1_CARHDR*/ +#define R0900_P1_CARHDR 0xf43e +#define F0900_P1_K_FREQ_HDR 0xf43e00ff + +/*P1_LDT*/ +#define R0900_P1_LDT 0xf43f +#define F0900_P1_CARLOCK_THRES 0xf43f01ff + +/*P1_LDT2*/ +#define R0900_P1_LDT2 0xf440 +#define F0900_P1_CARLOCK_THRES2 0xf44001ff + +/*P1_CFRICFG*/ +#define R0900_P1_CFRICFG 0xf441 +#define F0900_P1_CFRINIT_UNVALRNG 0xf4410080 +#define F0900_P1_CFRINIT_LUNVALCPT 0xf4410040 +#define F0900_P1_CFRINIT_ABORTDBL 0xf4410020 +#define F0900_P1_CFRINIT_ABORTPRED 0xf4410010 +#define F0900_P1_CFRINIT_UNVALSKIP 0xf4410008 +#define F0900_P1_CFRINIT_CSTINC 0xf4410004 +#define F0900_P1_NEG_CFRSTEP 0xf4410001 + +/*P1_CFRUP1*/ +#define R0900_P1_CFRUP1 0xf442 +#define F0900_P1_CFR_UP1 0xf44201ff + +/*P1_CFRUP0*/ +#define R0900_P1_CFRUP0 0xf443 +#define F0900_P1_CFR_UP0 0xf44300ff + +/*P1_CFRLOW1*/ +#define R0900_P1_CFRLOW1 0xf446 +#define F0900_P1_CFR_LOW1 0xf44601ff + +/*P1_CFRLOW0*/ +#define R0900_P1_CFRLOW0 0xf447 +#define F0900_P1_CFR_LOW0 0xf44700ff + +/*P1_CFRINIT1*/ +#define R0900_P1_CFRINIT1 0xf448 +#define F0900_P1_CFR_INIT1 0xf44801ff + +/*P1_CFRINIT0*/ +#define R0900_P1_CFRINIT0 0xf449 +#define F0900_P1_CFR_INIT0 0xf44900ff + +/*P1_CFRINC1*/ +#define R0900_P1_CFRINC1 0xf44a +#define F0900_P1_MANUAL_CFRINC 0xf44a0080 +#define F0900_P1_CFR_INC1 0xf44a017f + +/*P1_CFRINC0*/ +#define R0900_P1_CFRINC0 0xf44b +#define F0900_P1_CFR_INC0 0xf44b00f0 + +/*P1_CFR2*/ +#define R0900_P1_CFR2 0xf44c +#define F0900_P1_CAR_FREQ2 0xf44c01ff + +/*P1_CFR1*/ +#define R0900_P1_CFR1 0xf44d +#define F0900_P1_CAR_FREQ1 0xf44d00ff + +/*P1_CFR0*/ +#define R0900_P1_CFR0 0xf44e +#define F0900_P1_CAR_FREQ0 0xf44e00ff + +/*P1_LDI*/ +#define R0900_P1_LDI 0xf44f +#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff + +/*P1_TMGCFG*/ +#define R0900_P1_TMGCFG 0xf450 +#define F0900_P1_TMGLOCK_BETA 0xf45000c0 +#define F0900_P1_NOTMG_GROUPDELAY 0xf4500020 +#define F0900_P1_DO_TIMING_CORR 0xf4500010 +#define F0900_P1_MANUAL_SCAN 0xf450000c +#define F0900_P1_TMG_MINFREQ 0xf4500003 + +/*P1_RTC*/ +#define R0900_P1_RTC 0xf451 +#define F0900_P1_TMGALPHA_EXP 0xf45100f0 +#define F0900_P1_TMGBETA_EXP 0xf451000f + +/*P1_RTCS2*/ +#define R0900_P1_RTCS2 0xf452 +#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0 +#define F0900_P1_TMGBETAS2_EXP 0xf452000f + +/*P1_TMGTHRISE*/ +#define R0900_P1_TMGTHRISE 0xf453 +#define F0900_P1_TMGLOCK_THRISE 0xf45300ff + +/*P1_TMGTHFALL*/ +#define R0900_P1_TMGTHFALL 0xf454 +#define F0900_P1_TMGLOCK_THFALL 0xf45400ff + +/*P1_SFRUPRATIO*/ +#define R0900_P1_SFRUPRATIO 0xf455 +#define F0900_P1_SFR_UPRATIO 0xf45500ff + +/*P1_SFRLOWRATIO*/ +#define R0900_P1_SFRLOWRATIO 0xf456 +#define F0900_P1_SFR_LOWRATIO 0xf45600ff + +/*P1_KREFTMG*/ +#define R0900_P1_KREFTMG 0xf458 +#define F0900_P1_KREF_TMG 0xf45800ff + +/*P1_SFRSTEP*/ +#define R0900_P1_SFRSTEP 0xf459 +#define F0900_P1_SFR_SCANSTEP 0xf45900f0 +#define F0900_P1_SFR_CENTERSTEP 0xf459000f + +/*P1_TMGCFG2*/ +#define R0900_P1_TMGCFG2 0xf45a +#define F0900_P1_DIS_AUTOSAMP 0xf45a0008 +#define F0900_P1_SCANINIT_QUART 0xf45a0004 +#define F0900_P1_NOTMG_DVBS1DERAT 0xf45a0002 +#define F0900_P1_SFRRATIO_FINE 0xf45a0001 + +/*P1_SFRINIT1*/ +#define R0900_P1_SFRINIT1 0xf45e +#define F0900_P1_SFR_INIT1 0xf45e00ff + +/*P1_SFRINIT0*/ +#define R0900_P1_SFRINIT0 0xf45f +#define F0900_P1_SFR_INIT0 0xf45f00ff + +/*P1_SFRUP1*/ +#define R0900_P1_SFRUP1 0xf460 +#define F0900_P1_AUTO_GUP 0xf4600080 +#define F0900_P1_SYMB_FREQ_UP1 0xf460007f + +/*P1_SFRUP0*/ +#define R0900_P1_SFRUP0 0xf461 +#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff + +/*P1_SFRLOW1*/ +#define R0900_P1_SFRLOW1 0xf462 +#define F0900_P1_AUTO_GLOW 0xf4620080 +#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f + +/*P1_SFRLOW0*/ +#define R0900_P1_SFRLOW0 0xf463 +#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff + +/*P1_SFR3*/ +#define R0900_P1_SFR3 0xf464 +#define F0900_P1_SYMB_FREQ3 0xf46400ff + +/*P1_SFR2*/ +#define R0900_P1_SFR2 0xf465 +#define F0900_P1_SYMB_FREQ2 0xf46500ff + +/*P1_SFR1*/ +#define R0900_P1_SFR1 0xf466 +#define F0900_P1_SYMB_FREQ1 0xf46600ff + +/*P1_SFR0*/ +#define R0900_P1_SFR0 0xf467 +#define F0900_P1_SYMB_FREQ0 0xf46700ff + +/*P1_TMGREG2*/ +#define R0900_P1_TMGREG2 0xf468 +#define F0900_P1_TMGREG2 0xf46800ff + +/*P1_TMGREG1*/ +#define R0900_P1_TMGREG1 0xf469 +#define F0900_P1_TMGREG1 0xf46900ff + +/*P1_TMGREG0*/ +#define R0900_P1_TMGREG0 0xf46a +#define F0900_P1_TMGREG0 0xf46a00ff + +/*P1_TMGLOCK1*/ +#define R0900_P1_TMGLOCK1 0xf46b +#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff + +/*P1_TMGLOCK0*/ +#define R0900_P1_TMGLOCK0 0xf46c +#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff + +/*P1_TMGOBS*/ +#define R0900_P1_TMGOBS 0xf46d +#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0 +#define F0900_P1_SCAN_SIGN 0xf46d0030 +#define F0900_P1_TMG_SCANNING 0xf46d0008 +#define F0900_P1_CHCENTERING_MODE 0xf46d0004 +#define F0900_P1_TMG_SCANFAIL 0xf46d0002 + +/*P1_EQUALCFG*/ +#define R0900_P1_EQUALCFG 0xf46f +#define F0900_P1_NOTMG_NEGALWAIT 0xf46f0080 +#define F0900_P1_EQUAL_ON 0xf46f0040 +#define F0900_P1_SEL_EQUALCOR 0xf46f0038 +#define F0900_P1_MU_EQUALDFE 0xf46f0007 + +/*P1_EQUAI1*/ +#define R0900_P1_EQUAI1 0xf470 +#define F0900_P1_EQUA_ACCI1 0xf47001ff + +/*P1_EQUAQ1*/ +#define R0900_P1_EQUAQ1 0xf471 +#define F0900_P1_EQUA_ACCQ1 0xf47101ff + +/*P1_EQUAI2*/ +#define R0900_P1_EQUAI2 0xf472 +#define F0900_P1_EQUA_ACCI2 0xf47201ff + +/*P1_EQUAQ2*/ +#define R0900_P1_EQUAQ2 0xf473 +#define F0900_P1_EQUA_ACCQ2 0xf47301ff + +/*P1_EQUAI3*/ +#define R0900_P1_EQUAI3 0xf474 +#define F0900_P1_EQUA_ACCI3 0xf47401ff + +/*P1_EQUAQ3*/ +#define R0900_P1_EQUAQ3 0xf475 +#define F0900_P1_EQUA_ACCQ3 0xf47501ff + +/*P1_EQUAI4*/ +#define R0900_P1_EQUAI4 0xf476 +#define F0900_P1_EQUA_ACCI4 0xf47601ff + +/*P1_EQUAQ4*/ +#define R0900_P1_EQUAQ4 0xf477 +#define F0900_P1_EQUA_ACCQ4 0xf47701ff + +/*P1_EQUAI5*/ +#define R0900_P1_EQUAI5 0xf478 +#define F0900_P1_EQUA_ACCI5 0xf47801ff + +/*P1_EQUAQ5*/ +#define R0900_P1_EQUAQ5 0xf479 +#define F0900_P1_EQUA_ACCQ5 0xf47901ff + +/*P1_EQUAI6*/ +#define R0900_P1_EQUAI6 0xf47a +#define F0900_P1_EQUA_ACCI6 0xf47a01ff + +/*P1_EQUAQ6*/ +#define R0900_P1_EQUAQ6 0xf47b +#define F0900_P1_EQUA_ACCQ6 0xf47b01ff + +/*P1_EQUAI7*/ +#define R0900_P1_EQUAI7 0xf47c +#define F0900_P1_EQUA_ACCI7 0xf47c01ff + +/*P1_EQUAQ7*/ +#define R0900_P1_EQUAQ7 0xf47d +#define F0900_P1_EQUA_ACCQ7 0xf47d01ff + +/*P1_EQUAI8*/ +#define R0900_P1_EQUAI8 0xf47e +#define F0900_P1_EQUA_ACCI8 0xf47e01ff + +/*P1_EQUAQ8*/ +#define R0900_P1_EQUAQ8 0xf47f +#define F0900_P1_EQUA_ACCQ8 0xf47f01ff + +/*P1_NNOSDATAT1*/ +#define R0900_P1_NNOSDATAT1 0xf480 +#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff + +/*P1_NNOSDATAT0*/ +#define R0900_P1_NNOSDATAT0 0xf481 +#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff + +/*P1_NNOSDATA1*/ +#define R0900_P1_NNOSDATA1 0xf482 +#define F0900_P1_NOSDATA_NORMED1 0xf48200ff + +/*P1_NNOSDATA0*/ +#define R0900_P1_NNOSDATA0 0xf483 +#define F0900_P1_NOSDATA_NORMED0 0xf48300ff + +/*P1_NNOSPLHT1*/ +#define R0900_P1_NNOSPLHT1 0xf484 +#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff + +/*P1_NNOSPLHT0*/ +#define R0900_P1_NNOSPLHT0 0xf485 +#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff + +/*P1_NNOSPLH1*/ +#define R0900_P1_NNOSPLH1 0xf486 +#define F0900_P1_NOSPLH_NORMED1 0xf48600ff + +/*P1_NNOSPLH0*/ +#define R0900_P1_NNOSPLH0 0xf487 +#define F0900_P1_NOSPLH_NORMED0 0xf48700ff + +/*P1_NOSDATAT1*/ +#define R0900_P1_NOSDATAT1 0xf488 +#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff + +/*P1_NOSDATAT0*/ +#define R0900_P1_NOSDATAT0 0xf489 +#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff + +/*P1_NOSDATA1*/ +#define R0900_P1_NOSDATA1 0xf48a +#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff + +/*P1_NOSDATA0*/ +#define R0900_P1_NOSDATA0 0xf48b +#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff + +/*P1_NOSPLHT1*/ +#define R0900_P1_NOSPLHT1 0xf48c +#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff + +/*P1_NOSPLHT0*/ +#define R0900_P1_NOSPLHT0 0xf48d +#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff + +/*P1_NOSPLH1*/ +#define R0900_P1_NOSPLH1 0xf48e +#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff + +/*P1_NOSPLH0*/ +#define R0900_P1_NOSPLH0 0xf48f +#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff + +/*P1_CAR2CFG*/ +#define R0900_P1_CAR2CFG 0xf490 +#define F0900_P1_DESCRAMB_OFF 0xf4900080 +#define F0900_P1_PN4_SELECT 0xf4900040 +#define F0900_P1_CFR2_STOPDVBS1 0xf4900020 +#define F0900_P1_STOP_CFR2UPDATE 0xf4900010 +#define F0900_P1_STOP_NCO2UPDATE 0xf4900008 +#define F0900_P1_ROTA2ON 0xf4900004 +#define F0900_P1_PH_DET_ALGO2 0xf4900003 + +/*P1_ACLC2*/ +#define R0900_P1_ACLC2 0xf491 +#define F0900_P1_CAR2_PUNCT_ADERAT 0xf4910040 +#define F0900_P1_CAR2_ALPHA_MANT 0xf4910030 +#define F0900_P1_CAR2_ALPHA_EXP 0xf491000f + +/*P1_BCLC2*/ +#define R0900_P1_BCLC2 0xf492 +#define F0900_P1_DVBS2_NIP 0xf4920080 +#define F0900_P1_CAR2_PUNCT_BDERAT 0xf4920040 +#define F0900_P1_CAR2_BETA_MANT 0xf4920030 +#define F0900_P1_CAR2_BETA_EXP 0xf492000f + +/*P1_CFR22*/ +#define R0900_P1_CFR22 0xf493 +#define F0900_P1_CAR2_FREQ2 0xf49301ff + +/*P1_CFR21*/ +#define R0900_P1_CFR21 0xf494 +#define F0900_P1_CAR2_FREQ1 0xf49400ff + +/*P1_CFR20*/ +#define R0900_P1_CFR20 0xf495 +#define F0900_P1_CAR2_FREQ0 0xf49500ff + +/*P1_ACLC2S2Q*/ +#define R0900_P1_ACLC2S2Q 0xf497 +#define F0900_P1_ENAB_SPSKSYMB 0xf4970080 +#define F0900_P1_CAR2S2_QADERAT 0xf4970040 +#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030 +#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f + +/*P1_ACLC2S28*/ +#define R0900_P1_ACLC2S28 0xf498 +#define F0900_P1_OLDI3Q_MODE 0xf4980080 +#define F0900_P1_CAR2S2_8ADERAT 0xf4980040 +#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030 +#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f + +/*P1_ACLC2S216A*/ +#define R0900_P1_ACLC2S216A 0xf499 +#define F0900_P1_CAR2S2_16ADERAT 0xf4990040 +#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030 +#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f + +/*P1_ACLC2S232A*/ +#define R0900_P1_ACLC2S232A 0xf49a +#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040 +#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030 +#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f + +/*P1_BCLC2S2Q*/ +#define R0900_P1_BCLC2S2Q 0xf49c +#define F0900_P1_DVBS2S2Q_NIP 0xf49c0080 +#define F0900_P1_CAR2S2_QBDERAT 0xf49c0040 +#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030 +#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f + +/*P1_BCLC2S28*/ +#define R0900_P1_BCLC2S28 0xf49d +#define F0900_P1_DVBS2S28_NIP 0xf49d0080 +#define F0900_P1_CAR2S2_8BDERAT 0xf49d0040 +#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030 +#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f + +/*P1_BCLC2S216A*/ +#define R0900_P1_BCLC2S216A 0xf49e +#define F0900_P1_DVBS2S216A_NIP 0xf49e0080 +#define F0900_P1_CAR2S2_16BDERAT 0xf49e0040 +#define F0900_P1_CAR2S2_16A_BETA_M 0xf49e0030 +#define F0900_P1_CAR2S2_16A_BETA_E 0xf49e000f + +/*P1_BCLC2S232A*/ +#define R0900_P1_BCLC2S232A 0xf49f +#define F0900_P1_DVBS2S232A_NIP 0xf49f0080 +#define F0900_P1_CAR2S2_32BDERAT 0xf49f0040 +#define F0900_P1_CAR2S2_32A_BETA_M 0xf49f0030 +#define F0900_P1_CAR2S2_32A_BETA_E 0xf49f000f + +/*P1_PLROOT2*/ +#define R0900_P1_PLROOT2 0xf4ac +#define F0900_P1_SHORTFR_DISABLE 0xf4ac0080 +#define F0900_P1_LONGFR_DISABLE 0xf4ac0040 +#define F0900_P1_DUMMYPL_DISABLE 0xf4ac0020 +#define F0900_P1_SHORTFR_AVOID 0xf4ac0010 +#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c +#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003 + +/*P1_PLROOT1*/ +#define R0900_P1_PLROOT1 0xf4ad +#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff + +/*P1_PLROOT0*/ +#define R0900_P1_PLROOT0 0xf4ae +#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff + +/*P1_MODCODLST0*/ +#define R0900_P1_MODCODLST0 0xf4b0 +#define F0900_P1_EN_TOKEN31 0xf4b00080 +#define F0900_P1_SYNCTAG_SELECT 0xf4b00040 +#define F0900_P1_MODCODRQ_MODE 0xf4b00030 + +/*P1_MODCODLST1*/ +#define R0900_P1_MODCODLST1 0xf4b1 +#define F0900_P1_DIS_MODCOD29 0xf4b100f0 +#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f + +/*P1_MODCODLST2*/ +#define R0900_P1_MODCODLST2 0xf4b2 +#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0 +#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f + +/*P1_MODCODLST3*/ +#define R0900_P1_MODCODLST3 0xf4b3 +#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0 +#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f + +/*P1_MODCODLST4*/ +#define R0900_P1_MODCODLST4 0xf4b4 +#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0 +#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f + +/*P1_MODCODLST5*/ +#define R0900_P1_MODCODLST5 0xf4b5 +#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0 +#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f + +/*P1_MODCODLST6*/ +#define R0900_P1_MODCODLST6 0xf4b6 +#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0 +#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f + +/*P1_MODCODLST7*/ +#define R0900_P1_MODCODLST7 0xf4b7 +#define F0900_P1_DIS_8P_9_10 0xf4b700f0 +#define F0900_P1_DIS_8P_8_9 0xf4b7000f + +/*P1_MODCODLST8*/ +#define R0900_P1_MODCODLST8 0xf4b8 +#define F0900_P1_DIS_8P_5_6 0xf4b800f0 +#define F0900_P1_DIS_8P_3_4 0xf4b8000f + +/*P1_MODCODLST9*/ +#define R0900_P1_MODCODLST9 0xf4b9 +#define F0900_P1_DIS_8P_2_3 0xf4b900f0 +#define F0900_P1_DIS_8P_3_5 0xf4b9000f + +/*P1_MODCODLSTA*/ +#define R0900_P1_MODCODLSTA 0xf4ba +#define F0900_P1_DIS_QP_9_10 0xf4ba00f0 +#define F0900_P1_DIS_QP_8_9 0xf4ba000f + +/*P1_MODCODLSTB*/ +#define R0900_P1_MODCODLSTB 0xf4bb +#define F0900_P1_DIS_QP_5_6 0xf4bb00f0 +#define F0900_P1_DIS_QP_4_5 0xf4bb000f + +/*P1_MODCODLSTC*/ +#define R0900_P1_MODCODLSTC 0xf4bc +#define F0900_P1_DIS_QP_3_4 0xf4bc00f0 +#define F0900_P1_DIS_QP_2_3 0xf4bc000f + +/*P1_MODCODLSTD*/ +#define R0900_P1_MODCODLSTD 0xf4bd +#define F0900_P1_DIS_QP_3_5 0xf4bd00f0 +#define F0900_P1_DIS_QP_1_2 0xf4bd000f + +/*P1_MODCODLSTE*/ +#define R0900_P1_MODCODLSTE 0xf4be +#define F0900_P1_DIS_QP_2_5 0xf4be00f0 +#define F0900_P1_DIS_QP_1_3 0xf4be000f + +/*P1_MODCODLSTF*/ +#define R0900_P1_MODCODLSTF 0xf4bf +#define F0900_P1_DIS_QP_1_4 0xf4bf00f0 +#define F0900_P1_DDEMOD_SET 0xf4bf0002 +#define F0900_P1_DDEMOD_MASK 0xf4bf0001 + +/*P1_DMDRESCFG*/ +#define R0900_P1_DMDRESCFG 0xf4c6 +#define F0900_P1_DMDRES_RESET 0xf4c60080 +#define F0900_P1_DMDRES_NOISESQR 0xf4c60010 +#define F0900_P1_DMDRES_STRALL 0xf4c60008 +#define F0900_P1_DMDRES_NEWONLY 0xf4c60004 +#define F0900_P1_DMDRES_NOSTORE 0xf4c60002 +#define F0900_P1_DMDRES_AGC2MEM 0xf4c60001 + +/*P1_DMDRESADR*/ +#define R0900_P1_DMDRESADR 0xf4c7 +#define F0900_P1_SUSP_PREDCANAL 0xf4c70080 +#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040 +#define F0900_P1_DMDRES_MEMFULL 0xf4c70030 +#define F0900_P1_DMDRES_RESNBR 0xf4c7000f + +/*P1_DMDRESDATA7*/ +#define R0900_P1_DMDRESDATA7 0xf4c8 +#define F0900_P1_DMDRES_DATA7 0xf4c800ff + +/*P1_DMDRESDATA6*/ +#define R0900_P1_DMDRESDATA6 0xf4c9 +#define F0900_P1_DMDRES_DATA6 0xf4c900ff + +/*P1_DMDRESDATA5*/ +#define R0900_P1_DMDRESDATA5 0xf4ca +#define F0900_P1_DMDRES_DATA5 0xf4ca00ff + +/*P1_DMDRESDATA4*/ +#define R0900_P1_DMDRESDATA4 0xf4cb +#define F0900_P1_DMDRES_DATA4 0xf4cb00ff + +/*P1_DMDRESDATA3*/ +#define R0900_P1_DMDRESDATA3 0xf4cc +#define F0900_P1_DMDRES_DATA3 0xf4cc00ff + +/*P1_DMDRESDATA2*/ +#define R0900_P1_DMDRESDATA2 0xf4cd +#define F0900_P1_DMDRES_DATA2 0xf4cd00ff + +/*P1_DMDRESDATA1*/ +#define R0900_P1_DMDRESDATA1 0xf4ce +#define F0900_P1_DMDRES_DATA1 0xf4ce00ff + +/*P1_DMDRESDATA0*/ +#define R0900_P1_DMDRESDATA0 0xf4cf +#define F0900_P1_DMDRES_DATA0 0xf4cf00ff + +/*P1_FFEI1*/ +#define R0900_P1_FFEI1 0xf4d0 +#define F0900_P1_FFE_ACCI1 0xf4d001ff + +/*P1_FFEQ1*/ +#define R0900_P1_FFEQ1 0xf4d1 +#define F0900_P1_FFE_ACCQ1 0xf4d101ff + +/*P1_FFEI2*/ +#define R0900_P1_FFEI2 0xf4d2 +#define F0900_P1_FFE_ACCI2 0xf4d201ff + +/*P1_FFEQ2*/ +#define R0900_P1_FFEQ2 0xf4d3 +#define F0900_P1_FFE_ACCQ2 0xf4d301ff + +/*P1_FFEI3*/ +#define R0900_P1_FFEI3 0xf4d4 +#define F0900_P1_FFE_ACCI3 0xf4d401ff + +/*P1_FFEQ3*/ +#define R0900_P1_FFEQ3 0xf4d5 +#define F0900_P1_FFE_ACCQ3 0xf4d501ff + +/*P1_FFEI4*/ +#define R0900_P1_FFEI4 0xf4d6 +#define F0900_P1_FFE_ACCI4 0xf4d601ff + +/*P1_FFEQ4*/ +#define R0900_P1_FFEQ4 0xf4d7 +#define F0900_P1_FFE_ACCQ4 0xf4d701ff + +/*P1_FFECFG*/ +#define R0900_P1_FFECFG 0xf4d8 +#define F0900_P1_EQUALFFE_ON 0xf4d80040 +#define F0900_P1_EQUAL_USEDSYMB 0xf4d80030 +#define F0900_P1_MU_EQUALFFE 0xf4d80007 + +/*P1_TNRCFG*/ +#define R0900_P1_TNRCFG 0xf4e0 +#define F0900_P1_TUN_ACKFAIL 0xf4e00080 +#define F0900_P1_TUN_TYPE 0xf4e00070 +#define F0900_P1_TUN_SECSTOP 0xf4e00008 +#define F0900_P1_TUN_VCOSRCH 0xf4e00004 +#define F0900_P1_TUN_MADDRESS 0xf4e00003 + +/*P1_TNRCFG2*/ +#define R0900_P1_TNRCFG2 0xf4e1 +#define F0900_P1_TUN_IQSWAP 0xf4e10080 +#define F0900_P1_STB6110_STEP2MHZ 0xf4e10040 +#define F0900_P1_STB6120_DBLI2C 0xf4e10020 +#define F0900_P1_DIS_FCCK 0xf4e10010 +#define F0900_P1_DIS_LPEN 0xf4e10008 +#define F0900_P1_DIS_BWCALC 0xf4e10004 +#define F0900_P1_SHORT_WAITSTATES 0xf4e10002 +#define F0900_P1_DIS_2BWAGC1 0xf4e10001 + +/*P1_TNRXTAL*/ +#define R0900_P1_TNRXTAL 0xf4e4 +#define F0900_P1_TUN_MCLKDECIMAL 0xf4e400e0 +#define F0900_P1_TUN_XTALFREQ 0xf4e4001f + +/*P1_TNRSTEPS*/ +#define R0900_P1_TNRSTEPS 0xf4e7 +#define F0900_P1_TUNER_BW1P6 0xf4e70080 +#define F0900_P1_BWINC_OFFSET 0xf4e70070 +#define F0900_P1_SOFTSTEP_RNG 0xf4e70008 +#define F0900_P1_TUN_BWOFFSET 0xf4e70107 + +/*P1_TNRGAIN*/ +#define R0900_P1_TNRGAIN 0xf4e8 +#define F0900_P1_TUN_KDIVEN 0xf4e800c0 +#define F0900_P1_STB6X00_OCK 0xf4e80030 +#define F0900_P1_TUN_GAIN 0xf4e8000f + +/*P1_TNRRF1*/ +#define R0900_P1_TNRRF1 0xf4e9 +#define F0900_P1_TUN_RFFREQ2 0xf4e900ff + +/*P1_TNRRF0*/ +#define R0900_P1_TNRRF0 0xf4ea +#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff + +/*P1_TNRBW*/ +#define R0900_P1_TNRBW 0xf4eb +#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0 +#define F0900_P1_TUN_BW 0xf4eb003f + +/*P1_TNRADJ*/ +#define R0900_P1_TNRADJ 0xf4ec +#define F0900_P1_STB61X0_RCLK 0xf4ec0080 +#define F0900_P1_STB61X0_CALTIME 0xf4ec0040 +#define F0900_P1_STB6X00_DLB 0xf4ec0038 +#define F0900_P1_STB6000_FCL 0xf4ec0007 + +/*P1_TNRCTL2*/ +#define R0900_P1_TNRCTL2 0xf4ed +#define F0900_P1_STB61X0_LCP1_RCCKOFF 0xf4ed0080 +#define F0900_P1_STB61X0_LCP0 0xf4ed0040 +#define F0900_P1_STB61X0_XTOUT_RFOUTS 0xf4ed0020 +#define F0900_P1_STB61X0_XTON_MCKDV 0xf4ed0010 +#define F0900_P1_STB61X0_CALOFF_DCOFF 0xf4ed0008 +#define F0900_P1_STB6110_LPT 0xf4ed0004 +#define F0900_P1_STB6110_RX 0xf4ed0002 +#define F0900_P1_STB6110_SYN 0xf4ed0001 + +/*P1_TNRCFG3*/ +#define R0900_P1_TNRCFG3 0xf4ee +#define F0900_P1_STB6120_DISCTRL1 0xf4ee0080 +#define F0900_P1_STB6120_INVORDER 0xf4ee0040 +#define F0900_P1_STB6120_ENCTRL6 0xf4ee0020 +#define F0900_P1_TUN_PLLFREQ 0xf4ee001c +#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003 + +/*P1_TNRLAUNCH*/ +#define R0900_P1_TNRLAUNCH 0xf4f0 + +/*P1_TNRLD*/ +#define R0900_P1_TNRLD 0xf4f0 +#define F0900_P1_TUNLD_VCOING 0xf4f00080 +#define F0900_P1_TUN_REG1FAIL 0xf4f00040 +#define F0900_P1_TUN_REG2FAIL 0xf4f00020 +#define F0900_P1_TUN_REG3FAIL 0xf4f00010 +#define F0900_P1_TUN_REG4FAIL 0xf4f00008 +#define F0900_P1_TUN_REG5FAIL 0xf4f00004 +#define F0900_P1_TUN_BWING 0xf4f00002 +#define F0900_P1_TUN_LOCKED 0xf4f00001 + +/*P1_TNROBSL*/ +#define R0900_P1_TNROBSL 0xf4f6 +#define F0900_P1_TUN_I2CABORTED 0xf4f60080 +#define F0900_P1_TUN_LPEN 0xf4f60040 +#define F0900_P1_TUN_FCCK 0xf4f60020 +#define F0900_P1_TUN_I2CLOCKED 0xf4f60010 +#define F0900_P1_TUN_PROGDONE 0xf4f6000c +#define F0900_P1_TUN_RFRESTE1 0xf4f60003 + +/*P1_TNRRESTE*/ +#define R0900_P1_TNRRESTE 0xf4f7 +#define F0900_P1_TUN_RFRESTE0 0xf4f700ff + +/*P1_SMAPCOEF7*/ +#define R0900_P1_SMAPCOEF7 0xf500 +#define F0900_P1_DIS_QSCALE 0xf5000080 +#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f + +/*P1_SMAPCOEF6*/ +#define R0900_P1_SMAPCOEF6 0xf501 +#define F0900_P1_DIS_NEWSCALE 0xf5010008 +#define F0900_P1_ADJ_8PSKLLR1 0xf5010004 +#define F0900_P1_OLD_8PSKLLR1 0xf5010002 +#define F0900_P1_DIS_AB8PSK 0xf5010001 + +/*P1_SMAPCOEF5*/ +#define R0900_P1_SMAPCOEF5 0xf502 +#define F0900_P1_DIS_8SCALE 0xf5020080 +#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f + +/*P1_DMDPLHSTAT*/ +#define R0900_P1_DMDPLHSTAT 0xf520 +#define F0900_P1_PLH_STATISTIC 0xf52000ff + +/*P1_LOCKTIME3*/ +#define R0900_P1_LOCKTIME3 0xf522 +#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff + +/*P1_LOCKTIME2*/ +#define R0900_P1_LOCKTIME2 0xf523 +#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff + +/*P1_LOCKTIME1*/ +#define R0900_P1_LOCKTIME1 0xf524 +#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff + +/*P1_LOCKTIME0*/ +#define R0900_P1_LOCKTIME0 0xf525 +#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff + +/*P1_VITSCALE*/ +#define R0900_P1_VITSCALE 0xf532 +#define F0900_P1_NVTH_NOSRANGE 0xf5320080 +#define F0900_P1_VERROR_MAXMODE 0xf5320040 +#define F0900_P1_KDIV_MODE 0xf5320030 +#define F0900_P1_NSLOWSN_LOCKED 0xf5320008 +#define F0900_P1_DELOCK_PRFLOSS 0xf5320004 +#define F0900_P1_DIS_RSFLOCK 0xf5320002 + +/*P1_FECM*/ +#define R0900_P1_FECM 0xf533 +#define F0900_P1_DSS_DVB 0xf5330080 +#define F0900_P1_DEMOD_BYPASS 0xf5330040 +#define F0900_P1_CMP_SLOWMODE 0xf5330020 +#define F0900_P1_DSS_SRCH 0xf5330010 +#define F0900_P1_DIFF_MODEVIT 0xf5330004 +#define F0900_P1_SYNCVIT 0xf5330002 +#define F0900_P1_IQINV 0xf5330001 + +/*P1_VTH12*/ +#define R0900_P1_VTH12 0xf534 +#define F0900_P1_VTH12 0xf53400ff + +/*P1_VTH23*/ +#define R0900_P1_VTH23 0xf535 +#define F0900_P1_VTH23 0xf53500ff + +/*P1_VTH34*/ +#define R0900_P1_VTH34 0xf536 +#define F0900_P1_VTH34 0xf53600ff + +/*P1_VTH56*/ +#define R0900_P1_VTH56 0xf537 +#define F0900_P1_VTH56 0xf53700ff + +/*P1_VTH67*/ +#define R0900_P1_VTH67 0xf538 +#define F0900_P1_VTH67 0xf53800ff + +/*P1_VTH78*/ +#define R0900_P1_VTH78 0xf539 +#define F0900_P1_VTH78 0xf53900ff + +/*P1_VITCURPUN*/ +#define R0900_P1_VITCURPUN 0xf53a +#define F0900_P1_VIT_MAPPING 0xf53a00e0 +#define F0900_P1_VIT_CURPUN 0xf53a001f + +/*P1_VERROR*/ +#define R0900_P1_VERROR 0xf53b +#define F0900_P1_REGERR_VIT 0xf53b00ff + +/*P1_PRVIT*/ +#define R0900_P1_PRVIT 0xf53c +#define F0900_P1_DIS_VTHLOCK 0xf53c0040 +#define F0900_P1_E7_8VIT 0xf53c0020 +#define F0900_P1_E6_7VIT 0xf53c0010 +#define F0900_P1_E5_6VIT 0xf53c0008 +#define F0900_P1_E3_4VIT 0xf53c0004 +#define F0900_P1_E2_3VIT 0xf53c0002 +#define F0900_P1_E1_2VIT 0xf53c0001 + +/*P1_VAVSRVIT*/ +#define R0900_P1_VAVSRVIT 0xf53d +#define F0900_P1_AMVIT 0xf53d0080 +#define F0900_P1_FROZENVIT 0xf53d0040 +#define F0900_P1_SNVIT 0xf53d0030 +#define F0900_P1_TOVVIT 0xf53d000c +#define F0900_P1_HYPVIT 0xf53d0003 + +/*P1_VSTATUSVIT*/ +#define R0900_P1_VSTATUSVIT 0xf53e +#define F0900_P1_VITERBI_ON 0xf53e0080 +#define F0900_P1_END_LOOPVIT 0xf53e0040 +#define F0900_P1_VITERBI_DEPRF 0xf53e0020 +#define F0900_P1_PRFVIT 0xf53e0010 +#define F0900_P1_LOCKEDVIT 0xf53e0008 +#define F0900_P1_VITERBI_DELOCK 0xf53e0004 +#define F0900_P1_VIT_DEMODSEL 0xf53e0002 +#define F0900_P1_VITERBI_COMPOUT 0xf53e0001 + +/*P1_VTHINUSE*/ +#define R0900_P1_VTHINUSE 0xf53f +#define F0900_P1_VIT_INUSE 0xf53f00ff + +/*P1_KDIV12*/ +#define R0900_P1_KDIV12 0xf540 +#define F0900_P1_KDIV12_MANUAL 0xf5400080 +#define F0900_P1_K_DIVIDER_12 0xf540007f + +/*P1_KDIV23*/ +#define R0900_P1_KDIV23 0xf541 +#define F0900_P1_KDIV23_MANUAL 0xf5410080 +#define F0900_P1_K_DIVIDER_23 0xf541007f + +/*P1_KDIV34*/ +#define R0900_P1_KDIV34 0xf542 +#define F0900_P1_KDIV34_MANUAL 0xf5420080 +#define F0900_P1_K_DIVIDER_34 0xf542007f + +/*P1_KDIV56*/ +#define R0900_P1_KDIV56 0xf543 +#define F0900_P1_KDIV56_MANUAL 0xf5430080 +#define F0900_P1_K_DIVIDER_56 0xf543007f + +/*P1_KDIV67*/ +#define R0900_P1_KDIV67 0xf544 +#define F0900_P1_KDIV67_MANUAL 0xf5440080 +#define F0900_P1_K_DIVIDER_67 0xf544007f + +/*P1_KDIV78*/ +#define R0900_P1_KDIV78 0xf545 +#define F0900_P1_KDIV78_MANUAL 0xf5450080 +#define F0900_P1_K_DIVIDER_78 0xf545007f + +/*P1_PDELCTRL1*/ +#define R0900_P1_PDELCTRL1 0xf550 +#define F0900_P1_INV_MISMASK 0xf5500080 +#define F0900_P1_FORCE_ACCEPTED 0xf5500040 +#define F0900_P1_FILTER_EN 0xf5500020 +#define F0900_P1_FORCE_PKTDELINUSE 0xf5500010 +#define F0900_P1_HYSTEN 0xf5500008 +#define F0900_P1_HYSTSWRST 0xf5500004 +#define F0900_P1_EN_MIS00 0xf5500002 +#define F0900_P1_ALGOSWRST 0xf5500001 + +/*P1_PDELCTRL2*/ +#define R0900_P1_PDELCTRL2 0xf551 +#define F0900_P1_FORCE_CONTINUOUS 0xf5510080 +#define F0900_P1_RESET_UPKO_COUNT 0xf5510040 +#define F0900_P1_USER_PKTDELIN_NB 0xf5510020 +#define F0900_P1_FORCE_LOCKED 0xf5510010 +#define F0900_P1_DATA_UNBBSCRAM 0xf5510008 +#define F0900_P1_FORCE_LONGPKT 0xf5510004 +#define F0900_P1_FRAME_MODE 0xf5510002 + +/*P1_HYSTTHRESH*/ +#define R0900_P1_HYSTTHRESH 0xf554 +#define F0900_P1_UNLCK_THRESH 0xf55400f0 +#define F0900_P1_DELIN_LCK_THRESH 0xf554000f + +/*P1_ISIENTRY*/ +#define R0900_P1_ISIENTRY 0xf55e +#define F0900_P1_ISI_ENTRY 0xf55e00ff + +/*P1_ISIBITENA*/ +#define R0900_P1_ISIBITENA 0xf55f +#define F0900_P1_ISI_BIT_EN 0xf55f00ff + +/*P1_MATSTR1*/ +#define R0900_P1_MATSTR1 0xf560 +#define F0900_P1_MATYPE_CURRENT1 0xf56000ff + +/*P1_MATSTR0*/ +#define R0900_P1_MATSTR0 0xf561 +#define F0900_P1_MATYPE_CURRENT0 0xf56100ff + +/*P1_UPLSTR1*/ +#define R0900_P1_UPLSTR1 0xf562 +#define F0900_P1_UPL_CURRENT1 0xf56200ff + +/*P1_UPLSTR0*/ +#define R0900_P1_UPLSTR0 0xf563 +#define F0900_P1_UPL_CURRENT0 0xf56300ff + +/*P1_DFLSTR1*/ +#define R0900_P1_DFLSTR1 0xf564 +#define F0900_P1_DFL_CURRENT1 0xf56400ff + +/*P1_DFLSTR0*/ +#define R0900_P1_DFLSTR0 0xf565 +#define F0900_P1_DFL_CURRENT0 0xf56500ff + +/*P1_SYNCSTR*/ +#define R0900_P1_SYNCSTR 0xf566 +#define F0900_P1_SYNC_CURRENT 0xf56600ff + +/*P1_SYNCDSTR1*/ +#define R0900_P1_SYNCDSTR1 0xf567 +#define F0900_P1_SYNCD_CURRENT1 0xf56700ff + +/*P1_SYNCDSTR0*/ +#define R0900_P1_SYNCDSTR0 0xf568 +#define F0900_P1_SYNCD_CURRENT0 0xf56800ff + +/*P1_PDELSTATUS1*/ +#define R0900_P1_PDELSTATUS1 0xf569 +#define F0900_P1_PKTDELIN_DELOCK 0xf5690080 +#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040 +#define F0900_P1_CONTINUOUS_STREAM 0xf5690020 +#define F0900_P1_UNACCEPTED_STREAM 0xf5690010 +#define F0900_P1_BCH_ERROR_FLAG 0xf5690008 +#define F0900_P1_BBHCRCKO 0xf5690004 +#define F0900_P1_PKTDELIN_LOCK 0xf5690002 +#define F0900_P1_FIRST_LOCK 0xf5690001 + +/*P1_PDELSTATUS2*/ +#define R0900_P1_PDELSTATUS2 0xf56a +#define F0900_P1_PKTDEL_DEMODSEL 0xf56a0080 +#define F0900_P1_FRAME_MODCOD 0xf56a007c +#define F0900_P1_FRAME_TYPE 0xf56a0003 + +/*P1_BBFCRCKO1*/ +#define R0900_P1_BBFCRCKO1 0xf56b +#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff + +/*P1_BBFCRCKO0*/ +#define R0900_P1_BBFCRCKO0 0xf56c +#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff + +/*P1_UPCRCKO1*/ +#define R0900_P1_UPCRCKO1 0xf56d +#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff + +/*P1_UPCRCKO0*/ +#define R0900_P1_UPCRCKO0 0xf56e +#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff + +/*P1_TSSTATEM*/ +#define R0900_P1_TSSTATEM 0xf570 +#define F0900_P1_TSDIL_ON 0xf5700080 +#define F0900_P1_TSSKIPRS_ON 0xf5700040 +#define F0900_P1_TSRS_ON 0xf5700020 +#define F0900_P1_TSDESCRAMB_ON 0xf5700010 +#define F0900_P1_TSFRAME_MODE 0xf5700008 +#define F0900_P1_TS_DISABLE 0xf5700004 +#define F0900_P1_TSACM_MODE 0xf5700002 +#define F0900_P1_TSOUT_NOSYNC 0xf5700001 + +/*P1_TSCFGH*/ +#define R0900_P1_TSCFGH 0xf572 +#define F0900_P1_TSFIFO_DVBCI 0xf5720080 +#define F0900_P1_TSFIFO_SERIAL 0xf5720040 +#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020 +#define F0900_P1_TSFIFO_DUTY50 0xf5720010 +#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008 +#define F0900_P1_TSFIFO_ERRMODE 0xf5720006 +#define F0900_P1_RST_HWARE 0xf5720001 + +/*P1_TSCFGM*/ +#define R0900_P1_TSCFGM 0xf573 +#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0 +#define F0900_P1_TSFIFO_PERMDATA 0xf5730020 +#define F0900_P1_TSFIFO_NONEWSGNL 0xf5730010 +#define F0900_P1_TSFIFO_BITSPEED 0xf5730008 +#define F0900_P1_NPD_SPECDVBS2 0xf5730004 +#define F0900_P1_TSFIFO_STOPCKDIS 0xf5730002 +#define F0900_P1_TSFIFO_INVDATA 0xf5730001 + +/*P1_TSCFGL*/ +#define R0900_P1_TSCFGL 0xf574 +#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0 +#define F0900_P1_BCHERROR_MODE 0xf5740030 +#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008 +#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004 +#define F0900_P1_TSFIFO_DPUNACT 0xf5740002 +#define F0900_P1_TSFIFO_NPDOFF 0xf5740001 + +/*P1_TSINSDELH*/ +#define R0900_P1_TSINSDELH 0xf576 +#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080 +#define F0900_P1_TSDEL_XXHEADER 0xf5760040 +#define F0900_P1_TSDEL_BBHEADER 0xf5760020 +#define F0900_P1_TSDEL_DATAFIELD 0xf5760010 +#define F0900_P1_TSINSDEL_ISCR 0xf5760008 +#define F0900_P1_TSINSDEL_NPD 0xf5760004 +#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002 +#define F0900_P1_TSINSDEL_CRC8 0xf5760001 + +/*P1_TSSPEED*/ +#define R0900_P1_TSSPEED 0xf580 +#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff + +/*P1_TSSTATUS*/ +#define R0900_P1_TSSTATUS 0xf581 +#define F0900_P1_TSFIFO_LINEOK 0xf5810080 +#define F0900_P1_TSFIFO_ERROR 0xf5810040 +#define F0900_P1_TSFIFO_DATA7 0xf5810020 +#define F0900_P1_TSFIFO_NOSYNC 0xf5810010 +#define F0900_P1_ISCR_INITIALIZED 0xf5810008 +#define F0900_P1_ISCR_UPDATED 0xf5810004 +#define F0900_P1_SOFFIFO_UNREGUL 0xf5810002 +#define F0900_P1_DIL_READY 0xf5810001 + +/*P1_TSSTATUS2*/ +#define R0900_P1_TSSTATUS2 0xf582 +#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080 +#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040 +#define F0900_P1_DILXX_RESET 0xf5820020 +#define F0900_P1_TSSERIAL_IMPOS 0xf5820010 +#define F0900_P1_TSFIFO_LINENOK 0xf5820008 +#define F0900_P1_BITSPEED_EVENT 0xf5820004 +#define F0900_P1_SCRAMBDETECT 0xf5820002 +#define F0900_P1_ULDTV67_FALSELOCK 0xf5820001 + +/*P1_TSBITRATE1*/ +#define R0900_P1_TSBITRATE1 0xf583 +#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff + +/*P1_TSBITRATE0*/ +#define R0900_P1_TSBITRATE0 0xf584 +#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff + +/*P1_ERRCTRL1*/ +#define R0900_P1_ERRCTRL1 0xf598 +#define F0900_P1_ERR_SOURCE1 0xf59800f0 +#define F0900_P1_NUM_EVENT1 0xf5980007 + +/*P1_ERRCNT12*/ +#define R0900_P1_ERRCNT12 0xf599 +#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080 +#define F0900_P1_ERR_CNT12 0xf599007f + +/*P1_ERRCNT11*/ +#define R0900_P1_ERRCNT11 0xf59a +#define F0900_P1_ERR_CNT11 0xf59a00ff + +/*P1_ERRCNT10*/ +#define R0900_P1_ERRCNT10 0xf59b +#define F0900_P1_ERR_CNT10 0xf59b00ff + +/*P1_ERRCTRL2*/ +#define R0900_P1_ERRCTRL2 0xf59c +#define F0900_P1_ERR_SOURCE2 0xf59c00f0 +#define F0900_P1_NUM_EVENT2 0xf59c0007 + +/*P1_ERRCNT22*/ +#define R0900_P1_ERRCNT22 0xf59d +#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080 +#define F0900_P1_ERR_CNT22 0xf59d007f + +/*P1_ERRCNT21*/ +#define R0900_P1_ERRCNT21 0xf59e +#define F0900_P1_ERR_CNT21 0xf59e00ff + +/*P1_ERRCNT20*/ +#define R0900_P1_ERRCNT20 0xf59f +#define F0900_P1_ERR_CNT20 0xf59f00ff + +/*P1_FECSPY*/ +#define R0900_P1_FECSPY 0xf5a0 +#define F0900_P1_SPY_ENABLE 0xf5a00080 +#define F0900_P1_NO_SYNCBYTE 0xf5a00040 +#define F0900_P1_SERIAL_MODE 0xf5a00020 +#define F0900_P1_UNUSUAL_PACKET 0xf5a00010 +#define F0900_P1_BER_PACKMODE 0xf5a00008 +#define F0900_P1_BERMETER_LMODE 0xf5a00002 +#define F0900_P1_BERMETER_RESET 0xf5a00001 + +/*P1_FSPYCFG*/ +#define R0900_P1_FSPYCFG 0xf5a1 +#define F0900_P1_FECSPY_INPUT 0xf5a100c0 +#define F0900_P1_RST_ON_ERROR 0xf5a10020 +#define F0900_P1_ONE_SHOT 0xf5a10010 +#define F0900_P1_I2C_MODE 0xf5a1000c +#define F0900_P1_SPY_HYSTERESIS 0xf5a10003 + +/*P1_FSPYDATA*/ +#define R0900_P1_FSPYDATA 0xf5a2 +#define F0900_P1_SPY_STUFFING 0xf5a20080 +#define F0900_P1_NOERROR_PKTJITTER 0xf5a20040 +#define F0900_P1_SPY_CNULLPKT 0xf5a20020 +#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f + +/*P1_FSPYOUT*/ +#define R0900_P1_FSPYOUT 0xf5a3 +#define F0900_P1_FSPY_DIRECT 0xf5a30080 +#define F0900_P1_SPY_OUTDATA_BUS 0xf5a30038 +#define F0900_P1_STUFF_MODE 0xf5a30007 + +/*P1_FSTATUS*/ +#define R0900_P1_FSTATUS 0xf5a4 +#define F0900_P1_SPY_ENDSIM 0xf5a40080 +#define F0900_P1_VALID_SIM 0xf5a40040 +#define F0900_P1_FOUND_SIGNAL 0xf5a40020 +#define F0900_P1_DSS_SYNCBYTE 0xf5a40010 +#define F0900_P1_RESULT_STATE 0xf5a4000f + +/*P1_FBERCPT4*/ +#define R0900_P1_FBERCPT4 0xf5a8 +#define F0900_P1_FBERMETER_CPT4 0xf5a800ff + +/*P1_FBERCPT3*/ +#define R0900_P1_FBERCPT3 0xf5a9 +#define F0900_P1_FBERMETER_CPT3 0xf5a900ff + +/*P1_FBERCPT2*/ +#define R0900_P1_FBERCPT2 0xf5aa +#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff + +/*P1_FBERCPT1*/ +#define R0900_P1_FBERCPT1 0xf5ab +#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff + +/*P1_FBERCPT0*/ +#define R0900_P1_FBERCPT0 0xf5ac +#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff + +/*P1_FBERERR2*/ +#define R0900_P1_FBERERR2 0xf5ad +#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff + +/*P1_FBERERR1*/ +#define R0900_P1_FBERERR1 0xf5ae +#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff + +/*P1_FBERERR0*/ +#define R0900_P1_FBERERR0 0xf5af +#define F0900_P1_FBERMETER_ERR0 0xf5af00ff + +/*P1_FSPYBER*/ +#define R0900_P1_FSPYBER 0xf5b2 +#define F0900_P1_FSPYOBS_XORREAD 0xf5b20040 +#define F0900_P1_FSPYBER_OBSMODE 0xf5b20020 +#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010 +#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008 +#define F0900_P1_FSPYBER_CTIME 0xf5b20007 + +/*RCCFGH*/ +#define R0900_RCCFGH 0xf600 +#define F0900_TSRCFIFO_DVBCI 0xf6000080 +#define F0900_TSRCFIFO_SERIAL 0xf6000040 +#define F0900_TSRCFIFO_DISABLE 0xf6000020 +#define F0900_TSFIFO_2TORC 0xf6000010 +#define F0900_TSRCFIFO_HSGNLOUT 0xf6000008 +#define F0900_TSRCFIFO_ERRMODE 0xf6000006 + +/*TSGENERAL*/ +#define R0900_TSGENERAL 0xf630 +#define F0900_TSFIFO_BCLK1ALL 0xf6300020 +#define F0900_MUXSTREAM_OUTMODE 0xf6300008 +#define F0900_TSFIFO_PERMPARAL 0xf6300006 +#define F0900_RST_REEDSOLO 0xf6300001 + +/*TSGENERAL1X*/ +#define R0900_TSGENERAL1X 0xf670 +#define F0900_TSFIFO1X_BCLK1ALL 0xf6700020 +#define F0900_MUXSTREAM1X_OUTMODE 0xf6700008 +#define F0900_TSFIFO1X_PERMPARAL 0xf6700006 +#define F0900_RST1X_REEDSOLO 0xf6700001 + +/*NBITER_NF4*/ +#define R0900_NBITER_NF4 0xfa03 +#define F0900_NBITER_NF_QP_1_2 0xfa0300ff + +/*NBITER_NF5*/ +#define R0900_NBITER_NF5 0xfa04 +#define F0900_NBITER_NF_QP_3_5 0xfa0400ff + +/*NBITER_NF6*/ +#define R0900_NBITER_NF6 0xfa05 +#define F0900_NBITER_NF_QP_2_3 0xfa0500ff + +/*NBITER_NF7*/ +#define R0900_NBITER_NF7 0xfa06 +#define F0900_NBITER_NF_QP_3_4 0xfa0600ff + +/*NBITER_NF8*/ +#define R0900_NBITER_NF8 0xfa07 +#define F0900_NBITER_NF_QP_4_5 0xfa0700ff + +/*NBITER_NF9*/ +#define R0900_NBITER_NF9 0xfa08 +#define F0900_NBITER_NF_QP_5_6 0xfa0800ff + +/*NBITER_NF10*/ +#define R0900_NBITER_NF10 0xfa09 +#define F0900_NBITER_NF_QP_8_9 0xfa0900ff + +/*NBITER_NF11*/ +#define R0900_NBITER_NF11 0xfa0a +#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff + +/*NBITER_NF12*/ +#define R0900_NBITER_NF12 0xfa0b +#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff + +/*NBITER_NF13*/ +#define R0900_NBITER_NF13 0xfa0c +#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff + +/*NBITER_NF14*/ +#define R0900_NBITER_NF14 0xfa0d +#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff + +/*NBITER_NF15*/ +#define R0900_NBITER_NF15 0xfa0e +#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff + +/*NBITER_NF16*/ +#define R0900_NBITER_NF16 0xfa0f +#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff + +/*NBITER_NF17*/ +#define R0900_NBITER_NF17 0xfa10 +#define F0900_NBITER_NF_8P_9_10 0xfa1000ff + +/*NBITERNOERR*/ +#define R0900_NBITERNOERR 0xfa3f +#define F0900_NBITER_STOP_CRIT 0xfa3f000f + +/*GAINLLR_NF4*/ +#define R0900_GAINLLR_NF4 0xfa43 +#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f + +/*GAINLLR_NF5*/ +#define R0900_GAINLLR_NF5 0xfa44 +#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f + +/*GAINLLR_NF6*/ +#define R0900_GAINLLR_NF6 0xfa45 +#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f + +/*GAINLLR_NF7*/ +#define R0900_GAINLLR_NF7 0xfa46 +#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f + +/*GAINLLR_NF8*/ +#define R0900_GAINLLR_NF8 0xfa47 +#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f + +/*GAINLLR_NF9*/ +#define R0900_GAINLLR_NF9 0xfa48 +#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f + +/*GAINLLR_NF10*/ +#define R0900_GAINLLR_NF10 0xfa49 +#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f + +/*GAINLLR_NF11*/ +#define R0900_GAINLLR_NF11 0xfa4a +#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f + +/*GAINLLR_NF12*/ +#define R0900_GAINLLR_NF12 0xfa4b +#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f + +/*GAINLLR_NF13*/ +#define R0900_GAINLLR_NF13 0xfa4c +#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f + +/*GAINLLR_NF14*/ +#define R0900_GAINLLR_NF14 0xfa4d +#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f + +/*GAINLLR_NF15*/ +#define R0900_GAINLLR_NF15 0xfa4e +#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f + +/*GAINLLR_NF16*/ +#define R0900_GAINLLR_NF16 0xfa4f +#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f + +/*GAINLLR_NF17*/ +#define R0900_GAINLLR_NF17 0xfa50 +#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f + +/*CFGEXT*/ +#define R0900_CFGEXT 0xfa80 +#define F0900_STAGMODE 0xfa800080 +#define F0900_BYPBCH 0xfa800040 +#define F0900_BYPLDPC 0xfa800020 +#define F0900_LDPCMODE 0xfa800010 +#define F0900_INVLLRSIGN 0xfa800008 +#define F0900_SHORTMULT 0xfa800004 +#define F0900_EXTERNTX 0xfa800001 + +/*GENCFG*/ +#define R0900_GENCFG 0xfa86 +#define F0900_BROADCAST 0xfa860010 +#define F0900_NOSHFRD2 0xfa860008 +#define F0900_BCHERRFLAG 0xfa860004 +#define F0900_PRIORITY 0xfa860002 +#define F0900_DDEMOD 0xfa860001 + +/*LDPCERR1*/ +#define R0900_LDPCERR1 0xfa96 +#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff + +/*LDPCERR0*/ +#define R0900_LDPCERR0 0xfa97 +#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff + +/*BCHERR*/ +#define R0900_BCHERR 0xfa98 +#define F0900_ERRORFLAG 0xfa980010 +#define F0900_BCH_ERRORS_COUNTER 0xfa98000f + +/*TSTRES0*/ +#define R0900_TSTRES0 0xff11 +#define F0900_FRESFEC 0xff110080 +#define F0900_FRESTS 0xff110040 +#define F0900_FRESVIT1 0xff110020 +#define F0900_FRESVIT2 0xff110010 +#define F0900_FRESSYM1 0xff110008 +#define F0900_FRESSYM2 0xff110004 +#define F0900_FRESMAS 0xff110002 +#define F0900_FRESINT 0xff110001 + +/*P2_TSTDISRX*/ +#define R0900_P2_TSTDISRX 0xff65 +#define F0900_P2_EN_DISRX 0xff650080 +#define F0900_P2_TST_CURRSRC 0xff650040 +#define F0900_P2_IN_DIGSIGNAL 0xff650020 +#define F0900_P2_HIZ_CURRENTSRC 0xff650010 +#define F0900_TST_P2_PIN_SELECT 0xff650008 +#define F0900_P2_TST_DISRX 0xff650007 + +/*P1_TSTDISRX*/ +#define R0900_P1_TSTDISRX 0xff67 +#define F0900_P1_EN_DISRX 0xff670080 +#define F0900_P1_TST_CURRSRC 0xff670040 +#define F0900_P1_IN_DIGSIGNAL 0xff670020 +#define F0900_P1_HIZ_CURRENTSRC 0xff670010 +#define F0900_TST_P1_PIN_SELECT 0xff670008 +#define F0900_P1_TST_DISRX 0xff670007 + +#define STV0900_NBREGS 684 +#define STV0900_NBFIELDS 1702 + +#endif + -- cgit v1.2.1 From db7a4843dbd10db48752ded4dba81dfb9f580861 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Tue, 3 Mar 2009 11:41:39 -0300 Subject: V4L/DVB (10802): Add more headers for ST STV0900 dual demodulator. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_init.h | 439 +++++++++++++++++++++++++++++ drivers/media/dvb/frontends/stv0900_priv.h | 430 ++++++++++++++++++++++++++++ 2 files changed, 869 insertions(+) create mode 100644 drivers/media/dvb/frontends/stv0900_init.h create mode 100644 drivers/media/dvb/frontends/stv0900_priv.h (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/stv0900_init.h b/drivers/media/dvb/frontends/stv0900_init.h new file mode 100644 index 000000000000..fa8dbe197bd6 --- /dev/null +++ b/drivers/media/dvb/frontends/stv0900_init.h @@ -0,0 +1,439 @@ +/* + * stv0900_init.h + * + * Driver for ST STV0900 satellite demodulator IC. + * + * Copyright (C) ST Microelectronics. + * Copyright (C) 2009 NetUP Inc. + * Copyright (C) 2009 Igor M. Liplianin + * + * 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 STV0900_INIT_H +#define STV0900_INIT_H + +#include "stv0900_priv.h" + +/* DVBS2 C/N Look-Up table */ +static const struct stv0900_table stv0900_s2_cn = { + 55, + { + { -30, 13348 }, /*C/N=-3dB*/ + { -20, 12640 }, /*C/N=-2dB*/ + { -10, 11883 }, /*C/N=-1dB*/ + { 0, 11101 }, /*C/N=-0dB*/ + { 5, 10718 }, /*C/N=0.5dB*/ + { 10, 10339 }, /*C/N=1.0dB*/ + { 15, 9947 }, /*C/N=1.5dB*/ + { 20, 9552 }, /*C/N=2.0dB*/ + { 25, 9183 }, /*C/N=2.5dB*/ + { 30, 8799 }, /*C/N=3.0dB*/ + { 35, 8422 }, /*C/N=3.5dB*/ + { 40, 8062 }, /*C/N=4.0dB*/ + { 45, 7707 }, /*C/N=4.5dB*/ + { 50, 7353 }, /*C/N=5.0dB*/ + { 55, 7025 }, /*C/N=5.5dB*/ + { 60, 6684 }, /*C/N=6.0dB*/ + { 65, 6331 }, /*C/N=6.5dB*/ + { 70, 6036 }, /*C/N=7.0dB*/ + { 75, 5727 }, /*C/N=7.5dB*/ + { 80, 5437 }, /*C/N=8.0dB*/ + { 85, 5164 }, /*C/N=8.5dB*/ + { 90, 4902 }, /*C/N=9.0dB*/ + { 95, 4653 }, /*C/N=9.5dB*/ + { 100, 4408 }, /*C/N=10.0dB*/ + { 105, 4187 }, /*C/N=10.5dB*/ + { 110, 3961 }, /*C/N=11.0dB*/ + { 115, 3751 }, /*C/N=11.5dB*/ + { 120, 3558 }, /*C/N=12.0dB*/ + { 125, 3368 }, /*C/N=12.5dB*/ + { 130, 3191 }, /*C/N=13.0dB*/ + { 135, 3017 }, /*C/N=13.5dB*/ + { 140, 2862 }, /*C/N=14.0dB*/ + { 145, 2710 }, /*C/N=14.5dB*/ + { 150, 2565 }, /*C/N=15.0dB*/ + { 160, 2300 }, /*C/N=16.0dB*/ + { 170, 2058 }, /*C/N=17.0dB*/ + { 180, 1849 }, /*C/N=18.0dB*/ + { 190, 1663 }, /*C/N=19.0dB*/ + { 200, 1495 }, /*C/N=20.0dB*/ + { 210, 1349 }, /*C/N=21.0dB*/ + { 220, 1222 }, /*C/N=22.0dB*/ + { 230, 1110 }, /*C/N=23.0dB*/ + { 240, 1011 }, /*C/N=24.0dB*/ + { 250, 925 }, /*C/N=25.0dB*/ + { 260, 853 }, /*C/N=26.0dB*/ + { 270, 789 }, /*C/N=27.0dB*/ + { 280, 734 }, /*C/N=28.0dB*/ + { 290, 690 }, /*C/N=29.0dB*/ + { 300, 650 }, /*C/N=30.0dB*/ + { 310, 619 }, /*C/N=31.0dB*/ + { 320, 593 }, /*C/N=32.0dB*/ + { 330, 571 }, /*C/N=33.0dB*/ + { 400, 498 }, /*C/N=40.0dB*/ + { 450, 484 }, /*C/N=45.0dB*/ + { 500, 481 } /*C/N=50.0dB*/ + } +}; + +/* RF level C/N Look-Up table */ +static const struct stv0900_table stv0900_rf = { + 14, + { + { -5, 0xCAA1 }, /*-5dBm*/ + { -10, 0xC229 }, /*-10dBm*/ + { -15, 0xBB08 }, /*-15dBm*/ + { -20, 0xB4BC }, /*-20dBm*/ + { -25, 0xAD5A }, /*-25dBm*/ + { -30, 0xA298 }, /*-30dBm*/ + { -35, 0x98A8 }, /*-35dBm*/ + { -40, 0x8389 }, /*-40dBm*/ + { -45, 0x59BE }, /*-45dBm*/ + { -50, 0x3A14 }, /*-50dBm*/ + { -55, 0x2D11 }, /*-55dBm*/ + { -60, 0x210D }, /*-60dBm*/ + { -65, 0xA14F }, /*-65dBm*/ + { -70, 0x7AA } /*-70dBm*/ + } +}; + +struct stv0900_car_loop_optim { + enum fe_stv0900_modcode modcode; + u8 car_loop_pilots_on_2; + u8 car_loop_pilots_off_2; + u8 car_loop_pilots_on_5; + u8 car_loop_pilots_off_5; + u8 car_loop_pilots_on_10; + u8 car_loop_pilots_off_10; + u8 car_loop_pilots_on_20; + u8 car_loop_pilots_off_20; + u8 car_loop_pilots_on_30; + u8 car_loop_pilots_off_30; + +}; + +struct stv0900_short_frames_car_loop_optim { + enum fe_stv0900_modulation modulation; + u8 car_loop_cut12_2; /* Cut 1.2, SR<=3msps */ + u8 car_loop_cut20_2; /* Cut 2.0, SR<3msps */ + u8 car_loop_cut12_5; /* Cut 1.2, 3 + * + * 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 STV0900_PRIV_H +#define STV0900_PRIV_H + +#include + +#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X)) +#define INRANGE(X, Y, Z) ((((X) <= (Y)) && ((Y) <= (Z))) \ + || (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0) + +#ifndef MAKEWORD +#define MAKEWORD(X, Y) (((X) << 8) + (Y)) +#endif + +#define LSB(X) (((X) & 0xFF)) +#define MSB(Y) (((Y) >> 8) & 0xFF) + +#ifndef TRUE +#define TRUE (1 == 1) +#endif +#ifndef FALSE +#define FALSE (!TRUE) +#endif + +#define dmd_reg(a, b, c) \ + do { \ + a = 0; \ + switch (demod) { \ + case STV0900_DEMOD_1: \ + default: \ + a = b; \ + break; \ + case STV0900_DEMOD_2: \ + a = c; \ + break; \ + } \ + } while (0) + +#define dmd_choose(a, b) (demod = STV0900_DEMOD_2 ? b : a)) + +extern int debug; + +#define dprintk(args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG args); \ + } while (0) + +#define STV0900_MAXLOOKUPSIZE 500 +#define STV0900_BLIND_SEARCH_AGC2_TH 700 + +/* One point of the lookup table */ +struct stv000_lookpoint { + s32 realval;/* real value */ + s32 regval;/* binary value */ +}; + +/* Lookup table definition */ +struct stv0900_table{ + s32 size;/* Size of the lookup table */ + struct stv000_lookpoint table[STV0900_MAXLOOKUPSIZE];/* Lookup table */ +}; + +enum fe_stv0900_error { + STV0900_NO_ERROR = 0, + STV0900_INVALID_HANDLE, + STV0900_BAD_PARAMETER, + STV0900_I2C_ERROR, + STV0900_SEARCH_FAILED, +}; + +enum fe_stv0900_clock_type { + STV0900_USE_REGISTERS_DEFAULT, + STV0900_SERIAL_PUNCT_CLOCK,/*Serial punctured clock */ + STV0900_SERIAL_CONT_CLOCK,/*Serial continues clock */ + STV0900_PARALLEL_PUNCT_CLOCK,/*Parallel punctured clock */ + STV0900_DVBCI_CLOCK/*Parallel continues clock : DVBCI */ +}; + +enum fe_stv0900_search_state { + STV0900_SEARCH = 0, + STV0900_PLH_DETECTED, + STV0900_DVBS2_FOUND, + STV0900_DVBS_FOUND + +}; + +enum fe_stv0900_ldpc_state { + STV0900_PATH1_OFF_PATH2_OFF = 0, + STV0900_PATH1_ON_PATH2_OFF = 1, + STV0900_PATH1_OFF_PATH2_ON = 2, + STV0900_PATH1_ON_PATH2_ON = 3 +}; + +enum fe_stv0900_signal_type { + STV0900_NOAGC1 = 0, + STV0900_AGC1OK, + STV0900_NOTIMING, + STV0900_ANALOGCARRIER, + STV0900_TIMINGOK, + STV0900_NOAGC2, + STV0900_AGC2OK, + STV0900_NOCARRIER, + STV0900_CARRIEROK, + STV0900_NODATA, + STV0900_DATAOK, + STV0900_OUTOFRANGE, + STV0900_RANGEOK +}; + +enum fe_stv0900_demod_num { + STV0900_DEMOD_1, + STV0900_DEMOD_2 +}; + +enum fe_stv0900_tracking_standard { + STV0900_DVBS1_STANDARD,/* Found Standard*/ + STV0900_DVBS2_STANDARD, + STV0900_DSS_STANDARD, + STV0900_TURBOCODE_STANDARD, + STV0900_UNKNOWN_STANDARD +}; + +enum fe_stv0900_search_standard { + STV0900_AUTO_SEARCH, + STV0900_SEARCH_DVBS1,/* Search Standard*/ + STV0900_SEARCH_DVBS2, + STV0900_SEARCH_DSS, + STV0900_SEARCH_TURBOCODE +}; + +enum fe_stv0900_search_algo { + STV0900_BLIND_SEARCH,/* offset freq and SR are Unknown */ + STV0900_COLD_START,/* only the SR is known */ + STV0900_WARM_START/* offset freq and SR are known */ +}; + +enum fe_stv0900_modulation { + STV0900_QPSK, + STV0900_8PSK, + STV0900_16APSK, + STV0900_32APSK, + STV0900_UNKNOWN +}; + +enum fe_stv0900_modcode { + STV0900_DUMMY_PLF, + STV0900_QPSK_14, + STV0900_QPSK_13, + STV0900_QPSK_25, + STV0900_QPSK_12, + STV0900_QPSK_35, + STV0900_QPSK_23, + STV0900_QPSK_34, + STV0900_QPSK_45, + STV0900_QPSK_56, + STV0900_QPSK_89, + STV0900_QPSK_910, + STV0900_8PSK_35, + STV0900_8PSK_23, + STV0900_8PSK_34, + STV0900_8PSK_56, + STV0900_8PSK_89, + STV0900_8PSK_910, + STV0900_16APSK_23, + STV0900_16APSK_34, + STV0900_16APSK_45, + STV0900_16APSK_56, + STV0900_16APSK_89, + STV0900_16APSK_910, + STV0900_32APSK_34, + STV0900_32APSK_45, + STV0900_32APSK_56, + STV0900_32APSK_89, + STV0900_32APSK_910, + STV0900_MODCODE_UNKNOWN +}; + +enum fe_stv0900_fec {/*DVBS1, DSS and turbo code puncture rate*/ + STV0900_FEC_1_2 = 0, + STV0900_FEC_2_3, + STV0900_FEC_3_4, + STV0900_FEC_4_5,/*for turbo code only*/ + STV0900_FEC_5_6, + STV0900_FEC_6_7,/*for DSS only */ + STV0900_FEC_7_8, + STV0900_FEC_8_9,/*for turbo code only*/ + STV0900_FEC_UNKNOWN +}; + +enum fe_stv0900_frame_length { + STV0900_LONG_FRAME, + STV0900_SHORT_FRAME +}; + +enum fe_stv0900_pilot { + STV0900_PILOTS_OFF, + STV0900_PILOTS_ON +}; + +enum fe_stv0900_rolloff { + STV0900_35, + STV0900_25, + STV0900_20 +}; + +enum fe_stv0900_search_iq { + STV0900_IQ_AUTO, + STV0900_IQ_AUTO_NORMAL_FIRST, + STV0900_IQ_FORCE_NORMAL, + STV0900_IQ_FORCE_SWAPPED +}; + +enum stv0900_iq_inversion { + STV0900_IQ_NORMAL, + STV0900_IQ_SWAPPED +}; + +enum fe_stv0900_diseqc_mode { + STV0900_22KHZ_Continues = 0, + STV0900_DISEQC_2_3_PWM = 2, + STV0900_DISEQC_3_3_PWM = 3, + STV0900_DISEQC_2_3_ENVELOP = 4, + STV0900_DISEQC_3_3_ENVELOP = 5 +}; + +enum fe_stv0900_demod_mode { + STV0900_SINGLE = 0, + STV0900_DUAL +}; + +struct stv0900_init_params{ + u32 dmd_ref_clk;/* Refrence,Input clock for the demod in Hz */ + + /* Demodulator Type (single demod or dual demod) */ + enum fe_stv0900_demod_mode demod_mode; + enum fe_stv0900_rolloff rolloff; + enum fe_stv0900_clock_type path1_ts_clock; + + u8 tun1_maddress; + int tuner1_adc; + + /* IQ from the tuner1 to the demod */ + enum stv0900_iq_inversion tun1_iq_inversion; + enum fe_stv0900_clock_type path2_ts_clock; + + u8 tun2_maddress; + int tuner2_adc; + + /* IQ from the tuner2 to the demod */ + enum stv0900_iq_inversion tun2_iq_inversion; +}; + +struct stv0900_search_params { + enum fe_stv0900_demod_num path;/* Path Used demod1 or 2 */ + + u32 frequency;/* Transponder frequency (in KHz) */ + u32 symbol_rate;/* Transponder symbol rate (in bds)*/ + u32 search_range;/* Range of the search (in Hz) */ + + enum fe_stv0900_search_standard standard; + enum fe_stv0900_modulation modulation; + enum fe_stv0900_fec fec; + enum fe_stv0900_modcode modcode; + enum fe_stv0900_search_iq iq_inversion; + enum fe_stv0900_search_algo search_algo; + +}; + +struct stv0900_signal_info { + int locked;/* Transponder locked */ + u32 frequency;/* Transponder frequency (in KHz) */ + u32 symbol_rate;/* Transponder symbol rate (in Mbds) */ + + enum fe_stv0900_tracking_standard standard; + enum fe_stv0900_fec fec; + enum fe_stv0900_modcode modcode; + enum fe_stv0900_modulation modulation; + enum fe_stv0900_pilot pilot; + enum fe_stv0900_frame_length frame_length; + enum stv0900_iq_inversion spectrum; + enum fe_stv0900_rolloff rolloff; + + s32 Power;/* Power of the RF signal (dBm) */ + s32 C_N;/* Carrier to noise ratio (dB x10)*/ + u32 BER;/* Bit error rate (x10^7) */ + +}; + +struct stv0900_internal{ + s32 quartz; + s32 mclk; + /* manual RollOff for DVBS1/DSS only */ + enum fe_stv0900_rolloff rolloff; + /* Demodulator use for single demod or for dual demod) */ + enum fe_stv0900_demod_mode demod_mode; + + /*Demod 1*/ + s32 tuner1_freq; + s32 tuner1_bw; + s32 dmd1_symbol_rate; + s32 dmd1_srch_range; + + /* algorithm for search Blind, Cold or Warm*/ + enum fe_stv0900_search_algo dmd1_srch_algo; + /* search standard: Auto, DVBS1/DSS only or DVBS2 only*/ + enum fe_stv0900_search_standard dmd1_srch_standard; + /* inversion search : auto, auto norma first, normal or inverted */ + enum fe_stv0900_search_iq dmd1_srch_iq_inv; + enum fe_stv0900_modcode dmd1_modcode; + enum fe_stv0900_modulation dmd1_modulation; + enum fe_stv0900_fec dmd1_fec; + + struct stv0900_signal_info dmd1_rslts; + enum fe_stv0900_signal_type dmd1_state; + + enum fe_stv0900_error dmd1_err; + + /*Demod 2*/ + s32 tuner2_freq; + s32 tuner2_bw; + s32 dmd2_symbol_rate; + s32 dmd2_srch_range; + + enum fe_stv0900_search_algo dmd2_srch_algo; + enum fe_stv0900_search_standard dmd2_srch_stndrd; + /* inversion search : auto, auto normal first, normal or inverted */ + enum fe_stv0900_search_iq dmd2_srch_iq_inv; + enum fe_stv0900_modcode dmd2_modcode; + enum fe_stv0900_modulation dmd2_modulation; + enum fe_stv0900_fec dmd2_fec; + + /* results of the search*/ + struct stv0900_signal_info dmd2_rslts; + /* current state of the search algorithm */ + enum fe_stv0900_signal_type dmd2_state; + + enum fe_stv0900_error dmd2_err; + + struct i2c_adapter *i2c_adap; + u8 i2c_addr; + u8 clkmode;/* 0 for CLKI, 2 for XTALI */ + u8 chip_id; + enum fe_stv0900_error errs; + int dmds_used; +}; + +/* state for each demod */ +struct stv0900_state { + /* pointer for internal params, one for each pair of demods */ + struct stv0900_internal *internal; + struct i2c_adapter *i2c_adap; + const struct stv0900_config *config; + struct dvb_frontend frontend; + int demod; +}; + +extern s32 ge2comp(s32 a, s32 width); + +extern void stv0900_write_reg(struct stv0900_internal *i_params, + u16 reg_addr, u8 reg_data); + +extern u8 stv0900_read_reg(struct stv0900_internal *i_params, + u16 reg_addr); + +extern void stv0900_write_bits(struct stv0900_internal *i_params, + u32 label, u8 val); + +extern u8 stv0900_get_bits(struct stv0900_internal *i_params, + u32 label); + +extern int stv0900_get_demod_lock(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod, s32 time_out); +extern int stv0900_check_signal_presence(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod); + +extern enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe); + +extern void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency, + u32 bandwidth); +extern void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth); + +extern void stv0900_start_search(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod); + +extern u8 stv0900_get_optim_carr_loop(s32 srate, + enum fe_stv0900_modcode modcode, + s32 pilot, u8 chip_id); + +extern u8 stv0900_get_optim_short_carr_loop(s32 srate, + enum fe_stv0900_modulation modulation, + u8 chip_id); + +extern void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod); + +extern void stv0900_activate_s2_modcode(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod); + +extern void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod); + +extern enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe, + enum fe_stv0900_demod_num demod); + +#endif -- cgit v1.2.1 From 99277b3824e4bfd290c30e8981929373c9a9e6a4 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Tue, 3 Mar 2009 11:45:49 -0300 Subject: V4L/DVB (10803): Add core code for ST STV0900 dual demodulator. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_core.c | 1946 ++++++++++++++++++++++++++++ 1 file changed, 1946 insertions(+) create mode 100644 drivers/media/dvb/frontends/stv0900_core.c (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c new file mode 100644 index 000000000000..ee20fbfc45f4 --- /dev/null +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -0,0 +1,1946 @@ +/* + * stv0900_core.c + * + * Driver for ST STV0900 satellite demodulator IC. + * + * Copyright (C) ST Microelectronics. + * Copyright (C) 2009 NetUP Inc. + * Copyright (C) 2009 Igor M. Liplianin + * + * 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 "stv0900.h" +#include "stv0900_reg.h" +#include "stv0900_priv.h" +#include "stv0900_init.h" + +int debug = 1; +module_param(debug, int, 0644); + +/* internal params node */ +struct stv0900_inode { + /* pointer for internal params, one for each pair of demods */ + struct stv0900_internal *internal; + struct stv0900_inode *next_inode; +}; + +/* first internal params */ +static struct stv0900_inode *stv0900_first_inode; + +/* find chip by i2c adapter and i2c address */ +static struct stv0900_inode *find_inode(struct i2c_adapter *i2c_adap, + u8 i2c_addr) +{ + struct stv0900_inode *temp_chip = stv0900_first_inode; + + if (temp_chip != NULL) { + /* + Search of the last stv0900 chip or + find it by i2c adapter and i2c address */ + while ((temp_chip != NULL) && + ((temp_chip->internal->i2c_adap != i2c_adap) || + (temp_chip->internal->i2c_addr != i2c_addr))) { + + temp_chip = temp_chip->next_inode; + dprintk(KERN_INFO "%s: store.adap %x\n", __func__, + (int)&(*temp_chip->internal->i2c_adap)); + dprintk(KERN_INFO "%s: init.adap %x\n", __func__, + (int)&(*i2c_adap)); + } + if (temp_chip != NULL) {/* find by i2c adapter & address */ + dprintk(KERN_INFO "%s: store.adap %x\n", __func__, + (int)temp_chip->internal->i2c_adap); + dprintk(KERN_INFO "%s: init.adap %x\n", __func__, + (int)i2c_adap); + } + } + + return temp_chip; +} + +/* deallocating chip */ +static void remove_inode(struct stv0900_internal *internal) +{ + struct stv0900_inode *prev_node = stv0900_first_inode; + struct stv0900_inode *del_node = find_inode(internal->i2c_adap, + internal->i2c_addr); + + if (del_node != NULL) { + if (del_node == stv0900_first_inode) { + stv0900_first_inode = del_node->next_inode; + } else { + while (prev_node->next_inode != del_node) + prev_node = prev_node->next_inode; + + if (del_node->next_inode == NULL) + prev_node->next_inode = NULL; + else + prev_node->next_inode = + prev_node->next_inode->next_inode; + } + + kfree(del_node); + } +} + +/* allocating new chip */ +static struct stv0900_inode *append_internal(struct stv0900_internal *internal) +{ + struct stv0900_inode *new_node = stv0900_first_inode; + + if (new_node == NULL) { + new_node = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL); + stv0900_first_inode = new_node; + } else { + while (new_node->next_inode != NULL) + new_node = new_node->next_inode; + + new_node->next_inode = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL); + if (new_node->next_inode != NULL) + new_node = new_node->next_inode; + else + new_node = NULL; + } + + if (new_node != NULL) { + new_node->internal = internal; + new_node->next_inode = NULL; + } + + return new_node; +} + +s32 ge2comp(s32 a, s32 width) +{ + if (width == 32) + return a; + else + return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a; +} + +void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr, + u8 reg_data) +{ + u8 data[3]; + int ret; + struct i2c_msg i2cmsg = { + .addr = i_params->i2c_addr, + .flags = 0, + .len = 3, + .buf = data, + }; + + data[0] = MSB(reg_addr); + data[1] = LSB(reg_addr); + data[2] = reg_data; + + ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1); + if (ret != 1) + dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret); +} + +u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg_addr) +{ + u8 data[2]; + int ret; + struct i2c_msg i2cmsg = { + .addr = i_params->i2c_addr, + .flags = 0, + .len = 2, + .buf = data, + }; + + data[0] = MSB(reg_addr); + data[1] = LSB(reg_addr); + + ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1); + if (ret != 1) + dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret); + + i2cmsg.flags = I2C_M_RD; + i2cmsg.len = 1; + ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1); + if (ret != 1) + dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret); + + return data[0]; +} + +void extract_mask_pos(u32 label, u8 *mask, u8 *pos) +{ + u8 position = 0, i = 0; + + (*mask) = label & 0xff; + + while ((position == 0) && (i < 8)) { + position = ((*mask) >> i) & 0x01; + i++; + } + + (*pos) = (i - 1); +} + +void stv0900_write_bits(struct stv0900_internal *i_params, u32 label, u8 val) +{ + u8 reg, mask, pos; + + reg = stv0900_read_reg(i_params, (label >> 16) & 0xffff); + extract_mask_pos(label, &mask, &pos); + + val = mask & (val << pos); + + reg = (reg & (~mask)) | val; + stv0900_write_reg(i_params, (label >> 16) & 0xffff, reg); + +} + +u8 stv0900_get_bits(struct stv0900_internal *i_params, u32 label) +{ + u8 val = 0xff; + u8 mask, pos; + + extract_mask_pos(label, &mask, &pos); + + val = stv0900_read_reg(i_params, label >> 16); + val = (val & mask) >> pos; + + return val; +} + +enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params) +{ + s32 i; + enum fe_stv0900_error error; + + if (i_params != NULL) { + i_params->chip_id = stv0900_read_reg(i_params, R0900_MID); + if (i_params->errs == STV0900_NO_ERROR) { + /*Startup sequence*/ + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5c); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5c); + stv0900_write_reg(i_params, R0900_P1_TNRCFG, 0x6c); + stv0900_write_reg(i_params, R0900_P2_TNRCFG, 0x6f); + stv0900_write_reg(i_params, R0900_P1_I2CRPT, 0x24); + stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x24); + stv0900_write_reg(i_params, R0900_NCOARSE, 0x13); + msleep(3); + stv0900_write_reg(i_params, R0900_I2CCFG, 0x08); + + switch (i_params->clkmode) { + case 0: + case 2: + stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20 + | i_params->clkmode); + break; + default: + /* preserve SELOSCI bit */ + i = 0x02 & stv0900_read_reg(i_params, R0900_SYNTCTRL); + stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20 | i); + break; + } + + msleep(3); + for (i = 0; i < 180; i++) + stv0900_write_reg(i_params, STV0900_InitVal[i][0], STV0900_InitVal[i][1]); + + if (stv0900_read_reg(i_params, R0900_MID) >= 0x20) { + stv0900_write_reg(i_params, R0900_TSGENERAL, 0x0c); + for (i = 0; i < 32; i++) + stv0900_write_reg(i_params, STV0900_Cut20_AddOnVal[i][0], STV0900_Cut20_AddOnVal[i][1]); + } + + stv0900_write_reg(i_params, R0900_P1_FSPYCFG, 0x6c); + stv0900_write_reg(i_params, R0900_P2_FSPYCFG, 0x6c); + stv0900_write_reg(i_params, R0900_TSTRES0, 0x80); + stv0900_write_reg(i_params, R0900_TSTRES0, 0x00); + } + error = i_params->errs; + } else + error = STV0900_INVALID_HANDLE; + + return error; + +} + +u32 stv0900_get_mclk_freq(struct stv0900_internal *i_params, u32 ext_clk) +{ + u32 mclk = 90000000, div = 0, ad_div = 0; + + div = stv0900_get_bits(i_params, F0900_M_DIV); + ad_div = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6); + + mclk = (div + 1) * ext_clk / ad_div; + + dprintk(KERN_INFO "%s: Calculated Mclk = %d\n", __func__, mclk); + + return mclk; +} + +enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *i_params, u32 mclk) +{ + enum fe_stv0900_error error = STV0900_NO_ERROR; + u32 m_div, clk_sel; + + dprintk(KERN_INFO "%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, + i_params->quartz); + + if (i_params == NULL) + error = STV0900_INVALID_HANDLE; + else { + if (i_params->errs) + error = STV0900_I2C_ERROR; + else { + clk_sel = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6); + m_div = ((clk_sel * mclk) / i_params->quartz) - 1; + stv0900_write_bits(i_params, F0900_M_DIV, m_div); + i_params->mclk = stv0900_get_mclk_freq(i_params, + i_params->quartz); + + /*Set the DiseqC frequency to 22KHz */ + /* + Formula: + DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg) + DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg) + */ + m_div = i_params->mclk / 704000; + stv0900_write_reg(i_params, R0900_P1_F22TX, m_div); + stv0900_write_reg(i_params, R0900_P1_F22RX, m_div); + + stv0900_write_reg(i_params, R0900_P2_F22TX, m_div); + stv0900_write_reg(i_params, R0900_P2_F22RX, m_div); + + if ((i_params->errs)) + error = STV0900_I2C_ERROR; + } + } + + return error; +} + +u32 stv0900_get_err_count(struct stv0900_internal *i_params, int cntr, + enum fe_stv0900_demod_num demod) +{ + u32 lsb, msb, hsb, err_val; + s32 err1field_hsb, err1field_msb, err1field_lsb; + s32 err2field_hsb, err2field_msb, err2field_lsb; + + dmd_reg(err1field_hsb, F0900_P1_ERR_CNT12, F0900_P2_ERR_CNT12); + dmd_reg(err1field_msb, F0900_P1_ERR_CNT11, F0900_P2_ERR_CNT11); + dmd_reg(err1field_lsb, F0900_P1_ERR_CNT10, F0900_P2_ERR_CNT10); + + dmd_reg(err2field_hsb, F0900_P1_ERR_CNT22, F0900_P2_ERR_CNT22); + dmd_reg(err2field_msb, F0900_P1_ERR_CNT21, F0900_P2_ERR_CNT21); + dmd_reg(err2field_lsb, F0900_P1_ERR_CNT20, F0900_P2_ERR_CNT20); + + switch (cntr) { + case 0: + default: + hsb = stv0900_get_bits(i_params, err1field_hsb); + msb = stv0900_get_bits(i_params, err1field_msb); + lsb = stv0900_get_bits(i_params, err1field_lsb); + break; + case 1: + hsb = stv0900_get_bits(i_params, err2field_hsb); + msb = stv0900_get_bits(i_params, err2field_msb); + lsb = stv0900_get_bits(i_params, err2field_lsb); + break; + } + + err_val = (hsb << 16) + (msb << 8) + (lsb); + + return err_val; +} + +static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + + u32 fi2c; + + dmd_reg(fi2c, F0900_P1_I2CT_ON, F0900_P2_I2CT_ON); + if (enable) + stv0900_write_bits(i_params, fi2c, 1); + + return 0; +} + +static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params, + enum fe_stv0900_clock_type path1_ts, + enum fe_stv0900_clock_type path2_ts) +{ + + dprintk(KERN_INFO "%s\n", __func__); + + if (i_params->chip_id >= 0x20) { + switch (path1_ts) { + case STV0900_PARALLEL_PUNCT_CLOCK: + case STV0900_DVBCI_CLOCK: + switch (path2_ts) { + case STV0900_SERIAL_PUNCT_CLOCK: + case STV0900_SERIAL_CONT_CLOCK: + default: + stv0900_write_reg(i_params, R0900_TSGENERAL, + 0x00); + break; + case STV0900_PARALLEL_PUNCT_CLOCK: + case STV0900_DVBCI_CLOCK: + stv0900_write_reg(i_params, R0900_TSGENERAL, + 0x06); + stv0900_write_bits(i_params, + F0900_P1_TSFIFO_MANSPEED, 3); + stv0900_write_bits(i_params, + F0900_P2_TSFIFO_MANSPEED, 0); + stv0900_write_reg(i_params, + R0900_P1_TSSPEED, 0x14); + stv0900_write_reg(i_params, + R0900_P2_TSSPEED, 0x28); + break; + } + break; + case STV0900_SERIAL_PUNCT_CLOCK: + case STV0900_SERIAL_CONT_CLOCK: + default: + switch (path2_ts) { + case STV0900_SERIAL_PUNCT_CLOCK: + case STV0900_SERIAL_CONT_CLOCK: + default: + stv0900_write_reg(i_params, + R0900_TSGENERAL, 0x0C); + break; + case STV0900_PARALLEL_PUNCT_CLOCK: + case STV0900_DVBCI_CLOCK: + stv0900_write_reg(i_params, + R0900_TSGENERAL, 0x0A); + dprintk(KERN_INFO "%s: 0x0a\n", __func__); + break; + } + break; + } + } else { + switch (path1_ts) { + case STV0900_PARALLEL_PUNCT_CLOCK: + case STV0900_DVBCI_CLOCK: + switch (path2_ts) { + case STV0900_SERIAL_PUNCT_CLOCK: + case STV0900_SERIAL_CONT_CLOCK: + default: + stv0900_write_reg(i_params, R0900_TSGENERAL1X, + 0x10); + break; + case STV0900_PARALLEL_PUNCT_CLOCK: + case STV0900_DVBCI_CLOCK: + stv0900_write_reg(i_params, R0900_TSGENERAL1X, + 0x16); + stv0900_write_bits(i_params, + F0900_P1_TSFIFO_MANSPEED, 3); + stv0900_write_bits(i_params, + F0900_P2_TSFIFO_MANSPEED, 0); + stv0900_write_reg(i_params, R0900_P1_TSSPEED, + 0x14); + stv0900_write_reg(i_params, R0900_P2_TSSPEED, + 0x28); + break; + } + + break; + case STV0900_SERIAL_PUNCT_CLOCK: + case STV0900_SERIAL_CONT_CLOCK: + default: + switch (path2_ts) { + case STV0900_SERIAL_PUNCT_CLOCK: + case STV0900_SERIAL_CONT_CLOCK: + default: + stv0900_write_reg(i_params, R0900_TSGENERAL1X, + 0x14); + break; + case STV0900_PARALLEL_PUNCT_CLOCK: + case STV0900_DVBCI_CLOCK: + stv0900_write_reg(i_params, R0900_TSGENERAL1X, + 0x12); + dprintk(KERN_INFO "%s: 0x12\n", __func__); + break; + } + + break; + } + } + + switch (path1_ts) { + case STV0900_PARALLEL_PUNCT_CLOCK: + stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00); + stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00); + break; + case STV0900_DVBCI_CLOCK: + stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00); + stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01); + break; + case STV0900_SERIAL_PUNCT_CLOCK: + stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01); + stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00); + break; + case STV0900_SERIAL_CONT_CLOCK: + stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01); + stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01); + break; + default: + break; + } + + switch (path2_ts) { + case STV0900_PARALLEL_PUNCT_CLOCK: + stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00); + stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00); + break; + case STV0900_DVBCI_CLOCK: + stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00); + stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01); + break; + case STV0900_SERIAL_PUNCT_CLOCK: + stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01); + stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00); + break; + case STV0900_SERIAL_CONT_CLOCK: + stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01); + stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01); + break; + default: + break; + } + + stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1); + stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 0); + stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1); + stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 0); +} + +void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency, + u32 bandwidth) +{ + struct dvb_frontend_ops *frontend_ops = NULL; + struct dvb_tuner_ops *tuner_ops = NULL; + + if (&fe->ops) + frontend_ops = &fe->ops; + + if (&frontend_ops->tuner_ops) + tuner_ops = &frontend_ops->tuner_ops; + + if (tuner_ops->set_frequency) { + if ((tuner_ops->set_frequency(fe, frequency)) < 0) + dprintk("%s: Invalid parameter\n", __func__); + else + dprintk("%s: Frequency=%d\n", __func__, frequency); + + } + + if (tuner_ops->set_bandwidth) { + if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0) + dprintk("%s: Invalid parameter\n", __func__); + else + dprintk("%s: Bandwidth=%d\n", __func__, bandwidth); + + } +} + +void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) +{ + struct dvb_frontend_ops *frontend_ops = NULL; + struct dvb_tuner_ops *tuner_ops = NULL; + + if (&fe->ops) + frontend_ops = &fe->ops; + + if (&frontend_ops->tuner_ops) + tuner_ops = &frontend_ops->tuner_ops; + + if (tuner_ops->set_bandwidth) { + if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0) + dprintk("%s: Invalid parameter\n", __func__); + else + dprintk("%s: Bandwidth=%d\n", __func__, bandwidth); + + } +} + +static s32 stv0900_get_rf_level(struct stv0900_internal *i_params, + const struct stv0900_table *lookup, + enum fe_stv0900_demod_num demod) +{ + s32 agc_gain = 0, + imin, + imax, + i, + rf_lvl = 0; + + dprintk(KERN_INFO "%s\n", __func__); + + if ((lookup != NULL) && lookup->size) { + switch (demod) { + case STV0900_DEMOD_1: + default: + agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE1), + stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE0)); + break; + case STV0900_DEMOD_2: + agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE1), + stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE0)); + break; + } + + imin = 0; + imax = lookup->size - 1; + if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[imax].regval)) { + while ((imax - imin) > 1) { + i = (imax + imin) >> 1; + + if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[i].regval)) + imax = i; + else + imin = i; + } + + rf_lvl = (((s32)agc_gain - lookup->table[imin].regval) + * (lookup->table[imax].realval - lookup->table[imin].realval) + / (lookup->table[imax].regval - lookup->table[imin].regval)) + + lookup->table[imin].realval; + } else if (agc_gain > lookup->table[0].regval) + rf_lvl = 5; + else if (agc_gain < lookup->table[lookup->size-1].regval) + rf_lvl = -100; + + } + + dprintk(KERN_INFO "%s: RFLevel = %d\n", __func__, rf_lvl); + + return rf_lvl; +} + +static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *internal = state->internal; + s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf, + state->demod); + + *strength = (rflevel + 100) * (16383 / 105); + + return 0; +} + + +static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, + const struct stv0900_table *lookup) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + + s32 c_n = -100, + regval, imin, imax, + i, + lock_flag_field, + noise_field1, + noise_field0; + + dprintk(KERN_INFO "%s\n", __func__); + + dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF); + if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) { + dmd_reg(noise_field1, F0900_P1_NOSPLHT_NORMED1, F0900_P2_NOSPLHT_NORMED1); + dmd_reg(noise_field0, F0900_P1_NOSPLHT_NORMED0, F0900_P2_NOSPLHT_NORMED0); + } else { + dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1, F0900_P2_NOSDATAT_NORMED1); + dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0, F0900_P1_NOSDATAT_NORMED0); + } + + if (stv0900_get_bits(i_params, lock_flag_field)) { + if ((lookup != NULL) && lookup->size) { + regval = 0; + msleep(5); + for (i = 0; i < 16; i++) { + regval += MAKEWORD(stv0900_get_bits(i_params, noise_field1), + stv0900_get_bits(i_params, noise_field0)); + msleep(1); + } + + regval /= 16; + imin = 0; + imax = lookup->size - 1; + if (INRANGE(lookup->table[imin].regval, regval, lookup->table[imax].regval)) { + while ((imax - imin) > 1) { + i = (imax + imin) >> 1; + + if (INRANGE(lookup->table[imin].regval, regval, lookup->table[i].regval)) + imax = i; + else + imin = i; + } + + c_n = ((regval - lookup->table[imin].regval) + * (lookup->table[imax].realval - lookup->table[imin].realval) + / (lookup->table[imax].regval - lookup->table[imin].regval)) + + lookup->table[imin].realval; + } else if (regval < lookup->table[imin].regval) + c_n = 1000; + } + } + + return c_n; +} + +static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + *snr = (16383 / 1030) * (30 + stv0900_carr_get_quality(fe, (const struct stv0900_table *)&stv0900_s2_cn)); + + return 0; +} + +static u32 stv0900_get_ber(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + u32 ber = 10000000, i; + s32 dmd_state_reg; + s32 demod_state; + s32 vstatus_reg; + s32 prvit_field; + s32 pdel_status_reg; + s32 pdel_lock_field; + + dmd_reg(dmd_state_reg, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); + dmd_reg(vstatus_reg, R0900_P1_VSTATUSVIT, R0900_P2_VSTATUSVIT); + dmd_reg(prvit_field, F0900_P1_PRFVIT, F0900_P2_PRFVIT); + dmd_reg(pdel_status_reg, R0900_P1_PDELSTATUS1, R0900_P2_PDELSTATUS1); + dmd_reg(pdel_lock_field, F0900_P1_PKTDELIN_LOCK, + F0900_P2_PKTDELIN_LOCK); + + demod_state = stv0900_get_bits(i_params, dmd_state_reg); + + switch (demod_state) { + case STV0900_SEARCH: + case STV0900_PLH_DETECTED: + default: + ber = 10000000; + break; + case STV0900_DVBS_FOUND: + ber = 0; + for (i = 0; i < 5; i++) { + msleep(5); + ber += stv0900_get_err_count(i_params, 0, demod); + } + + ber /= 5; + if (stv0900_get_bits(i_params, prvit_field)) { + ber *= 9766; + ber = ber >> 13; + } + + break; + case STV0900_DVBS2_FOUND: + ber = 0; + for (i = 0; i < 5; i++) { + msleep(5); + ber += stv0900_get_err_count(i_params, 0, demod); + } + + ber /= 5; + if (stv0900_get_bits(i_params, pdel_lock_field)) { + ber *= 9766; + ber = ber >> 13; + } + + break; + } + + return ber; +} + +static int stv0900_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *internal = state->internal; + + *ber = stv0900_get_ber(internal, state->demod); + + return 0; +} + +int stv0900_get_demod_lock(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod, s32 time_out) +{ + s32 timer = 0, + lock = 0, + header_field, + lock_field; + + enum fe_stv0900_search_state dmd_state; + + dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); + dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF); + while ((timer < time_out) && (lock == 0)) { + dmd_state = stv0900_get_bits(i_params, header_field); + dprintk("Demod State = %d\n", dmd_state); + switch (dmd_state) { + case STV0900_SEARCH: + case STV0900_PLH_DETECTED: + default: + lock = 0; + break; + case STV0900_DVBS2_FOUND: + case STV0900_DVBS_FOUND: + lock = stv0900_get_bits(i_params, lock_field); + break; + } + + if (lock == 0) + msleep(10); + + timer += 10; + } + + if (lock) + dprintk("DEMOD LOCK OK\n"); + else + dprintk("DEMOD LOCK FAIL\n"); + + return lock; +} + +void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + s32 regflist, + i; + + dprintk(KERN_INFO "%s\n", __func__); + + dmd_reg(regflist, R0900_P1_MODCODLST0, R0900_P2_MODCODLST0); + + for (i = 0; i < 16; i++) + stv0900_write_reg(i_params, regflist + i, 0xff); +} + +void stv0900_activate_s2_modcode(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + u32 matype, + mod_code, + fmod, + reg_index, + field_index; + + dprintk(KERN_INFO "%s\n", __func__); + + if (i_params->chip_id <= 0x11) { + msleep(5); + + switch (demod) { + case STV0900_DEMOD_1: + default: + mod_code = stv0900_read_reg(i_params, + R0900_P1_PLHMODCOD); + matype = mod_code & 0x3; + mod_code = (mod_code & 0x7f) >> 2; + + reg_index = R0900_P1_MODCODLSTF - mod_code / 2; + field_index = mod_code % 2; + break; + case STV0900_DEMOD_2: + mod_code = stv0900_read_reg(i_params, + R0900_P2_PLHMODCOD); + matype = mod_code & 0x3; + mod_code = (mod_code & 0x7f) >> 2; + + reg_index = R0900_P2_MODCODLSTF - mod_code / 2; + field_index = mod_code % 2; + break; + } + + + switch (matype) { + case 0: + default: + fmod = 14; + break; + case 1: + fmod = 13; + break; + case 2: + fmod = 11; + break; + case 3: + fmod = 7; + break; + } + + if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910)) + && (matype <= 1)) { + if (field_index == 0) + stv0900_write_reg(i_params, reg_index, + 0xf0 | fmod); + else + stv0900_write_reg(i_params, reg_index, + (fmod << 4) | 0xf); + } + } else if (i_params->chip_id >= 0x12) { + switch (demod) { + case STV0900_DEMOD_1: + default: + for (reg_index = 0; reg_index < 7; reg_index++) + stv0900_write_reg(i_params, R0900_P1_MODCODLST0 + reg_index, 0xff); + + stv0900_write_reg(i_params, R0900_P1_MODCODLSTE, 0xff); + stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0xcf); + for (reg_index = 0; reg_index < 8; reg_index++) + stv0900_write_reg(i_params, R0900_P1_MODCODLST7 + reg_index, 0xcc); + + break; + case STV0900_DEMOD_2: + for (reg_index = 0; reg_index < 7; reg_index++) + stv0900_write_reg(i_params, R0900_P2_MODCODLST0 + reg_index, 0xff); + + stv0900_write_reg(i_params, R0900_P2_MODCODLSTE, 0xff); + stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0xcf); + for (reg_index = 0; reg_index < 8; reg_index++) + stv0900_write_reg(i_params, R0900_P2_MODCODLST7 + reg_index, 0xcc); + + break; + } + + } +} + +void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + u32 reg_index; + + dprintk(KERN_INFO "%s\n", __func__); + + switch (demod) { + case STV0900_DEMOD_1: + default: + stv0900_write_reg(i_params, R0900_P1_MODCODLST0, 0xff); + stv0900_write_reg(i_params, R0900_P1_MODCODLST1, 0xf0); + stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0x0f); + for (reg_index = 0; reg_index < 13; reg_index++) + stv0900_write_reg(i_params, + R0900_P1_MODCODLST2 + reg_index, 0); + + break; + case STV0900_DEMOD_2: + stv0900_write_reg(i_params, R0900_P2_MODCODLST0, 0xff); + stv0900_write_reg(i_params, R0900_P2_MODCODLST1, 0xf0); + stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0x0f); + for (reg_index = 0; reg_index < 13; reg_index++) + stv0900_write_reg(i_params, + R0900_P2_MODCODLST2 + reg_index, 0); + + break; + } +} + +static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe) +{ + return DVBFE_ALGO_CUSTOM; +} + +static int stb0900_set_property(struct dvb_frontend *fe, + struct dtv_property *tvp) +{ + dprintk(KERN_INFO "%s(..)\n", __func__); + + return 0; +} + +static int stb0900_get_property(struct dvb_frontend *fe, + struct dtv_property *tvp) +{ + dprintk(KERN_INFO "%s(..)\n", __func__); + + return 0; +} + +void stv0900_start_search(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + + switch (demod) { + case STV0900_DEMOD_1: + default: + stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1f); + + if (i_params->chip_id == 0x10) + stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xaa); + + if (i_params->chip_id < 0x20) + stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55); + + if (i_params->dmd1_symbol_rate <= 5000000) { + stv0900_write_reg(i_params, R0900_P1_CARCFG, 0x44); + stv0900_write_reg(i_params, R0900_P1_CFRUP1, 0x0f); + stv0900_write_reg(i_params, R0900_P1_CFRUP0, 0xff); + stv0900_write_reg(i_params, R0900_P1_CFRLOW1, 0xf0); + stv0900_write_reg(i_params, R0900_P1_CFRLOW0, 0x00); + stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68); + } else { + stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xc4); + stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44); + } + + stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0); + stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0); + + if (i_params->chip_id >= 0x20) { + stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41); + stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41); + + if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) { + stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82); + stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0); + } + } + + stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00); + stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xe0); + stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xc0); + stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); + stv0900_write_bits(i_params, F0900_P1_S1S2_SEQUENTIAL, 0); + stv0900_write_reg(i_params, R0900_P1_RTC, 0x88); + if (i_params->chip_id >= 0x20) { + if (i_params->dmd1_symbol_rate < 2000000) { + stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x39); + stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x40); + } + + if (i_params->dmd1_symbol_rate < 10000000) { + stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4c); + stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20); + } else { + stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4b); + stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20); + } + + } else { + if (i_params->dmd1_symbol_rate < 10000000) + stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xef); + else + stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed); + } + + switch (i_params->dmd1_srch_algo) { + case STV0900_WARM_START: + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); + break; + case STV0900_COLD_START: + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); + break; + default: + break; + } + + break; + case STV0900_DEMOD_2: + stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1f); + if (i_params->chip_id == 0x10) + stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xaa); + + if (i_params->chip_id < 0x20) + stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55); + + if (i_params->dmd2_symbol_rate <= 5000000) { + stv0900_write_reg(i_params, R0900_P2_CARCFG, 0x44); + stv0900_write_reg(i_params, R0900_P2_CFRUP1, 0x0f); + stv0900_write_reg(i_params, R0900_P2_CFRUP0, 0xff); + stv0900_write_reg(i_params, R0900_P2_CFRLOW1, 0xf0); + stv0900_write_reg(i_params, R0900_P2_CFRLOW0, 0x00); + stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68); + } else { + stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xc4); + stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44); + } + + stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0); + stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0); + + if (i_params->chip_id >= 0x20) { + stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41); + stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41); + if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) { + stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82); + stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0); + } + } + + stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00); + stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xe0); + stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xc0); + stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); + stv0900_write_bits(i_params, F0900_P2_S1S2_SEQUENTIAL, 0); + stv0900_write_reg(i_params, R0900_P2_RTC, 0x88); + if (i_params->chip_id >= 0x20) { + if (i_params->dmd2_symbol_rate < 2000000) { + stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x39); + stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x40); + } + + if (i_params->dmd2_symbol_rate < 10000000) { + stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4c); + stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20); + } else { + stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4b); + stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20); + } + + } else { + if (i_params->dmd2_symbol_rate < 10000000) + stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xef); + else + stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed); + } + + switch (i_params->dmd2_srch_algo) { + case STV0900_WARM_START: + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); + break; + case STV0900_COLD_START: + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); + break; + default: + break; + } + + break; + } +} + +u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode, + s32 pilot, u8 chip_id) +{ + u8 aclc_value = 0x29; + s32 i; + const struct stv0900_car_loop_optim *car_loop_s2; + + dprintk(KERN_INFO "%s\n", __func__); + + if (chip_id <= 0x12) + car_loop_s2 = FE_STV0900_S2CarLoop; + else if (chip_id == 0x20) + car_loop_s2 = FE_STV0900_S2CarLoopCut20; + else + car_loop_s2 = FE_STV0900_S2CarLoop; + + if (modcode < STV0900_QPSK_12) { + i = 0; + while ((i < 3) && (modcode != FE_STV0900_S2LowQPCarLoopCut20[i].modcode)) + i++; + + if (i >= 3) + i = 2; + } else { + i = 0; + while ((i < 14) && (modcode != car_loop_s2[i].modcode)) + i++; + + if (i >= 14) { + i = 0; + while ((i < 11) && (modcode != FE_STV0900_S2APSKCarLoopCut20[i].modcode)) + i++; + + if (i >= 11) + i = 10; + } + } + + if (modcode <= STV0900_QPSK_25) { + if (pilot) { + if (srate <= 3000000) + aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_2; + else if (srate <= 7000000) + aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_5; + else if (srate <= 15000000) + aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_10; + else if (srate <= 25000000) + aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_20; + else + aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_30; + } else { + if (srate <= 3000000) + aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_2; + else if (srate <= 7000000) + aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_5; + else if (srate <= 15000000) + aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_10; + else if (srate <= 25000000) + aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_20; + else + aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_30; + } + + } else if (modcode <= STV0900_8PSK_910) { + if (pilot) { + if (srate <= 3000000) + aclc_value = car_loop_s2[i].car_loop_pilots_on_2; + else if (srate <= 7000000) + aclc_value = car_loop_s2[i].car_loop_pilots_on_5; + else if (srate <= 15000000) + aclc_value = car_loop_s2[i].car_loop_pilots_on_10; + else if (srate <= 25000000) + aclc_value = car_loop_s2[i].car_loop_pilots_on_20; + else + aclc_value = car_loop_s2[i].car_loop_pilots_on_30; + } else { + if (srate <= 3000000) + aclc_value = car_loop_s2[i].car_loop_pilots_off_2; + else if (srate <= 7000000) + aclc_value = car_loop_s2[i].car_loop_pilots_off_5; + else if (srate <= 15000000) + aclc_value = car_loop_s2[i].car_loop_pilots_off_10; + else if (srate <= 25000000) + aclc_value = car_loop_s2[i].car_loop_pilots_off_20; + else + aclc_value = car_loop_s2[i].car_loop_pilots_off_30; + } + + } else { + if (srate <= 3000000) + aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_2; + else if (srate <= 7000000) + aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_5; + else if (srate <= 15000000) + aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_10; + else if (srate <= 25000000) + aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_20; + else + aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_30; + } + + return aclc_value; +} + +u8 stv0900_get_optim_short_carr_loop(s32 srate, enum fe_stv0900_modulation modulation, u8 chip_id) +{ + s32 mod_index = 0; + + u8 aclc_value = 0x0b; + + dprintk(KERN_INFO "%s\n", __func__); + + switch (modulation) { + case STV0900_QPSK: + default: + mod_index = 0; + break; + case STV0900_8PSK: + mod_index = 1; + break; + case STV0900_16APSK: + mod_index = 2; + break; + case STV0900_32APSK: + mod_index = 3; + break; + } + + switch (chip_id) { + case 0x20: + if (srate <= 3000000) + aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_2; + else if (srate <= 7000000) + aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_5; + else if (srate <= 15000000) + aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_10; + else if (srate <= 25000000) + aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_20; + else + aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_30; + + break; + case 0x12: + default: + if (srate <= 3000000) + aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_2; + else if (srate <= 7000000) + aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_5; + else if (srate <= 15000000) + aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_10; + else if (srate <= 25000000) + aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_20; + else + aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_30; + + break; + } + + return aclc_value; +} + +static enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *i_params, + enum fe_stv0900_demod_mode LDPC_Mode, + enum fe_stv0900_demod_num demod) +{ + enum fe_stv0900_error error = STV0900_NO_ERROR; + + dprintk(KERN_INFO "%s\n", __func__); + + switch (LDPC_Mode) { + case STV0900_DUAL: + default: + if ((i_params->demod_mode != STV0900_DUAL) + || (stv0900_get_bits(i_params, F0900_DDEMOD) != 1)) { + stv0900_write_reg(i_params, R0900_GENCFG, 0x1d); + + i_params->demod_mode = STV0900_DUAL; + + stv0900_write_bits(i_params, F0900_FRESFEC, 1); + stv0900_write_bits(i_params, F0900_FRESFEC, 0); + } + + break; + case STV0900_SINGLE: + if (demod == STV0900_DEMOD_2) + stv0900_write_reg(i_params, R0900_GENCFG, 0x06); + else + stv0900_write_reg(i_params, R0900_GENCFG, 0x04); + + i_params->demod_mode = STV0900_SINGLE; + + stv0900_write_bits(i_params, F0900_FRESFEC, 1); + stv0900_write_bits(i_params, F0900_FRESFEC, 0); + stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1); + stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0); + stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1); + stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0); + break; + } + + return error; +} + +static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, + struct stv0900_init_params *p_init) +{ + struct stv0900_state *state = fe->demodulator_priv; + enum fe_stv0900_error error = STV0900_NO_ERROR; + enum fe_stv0900_error demodError = STV0900_NO_ERROR; + int selosci; + + struct stv0900_inode *temp_int = find_inode(state->i2c_adap, + state->config->demod_address); + + dprintk(KERN_INFO "%s\n", __func__); + + if (temp_int != NULL) { + state->internal = temp_int->internal; + (state->internal->dmds_used)++; + dprintk(KERN_INFO "%s: Find Internal Structure!\n", __func__); + return STV0900_NO_ERROR; + } else { + state->internal = kmalloc(sizeof(struct stv0900_internal), GFP_KERNEL); + temp_int = append_internal(state->internal); + state->internal->dmds_used = 1; + state->internal->i2c_adap = state->i2c_adap; + state->internal->i2c_addr = state->config->demod_address; + state->internal->clkmode = state->config->clkmode; + state->internal->errs = STV0900_NO_ERROR; + dprintk(KERN_INFO "%s: Create New Internal Structure!\n", __func__); + } + + if (state->internal != NULL) { + demodError = stv0900_initialize(state->internal); + if (demodError == STV0900_NO_ERROR) { + error = STV0900_NO_ERROR; + } else { + if (demodError == STV0900_INVALID_HANDLE) + error = STV0900_INVALID_HANDLE; + else + error = STV0900_I2C_ERROR; + } + + if (state->internal != NULL) { + if (error == STV0900_NO_ERROR) { + state->internal->demod_mode = p_init->demod_mode; + + stv0900_st_dvbs2_single(state->internal, state->internal->demod_mode, STV0900_DEMOD_1); + + state->internal->chip_id = stv0900_read_reg(state->internal, R0900_MID); + state->internal->rolloff = p_init->rolloff; + state->internal->quartz = p_init->dmd_ref_clk; + + stv0900_write_bits(state->internal, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff); + stv0900_write_bits(state->internal, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff); + + stv0900_set_ts_parallel_serial(state->internal, p_init->path1_ts_clock, p_init->path2_ts_clock); + stv0900_write_bits(state->internal, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress); + switch (p_init->tuner1_adc) { + case 1: + stv0900_write_reg(state->internal, R0900_TSTTNR1, 0x26); + break; + default: + break; + } + + stv0900_write_bits(state->internal, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress); + switch (p_init->tuner2_adc) { + case 1: + stv0900_write_reg(state->internal, R0900_TSTTNR3, 0x26); + break; + default: + break; + } + + stv0900_write_bits(state->internal, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inversion); + stv0900_write_bits(state->internal, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inversion); + stv0900_set_mclk(state->internal, 135000000); + msleep(3); + + switch (state->internal->clkmode) { + case 0: + case 2: + stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | state->internal->clkmode); + break; + default: + selosci = 0x02 & stv0900_read_reg(state->internal, R0900_SYNTCTRL); + stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | selosci); + break; + } + msleep(3); + + state->internal->mclk = stv0900_get_mclk_freq(state->internal, state->internal->quartz); + if (state->internal->errs) + error = STV0900_I2C_ERROR; + } + } else { + error = STV0900_INVALID_HANDLE; + } + } + + return error; +} + +static int stv0900_status(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + enum fe_stv0900_search_state demod_state; + s32 mode_field, delin_field, lock_field, fifo_field, lockedvit_field; + int locked = FALSE; + + dmd_reg(mode_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); + dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF); + dmd_reg(delin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK); + dmd_reg(fifo_field, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK); + dmd_reg(lockedvit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT); + + demod_state = stv0900_get_bits(i_params, mode_field); + switch (demod_state) { + case STV0900_SEARCH: + case STV0900_PLH_DETECTED: + default: + locked = FALSE; + break; + case STV0900_DVBS2_FOUND: + locked = stv0900_get_bits(i_params, lock_field) && + stv0900_get_bits(i_params, delin_field) && + stv0900_get_bits(i_params, fifo_field); + break; + case STV0900_DVBS_FOUND: + locked = stv0900_get_bits(i_params, lock_field) && + stv0900_get_bits(i_params, lockedvit_field) && + stv0900_get_bits(i_params, fifo_field); + break; + } + + return locked; +} + +static enum dvbfe_search stv0900_search(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + struct stv0900_search_params p_search; + struct stv0900_signal_info p_result; + + enum fe_stv0900_error error = STV0900_NO_ERROR; + + dprintk(KERN_INFO "%s: Internal = %x\n", __func__, (u32)i_params); + + p_result.locked = FALSE; + p_search.path = state->demod; + p_search.frequency = c->frequency; + p_search.symbol_rate = c->symbol_rate; + p_search.search_range = 10000000; + p_search.fec = STV0900_FEC_UNKNOWN; + p_search.standard = STV0900_AUTO_SEARCH; + p_search.iq_inversion = STV0900_IQ_AUTO; + p_search.search_algo = STV0900_BLIND_SEARCH; + + if ((INRANGE(100000, p_search.symbol_rate, 70000000)) && + (INRANGE(100000, p_search.search_range, 50000000))) { + switch (p_search.path) { + case STV0900_DEMOD_1: + default: + i_params->dmd1_srch_standard = p_search.standard; + i_params->dmd1_symbol_rate = p_search.symbol_rate; + i_params->dmd1_srch_range = p_search.search_range; + i_params->tuner1_freq = p_search.frequency; + i_params->dmd1_srch_algo = p_search.search_algo; + i_params->dmd1_srch_iq_inv = p_search.iq_inversion; + i_params->dmd1_fec = p_search.fec; + break; + + case STV0900_DEMOD_2: + i_params->dmd2_srch_stndrd = p_search.standard; + i_params->dmd2_symbol_rate = p_search.symbol_rate; + i_params->dmd2_srch_range = p_search.search_range; + i_params->tuner2_freq = p_search.frequency; + i_params->dmd2_srch_algo = p_search.search_algo; + i_params->dmd2_srch_iq_inv = p_search.iq_inversion; + i_params->dmd2_fec = p_search.fec; + break; + } + + if ((stv0900_algo(fe) == STV0900_RANGEOK) && + (i_params->errs == STV0900_NO_ERROR)) { + switch (p_search.path) { + case STV0900_DEMOD_1: + default: + p_result.locked = i_params->dmd1_rslts.locked; + p_result.standard = i_params->dmd1_rslts.standard; + p_result.frequency = i_params->dmd1_rslts.frequency; + p_result.symbol_rate = i_params->dmd1_rslts.symbol_rate; + p_result.fec = i_params->dmd1_rslts.fec; + p_result.modcode = i_params->dmd1_rslts.modcode; + p_result.pilot = i_params->dmd1_rslts.pilot; + p_result.frame_length = i_params->dmd1_rslts.frame_length; + p_result.spectrum = i_params->dmd1_rslts.spectrum; + p_result.rolloff = i_params->dmd1_rslts.rolloff; + p_result.modulation = i_params->dmd1_rslts.modulation; + break; + case STV0900_DEMOD_2: + p_result.locked = i_params->dmd2_rslts.locked; + p_result.standard = i_params->dmd2_rslts.standard; + p_result.frequency = i_params->dmd2_rslts.frequency; + p_result.symbol_rate = i_params->dmd2_rslts.symbol_rate; + p_result.fec = i_params->dmd2_rslts.fec; + p_result.modcode = i_params->dmd2_rslts.modcode; + p_result.pilot = i_params->dmd2_rslts.pilot; + p_result.frame_length = i_params->dmd2_rslts.frame_length; + p_result.spectrum = i_params->dmd2_rslts.spectrum; + p_result.rolloff = i_params->dmd2_rslts.rolloff; + p_result.modulation = i_params->dmd2_rslts.modulation; + break; + } + + } else { + p_result.locked = FALSE; + switch (p_search.path) { + case STV0900_DEMOD_1: + switch (i_params->dmd1_err) { + case STV0900_I2C_ERROR: + error = STV0900_I2C_ERROR; + break; + case STV0900_NO_ERROR: + default: + error = STV0900_SEARCH_FAILED; + break; + } + break; + case STV0900_DEMOD_2: + switch (i_params->dmd2_err) { + case STV0900_I2C_ERROR: + error = STV0900_I2C_ERROR; + break; + case STV0900_NO_ERROR: + default: + error = STV0900_SEARCH_FAILED; + break; + } + break; + } + } + + } else + error = STV0900_BAD_PARAMETER; + + if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) { + dprintk(KERN_INFO "Search Success\n"); + return DVBFE_ALGO_SEARCH_SUCCESS; + } else { + dprintk(KERN_INFO "Search Fail\n"); + return DVBFE_ALGO_SEARCH_FAILED; + } + + return DVBFE_ALGO_SEARCH_ERROR; +} + +static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status) +{ + struct stv0900_state *state = fe->demodulator_priv; + + dprintk("%s: Internal = %x\n", __func__, (unsigned int)state->internal); + + if ((stv0900_status(state->internal, state->demod)) == TRUE) { + dprintk("DEMOD LOCK OK\n"); + *status = FE_HAS_CARRIER + | FE_HAS_VITERBI + | FE_HAS_SYNC + | FE_HAS_LOCK; + } else + dprintk("DEMOD LOCK FAIL\n"); + + return 0; +} + +static int stv0900_track(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + return 0; +} + +static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts) +{ + + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + s32 rst_field; + + dmd_reg(rst_field, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE); + + if (stop_ts == TRUE) + stv0900_write_bits(i_params, rst_field, 1); + else + stv0900_write_bits(i_params, rst_field, 0); + + return 0; +} + +static int stv0900_diseqc_init(struct dvb_frontend *fe) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + s32 mode_field, reset_field; + + dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); + dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET); + + stv0900_write_bits(i_params, mode_field, state->config->diseqc_mode); + stv0900_write_bits(i_params, reset_field, 1); + stv0900_write_bits(i_params, reset_field, 0); + + return 0; +} + +static int stv0900_init(struct dvb_frontend *fe) +{ + dprintk(KERN_INFO "%s\n", __func__); + + stv0900_stop_ts(fe, 1); + stv0900_diseqc_init(fe); + + return 0; +} + +static int stv0900_diseqc_send(struct stv0900_internal *i_params , u8 *Data, + u32 NbData, enum fe_stv0900_demod_num demod) +{ + s32 i = 0; + + switch (demod) { + case STV0900_DEMOD_1: + default: + stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 1); + while (i < NbData) { + while (stv0900_get_bits(i_params, F0900_P1_FIFO_FULL)) + ;/* checkpatch complains */ + stv0900_write_reg(i_params, R0900_P1_DISTXDATA, Data[i]); + i++; + } + + stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 0); + i = 0; + while ((stv0900_get_bits(i_params, F0900_P1_TX_IDLE) != 1) && (i < 10)) { + msleep(10); + i++; + } + + break; + case STV0900_DEMOD_2: + stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 1); + + while (i < NbData) { + while (stv0900_get_bits(i_params, F0900_P2_FIFO_FULL)) + ;/* checkpatch complains */ + stv0900_write_reg(i_params, R0900_P2_DISTXDATA, Data[i]); + i++; + } + + stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 0); + i = 0; + while ((stv0900_get_bits(i_params, F0900_P2_TX_IDLE) != 1) && (i < 10)) { + msleep(10); + i++; + } + + break; + } + + return 0; +} + +static int stv0900_send_master_cmd(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *cmd) +{ + struct stv0900_state *state = fe->demodulator_priv; + + return stv0900_diseqc_send(state->internal, + cmd->msg, + cmd->msg_len, + state->demod); +} + +static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + s32 mode_field; + u32 diseqc_fifo; + + dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); + dmd_reg(diseqc_fifo, R0900_P1_DISTXDATA, R0900_P2_DISTXDATA); + + switch (burst) { + case SEC_MINI_A: + stv0900_write_bits(i_params, mode_field, 3);/* Unmodulated */ + stv0900_write_reg(i_params, diseqc_fifo, 0x00); + break; + case SEC_MINI_B: + stv0900_write_bits(i_params, mode_field, 2);/* Modulated */ + stv0900_write_reg(i_params, diseqc_fifo, 0xff); + break; + } + + return 0; +} + +static int stv0900_recv_slave_reply(struct dvb_frontend *fe, + struct dvb_diseqc_slave_reply *reply) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + s32 i = 0; + + switch (state->demod) { + case STV0900_DEMOD_1: + default: + reply->msg_len = 0; + + while ((stv0900_get_bits(i_params, F0900_P1_RX_END) != 1) && (i < 10)) { + msleep(10); + i++; + } + + if (stv0900_get_bits(i_params, F0900_P1_RX_END)) { + reply->msg_len = stv0900_get_bits(i_params, F0900_P1_FIFO_BYTENBR); + + for (i = 0; i < reply->msg_len; i++) + reply->msg[i] = stv0900_read_reg(i_params, R0900_P1_DISRXDATA); + } + break; + case STV0900_DEMOD_2: + reply->msg_len = 0; + + while ((stv0900_get_bits(i_params, F0900_P2_RX_END) != 1) && (i < 10)) { + msleep(10); + i++; + } + + if (stv0900_get_bits(i_params, F0900_P2_RX_END)) { + reply->msg_len = stv0900_get_bits(i_params, F0900_P2_FIFO_BYTENBR); + + for (i = 0; i < reply->msg_len; i++) + reply->msg[i] = stv0900_read_reg(i_params, R0900_P2_DISRXDATA); + } + break; + } + + return 0; +} + +static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + s32 mode_field, reset_field; + + dprintk(KERN_INFO "%s: %s\n", __func__, ((tone == 0) ? "Off" : "On")); + + dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE); + dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET); + + if (tone) { + /*Set the DiseqC mode to 22Khz continues tone*/ + stv0900_write_bits(i_params, mode_field, 0); + stv0900_write_bits(i_params, reset_field, 1); + /*release DiseqC reset to enable the 22KHz tone*/ + stv0900_write_bits(i_params, reset_field, 0); + } else { + stv0900_write_bits(i_params, mode_field, 0); + /*maintain the DiseqC reset to disable the 22KHz tone*/ + stv0900_write_bits(i_params, reset_field, 1); + } + + return 0; +} + +static void stv0900_release(struct dvb_frontend *fe) +{ + struct stv0900_state *state = fe->demodulator_priv; + + dprintk(KERN_INFO "%s\n", __func__); + + if ((--(state->internal->dmds_used)) <= 0) { + + dprintk(KERN_INFO "%s: Actually removing\n", __func__); + + remove_inode(state->internal); + kfree(state->internal); + } + + kfree(state); +} + +static struct dvb_frontend_ops stv0900_ops = { + + .info = { + .name = "STV0900 frontend", + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 125, + .frequency_tolerance = 0, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .symbol_rate_tolerance = 500, + .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_QPSK | + FE_CAN_2G_MODULATION | + FE_CAN_FEC_AUTO + }, + .release = stv0900_release, + .init = stv0900_init, + .get_frontend_algo = stv0900_frontend_algo, + .i2c_gate_ctrl = stv0900_i2c_gate_ctrl, + .diseqc_send_master_cmd = stv0900_send_master_cmd, + .diseqc_send_burst = stv0900_send_burst, + .diseqc_recv_slave_reply = stv0900_recv_slave_reply, + .set_tone = stv0900_set_tone, + .set_property = stb0900_set_property, + .get_property = stb0900_get_property, + .search = stv0900_search, + .track = stv0900_track, + .read_status = stv0900_read_status, + .read_ber = stv0900_read_ber, + .read_signal_strength = stv0900_read_signal_strength, + .read_snr = stv0900_read_snr, +}; + +struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, + struct i2c_adapter *i2c, + int demod) +{ + struct stv0900_state *state = NULL; + struct stv0900_init_params init_params; + enum fe_stv0900_error err_stv0900; + + state = kzalloc(sizeof(struct stv0900_state), GFP_KERNEL); + if (state == NULL) + goto error; + + state->demod = demod; + state->config = config; + state->i2c_adap = i2c; + + memcpy(&state->frontend.ops, &stv0900_ops, + sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + + switch (demod) { + case 0: + case 1: + init_params.dmd_ref_clk = config->xtal; + init_params.demod_mode = STV0900_DUAL; + init_params.rolloff = STV0900_35; + init_params.path1_ts_clock = config->path1_mode; + init_params.tun1_maddress = config->tun1_maddress; + init_params.tun1_iq_inversion = STV0900_IQ_NORMAL; + init_params.tuner1_adc = config->tun1_adc; + init_params.path2_ts_clock = config->path2_mode; + init_params.tun2_maddress = config->tun2_maddress; + init_params.tuner2_adc = config->tun2_adc; + init_params.tun2_iq_inversion = STV0900_IQ_SWAPPED; + + err_stv0900 = stv0900_init_internal(&state->frontend, + &init_params); + + if (err_stv0900) + goto error; + + dprintk(KERN_INFO "%s: Init Result = %d, handle_stv0900 = %x\n", + __func__, err_stv0900, (unsigned int)state->internal); + break; + default: + goto error; + break; + } + + dprintk("%s: Attaching STV0900 demodulator(%d) \n", __func__, demod); + return &state->frontend; + +error: + dprintk("%s: Failed to attach STV0900 demodulator(%d) \n", + __func__, demod); + kfree(state); + return NULL; +} +EXPORT_SYMBOL(stv0900_attach); + +MODULE_PARM_DESC(debug, "Set debug"); + +MODULE_AUTHOR("Igor M. Liplianin"); +MODULE_DESCRIPTION("ST STV0900 frontend"); +MODULE_LICENSE("GPL"); -- cgit v1.2.1 From ce45264eca4963e666ec170af1eeb0c4f5f8339e Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Tue, 3 Mar 2009 11:55:20 -0300 Subject: V4L/DVB (10804): Add support for ST STV0900 dual demodulator. Add last piece of code to support ST STV0900 dual demodulator. The IC consist of two dependent parts. It may use single or dual mode. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 7 + drivers/media/dvb/frontends/Makefile | 2 + drivers/media/dvb/frontends/stv0900_sw.c | 2847 ++++++++++++++++++++++++++++++ 3 files changed, 2856 insertions(+) create mode 100644 drivers/media/dvb/frontends/stv0900_sw.c (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index d3cfced2ce23..a7ea355907b6 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -90,6 +90,13 @@ config DVB_STV6110 help A DVB-S silicon tuner module. Say Y when you want to support this tuner. +config DVB_STV0900 + tristate "ST STV0900 based" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A DVB-S/S2 demodulator. Say Y when you want to support this frontend. + config DVB_TDA8083 tristate "Philips TDA8083 based" depends on DVB_CORE && I2C diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 1d180fc71023..2231c68291d0 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -7,6 +7,7 @@ EXTRA_CFLAGS += -Idrivers/media/common/tuners/ s921-objs := s921_module.o s921_core.o stb0899-objs = stb0899_drv.o stb0899_algo.o +stv0900-objs = stv0900_core.o stv0900_sw.o obj-$(CONFIG_DVB_PLL) += dvb-pll.o obj-$(CONFIG_DVB_STV0299) += stv0299.o @@ -65,4 +66,5 @@ obj-$(CONFIG_DVB_STV0288) += stv0288.o obj-$(CONFIG_DVB_STB6000) += stb6000.o obj-$(CONFIG_DVB_S921) += s921.o obj-$(CONFIG_DVB_STV6110) += stv6110.o +obj-$(CONFIG_DVB_STV0900) += stv0900.o diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c new file mode 100644 index 000000000000..a5a31536cbcb --- /dev/null +++ b/drivers/media/dvb/frontends/stv0900_sw.c @@ -0,0 +1,2847 @@ +/* + * stv0900_sw.c + * + * Driver for ST STV0900 satellite demodulator IC. + * + * Copyright (C) ST Microelectronics. + * Copyright (C) 2009 NetUP Inc. + * Copyright (C) 2009 Igor M. Liplianin + * + * 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 "stv0900.h" +#include "stv0900_reg.h" +#include "stv0900_priv.h" + +int stv0900_check_signal_presence(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + s32 carr_offset, + agc2_integr, + max_carrier; + + int no_signal; + + switch (demod) { + case STV0900_DEMOD_1: + default: + carr_offset = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8) + | stv0900_read_reg(i_params, + R0900_P1_CFR1); + carr_offset = ge2comp(carr_offset, 16); + agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) + | stv0900_read_reg(i_params, + R0900_P1_AGC2I0); + max_carrier = i_params->dmd1_srch_range / 1000; + break; + case STV0900_DEMOD_2: + carr_offset = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8) + | stv0900_read_reg(i_params, + R0900_P2_CFR1); + carr_offset = ge2comp(carr_offset, 16); + agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) + | stv0900_read_reg(i_params, + R0900_P2_AGC2I0); + max_carrier = i_params->dmd2_srch_range / 1000; + break; + } + + max_carrier += (max_carrier / 10); + max_carrier = 65536 * (max_carrier / 2); + max_carrier /= i_params->mclk / 1000; + if (max_carrier > 0x4000) + max_carrier = 0x4000; + + if ((agc2_integr > 0x2000) + || (carr_offset > + 2*max_carrier) + || (carr_offset < -2*max_carrier)) + no_signal = TRUE; + else + no_signal = FALSE; + + return no_signal; +} + +static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params, + s32 *frequency_inc, s32 *sw_timeout, + s32 *steps, + enum fe_stv0900_demod_num demod) +{ + s32 timeout, freq_inc, max_steps, srate, max_carrier; + + enum fe_stv0900_search_standard standard; + + switch (demod) { + case STV0900_DEMOD_1: + default: + srate = i_params->dmd1_symbol_rate; + max_carrier = i_params->dmd1_srch_range / 1000; + max_carrier += max_carrier / 10; + standard = i_params->dmd1_srch_standard; + break; + case STV0900_DEMOD_2: + srate = i_params->dmd2_symbol_rate; + max_carrier = i_params->dmd2_srch_range / 1000; + max_carrier += max_carrier / 10; + standard = i_params->dmd2_srch_stndrd; + break; + } + + max_carrier = 65536 * (max_carrier / 2); + max_carrier /= i_params->mclk / 1000; + + if (max_carrier > 0x4000) + max_carrier = 0x4000; + + freq_inc = srate; + freq_inc /= i_params->mclk >> 10; + freq_inc = freq_inc << 6; + + switch (standard) { + case STV0900_SEARCH_DVBS1: + case STV0900_SEARCH_DSS: + freq_inc *= 3; + timeout = 20; + break; + case STV0900_SEARCH_DVBS2: + freq_inc *= 4; + timeout = 25; + break; + case STV0900_AUTO_SEARCH: + default: + freq_inc *= 3; + timeout = 25; + break; + } + + freq_inc /= 100; + + if ((freq_inc > max_carrier) || (freq_inc < 0)) + freq_inc = max_carrier / 2; + + timeout *= 27500; + + if (srate > 0) + timeout /= srate / 1000; + + if ((timeout > 100) || (timeout < 0)) + timeout = 100; + + max_steps = (max_carrier / freq_inc) + 1; + + if ((max_steps > 100) || (max_steps < 0)) { + max_steps = 100; + freq_inc = max_carrier / max_steps; + } + + *frequency_inc = freq_inc; + *sw_timeout = timeout; + *steps = max_steps; + +} + +static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params, + s32 FreqIncr, s32 Timeout, int zigzag, + s32 MaxStep, enum fe_stv0900_demod_num demod) +{ + int no_signal, + lock = FALSE; + s32 stepCpt, + freqOffset, + max_carrier; + + switch (demod) { + case STV0900_DEMOD_1: + default: + max_carrier = i_params->dmd1_srch_range / 1000; + max_carrier += (max_carrier / 10); + break; + case STV0900_DEMOD_2: + max_carrier = i_params->dmd2_srch_range / 1000; + max_carrier += (max_carrier / 10); + break; + } + + max_carrier = 65536 * (max_carrier / 2); + max_carrier /= i_params->mclk / 1000; + + if (max_carrier > 0x4000) + max_carrier = 0x4000; + + if (zigzag == TRUE) + freqOffset = 0; + else + freqOffset = -max_carrier + FreqIncr; + + stepCpt = 0; + + do { + switch (demod) { + case STV0900_DEMOD_1: + default: + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); + stv0900_write_reg(i_params, R0900_P1_CFRINIT1, + (freqOffset / 256) & 0xFF); + stv0900_write_reg(i_params, R0900_P1_CFRINIT0, + freqOffset & 0xFF); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); + stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1); + + if (i_params->chip_id == 0x12) { + stv0900_write_bits(i_params, + F0900_P1_RST_HWARE, 1); + stv0900_write_bits(i_params, + F0900_P1_RST_HWARE, 0); + } + break; + case STV0900_DEMOD_2: + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C); + stv0900_write_reg(i_params, R0900_P2_CFRINIT1, + (freqOffset / 256) & 0xFF); + stv0900_write_reg(i_params, R0900_P2_CFRINIT0, + freqOffset & 0xFF); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); + stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1); + + if (i_params->chip_id == 0x12) { + stv0900_write_bits(i_params, + F0900_P2_RST_HWARE, 1); + stv0900_write_bits(i_params, + F0900_P2_RST_HWARE, 0); + } + break; + } + + if (zigzag == TRUE) { + if (freqOffset >= 0) + freqOffset = -freqOffset - 2 * FreqIncr; + else + freqOffset = -freqOffset; + } else + freqOffset += + 2 * FreqIncr; + + stepCpt++; + lock = stv0900_get_demod_lock(i_params, demod, Timeout); + no_signal = stv0900_check_signal_presence(i_params, demod); + + } while ((lock == FALSE) + && (no_signal == FALSE) + && ((freqOffset - FreqIncr) < max_carrier) + && ((freqOffset + FreqIncr) > -max_carrier) + && (stepCpt < MaxStep)); + + switch (demod) { + case STV0900_DEMOD_1: + default: + stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0); + break; + case STV0900_DEMOD_2: + stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0); + break; + } + + return lock; +} + +int stv0900_sw_algo(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + int lock = FALSE; + + int no_signal, + zigzag; + s32 dvbs2_fly_wheel; + + s32 freqIncrement, softStepTimeout, trialCounter, max_steps; + + stv0900_get_sw_loop_params(i_params, &freqIncrement, &softStepTimeout, + &max_steps, demod); + switch (demod) { + case STV0900_DEMOD_1: + default: + switch (i_params->dmd1_srch_standard) { + case STV0900_SEARCH_DVBS1: + case STV0900_SEARCH_DSS: + if (i_params->chip_id >= 0x20) + stv0900_write_reg(i_params, R0900_P1_CARFREQ, + 0x3B); + else + stv0900_write_reg(i_params, R0900_P1_CARFREQ, + 0xef); + + stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x49); + zigzag = FALSE; + break; + case STV0900_SEARCH_DVBS2: + if (i_params->chip_id >= 0x20) + stv0900_write_reg(i_params, R0900_P1_CORRELABS, + 0x79); + else + stv0900_write_reg(i_params, R0900_P1_CORRELABS, + 0x68); + + stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, + 0x89); + + zigzag = TRUE; + break; + case STV0900_AUTO_SEARCH: + default: + if (i_params->chip_id >= 0x20) { + stv0900_write_reg(i_params, R0900_P1_CARFREQ, + 0x3B); + stv0900_write_reg(i_params, R0900_P1_CORRELABS, + 0x79); + } else { + stv0900_write_reg(i_params, R0900_P1_CARFREQ, + 0xef); + stv0900_write_reg(i_params, R0900_P1_CORRELABS, + 0x68); + } + + stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, + 0xc9); + zigzag = FALSE; + break; + } + + trialCounter = 0; + do { + lock = stv0900_search_carr_sw_loop(i_params, + freqIncrement, + softStepTimeout, + zigzag, + max_steps, + demod); + no_signal = stv0900_check_signal_presence(i_params, + demod); + trialCounter++; + if ((lock == TRUE) + || (no_signal == TRUE) + || (trialCounter == 2)) { + + if (i_params->chip_id >= 0x20) { + stv0900_write_reg(i_params, + R0900_P1_CARFREQ, + 0x49); + stv0900_write_reg(i_params, + R0900_P1_CORRELABS, + 0x9e); + } else { + stv0900_write_reg(i_params, + R0900_P1_CARFREQ, + 0xed); + stv0900_write_reg(i_params, + R0900_P1_CORRELABS, + 0x88); + } + + if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS2_FOUND)) { + msleep(softStepTimeout); + dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT); + + if (dvbs2_fly_wheel < 0xd) { + msleep(softStepTimeout); + dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT); + } + + if (dvbs2_fly_wheel < 0xd) { + lock = FALSE; + + if (trialCounter < 2) { + if (i_params->chip_id >= 0x20) + stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x79); + else + stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x68); + + stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x89); + } + } + } + } + + } while ((lock == FALSE) + && (trialCounter < 2) + && (no_signal == FALSE)); + + break; + case STV0900_DEMOD_2: + switch (i_params->dmd2_srch_stndrd) { + case STV0900_SEARCH_DVBS1: + case STV0900_SEARCH_DSS: + if (i_params->chip_id >= 0x20) + stv0900_write_reg(i_params, R0900_P2_CARFREQ, + 0x3b); + else + stv0900_write_reg(i_params, R0900_P2_CARFREQ, + 0xef); + + stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, + 0x49); + zigzag = FALSE; + break; + case STV0900_SEARCH_DVBS2: + if (i_params->chip_id >= 0x20) + stv0900_write_reg(i_params, R0900_P2_CORRELABS, + 0x79); + else + stv0900_write_reg(i_params, R0900_P2_CORRELABS, + 0x68); + + stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89); + zigzag = TRUE; + break; + case STV0900_AUTO_SEARCH: + default: + if (i_params->chip_id >= 0x20) { + stv0900_write_reg(i_params, R0900_P2_CARFREQ, + 0x3b); + stv0900_write_reg(i_params, R0900_P2_CORRELABS, + 0x79); + } else { + stv0900_write_reg(i_params, R0900_P2_CARFREQ, + 0xef); + stv0900_write_reg(i_params, R0900_P2_CORRELABS, + 0x68); + } + + stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0xc9); + + zigzag = FALSE; + break; + } + + trialCounter = 0; + + do { + lock = stv0900_search_carr_sw_loop(i_params, + freqIncrement, + softStepTimeout, + zigzag, + max_steps, + demod); + no_signal = stv0900_check_signal_presence(i_params, + demod); + trialCounter++; + if ((lock == TRUE) + || (no_signal == TRUE) + || (trialCounter == 2)) { + if (i_params->chip_id >= 0x20) { + stv0900_write_reg(i_params, + R0900_P2_CARFREQ, + 0x49); + stv0900_write_reg(i_params, + R0900_P2_CORRELABS, + 0x9e); + } else { + stv0900_write_reg(i_params, + R0900_P2_CARFREQ, + 0xed); + stv0900_write_reg(i_params, + R0900_P2_CORRELABS, + 0x88); + } + + if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS2_FOUND)) { + msleep(softStepTimeout); + dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT); + if (dvbs2_fly_wheel < 0xd) { + msleep(softStepTimeout); + dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT); + } + + if (dvbs2_fly_wheel < 0xd) { + lock = FALSE; + if (trialCounter < 2) { + if (i_params->chip_id >= 0x20) + stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x79); + else + stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x68); + + stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89); + } + } + } + } + + } while ((lock == FALSE) && (trialCounter < 2) && (no_signal == FALSE)); + + break; + } + + return lock; +} + +static u32 stv0900_get_symbol_rate(struct stv0900_internal *i_params, + u32 mclk, + enum fe_stv0900_demod_num demod) +{ + s32 sfr_field3, sfr_field2, sfr_field1, sfr_field0, + rem1, rem2, intval1, intval2, srate; + + dmd_reg(sfr_field3, F0900_P1_SYMB_FREQ3, F0900_P2_SYMB_FREQ3); + dmd_reg(sfr_field2, F0900_P1_SYMB_FREQ2, F0900_P2_SYMB_FREQ2); + dmd_reg(sfr_field1, F0900_P1_SYMB_FREQ1, F0900_P2_SYMB_FREQ1); + dmd_reg(sfr_field0, F0900_P1_SYMB_FREQ0, F0900_P2_SYMB_FREQ0); + + srate = (stv0900_get_bits(i_params, sfr_field3) << 24) + + (stv0900_get_bits(i_params, sfr_field2) << 16) + + (stv0900_get_bits(i_params, sfr_field1) << 8) + + (stv0900_get_bits(i_params, sfr_field0)); + dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n", + srate, stv0900_get_bits(i_params, sfr_field0), + stv0900_get_bits(i_params, sfr_field1), + stv0900_get_bits(i_params, sfr_field2), + stv0900_get_bits(i_params, sfr_field3)); + + intval1 = (mclk) >> 16; + intval2 = (srate) >> 16; + + rem1 = (mclk) % 0x10000; + rem2 = (srate) % 0x10000; + srate = (intval1 * intval2) + + ((intval1 * rem2) >> 16) + + ((intval2 * rem1) >> 16); + + return srate; +} + +static void stv0900_set_symbol_rate(struct stv0900_internal *i_params, + u32 mclk, u32 srate, + enum fe_stv0900_demod_num demod) +{ + s32 sfr_init_reg; + u32 symb; + + dprintk(KERN_INFO "%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk, + srate, demod); + + dmd_reg(sfr_init_reg, R0900_P1_SFRINIT1, R0900_P2_SFRINIT1); + + if (srate > 60000000) { + symb = srate << 4; + symb /= (mclk >> 12); + } else if (srate > 6000000) { + symb = srate << 6; + symb /= (mclk >> 10); + } else { + symb = srate << 9; + symb /= (mclk >> 7); + } + + stv0900_write_reg(i_params, sfr_init_reg, (symb >> 8) & 0x7F); + stv0900_write_reg(i_params, sfr_init_reg + 1, (symb & 0xFF)); +} + +static void stv0900_set_max_symbol_rate(struct stv0900_internal *i_params, + u32 mclk, u32 srate, + enum fe_stv0900_demod_num demod) +{ + s32 sfr_max_reg; + u32 symb; + + dmd_reg(sfr_max_reg, R0900_P1_SFRUP1, R0900_P2_SFRUP1); + + srate = 105 * (srate / 100); + + if (srate > 60000000) { + symb = srate << 4; + symb /= (mclk >> 12); + } else if (srate > 6000000) { + symb = srate << 6; + symb /= (mclk >> 10); + } else { + symb = srate << 9; + symb /= (mclk >> 7); + } + + if (symb < 0x7fff) { + stv0900_write_reg(i_params, sfr_max_reg, (symb >> 8) & 0x7F); + stv0900_write_reg(i_params, sfr_max_reg + 1, (symb & 0xFF)); + } else { + stv0900_write_reg(i_params, sfr_max_reg, 0x7F); + stv0900_write_reg(i_params, sfr_max_reg + 1, 0xFF); + } +} + +static void stv0900_set_min_symbol_rate(struct stv0900_internal *i_params, + u32 mclk, u32 srate, + enum fe_stv0900_demod_num demod) +{ + s32 sfr_min_reg; + u32 symb; + + dmd_reg(sfr_min_reg, R0900_P1_SFRLOW1, R0900_P2_SFRLOW1); + + srate = 95 * (srate / 100); + if (srate > 60000000) { + symb = srate << 4; + symb /= (mclk >> 12); + + } else if (srate > 6000000) { + symb = srate << 6; + symb /= (mclk >> 10); + + } else { + symb = srate << 9; + symb /= (mclk >> 7); + } + + stv0900_write_reg(i_params, sfr_min_reg, (symb >> 8) & 0xFF); + stv0900_write_reg(i_params, sfr_min_reg + 1, (symb & 0xFF)); +} + +static s32 stv0900_get_timing_offst(struct stv0900_internal *i_params, + u32 srate, + enum fe_stv0900_demod_num demod) +{ + s32 tmgreg, + timingoffset; + + dmd_reg(tmgreg, R0900_P1_TMGREG2, R0900_P2_TMGREG2); + + timingoffset = (stv0900_read_reg(i_params, tmgreg) << 16) + + (stv0900_read_reg(i_params, tmgreg + 1) << 8) + + (stv0900_read_reg(i_params, tmgreg + 2)); + + timingoffset = ge2comp(timingoffset, 24); + + + if (timingoffset == 0) + timingoffset = 1; + + timingoffset = ((s32)srate * 10) / ((s32)0x1000000 / timingoffset); + timingoffset /= 320; + + return timingoffset; +} + +static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + s32 rolloff, man_fld, matstr_reg, rolloff_ctl_fld; + + dmd_reg(man_fld, F0900_P1_MANUAL_ROLLOFF, F0900_P2_MANUAL_ROLLOFF); + dmd_reg(matstr_reg, R0900_P1_MATSTR1, R0900_P2_MATSTR1); + dmd_reg(rolloff_ctl_fld, F0900_P1_ROLLOFF_CONTROL, + F0900_P2_ROLLOFF_CONTROL); + + if (i_params->chip_id == 0x10) { + stv0900_write_bits(i_params, man_fld, 1); + rolloff = stv0900_read_reg(i_params, matstr_reg) & 0x03; + stv0900_write_bits(i_params, rolloff_ctl_fld, rolloff); + } else + stv0900_write_bits(i_params, man_fld, 0); +} + +static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro) +{ + u32 rolloff; + + switch (ro) { + case STV0900_20: + rolloff = 20; + break; + case STV0900_25: + rolloff = 25; + break; + case STV0900_35: + default: + rolloff = 35; + break; + } + + return srate + (srate * rolloff) / 100; +} + +static int stv0900_check_timing_lock(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + int timingLock = FALSE; + s32 i, + timingcpt = 0; + u8 carFreq, + tmgTHhigh, + tmgTHLow; + + switch (demod) { + case STV0900_DEMOD_1: + default: + carFreq = stv0900_read_reg(i_params, R0900_P1_CARFREQ); + tmgTHhigh = stv0900_read_reg(i_params, R0900_P1_TMGTHRISE); + tmgTHLow = stv0900_read_reg(i_params, R0900_P1_TMGTHFALL); + stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20); + stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x0); + stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); + stv0900_write_reg(i_params, R0900_P1_RTC, 0x80); + stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x40); + stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x0); + stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0x0); + stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0x0); + stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x65); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); + msleep(7); + + for (i = 0; i < 10; i++) { + if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2) + timingcpt++; + + msleep(1); + } + + if (timingcpt >= 3) + timingLock = TRUE; + + stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); + stv0900_write_reg(i_params, R0900_P1_RTC, 0x88); + stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68); + stv0900_write_reg(i_params, R0900_P1_CARFREQ, carFreq); + stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, tmgTHhigh); + stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, tmgTHLow); + break; + case STV0900_DEMOD_2: + carFreq = stv0900_read_reg(i_params, R0900_P2_CARFREQ); + tmgTHhigh = stv0900_read_reg(i_params, R0900_P2_TMGTHRISE); + tmgTHLow = stv0900_read_reg(i_params, R0900_P2_TMGTHFALL); + stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20); + stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0); + stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); + stv0900_write_reg(i_params, R0900_P2_RTC, 0x80); + stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x40); + stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x0); + stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0x0); + stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0x0); + stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x65); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); + msleep(5); + for (i = 0; i < 10; i++) { + if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2) + timingcpt++; + + msleep(1); + } + + if (timingcpt >= 3) + timingLock = TRUE; + + stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); + stv0900_write_reg(i_params, R0900_P2_RTC, 0x88); + stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68); + stv0900_write_reg(i_params, R0900_P2_CARFREQ, carFreq); + stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, tmgTHhigh); + stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, tmgTHLow); + break; + } + + return timingLock; +} + +static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe, + s32 demod_timeout) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + + int lock = FALSE; + s32 srate, search_range, locktimeout, + currier_step, nb_steps, current_step, + direction, tuner_freq, timeout; + + switch (demod) { + case STV0900_DEMOD_1: + default: + srate = i_params->dmd1_symbol_rate; + search_range = i_params->dmd1_srch_range; + break; + + case STV0900_DEMOD_2: + srate = i_params->dmd2_symbol_rate; + search_range = i_params->dmd2_srch_range; + break; + } + + if (srate >= 10000000) + locktimeout = demod_timeout / 3; + else + locktimeout = demod_timeout / 2; + + lock = stv0900_get_demod_lock(i_params, demod, locktimeout); + + if (lock == FALSE) { + if (srate >= 10000000) { + if (stv0900_check_timing_lock(i_params, demod) == TRUE) { + switch (demod) { + case STV0900_DEMOD_1: + default: + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); + break; + case STV0900_DEMOD_2: + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); + break; + } + + lock = stv0900_get_demod_lock(i_params, demod, demod_timeout); + } else + lock = FALSE; + } else { + if (srate <= 4000000) + currier_step = 1000; + else if (srate <= 7000000) + currier_step = 2000; + else if (srate <= 10000000) + currier_step = 3000; + else + currier_step = 5000; + + nb_steps = ((search_range / 1000) / currier_step); + nb_steps /= 2; + nb_steps = (2 * (nb_steps + 1)); + if (nb_steps < 0) + nb_steps = 2; + else if (nb_steps > 12) + nb_steps = 12; + + current_step = 1; + direction = 1; + timeout = (demod_timeout / 3); + if (timeout > 1000) + timeout = 1000; + + switch (demod) { + case STV0900_DEMOD_1: + default: + if (lock == FALSE) { + tuner_freq = i_params->tuner1_freq; + i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + i_params->dmd1_symbol_rate; + + while ((current_step <= nb_steps) && (lock == FALSE)) { + + if (direction > 0) + tuner_freq += (current_step * currier_step); + else + tuner_freq -= (current_step * currier_step); + + stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); + if (i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS2) { + stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); + } + + stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0); + stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); + lock = stv0900_get_demod_lock(i_params, demod, timeout); + direction *= -1; + current_step++; + } + } + break; + case STV0900_DEMOD_2: + if (lock == FALSE) { + tuner_freq = i_params->tuner2_freq; + i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + srate; + + while ((current_step <= nb_steps) && (lock == FALSE)) { + + if (direction > 0) + tuner_freq += (current_step * currier_step); + else + tuner_freq -= (current_step * currier_step); + + stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C); + if (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS2) { + stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); + } + + stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0); + stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); + lock = stv0900_get_demod_lock(i_params, demod, timeout); + direction *= -1; + current_step++; + } + } + break; + } + } + } + + return lock; +} + +static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout, + s32 srate, + enum fe_stv0900_search_algo algo) +{ + switch (algo) { + case STV0900_BLIND_SEARCH: + if (srate <= 1500000) { + (*demod_timeout) = 1500; + (*fec_timeout) = 400; + } else if (srate <= 5000000) { + (*demod_timeout) = 1000; + (*fec_timeout) = 300; + } else { + (*demod_timeout) = 700; + (*fec_timeout) = 100; + } + + break; + case STV0900_COLD_START: + case STV0900_WARM_START: + default: + if (srate <= 1000000) { + (*demod_timeout) = 3000; + (*fec_timeout) = 1700; + } else if (srate <= 2000000) { + (*demod_timeout) = 2500; + (*fec_timeout) = 1100; + } else if (srate <= 5000000) { + (*demod_timeout) = 1000; + (*fec_timeout) = 550; + } else if (srate <= 10000000) { + (*demod_timeout) = 700; + (*fec_timeout) = 250; + } else if (srate <= 20000000) { + (*demod_timeout) = 400; + (*fec_timeout) = 130; + } + + else { + (*demod_timeout) = 300; + (*fec_timeout) = 100; + } + + break; + + } + + if (algo == STV0900_WARM_START) + (*demod_timeout) /= 2; +} + +static void stv0900_set_viterbi_tracq(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + + s32 vth_reg; + + dprintk(KERN_INFO "%s\n", __func__); + + dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12); + + stv0900_write_reg(i_params, vth_reg++, 0xd0); + stv0900_write_reg(i_params, vth_reg++, 0x7d); + stv0900_write_reg(i_params, vth_reg++, 0x53); + stv0900_write_reg(i_params, vth_reg++, 0x2F); + stv0900_write_reg(i_params, vth_reg++, 0x24); + stv0900_write_reg(i_params, vth_reg++, 0x1F); +} + +static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params, + enum fe_stv0900_search_standard Standard, + enum fe_stv0900_fec PunctureRate, + enum fe_stv0900_demod_num demod) +{ + + s32 fecmReg, + prvitReg; + + dprintk(KERN_INFO "%s: ViterbiStandard = ", __func__); + + switch (demod) { + case STV0900_DEMOD_1: + default: + fecmReg = R0900_P1_FECM; + prvitReg = R0900_P1_PRVIT; + break; + case STV0900_DEMOD_2: + fecmReg = R0900_P2_FECM; + prvitReg = R0900_P2_PRVIT; + break; + } + + switch (Standard) { + case STV0900_AUTO_SEARCH: + dprintk("Auto\n"); + stv0900_write_reg(i_params, fecmReg, 0x10); + stv0900_write_reg(i_params, prvitReg, 0x3F); + break; + case STV0900_SEARCH_DVBS1: + dprintk("DVBS1\n"); + stv0900_write_reg(i_params, fecmReg, 0x00); + switch (PunctureRate) { + case STV0900_FEC_UNKNOWN: + default: + stv0900_write_reg(i_params, prvitReg, 0x2F); + break; + case STV0900_FEC_1_2: + stv0900_write_reg(i_params, prvitReg, 0x01); + break; + case STV0900_FEC_2_3: + stv0900_write_reg(i_params, prvitReg, 0x02); + break; + case STV0900_FEC_3_4: + stv0900_write_reg(i_params, prvitReg, 0x04); + break; + case STV0900_FEC_5_6: + stv0900_write_reg(i_params, prvitReg, 0x08); + break; + case STV0900_FEC_7_8: + stv0900_write_reg(i_params, prvitReg, 0x20); + break; + } + + break; + case STV0900_SEARCH_DSS: + dprintk("DSS\n"); + stv0900_write_reg(i_params, fecmReg, 0x80); + switch (PunctureRate) { + case STV0900_FEC_UNKNOWN: + default: + stv0900_write_reg(i_params, prvitReg, 0x13); + break; + case STV0900_FEC_1_2: + stv0900_write_reg(i_params, prvitReg, 0x01); + break; + case STV0900_FEC_2_3: + stv0900_write_reg(i_params, prvitReg, 0x02); + break; + case STV0900_FEC_6_7: + stv0900_write_reg(i_params, prvitReg, 0x10); + break; + } + break; + default: + break; + } +} + +static void stv0900_track_optimization(struct dvb_frontend *fe) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + + s32 srate, pilots, aclc, freq1, freq0, + i = 0, timed, timef, blindTunSw = 0; + + enum fe_stv0900_rolloff rolloff; + enum fe_stv0900_modcode foundModcod; + + dprintk(KERN_INFO "%s\n", __func__); + + srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); + srate += stv0900_get_timing_offst(i_params, srate, demod); + + switch (demod) { + case STV0900_DEMOD_1: + default: + switch (i_params->dmd1_rslts.standard) { + case STV0900_DVBS1_STANDARD: + if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) { + stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); + } + + stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff); + stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); + stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); + break; + case STV0900_DSS_STANDARD: + if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) { + stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); + } + + stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff); + stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); + stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); + break; + case STV0900_DVBS2_STANDARD: + stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); + stv0900_write_reg(i_params, R0900_P1_ACLC, 0); + stv0900_write_reg(i_params, R0900_P1_BCLC, 0); + if (i_params->dmd1_rslts.frame_length == STV0900_LONG_FRAME) { + foundModcod = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD); + pilots = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01; + aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id); + if (foundModcod <= STV0900_QPSK_910) + stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc); + else if (foundModcod <= STV0900_8PSK_910) { + stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); + stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc); + } + + if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) { + if (foundModcod <= STV0900_16APSK_910) { + stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); + stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc); + } else if (foundModcod <= STV0900_32APSK_910) { + stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); + stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc); + } + } + + } else { + aclc = stv0900_get_optim_short_carr_loop(srate, i_params->dmd1_rslts.modulation, i_params->chip_id); + if (i_params->dmd1_rslts.modulation == STV0900_QPSK) + stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc); + + else if (i_params->dmd1_rslts.modulation == STV0900_8PSK) { + stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); + stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc); + } else if (i_params->dmd1_rslts.modulation == STV0900_16APSK) { + stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); + stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc); + } else if (i_params->dmd1_rslts.modulation == STV0900_32APSK) { + stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); + stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc); + } + + } + + if (i_params->chip_id <= 0x11) { + if (i_params->demod_mode != STV0900_SINGLE) + stv0900_activate_s2_modcode(i_params, demod); + + } + + stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67); + break; + case STV0900_UNKNOWN_STANDARD: + default: + stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); + break; + } + + freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2); + freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1); + rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS); + if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { + stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00); + stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); + stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01); + stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); + stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod); + stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod); + blindTunSw = 1; + } + + if (i_params->chip_id >= 0x20) { + if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) { + stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0a); + stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x0); + } + } + + if (i_params->chip_id < 0x20) + stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x08); + + if (i_params->chip_id == 0x10) + stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0x0A); + + stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); + + if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd1_symbol_rate < 10000000)) { + stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); + stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); + i_params->tuner1_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000; + + if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) { + if (i_params->dmd1_srch_algo != STV0900_WARM_START) + stv0900_set_bandwidth(fe, i_params->tuner1_bw); + } + + if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) + msleep(50); + else + msleep(5); + + stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START); + + if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) { + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); + stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); + stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); + i = 0; + while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) { + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); + stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); + stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); + i++; + } + } + + } + + if (i_params->chip_id >= 0x20) + stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49); + + if ((i_params->dmd1_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd1_rslts.standard == STV0900_DSS_STANDARD)) + stv0900_set_viterbi_tracq(i_params, demod); + + break; + + case STV0900_DEMOD_2: + switch (i_params->dmd2_rslts.standard) { + case STV0900_DVBS1_STANDARD: + + if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) { + stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); + } + + stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff); + stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); + stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75); + break; + case STV0900_DSS_STANDARD: + if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) { + stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); + } + + stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff); + stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); + stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75); + break; + case STV0900_DVBS2_STANDARD: + stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); + stv0900_write_reg(i_params, R0900_P2_ACLC, 0); + stv0900_write_reg(i_params, R0900_P2_BCLC, 0); + if (i_params->dmd2_rslts.frame_length == STV0900_LONG_FRAME) { + foundModcod = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD); + pilots = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01; + aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id); + if (foundModcod <= STV0900_QPSK_910) + stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc); + else if (foundModcod <= STV0900_8PSK_910) { + stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); + stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc); + } + + if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) { + if (foundModcod <= STV0900_16APSK_910) { + stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); + stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc); + } else if (foundModcod <= STV0900_32APSK_910) { + stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); + stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc); + } + + } + + } else { + aclc = stv0900_get_optim_short_carr_loop(srate, + i_params->dmd2_rslts.modulation, + i_params->chip_id); + + if (i_params->dmd2_rslts.modulation == STV0900_QPSK) + stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc); + + else if (i_params->dmd2_rslts.modulation == STV0900_8PSK) { + stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); + stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc); + } else if (i_params->dmd2_rslts.modulation == STV0900_16APSK) { + stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); + stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc); + } else if (i_params->dmd2_rslts.modulation == STV0900_32APSK) { + stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); + stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc); + } + } + + stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67); + + break; + case STV0900_UNKNOWN_STANDARD: + default: + stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); + break; + } + + freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2); + freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1); + rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS); + if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { + stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00); + stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); + stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); + stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); + stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod); + stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod); + blindTunSw = 1; + } + + if (i_params->chip_id >= 0x20) { + if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) { + stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0a); + stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x0); + } + } + + if (i_params->chip_id < 0x20) + stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x08); + + if (i_params->chip_id == 0x10) + stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0x0a); + + stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); + if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd2_symbol_rate < 10000000)) { + stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); + stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); + i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000; + + if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) { + if (i_params->dmd2_srch_algo != STV0900_WARM_START) + stv0900_set_bandwidth(fe, i_params->tuner2_bw); + } + + if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) + msleep(50); + else + msleep(5); + + stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START); + if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) { + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); + stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); + stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); + i = 0; + while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) { + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); + stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); + stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); + i++; + } + } + } + + if (i_params->chip_id >= 0x20) + stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49); + + if ((i_params->dmd2_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd2_rslts.standard == STV0900_DSS_STANDARD)) + stv0900_set_viterbi_tracq(i_params, demod); + + break; + } +} + +static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv0900_demod_num demod, s32 time_out) +{ + s32 timer = 0, lock = 0, header_field, pktdelin_field, lock_vit_field; + + enum fe_stv0900_search_state dmd_state; + + dprintk(KERN_INFO "%s\n", __func__); + + dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); + dmd_reg(pktdelin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK); + dmd_reg(lock_vit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT); + + dmd_state = stv0900_get_bits(i_params, header_field); + + while ((timer < time_out) && (lock == 0)) { + switch (dmd_state) { + case STV0900_SEARCH: + case STV0900_PLH_DETECTED: + default: + lock = 0; + break; + case STV0900_DVBS2_FOUND: + lock = stv0900_get_bits(i_params, pktdelin_field); + break; + case STV0900_DVBS_FOUND: + lock = stv0900_get_bits(i_params, lock_vit_field); + break; + } + + if (lock == 0) { + msleep(10); + timer += 10; + } + } + + if (lock) + dprintk("DEMOD FEC LOCK OK\n"); + else + dprintk("DEMOD FEC LOCK FAIL\n"); + + return lock; +} + +static int stv0900_wait_for_lock(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod, + s32 dmd_timeout, s32 fec_timeout) +{ + + s32 timer = 0, lock = 0, str_merg_rst_fld, str_merg_lock_fld; + + dprintk(KERN_INFO "%s\n", __func__); + + dmd_reg(str_merg_rst_fld, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE); + dmd_reg(str_merg_lock_fld, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK); + + lock = stv0900_get_demod_lock(i_params, demod, dmd_timeout); + + if (lock) + lock = lock && stv0900_get_fec_lock(i_params, demod, fec_timeout); + + if (lock) { + lock = 0; + + dprintk(KERN_INFO "%s: Timer = %d, time_out = %d\n", __func__, timer, fec_timeout); + + while ((timer < fec_timeout) && (lock == 0)) { + lock = stv0900_get_bits(i_params, str_merg_lock_fld); + msleep(1); + timer++; + } + } + + if (lock) + dprintk(KERN_INFO "%s: DEMOD LOCK OK\n", __func__); + else + dprintk(KERN_INFO "%s: DEMOD LOCK FAIL\n", __func__); + + if (lock) + return TRUE; + else + return FALSE; +} + +enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe, + enum fe_stv0900_demod_num demod) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_tracking_standard fnd_standard; + s32 state_field, + dss_dvb_field; + + dprintk(KERN_INFO "%s\n", __func__); + + dmd_reg(state_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); + dmd_reg(dss_dvb_field, F0900_P1_DSS_DVB, F0900_P2_DSS_DVB); + + if (stv0900_get_bits(i_params, state_field) == 2) + fnd_standard = STV0900_DVBS2_STANDARD; + + else if (stv0900_get_bits(i_params, state_field) == 3) { + if (stv0900_get_bits(i_params, dss_dvb_field) == 1) + fnd_standard = STV0900_DSS_STANDARD; + else + fnd_standard = STV0900_DVBS1_STANDARD; + } else + fnd_standard = STV0900_UNKNOWN_STANDARD; + + return fnd_standard; +} + +static s32 stv0900_get_carr_freq(struct stv0900_internal *i_params, u32 mclk, + enum fe_stv0900_demod_num demod) +{ + s32 cfr_field2, cfr_field1, cfr_field0, + derot, rem1, rem2, intval1, intval2; + + dmd_reg(cfr_field2, F0900_P1_CAR_FREQ2, F0900_P2_CAR_FREQ2); + dmd_reg(cfr_field1, F0900_P1_CAR_FREQ1, F0900_P2_CAR_FREQ1); + dmd_reg(cfr_field0, F0900_P1_CAR_FREQ0, F0900_P2_CAR_FREQ0); + + derot = (stv0900_get_bits(i_params, cfr_field2) << 16) + + (stv0900_get_bits(i_params, cfr_field1) << 8) + + (stv0900_get_bits(i_params, cfr_field0)); + + derot = ge2comp(derot, 24); + intval1 = mclk >> 12; + intval2 = derot >> 12; + rem1 = mclk % 0x1000; + rem2 = derot % 0x1000; + derot = (intval1 * intval2) + + ((intval1 * rem2) >> 12) + + ((intval2 * rem1) >> 12); + + return derot; +} + +static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe) +{ + struct dvb_frontend_ops *frontend_ops = NULL; + struct dvb_tuner_ops *tuner_ops = NULL; + u32 frequency = 0; + + if (&fe->ops) + frontend_ops = &fe->ops; + + if (&frontend_ops->tuner_ops) + tuner_ops = &frontend_ops->tuner_ops; + + if (tuner_ops->get_frequency) { + if ((tuner_ops->get_frequency(fe, &frequency)) < 0) + dprintk("%s: Invalid parameter\n", __func__); + else + dprintk("%s: Frequency=%d\n", __func__, frequency); + + } + + return frequency; +} + +static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + s32 rate_fld, vit_curpun_fld; + enum fe_stv0900_fec prate; + + dmd_reg(vit_curpun_fld, F0900_P1_VIT_CURPUN, F0900_P2_VIT_CURPUN); + rate_fld = stv0900_get_bits(i_params, vit_curpun_fld); + + switch (rate_fld) { + case 13: + prate = STV0900_FEC_1_2; + break; + case 18: + prate = STV0900_FEC_2_3; + break; + case 21: + prate = STV0900_FEC_3_4; + break; + case 24: + prate = STV0900_FEC_5_6; + break; + case 25: + prate = STV0900_FEC_6_7; + break; + case 26: + prate = STV0900_FEC_7_8; + break; + default: + prate = STV0900_FEC_UNKNOWN; + break; + } + + return prate; +} + +static enum fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE; + s32 offsetFreq, + srate_offset, + i = 0; + + u8 timing; + + msleep(5); + switch (demod) { + case STV0900_DEMOD_1: + default: + if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { + timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2); + i = 0; + stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x5c); + + while ((i <= 50) && (timing != 0) && (timing != 0xFF)) { + timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2); + msleep(5); + i += 5; + } + } + + i_params->dmd1_rslts.standard = stv0900_get_standard(fe, demod); + i_params->dmd1_rslts.frequency = stv0900_get_tuner_freq(fe); + offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000; + i_params->dmd1_rslts.frequency += offsetFreq; + i_params->dmd1_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); + srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd1_rslts.symbol_rate, demod); + i_params->dmd1_rslts.symbol_rate += srate_offset; + i_params->dmd1_rslts.fec = stv0900_get_vit_fec(i_params, demod); + i_params->dmd1_rslts.modcode = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD); + i_params->dmd1_rslts.pilot = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01; + i_params->dmd1_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE)) >> 1; + i_params->dmd1_rslts.rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS); + switch (i_params->dmd1_rslts.standard) { + case STV0900_DVBS2_STANDARD: + i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_SPECINV_DEMOD); + if (i_params->dmd1_rslts.modcode <= STV0900_QPSK_910) + i_params->dmd1_rslts.modulation = STV0900_QPSK; + else if (i_params->dmd1_rslts.modcode <= STV0900_8PSK_910) + i_params->dmd1_rslts.modulation = STV0900_8PSK; + else if (i_params->dmd1_rslts.modcode <= STV0900_16APSK_910) + i_params->dmd1_rslts.modulation = STV0900_16APSK; + else if (i_params->dmd1_rslts.modcode <= STV0900_32APSK_910) + i_params->dmd1_rslts.modulation = STV0900_32APSK; + else + i_params->dmd1_rslts.modulation = STV0900_UNKNOWN; + break; + case STV0900_DVBS1_STANDARD: + case STV0900_DSS_STANDARD: + i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_IQINV); + i_params->dmd1_rslts.modulation = STV0900_QPSK; + break; + default: + break; + } + + if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) { + offsetFreq = i_params->dmd1_rslts.frequency - i_params->tuner1_freq; + i_params->tuner1_freq = stv0900_get_tuner_freq(fe); + if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500)) + range = STV0900_RANGEOK; + else + if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd1_rslts.symbol_rate, i_params->dmd1_rslts.rolloff) / 2000)) + range = STV0900_RANGEOK; + else + range = STV0900_OUTOFRANGE; + + } else { + if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500)) + range = STV0900_RANGEOK; + else + range = STV0900_OUTOFRANGE; + } + break; + case STV0900_DEMOD_2: + if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { + timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2); + i = 0; + stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x5c); + + while ((i <= 50) && (timing != 0) && (timing != 0xff)) { + timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2); + msleep(5); + i += 5; + } + } + + i_params->dmd2_rslts.standard = stv0900_get_standard(fe, demod); + i_params->dmd2_rslts.frequency = stv0900_get_tuner_freq(fe); + offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000; + i_params->dmd2_rslts.frequency += offsetFreq; + i_params->dmd2_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); + srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd2_rslts.symbol_rate, demod); + i_params->dmd2_rslts.symbol_rate += srate_offset; + i_params->dmd2_rslts.fec = stv0900_get_vit_fec(i_params, demod); + i_params->dmd2_rslts.modcode = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD); + i_params->dmd2_rslts.pilot = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01; + i_params->dmd2_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE)) >> 1; + i_params->dmd2_rslts.rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS); + switch (i_params->dmd2_rslts.standard) { + case STV0900_DVBS2_STANDARD: + i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_SPECINV_DEMOD); + if (i_params->dmd2_rslts.modcode <= STV0900_QPSK_910) + i_params->dmd2_rslts.modulation = STV0900_QPSK; + else if (i_params->dmd2_rslts.modcode <= STV0900_8PSK_910) + i_params->dmd2_rslts.modulation = STV0900_8PSK; + else if (i_params->dmd2_rslts.modcode <= STV0900_16APSK_910) + i_params->dmd2_rslts.modulation = STV0900_16APSK; + else if (i_params->dmd2_rslts.modcode <= STV0900_32APSK_910) + i_params->dmd2_rslts.modulation = STV0900_32APSK; + else + i_params->dmd2_rslts.modulation = STV0900_UNKNOWN; + break; + case STV0900_DVBS1_STANDARD: + case STV0900_DSS_STANDARD: + i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_IQINV); + i_params->dmd2_rslts.modulation = STV0900_QPSK; + break; + default: + break; + } + + if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) { + offsetFreq = i_params->dmd2_rslts.frequency - i_params->tuner2_freq; + i_params->tuner2_freq = stv0900_get_tuner_freq(fe); + + if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500)) + range = STV0900_RANGEOK; + else + if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd2_rslts.symbol_rate, i_params->dmd2_rslts.rolloff) / 2000)) + range = STV0900_RANGEOK; + else + range = STV0900_OUTOFRANGE; + } else { + if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500)) + range = STV0900_RANGEOK; + else + range = STV0900_OUTOFRANGE; + } + + break; + } + + return range; +} + +static enum fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + + s32 srate, demod_timeout, + fec_timeout, freq1, freq0; + enum fe_stv0900_signal_type signal_type = STV0900_NODATA;; + + switch (demod) { + case STV0900_DEMOD_1: + default: + i_params->dmd1_rslts.locked = FALSE; + if (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) { + srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); + srate += stv0900_get_timing_offst(i_params, srate, demod); + if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) + stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); + + stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START); + freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2); + freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1); + stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); + stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); + stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); + stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); + if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { + i_params->dmd1_rslts.locked = TRUE; + signal_type = stv0900_get_signal_params(fe); + stv0900_track_optimization(fe); + } else { + stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1c); + stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); + stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); + if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { + i_params->dmd1_rslts.locked = TRUE; + signal_type = stv0900_get_signal_params(fe); + stv0900_track_optimization(fe); + } + + } + + } else + i_params->dmd1_rslts.locked = FALSE; + + break; + case STV0900_DEMOD_2: + i_params->dmd2_rslts.locked = FALSE; + if (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) { + srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); + srate += stv0900_get_timing_offst(i_params, srate, demod); + + if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) + stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); + + stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START); + freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2); + freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1); + stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); + stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C); + stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); + stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); + + if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { + i_params->dmd2_rslts.locked = TRUE; + signal_type = stv0900_get_signal_params(fe); + stv0900_track_optimization(fe); + } else { + stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1c); + stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); + stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); + + if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { + i_params->dmd2_rslts.locked = TRUE; + signal_type = stv0900_get_signal_params(fe); + stv0900_track_optimization(fe); + } + + } + + } else + i_params->dmd1_rslts.locked = FALSE; + + break; + } + + return signal_type; +} + +static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + u32 minagc2level = 0xffff, + agc2level, + init_freq, freq_step; + + s32 i, j, nb_steps, direction; + + dprintk(KERN_INFO "%s\n", __func__); + + switch (demod) { + case STV0900_DEMOD_1: + default: + stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); + stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1); + + stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83); + stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0); + + stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82); + stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0); + stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0); + + stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); + nb_steps = -1 + (i_params->dmd1_srch_range / 1000000); + nb_steps /= 2; + nb_steps = (2 * nb_steps) + 1; + + if (nb_steps < 0) + nb_steps = 1; + + direction = 1; + + freq_step = (1000000 << 8) / (i_params->mclk >> 8); + + init_freq = 0; + + for (i = 0; i < nb_steps; i++) { + if (direction > 0) + init_freq = init_freq + (freq_step * i); + else + init_freq = init_freq - (freq_step * i); + + direction *= -1; + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C); + stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (init_freq >> 8) & 0xff); + stv0900_write_reg(i_params, R0900_P1_CFRINIT0, init_freq & 0xff); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x58); + msleep(10); + agc2level = 0; + + for (j = 0; j < 10; j++) + agc2level += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) + | stv0900_read_reg(i_params, R0900_P1_AGC2I0); + + agc2level /= 10; + + if (agc2level < minagc2level) + minagc2level = agc2level; + } + break; + case STV0900_DEMOD_2: + stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); + stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1); + stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83); + stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0); + stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82); + stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0); + stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0); + stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); + nb_steps = -1 + (i_params->dmd2_srch_range / 1000000); + nb_steps /= 2; + nb_steps = (2 * nb_steps) + 1; + + if (nb_steps < 0) + nb_steps = 1; + + direction = 1; + freq_step = (1000000 << 8) / (i_params->mclk >> 8); + init_freq = 0; + for (i = 0; i < nb_steps; i++) { + if (direction > 0) + init_freq = init_freq + (freq_step * i); + else + init_freq = init_freq - (freq_step * i); + + direction *= -1; + + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C); + stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (init_freq >> 8) & 0xff); + stv0900_write_reg(i_params, R0900_P2_CFRINIT0, init_freq & 0xff); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x58); + + msleep(10); + agc2level = 0; + for (j = 0; j < 10; j++) + agc2level += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) + | stv0900_read_reg(i_params, R0900_P2_AGC2I0); + + agc2level /= 10; + + if (agc2level < minagc2level) + minagc2level = agc2level; + } + break; + } + + return (u16)minagc2level; +} + +static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + int timingLock = FALSE; + s32 i, timingcpt = 0, + direction = 1, + nb_steps, + current_step = 0, + tuner_freq; + + u32 coarse_srate = 0, agc2_integr = 0, currier_step = 1200; + + switch (demod) { + case STV0900_DEMOD_1: + default: + stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1F); + stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0x12); + stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xf0); + stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xe0); + stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1); + stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83); + stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0); + stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82); + stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0); + stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0); + stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x50); + + if (i_params->chip_id >= 0x20) { + stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x6a); + stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x95); + } else { + stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed); + stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x73); + } + + if (i_params->dmd1_symbol_rate <= 2000000) + currier_step = 1000; + else if (i_params->dmd1_symbol_rate <= 5000000) + currier_step = 2000; + else if (i_params->dmd1_symbol_rate <= 12000000) + currier_step = 3000; + else + currier_step = 5000; + + nb_steps = -1 + ((i_params->dmd1_srch_range / 1000) / currier_step); + nb_steps /= 2; + nb_steps = (2 * nb_steps) + 1; + + if (nb_steps < 0) + nb_steps = 1; + + else if (nb_steps > 10) { + nb_steps = 11; + currier_step = (i_params->dmd1_srch_range / 1000) / 10; + } + + current_step = 0; + + direction = 1; + tuner_freq = i_params->tuner1_freq; + + while ((timingLock == FALSE) && (current_step < nb_steps)) { + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5F); + stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x0); + + msleep(50); + + for (i = 0; i < 10; i++) { + if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2) + timingcpt++; + + agc2_integr += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) | stv0900_read_reg(i_params, R0900_P1_AGC2I0); + + } + + agc2_integr /= 10; + coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); + current_step++; + direction *= -1; + + dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started. tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n", tuner_freq, agc2_integr, coarse_srate, timingcpt); + + if ((timingcpt >= 5) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) { + timingLock = TRUE; + } + + else if (current_step < nb_steps) { + if (direction > 0) + tuner_freq += (current_step * currier_step); + else + tuner_freq -= (current_step * currier_step); + + stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw); + } + } + + if (timingLock == FALSE) + coarse_srate = 0; + else + coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); + break; + case STV0900_DEMOD_2: + stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1F); + stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0x12); + stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xf0); + stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xe0); + stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1); + stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83); + stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0); + stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82); + stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0); + stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0); + stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x50); + + if (i_params->chip_id >= 0x20) { + stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x6a); + stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x95); + } else { + stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed); + stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x73); + } + + if (i_params->dmd2_symbol_rate <= 2000000) + currier_step = 1000; + else if (i_params->dmd2_symbol_rate <= 5000000) + currier_step = 2000; + else if (i_params->dmd2_symbol_rate <= 12000000) + currier_step = 3000; + else + currier_step = 5000; + + + nb_steps = -1 + ((i_params->dmd2_srch_range / 1000) / currier_step); + nb_steps /= 2; + nb_steps = (2 * nb_steps) + 1; + + if (nb_steps < 0) + nb_steps = 1; + else if (nb_steps > 10) { + nb_steps = 11; + currier_step = (i_params->dmd2_srch_range / 1000) / 10; + } + + current_step = 0; + direction = 1; + tuner_freq = i_params->tuner2_freq; + + while ((timingLock == FALSE) && (current_step < nb_steps)) { + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5F); + stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x0); + + msleep(50); + timingcpt = 0; + + for (i = 0; i < 20; i++) { + if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2) + timingcpt++; + agc2_integr += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) + | stv0900_read_reg(i_params, R0900_P2_AGC2I0); + } + + agc2_integr /= 20; + coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); + if ((timingcpt >= 10) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) + timingLock = TRUE; + else { + current_step++; + direction *= -1; + + if (direction > 0) + tuner_freq += (current_step * currier_step); + else + tuner_freq -= (current_step * currier_step); + + stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw); + } + } + + if (timingLock == FALSE) + coarse_srate = 0; + else + coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); + break; + } + + return coarse_srate; +} + +static u32 stv0900_search_srate_fine(struct dvb_frontend *fe) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + u32 coarse_srate, + coarse_freq, + symb; + + coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); + + switch (demod) { + case STV0900_DEMOD_1: + default: + coarse_freq = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8) + | stv0900_read_reg(i_params, R0900_P1_CFR1); + symb = 13 * (coarse_srate / 10); + + if (symb < i_params->dmd1_symbol_rate) + coarse_srate = 0; + else { + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); + stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01); + stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20); + stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x00); + stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2); + stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); + + if (i_params->chip_id >= 0x20) + stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49); + else + stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed); + + if (coarse_srate > 3000000) { + symb = 13 * (coarse_srate / 10); + symb = (symb / 1000) * 65536; + symb /= (i_params->mclk / 1000); + stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F); + stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF)); + + symb = 10 * (coarse_srate / 13); + symb = (symb / 1000) * 65536; + symb /= (i_params->mclk / 1000); + + stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F); + stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF)); + + symb = (coarse_srate / 1000) * 65536; + symb /= (i_params->mclk / 1000); + stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF); + stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF)); + } else { + symb = 13 * (coarse_srate / 10); + symb = (symb / 100) * 65536; + symb /= (i_params->mclk / 100); + stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F); + stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF)); + + symb = 10 * (coarse_srate / 14); + symb = (symb / 100) * 65536; + symb /= (i_params->mclk / 100); + stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F); + stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF)); + + symb = (coarse_srate / 100) * 65536; + symb /= (i_params->mclk / 100); + stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF); + stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF)); + } + + stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20); + stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (coarse_freq >> 8) & 0xff); + stv0900_write_reg(i_params, R0900_P1_CFRINIT0, coarse_freq & 0xff); + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); + } + break; + case STV0900_DEMOD_2: + coarse_freq = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8) + | stv0900_read_reg(i_params, R0900_P2_CFR1); + + symb = 13 * (coarse_srate / 10); + + if (symb < i_params->dmd2_symbol_rate) + coarse_srate = 0; + else { + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); + stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); + stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20); + stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0x00); + stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2); + stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); + + if (i_params->chip_id >= 0x20) + stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49); + else + stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed); + + if (coarse_srate > 3000000) { + symb = 13 * (coarse_srate / 10); + symb = (symb / 1000) * 65536; + symb /= (i_params->mclk / 1000); + stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F); + stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF)); + + symb = 10 * (coarse_srate / 13); + symb = (symb / 1000) * 65536; + symb /= (i_params->mclk / 1000); + + stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F); + stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF)); + + symb = (coarse_srate / 1000) * 65536; + symb /= (i_params->mclk / 1000); + stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF); + stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF)); + } else { + symb = 13 * (coarse_srate / 10); + symb = (symb / 100) * 65536; + symb /= (i_params->mclk / 100); + stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F); + stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF)); + + symb = 10 * (coarse_srate / 14); + symb = (symb / 100) * 65536; + symb /= (i_params->mclk / 100); + stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F); + stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF)); + + symb = (coarse_srate / 100) * 65536; + symb /= (i_params->mclk / 100); + stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF); + stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF)); + } + + stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20); + stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (coarse_freq >> 8) & 0xff); + stv0900_write_reg(i_params, R0900_P2_CFRINIT0, coarse_freq & 0xff); + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); + } + + break; + } + + return coarse_srate; +} + +static int stv0900_blind_search_algo(struct dvb_frontend *fe) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + u8 k_ref_tmg, k_ref_tmg_max, k_ref_tmg_min; + u32 coarse_srate; + int lock = FALSE, coarse_fail = FALSE; + s32 demod_timeout = 500, fec_timeout = 50, kref_tmg_reg, fail_cpt, i, agc2_overflow; + u16 agc2_integr; + u8 dstatus2; + + dprintk(KERN_INFO "%s\n", __func__); + + if (i_params->chip_id < 0x20) { + k_ref_tmg_max = 233; + k_ref_tmg_min = 143; + } else { + k_ref_tmg_max = 120; + k_ref_tmg_min = 30; + } + + agc2_integr = stv0900_blind_check_agc2_min_level(i_params, demod); + + if (agc2_integr > STV0900_BLIND_SEARCH_AGC2_TH) { + lock = FALSE; + + } else { + switch (demod) { + case STV0900_DEMOD_1: + default: + if (i_params->chip_id == 0x10) + stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xAA); + + if (i_params->chip_id < 0x20) + stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55); + + stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xC4); + stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44); + + if (i_params->chip_id >= 0x20) { + stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41); + stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41); + stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82); + stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0); + } + + kref_tmg_reg = R0900_P1_KREFTMG; + break; + case STV0900_DEMOD_2: + if (i_params->chip_id == 0x10) + stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xAA); + + if (i_params->chip_id < 0x20) + stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55); + + stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xC4); + stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44); + + if (i_params->chip_id >= 0x20) { + stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41); + stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41); + stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82); + stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0); + } + + kref_tmg_reg = R0900_P2_KREFTMG; + break; + } + + k_ref_tmg = k_ref_tmg_max; + + do { + stv0900_write_reg(i_params, kref_tmg_reg, k_ref_tmg); + if (stv0900_search_srate_coarse(fe) != 0) { + coarse_srate = stv0900_search_srate_fine(fe); + + if (coarse_srate != 0) { + stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, coarse_srate, STV0900_BLIND_SEARCH); + lock = stv0900_get_demod_lock(i_params, demod, demod_timeout); + } else + lock = FALSE; + } else { + fail_cpt = 0; + agc2_overflow = 0; + + switch (demod) { + case STV0900_DEMOD_1: + default: + for (i = 0; i < 10; i++) { + agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) + | stv0900_read_reg(i_params, R0900_P1_AGC2I0); + + if (agc2_integr >= 0xff00) + agc2_overflow++; + + dstatus2 = stv0900_read_reg(i_params, R0900_P1_DSTATUS2); + + if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1)) + fail_cpt++; + } + break; + case STV0900_DEMOD_2: + for (i = 0; i < 10; i++) { + agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) + | stv0900_read_reg(i_params, R0900_P2_AGC2I0); + + if (agc2_integr >= 0xff00) + agc2_overflow++; + + dstatus2 = stv0900_read_reg(i_params, R0900_P2_DSTATUS2); + + if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1)) + fail_cpt++; + } + break; + } + + if ((fail_cpt > 7) || (agc2_overflow > 7)) + coarse_fail = TRUE; + + lock = FALSE; + } + k_ref_tmg -= 30; + } while ((k_ref_tmg >= k_ref_tmg_min) && (lock == FALSE) && (coarse_fail == FALSE)); + } + + return lock; +} + +static void stv0900_set_viterbi_acq(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + s32 vth_reg; + + dprintk(KERN_INFO "%s\n", __func__); + + dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12); + + stv0900_write_reg(i_params, vth_reg++, 0x96); + stv0900_write_reg(i_params, vth_reg++, 0x64); + stv0900_write_reg(i_params, vth_reg++, 0x36); + stv0900_write_reg(i_params, vth_reg++, 0x23); + stv0900_write_reg(i_params, vth_reg++, 0x1E); + stv0900_write_reg(i_params, vth_reg++, 0x19); +} + +static void stv0900_set_search_standard(struct stv0900_internal *i_params, + enum fe_stv0900_demod_num demod) +{ + + int sstndrd; + + dprintk(KERN_INFO "%s\n", __func__); + + sstndrd = i_params->dmd1_srch_standard; + if (demod == 1) + sstndrd = i_params->dmd2_srch_stndrd; + + switch (sstndrd) { + case STV0900_SEARCH_DVBS1: + dprintk("Search Standard = DVBS1\n"); + break; + case STV0900_SEARCH_DSS: + dprintk("Search Standard = DSS\n"); + case STV0900_SEARCH_DVBS2: + break; + dprintk("Search Standard = DVBS2\n"); + case STV0900_AUTO_SEARCH: + default: + dprintk("Search Standard = AUTO\n"); + break; + } + + switch (demod) { + case STV0900_DEMOD_1: + default: + switch (i_params->dmd1_srch_standard) { + case STV0900_SEARCH_DVBS1: + case STV0900_SEARCH_DSS: + stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); + + stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0); + stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a); + stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09); + stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x22); + + stv0900_set_viterbi_acq(i_params, demod); + stv0900_set_viterbi_standard(i_params, + i_params->dmd1_srch_standard, + i_params->dmd1_fec, demod); + + break; + case STV0900_SEARCH_DVBS2: + stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); + stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 1); + stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a); + stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09); + stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26); + if (i_params->demod_mode != STV0900_SINGLE) { + if (i_params->chip_id <= 0x11) + stv0900_stop_all_s2_modcod(i_params, demod); + else + stv0900_activate_s2_modcode(i_params, demod); + + } else + stv0900_activate_s2_modcode_single(i_params, demod); + + stv0900_set_viterbi_tracq(i_params, demod); + + break; + case STV0900_AUTO_SEARCH: + default: + stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); + stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0); + stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a); + stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09); + stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26); + if (i_params->demod_mode != STV0900_SINGLE) { + if (i_params->chip_id <= 0x11) + stv0900_stop_all_s2_modcod(i_params, demod); + else + stv0900_activate_s2_modcode(i_params, demod); + + } else + stv0900_activate_s2_modcode_single(i_params, demod); + + if (i_params->dmd1_symbol_rate >= 2000000) + stv0900_set_viterbi_acq(i_params, demod); + else + stv0900_set_viterbi_tracq(i_params, demod); + + stv0900_set_viterbi_standard(i_params, i_params->dmd1_srch_standard, i_params->dmd1_fec, demod); + + break; + } + break; + case STV0900_DEMOD_2: + switch (i_params->dmd2_srch_stndrd) { + case STV0900_SEARCH_DVBS1: + case STV0900_SEARCH_DSS: + stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); + stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0); + stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a); + stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09); + stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x22); + stv0900_set_viterbi_acq(i_params, demod); + stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod); + break; + case STV0900_SEARCH_DVBS2: + stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); + stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 1); + stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a); + stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09); + stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26); + if (i_params->demod_mode != STV0900_SINGLE) + stv0900_activate_s2_modcode(i_params, demod); + else + stv0900_activate_s2_modcode_single(i_params, demod); + + stv0900_set_viterbi_tracq(i_params, demod); + break; + case STV0900_AUTO_SEARCH: + default: + stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); + stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); + stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); + stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0); + stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a); + stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09); + stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26); + if (i_params->demod_mode != STV0900_SINGLE) + stv0900_activate_s2_modcode(i_params, demod); + else + stv0900_activate_s2_modcode_single(i_params, demod); + + if (i_params->dmd2_symbol_rate >= 2000000) + stv0900_set_viterbi_acq(i_params, demod); + else + stv0900_set_viterbi_tracq(i_params, demod); + + stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod); + + break; + } + + break; + } +} + +enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe) +{ + struct stv0900_state *state = fe->demodulator_priv; + struct stv0900_internal *i_params = state->internal; + enum fe_stv0900_demod_num demod = state->demod; + + s32 demod_timeout = 500, fec_timeout = 50, stream_merger_field; + + int lock = FALSE, low_sr = FALSE; + + enum fe_stv0900_signal_type signal_type = STV0900_NOCARRIER; + enum fe_stv0900_search_algo algo; + int no_signal = FALSE; + + dprintk(KERN_INFO "%s\n", __func__); + + switch (demod) { + case STV0900_DEMOD_1: + default: + algo = i_params->dmd1_srch_algo; + + stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1); + stream_merger_field = F0900_P1_RST_HWARE; + + stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C); + + if (i_params->chip_id >= 0x20) + stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x9e); + else + stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x88); + + stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd1_symbol_rate, i_params->dmd1_srch_algo); + + if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { + i_params->tuner1_bw = 2 * 36000000; + + stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x00); + stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70); + + stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); + } else { + stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20); + stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2); + + if (i_params->dmd1_symbol_rate < 2000000) + stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x63); + else + stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70); + + stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); + if (i_params->chip_id >= 0x20) { + stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0x5a); + + if (i_params->dmd1_srch_algo == STV0900_COLD_START) + i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10; + else if (i_params->dmd1_srch_algo == STV0900_WARM_START) + i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000; + } else { + stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0xc1); + i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10; + } + + stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01); + + stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod); + stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod); + stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod); + if (i_params->dmd1_symbol_rate >= 10000000) + low_sr = FALSE; + else + low_sr = TRUE; + + } + + stv0900_set_tuner(fe, i_params->tuner1_freq, i_params->tuner1_bw); + + stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, i_params->dmd1_srch_iq_inv); + stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); + + stv0900_set_search_standard(i_params, demod); + + if (i_params->dmd1_srch_algo != STV0900_BLIND_SEARCH) + stv0900_start_search(i_params, demod); + break; + case STV0900_DEMOD_2: + algo = i_params->dmd2_srch_algo; + + stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1); + + stream_merger_field = F0900_P2_RST_HWARE; + + stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C); + + if (i_params->chip_id >= 0x20) + stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x9e); + else + stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x88); + + stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd2_symbol_rate, i_params->dmd2_srch_algo); + + if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { + i_params->tuner2_bw = 2 * 36000000; + + stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x00); + stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70); + + stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); + } else { + stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20); + stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2); + + if (i_params->dmd2_symbol_rate < 2000000) + stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x63); + else + stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70); + + if (i_params->dmd2_symbol_rate >= 10000000) + stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); + else + stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x60); + + if (i_params->chip_id >= 0x20) { + stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0x5a); + + if (i_params->dmd2_srch_algo == STV0900_COLD_START) + i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate, + i_params->rolloff) + 10000000)) / 10; + else if (i_params->dmd2_srch_algo == STV0900_WARM_START) + i_params->tuner2_bw = stv0900_carrier_width(i_params->dmd2_symbol_rate, + i_params->rolloff) + 10000000; + } else { + stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0xc1); + i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate, + i_params->rolloff) + 10000000)) / 10; + } + + stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); + + stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod); + stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod); + stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod); + if (i_params->dmd2_symbol_rate >= 10000000) + low_sr = FALSE; + else + low_sr = TRUE; + + } + + stv0900_set_tuner(fe, i_params->tuner2_freq, i_params->tuner2_bw); + + stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, i_params->dmd2_srch_iq_inv); + stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); + + stv0900_set_search_standard(i_params, demod); + + if (i_params->dmd2_srch_algo != STV0900_BLIND_SEARCH) + stv0900_start_search(i_params, demod); + break; + } + + if (i_params->chip_id == 0x12) { + stv0900_write_bits(i_params, stream_merger_field, 0); + msleep(3); + stv0900_write_bits(i_params, stream_merger_field, 1); + stv0900_write_bits(i_params, stream_merger_field, 0); + } + + if (algo == STV0900_BLIND_SEARCH) + lock = stv0900_blind_search_algo(fe); + else if (algo == STV0900_COLD_START) + lock = stv0900_get_demod_cold_lock(fe, demod_timeout); + else if (algo == STV0900_WARM_START) + lock = stv0900_get_demod_lock(i_params, demod, demod_timeout); + + if ((lock == FALSE) && (algo == STV0900_COLD_START)) { + if (low_sr == FALSE) { + if (stv0900_check_timing_lock(i_params, demod) == TRUE) + lock = stv0900_sw_algo(i_params, demod); + } + } + + if (lock == TRUE) + signal_type = stv0900_get_signal_params(fe); + + if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) { + stv0900_track_optimization(fe); + if (i_params->chip_id <= 0x11) { + if ((stv0900_get_standard(fe, STV0900_DEMOD_1) == STV0900_DVBS1_STANDARD) && (stv0900_get_standard(fe, STV0900_DEMOD_2) == STV0900_DVBS1_STANDARD)) { + msleep(20); + stv0900_write_bits(i_params, stream_merger_field, 0); + } else { + stv0900_write_bits(i_params, stream_merger_field, 0); + msleep(3); + stv0900_write_bits(i_params, stream_merger_field, 1); + stv0900_write_bits(i_params, stream_merger_field, 0); + } + } else if (i_params->chip_id == 0x20) { + stv0900_write_bits(i_params, stream_merger_field, 0); + msleep(3); + stv0900_write_bits(i_params, stream_merger_field, 1); + stv0900_write_bits(i_params, stream_merger_field, 0); + } + + if (stv0900_wait_for_lock(i_params, demod, fec_timeout, fec_timeout) == TRUE) { + lock = TRUE; + switch (demod) { + case STV0900_DEMOD_1: + default: + i_params->dmd1_rslts.locked = TRUE; + if (i_params->dmd1_rslts.standard == STV0900_DVBS2_STANDARD) { + stv0900_set_dvbs2_rolloff(i_params, demod); + stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0x40); + stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0); + stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67); + } else { + stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); + } + + stv0900_write_reg(i_params, R0900_P1_FBERCPT4, 0); + stv0900_write_reg(i_params, R0900_P1_ERRCTRL2, 0xc1); + break; + case STV0900_DEMOD_2: + i_params->dmd2_rslts.locked = TRUE; + + if (i_params->dmd2_rslts.standard == STV0900_DVBS2_STANDARD) { + stv0900_set_dvbs2_rolloff(i_params, demod); + stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x60); + stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x20); + stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67); + } else { + stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75); + } + + stv0900_write_reg(i_params, R0900_P2_FBERCPT4, 0); + + stv0900_write_reg(i_params, R0900_P2_ERRCTRL2, 0xc1); + break; + } + } else { + lock = FALSE; + signal_type = STV0900_NODATA; + no_signal = stv0900_check_signal_presence(i_params, demod); + + switch (demod) { + case STV0900_DEMOD_1: + default: + i_params->dmd1_rslts.locked = FALSE; + break; + case STV0900_DEMOD_2: + i_params->dmd2_rslts.locked = FALSE; + break; + } + } + } + + if ((signal_type == STV0900_NODATA) && (no_signal == FALSE)) { + switch (demod) { + case STV0900_DEMOD_1: + default: + if (i_params->chip_id <= 0x11) { + if ((stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) && + (i_params->dmd1_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST)) + signal_type = stv0900_dvbs1_acq_workaround(fe); + } else + i_params->dmd1_rslts.locked = FALSE; + + break; + case STV0900_DEMOD_2: + if (i_params->chip_id <= 0x11) { + if ((stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) && + (i_params->dmd2_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST)) + signal_type = stv0900_dvbs1_acq_workaround(fe); + } else + i_params->dmd2_rslts.locked = FALSE; + break; + } + } + + return signal_type; +} + -- cgit v1.2.1 From 55d5834d370416946fda7781a5a9ed394a465580 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Wed, 4 Mar 2009 10:40:31 -0300 Subject: V4L/DVB (10808): Fix typo in lnbp21.c It was a typo in the function name, it should be lnbh24_attach, and not lnbp24_attach. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/lnbp21.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c index 772a0bbb0dd8..1dcc56f32bff 100644 --- a/drivers/media/dvb/frontends/lnbp21.c +++ b/drivers/media/dvb/frontends/lnbp21.c @@ -138,7 +138,7 @@ static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe, return fe; } -struct dvb_frontend *lnbp24_attach(struct dvb_frontend *fe, +struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear, u8 i2c_addr) { -- cgit v1.2.1 From 68b3289fdb27f5d3e32587766ddafa487037b0bd Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Tue, 24 Feb 2009 12:35:15 -0300 Subject: V4L/DVB (10822): Add support for Zarlink ZL10036 DVB-S tuner. This driver is based on initial work by Tino Reichardt and was heavily changed. The datasheet of the zl10036 can be found here and on other places on the net: http://www.mcmilk.de/projects/dvb-card/datasheets/ZL10036.pdf The zl10038 is similar to the zl10036, so it is maybe possible to write a common driver of necessary. Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 7 + drivers/media/dvb/frontends/Makefile | 1 + drivers/media/dvb/frontends/zl10036.c | 519 ++++++++++++++++++++++++++++++++++ drivers/media/dvb/frontends/zl10036.h | 53 ++++ 4 files changed, 580 insertions(+) create mode 100644 drivers/media/dvb/frontends/zl10036.c create mode 100644 drivers/media/dvb/frontends/zl10036.h (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index a7ea355907b6..4059d22a1e55 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -55,6 +55,13 @@ config DVB_MT312 help A DVB-S tuner module. Say Y when you want to support this frontend. +config DVB_ZL10036 + tristate "Zarlink ZL10036 silicon tuner" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A DVB-S tuner module. Say Y when you want to support this frontend. + config DVB_S5H1420 tristate "Samsung S5H1420 based" depends on DVB_CORE && I2C diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 2231c68291d0..1e3866b2fd2e 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o obj-$(CONFIG_DVB_SP887X) += sp887x.o obj-$(CONFIG_DVB_NXT6000) += nxt6000.o obj-$(CONFIG_DVB_MT352) += mt352.o +obj-$(CONFIG_DVB_ZL10036) += zl10036.o obj-$(CONFIG_DVB_ZL10353) += zl10353.o obj-$(CONFIG_DVB_CX22702) += cx22702.o obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c new file mode 100644 index 000000000000..e22a0b381dc4 --- /dev/null +++ b/drivers/media/dvb/frontends/zl10036.c @@ -0,0 +1,519 @@ +/** + * Driver for Zarlink zl10036 DVB-S silicon tuner + * + * Copyright (C) 2006 Tino Reichardt + * Copyright (C) 2007-2009 Matthias Schwarzott + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + ** + * The data sheet for this tuner can be found at: + * http://www.mcmilk.de/projects/dvb-card/datasheets/ZL10036.pdf + * + * This one is working: (at my Avermedia DVB-S Pro) + * - zl10036 (40pin, FTA) + * + * A driver for zl10038 should be very similar. + */ + +#include +#include +#include + +#include "zl10036.h" + +static int zl10036_debug; +#define dprintk(level, args...) \ + do { if (zl10036_debug & level) printk(KERN_DEBUG "zl10036: " args); \ + } while (0) + +#define deb_info(args...) dprintk(0x01, args) +#define deb_i2c(args...) dprintk(0x02, args) + +struct zl10036_state { + struct i2c_adapter *i2c; + const struct zl10036_config *config; + u32 frequency; + u8 br, bf; +}; + + +/* This driver assumes the tuner is driven by a 10.111MHz Cristal */ +#define _XTAL 10111 + +/* Some of the possible dividers: + * 64, (write 0x05 to reg), freq step size 158kHz + * 10, (write 0x0a to reg), freq step size 1.011kHz (used here) + * 5, (write 0x09 to reg), freq step size 2.022kHz + */ + +#define _RDIV 10 +#define _RDIV_REG 0x0a +#define _FR (_XTAL/_RDIV) + +#define STATUS_POR 0x80 /* Power on Reset */ +#define STATUS_FL 0x40 /* Frequency & Phase Lock */ + +/* read/write for zl10036 and zl10038 */ + +static int zl10036_read_status_reg(struct zl10036_state *state) +{ + u8 status; + struct i2c_msg msg[1] = { + { .addr = state->config->tuner_address, .flags = I2C_M_RD, + .buf = &status, .len = sizeof(status) }, + }; + + if (i2c_transfer(state->i2c, msg, 1) != 1) { + printk(KERN_ERR "%s: i2c read failed at addr=%02x\n", + __func__, state->config->tuner_address); + return -EIO; + } + + deb_i2c("R(status): %02x [FL=%d]\n", status, + (status & STATUS_FL) ? 1 : 0); + if (status & STATUS_POR) + deb_info("%s: Power-On-Reset bit enabled - " + "need to initialize the tuner\n", __func__); + + return status; +} + +static int zl10036_write(struct zl10036_state *state, u8 buf[], u8 count) +{ + struct i2c_msg msg[1] = { + { .addr = state->config->tuner_address, .flags = 0, + .buf = buf, .len = count }, + }; + u8 reg = 0; + int ret; + + if (zl10036_debug & 0x02) { + /* every 8bit-value satisifes this! + * so only check for debug log */ + if ((buf[0] & 0x80) == 0x00) + reg = 2; + else if ((buf[0] & 0xc0) == 0x80) + reg = 4; + else if ((buf[0] & 0xf0) == 0xc0) + reg = 6; + else if ((buf[0] & 0xf0) == 0xd0) + reg = 8; + else if ((buf[0] & 0xf0) == 0xe0) + reg = 10; + else if ((buf[0] & 0xf0) == 0xf0) + reg = 12; + + deb_i2c("W(%d):", reg); + { + int i; + for (i = 0; i < count; i++) + printk(KERN_CONT " %02x", buf[i]); + printk(KERN_CONT "\n"); + } + } + + ret = i2c_transfer(state->i2c, msg, 1); + if (ret != 1) { + printk(KERN_ERR "%s: i2c error, ret=%d\n", __func__, ret); + return -EIO; + } + + return 0; +} + +static int zl10036_release(struct dvb_frontend *fe) +{ + struct zl10036_state *state = fe->tuner_priv; + + fe->tuner_priv = NULL; + kfree(state); + + return 0; +} + +static int zl10036_sleep(struct dvb_frontend *fe) +{ + struct zl10036_state *state = fe->tuner_priv; + u8 buf[] = { 0xf0, 0x80 }; /* regs 12/13 */ + int ret; + + deb_info("%s\n", __func__); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ + + ret = zl10036_write(state, buf, sizeof(buf)); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ + + return ret; +} + +/** + * register map of the ZL10036/ZL10038 + * + * reg[default] content + * 2[0x00]: 0 | N14 | N13 | N12 | N11 | N10 | N9 | N8 + * 3[0x00]: N7 | N6 | N5 | N4 | N3 | N2 | N1 | N0 + * 4[0x80]: 1 | 0 | RFG | BA1 | BA0 | BG1 | BG0 | LEN + * 5[0x00]: P0 | C1 | C0 | R4 | R3 | R2 | R1 | R0 + * 6[0xc0]: 1 | 1 | 0 | 0 | RSD | 0 | 0 | 0 + * 7[0x20]: P1 | BF6 | BF5 | BF4 | BF3 | BF2 | BF1 | 0 + * 8[0xdb]: 1 | 1 | 0 | 1 | 0 | CC | 1 | 1 + * 9[0x30]: VSD | V2 | V1 | V0 | S3 | S2 | S1 | S0 + * 10[0xe1]: 1 | 1 | 1 | 0 | 0 | LS2 | LS1 | LS0 + * 11[0xf5]: WS | WH2 | WH1 | WH0 | WL2 | WL1 | WL0 | WRE + * 12[0xf0]: 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 + * 13[0x28]: PD | BR4 | BR3 | BR2 | BR1 | BR0 | CLR | TL + */ + +static int zl10036_set_frequency(struct zl10036_state *state, u32 frequency) +{ + u8 buf[2]; + u32 div, foffset; + + div = (frequency + _FR/2) / _FR; + state->frequency = div * _FR; + + foffset = frequency - state->frequency; + + buf[0] = (div >> 8) & 0x7f; + buf[1] = (div >> 0) & 0xff; + + deb_info("%s: ftodo=%u fpriv=%u ferr=%d div=%u\n", __func__, + frequency, state->frequency, foffset, div); + + return zl10036_write(state, buf, sizeof(buf)); +} + +static int zl10036_set_bandwidth(struct zl10036_state *state, u32 fbw) +{ + /* fbw is measured in kHz */ + u8 br, bf; + int ret; + u8 buf_bf[] = { + 0xc0, 0x00, /* 6/7: rsd=0 bf=0 */ + }; + u8 buf_br[] = { + 0xf0, 0x00, /* 12/13: br=0xa clr=0 tl=0*/ + }; + u8 zl10036_rsd_off[] = { 0xc8 }; /* set RSD=1 */ + + /* ensure correct values */ + if (fbw > 35000) + fbw = 35000; + if (fbw < 8000) + fbw = 8000; + +#define _BR_MAXIMUM (_XTAL/575) /* _XTAL / 575kHz = 17 */ + + /* <= 28,82 MHz */ + if (fbw <= 28820) { + br = _BR_MAXIMUM; + } else { + /** + * f(bw)=34,6MHz f(xtal)=10.111MHz + * br = (10111/34600) * 63 * 1/K = 14; + */ + br = ((_XTAL * 21 * 1000) / (fbw * 419)); + } + + /* ensure correct values */ + if (br < 4) + br = 4; + if (br > _BR_MAXIMUM) + br = _BR_MAXIMUM; + + /* + * k = 1.257 + * bf = fbw/_XTAL * br * k - 1 */ + + bf = (fbw * br * 1257) / (_XTAL * 1000) - 1; + + /* ensure correct values */ + if (bf > 62) + bf = 62; + + buf_bf[1] = (bf << 1) & 0x7e; + buf_br[1] = (br << 2) & 0x7c; + deb_info("%s: BW=%d br=%u bf=%u\n", __func__, fbw, br, bf); + + if (br != state->br) { + ret = zl10036_write(state, buf_br, sizeof(buf_br)); + if (ret < 0) + return ret; + } + + if (bf != state->bf) { + ret = zl10036_write(state, buf_bf, sizeof(buf_bf)); + if (ret < 0) + return ret; + + /* time = br/(32* fxtal) */ + /* minimal sleep time to be calculated + * maximum br is 63 -> max time = 2 /10 MHz = 2e-7 */ + msleep(1); + + ret = zl10036_write(state, zl10036_rsd_off, + sizeof(zl10036_rsd_off)); + if (ret < 0) + return ret; + } + + state->br = br; + state->bf = bf; + + return 0; +} + +static int zl10036_set_gain_params(struct zl10036_state *state, + int c) +{ + u8 buf[2]; + u8 rfg, ba, bg; + + /* default values */ + rfg = 0; /* enable when using an lna */ + ba = 1; + bg = 1; + + /* reg 4 */ + buf[0] = 0x80 | ((rfg << 5) & 0x20) + | ((ba << 3) & 0x18) | ((bg << 1) & 0x06); + + if (!state->config->rf_loop_enable) + buf[0] |= 0x01; + + /* P0=0 */ + buf[1] = _RDIV_REG | ((c << 5) & 0x60); + + deb_info("%s: c=%u rfg=%u ba=%u bg=%u\n", __func__, c, rfg, ba, bg); + return zl10036_write(state, buf, sizeof(buf)); +} + +static int zl10036_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct zl10036_state *state = fe->tuner_priv; + int ret = 0; + u32 frequency = params->frequency; + u32 fbw; + int i; + u8 c; + + /* ensure correct values + * maybe redundant as core already checks this */ + if ((frequency < fe->ops.info.frequency_min) + || (frequency > fe->ops.info.frequency_max)) + return -EINVAL; + + /** + * alpha = 1.35 for dvb-s + * fBW = (alpha*symbolrate)/(2*0.8) + * 1.35 / (2*0.8) = 27 / 32 + */ + fbw = (27 * params->u.qpsk.symbol_rate) / 32; + + /* scale to kHz */ + fbw /= 1000; + + /* Add safe margin of 3MHz */ + fbw += 3000; + + /* setting the charge pump - guessed values */ + if (frequency < 950000) + return -EINVAL; + else if (frequency < 1250000) + c = 0; + else if (frequency < 1750000) + c = 1; + else if (frequency < 2175000) + c = 2; + else + return -EINVAL; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ + + ret = zl10036_set_gain_params(state, c); + if (ret < 0) + goto error; + + ret = zl10036_set_frequency(state, params->frequency); + if (ret < 0) + goto error; + + ret = zl10036_set_bandwidth(state, fbw); + if (ret < 0) + goto error; + + /* wait for tuner lock - no idea if this is really needed */ + for (i = 0; i < 20; i++) { + ret = zl10036_read_status_reg(state); + if (ret < 0) + goto error; + + /* check Frequency & Phase Lock Bit */ + if (ret & STATUS_FL) + break; + + msleep(10); + } + +error: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ + + return ret; +} + +static int zl10036_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct zl10036_state *state = fe->tuner_priv; + + *frequency = state->frequency; + + return 0; +} + +static int zl10036_init_regs(struct zl10036_state *state) +{ + int ret; + int i; + + /* could also be one block from reg 2 to 13 and additional 10/11 */ + u8 zl10036_init_tab[][2] = { + { 0x04, 0x00 }, /* 2/3: div=0x400 - arbitrary value */ + { 0x8b, _RDIV_REG }, /* 4/5: rfg=0 ba=1 bg=1 len=? */ + /* p0=0 c=0 r=_RDIV_REG */ + { 0xc0, 0x20 }, /* 6/7: rsd=0 bf=0x10 */ + { 0xd3, 0x40 }, /* 8/9: from datasheet */ + { 0xe3, 0x5b }, /* 10/11: lock window level */ + { 0xf0, 0x28 }, /* 12/13: br=0xa clr=0 tl=0*/ + { 0xe3, 0xf9 }, /* 10/11: unlock window level */ + }; + + /* invalid values to trigger writing */ + state->br = 0xff; + state->bf = 0xff; + + if (!state->config->rf_loop_enable) + zl10036_init_tab[1][2] |= 0x01; + + deb_info("%s\n", __func__); + + for (i = 0; i < ARRAY_SIZE(zl10036_init_tab); i++) { + ret = zl10036_write(state, zl10036_init_tab[i], 2); + if (ret < 0) + return ret; + } + + return 0; +} + +static int zl10036_init(struct dvb_frontend *fe) +{ + struct zl10036_state *state = fe->tuner_priv; + int ret = 0; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ + + ret = zl10036_read_status_reg(state); + if (ret < 0) + return ret; + + /* Only init if Power-on-Reset bit is set? */ + ret = zl10036_init_regs(state); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ + + return ret; +} + +static struct dvb_tuner_ops zl10036_tuner_ops = { + .info = { + .name = "Zarlink ZL10036", + .frequency_min = 950000, + .frequency_max = 2175000 + }, + .init = zl10036_init, + .release = zl10036_release, + .sleep = zl10036_sleep, + .set_params = zl10036_set_params, + .get_frequency = zl10036_get_frequency, +}; + +struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe, + const struct zl10036_config *config, + struct i2c_adapter *i2c) +{ + struct zl10036_state *state = NULL; + int ret; + + if (NULL == config) { + printk(KERN_ERR "%s: no config specified", __func__); + goto error; + } + + state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL); + if (NULL == state) + return NULL; + + state->config = config; + state->i2c = i2c; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ + + ret = zl10036_read_status_reg(state); + if (ret < 0) { + printk(KERN_ERR "%s: No zl10036 found\n", __func__); + goto error; + } + + ret = zl10036_init_regs(state); + if (ret < 0) { + printk(KERN_ERR "%s: tuner initialization failed\n", + __func__); + goto error; + } + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ + + fe->tuner_priv = state; + + memcpy(&fe->ops.tuner_ops, &zl10036_tuner_ops, + sizeof(struct dvb_tuner_ops)); + printk(KERN_INFO "%s: tuner initialization (%s addr=0x%02x) ok\n", + __func__, fe->ops.tuner_ops.info.name, config->tuner_address); + + return fe; + +error: + zl10036_release(fe); + return NULL; +} +EXPORT_SYMBOL(zl10036_attach); + +module_param_named(debug, zl10036_debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); +MODULE_DESCRIPTION("DVB ZL10036 driver"); +MODULE_AUTHOR("Tino Reichardt"); +MODULE_AUTHOR("Matthias Schwarzott"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/zl10036.h b/drivers/media/dvb/frontends/zl10036.h new file mode 100644 index 000000000000..d84b8f8215e9 --- /dev/null +++ b/drivers/media/dvb/frontends/zl10036.h @@ -0,0 +1,53 @@ +/** + * Driver for Zarlink ZL10036 DVB-S silicon tuner + * + * Copyright (C) 2006 Tino Reichardt + * Copyright (C) 2007-2009 Matthias Schwarzott + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVB_ZL10036_H +#define DVB_ZL10036_H + +#include +#include "dvb_frontend.h" + +/** + * Attach a zl10036 tuner to the supplied frontend structure. + * + * @param fe Frontend to attach to. + * @param config zl10036_config structure + * @return FE pointer on success, NULL on failure. + */ + +struct zl10036_config { + u8 tuner_address; + int rf_loop_enable; +}; + +#if defined(CONFIG_DVB_ZL10036) || \ + (defined(CONFIG_DVB_ZL10036_MODULE) && defined(MODULE)) +extern struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe, + const struct zl10036_config *config, struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe, + const struct zl10036_config *config, struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif /* DVB_ZL10036_H */ -- cgit v1.2.1 From 4609bdd927913c63db4477b066d002aed9cfc504 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 6 Mar 2009 08:31:39 -0300 Subject: V4L/DVB (10837): Kconfig: only open the customise menu if selected Instead of asking a lot of questions for the poor users, let's just hide the frontend customise menu, if the user doesn't want to customise. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 4059d22a1e55..f9a9273028a9 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -1,17 +1,21 @@ -menu "Customise DVB Frontends" - depends on DVB_CORE - config DVB_FE_CUSTOMISE bool "Customise the frontend modules to build" + depends on DVB_CORE default N help - This allows the user to deselect frontend drivers unnecessary - for their hardware from the build. Use this option with care - as deselecting frontends which are in fact necessary will result - in DVB devices which cannot be tuned due to lack of driver support. + This allows the user to select/deselect frontend drivers for their + hardware from the build. + + Use this option with care as deselecting frontends which are in fact + necessary will result in DVB devices which cannot be tuned due to lack + of driver support. If unsure say N. +if DVB_FE_CUSTOMISE + +menu "Customise DVB Frontends" + comment "Multistandard (satellite) frontends" depends on DVB_CORE @@ -507,3 +511,5 @@ config DVB_AF9013 help Say Y when you want to support this frontend. endmenu + +endif -- cgit v1.2.1 From 5a771cb186dfa1f663ea15cdff3e32e04a8427e3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 8 Mar 2009 23:01:08 -0300 Subject: V4L/DVB (10846): dvb/frontends: fix duplicate 'debug' symbol Fix dvb frontend debug variable to be static, to avoid linker errors: drivers/built-in.o:(.data+0xf4b0): multiple definition of `debug' arch/x86/kernel/built-in.o:(.kprobes.text+0x90): first defined here ld: Warning: size of symbol `debug' changed from 85 in arch/x86/kernel/built-in.o to 4 in drivers/built-in.o It would also be Good if arch/x86/kernel/entry_32.S didn't have a non-static 'debug' symbol. OTOH, it helps catch things like this one. Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_core.c | 4 ++-- drivers/media/dvb/frontends/stv0900_priv.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index ee20fbfc45f4..ca26518eafcd 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -34,8 +34,8 @@ #include "stv0900_priv.h" #include "stv0900_init.h" -int debug = 1; -module_param(debug, int, 0644); +static int stvdebug = 1; +module_param_named(debug, stvdebug, int, 0644); /* internal params node */ struct stv0900_inode { diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h index 28350fbeb08d..762d5af62d7a 100644 --- a/drivers/media/dvb/frontends/stv0900_priv.h +++ b/drivers/media/dvb/frontends/stv0900_priv.h @@ -62,11 +62,11 @@ #define dmd_choose(a, b) (demod = STV0900_DEMOD_2 ? b : a)) -extern int debug; +static int stvdebug; #define dprintk(args...) \ do { \ - if (debug) \ + if (stvdebug) \ printk(KERN_DEBUG args); \ } while (0) -- cgit v1.2.1 From 78175bf2c5e4beb0874aee27dcfce58c4c7d4fb4 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 6 Mar 2009 19:32:54 -0300 Subject: V4L/DVB (10871): stv0900: delete debug messages not related to stv0900 tuning algorythm Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_core.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index ca26518eafcd..3cc6626fe633 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -59,20 +59,10 @@ static struct stv0900_inode *find_inode(struct i2c_adapter *i2c_adap, find it by i2c adapter and i2c address */ while ((temp_chip != NULL) && ((temp_chip->internal->i2c_adap != i2c_adap) || - (temp_chip->internal->i2c_addr != i2c_addr))) { + (temp_chip->internal->i2c_addr != i2c_addr))) temp_chip = temp_chip->next_inode; - dprintk(KERN_INFO "%s: store.adap %x\n", __func__, - (int)&(*temp_chip->internal->i2c_adap)); - dprintk(KERN_INFO "%s: init.adap %x\n", __func__, - (int)&(*i2c_adap)); - } - if (temp_chip != NULL) {/* find by i2c adapter & address */ - dprintk(KERN_INFO "%s: store.adap %x\n", __func__, - (int)temp_chip->internal->i2c_adap); - dprintk(KERN_INFO "%s: init.adap %x\n", __func__, - (int)i2c_adap); - } + } return temp_chip; @@ -1492,7 +1482,7 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe, enum fe_stv0900_error error = STV0900_NO_ERROR; - dprintk(KERN_INFO "%s: Internal = %x\n", __func__, (u32)i_params); + dprintk(KERN_INFO "%s: ", __func__); p_result.locked = FALSE; p_search.path = state->demod; @@ -1607,7 +1597,7 @@ static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct stv0900_state *state = fe->demodulator_priv; - dprintk("%s: Internal = %x\n", __func__, (unsigned int)state->internal); + dprintk("%s: ", __func__); if ((stv0900_status(state->internal, state->demod)) == TRUE) { dprintk("DEMOD LOCK OK\n"); @@ -1920,8 +1910,6 @@ struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, if (err_stv0900) goto error; - dprintk(KERN_INFO "%s: Init Result = %d, handle_stv0900 = %x\n", - __func__, err_stv0900, (unsigned int)state->internal); break; default: goto error; -- cgit v1.2.1 From 79a6650525755aaa3d30a9b6d8f9bc96788c1262 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 10 Mar 2009 00:49:58 -0300 Subject: V4L/DVB (10896): /frontends/Kconfig: Move af9013 Kconfig option to its proper place af9013 is not a development tool. It is, instead, a DVB-T module. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index f9a9273028a9..2887d3398fb8 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -313,6 +313,13 @@ config DVB_TDA10048 help A DVB-T tuner module. Say Y when you want to support this frontend. +config DVB_AF9013 + tristate "Afatech AF9013 demodulator" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + Say Y when you want to support this frontend. + comment "DVB-C (cable) frontends" depends on DVB_CORE @@ -503,13 +510,6 @@ comment "Tools to develop new frontends" config DVB_DUMMY_FE tristate "Dummy frontend driver" default n - -config DVB_AF9013 - tristate "Afatech AF9013 demodulator" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - Say Y when you want to support this frontend. endmenu endif -- cgit v1.2.1 From 181bc8d97a7433ee6e5b7eb14b467914e0437276 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 9 Mar 2009 00:03:25 -0300 Subject: V4L/DVB (10898): remove build-time dependencies on dib7000m Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib7000m.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/dib7000m.h b/drivers/media/dvb/frontends/dib7000m.h index 597e9cc2da62..f93db0fda47e 100644 --- a/drivers/media/dvb/frontends/dib7000m.h +++ b/drivers/media/dvb/frontends/dib7000m.h @@ -38,8 +38,28 @@ struct dib7000m_config { #define DEFAULT_DIB7000M_I2C_ADDRESS 18 +#if defined(CONFIG_DVB_DIB7000M) || (defined(CONFIG_DVB_DIB7000M_MODULE) && \ + defined(MODULE)) extern struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg); extern struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); +#else +static inline +struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap, + u8 i2c_addr, struct dib7000m_config *cfg) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} + +static inline +struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *demod, + enum dibx000_i2c_interface intf, + int gating) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* TODO extern INT dib7000m_set_gpio(struct dibDemod *demod, UCHAR num, UCHAR dir, UCHAR val); -- cgit v1.2.1 From 5aed9755bcdc20205901b5925a684f4e60060f23 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 9 Mar 2009 00:04:17 -0300 Subject: V4L/DVB (10899): remove build-time dependencies on dib7000p Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib7000p.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index aab8112e2db2..4e3fd7639276 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h @@ -49,6 +49,7 @@ extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, struct dib7000p_config cfg[]); extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value); +extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); #else static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, @@ -88,8 +89,12 @@ int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value) printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } -#endif -extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); +static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} +#endif #endif -- cgit v1.2.1 From 53655c6a63bfa3224977fcc1edca28fb6529fc2b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 9 Mar 2009 00:59:09 -0300 Subject: V4L/DVB (10900): remove build-time dependencies on dib3000mc Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib3000mc.h | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h index 4142ed7a47d0..b49bf3cb1ed7 100644 --- a/drivers/media/dvb/frontends/dib3000mc.h +++ b/drivers/media/dvb/frontends/dib3000mc.h @@ -40,18 +40,41 @@ struct dib3000mc_config { #define DEFAULT_DIB3000P_I2C_ADDRESS 24 #if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE)) -extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg); +extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap, + u8 i2c_addr, + struct dib3000mc_config *cfg); +extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, + int no_of_demods, u8 default_addr, + struct dib3000mc_config cfg[]); +extern +struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, + int gating); #else -static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg) +static inline +struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, + struct dib3000mc_config *cfg) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -#endif // CONFIG_DVB_DIB3000MC -extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[]); +static inline +int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, + int no_of_demods, u8 default_addr, + struct dib3000mc_config cfg[]) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} -extern struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating); +static inline +struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, + int gating) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif // CONFIG_DVB_DIB3000MC extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff); extern int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff); -- cgit v1.2.1 From 4ec030b459917a11b1a8b07512c0a606371d2643 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 9 Mar 2009 02:29:01 -0300 Subject: V4L/DVB (10901): cleanup linewraps in dib7000p.h Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib7000p.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index 4e3fd7639276..02a4c82f0c70 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h @@ -37,7 +37,8 @@ struct dib7000p_config { #define DEFAULT_DIB7000P_I2C_ADDRESS 18 -#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \ + defined(MODULE)) extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg); @@ -51,9 +52,9 @@ extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value); extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); #else -static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, - u8 i2c_addr, - struct dib7000p_config *cfg) +static inline +struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, + struct dib7000p_config *cfg) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; @@ -61,30 +62,29 @@ static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, static inline struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, - enum dibx000_i2c_interface i, int x) + enum dibx000_i2c_interface i, + int x) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -static inline -int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, - int no_of_demods, u8 default_addr, - struct dib7000p_config cfg[]) +static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, + int no_of_demods, u8 default_addr, + struct dib7000p_config cfg[]) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } -static inline -int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) +static inline int dib7000p_set_gpio(struct dvb_frontend *fe, + u8 num, u8 dir, u8 val) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; } -static inline -int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value) +static inline int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -ENODEV; -- cgit v1.2.1 From 7991704dbd5c69bbf047ef6b9332a8701334975b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 9 Mar 2009 02:37:55 -0300 Subject: V4L/DVB (10902): cleanup linewraps in dib7000m.h Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib7000m.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/dib7000m.h b/drivers/media/dvb/frontends/dib7000m.h index f93db0fda47e..113819ce9f0d 100644 --- a/drivers/media/dvb/frontends/dib7000m.h +++ b/drivers/media/dvb/frontends/dib7000m.h @@ -40,8 +40,12 @@ struct dib7000m_config { #if defined(CONFIG_DVB_DIB7000M) || (defined(CONFIG_DVB_DIB7000M_MODULE) && \ defined(MODULE)) -extern struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg); -extern struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); +extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap, + u8 i2c_addr, + struct dib7000m_config *cfg); +extern struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *, + enum dibx000_i2c_interface, + int); #else static inline struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap, -- cgit v1.2.1 From 7d828bf2b094c86f7904811e348d610d7c20f6fb Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 10 Mar 2009 00:53:57 -0300 Subject: V4L/DVB (10903): cleanup linewraps in dib3000mc.h Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib3000mc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h index b49bf3cb1ed7..d75ffad2d752 100644 --- a/drivers/media/dvb/frontends/dib3000mc.h +++ b/drivers/media/dvb/frontends/dib3000mc.h @@ -39,7 +39,8 @@ struct dib3000mc_config { #define DEFAULT_DIB3000MC_I2C_ADDRESS 16 #define DEFAULT_DIB3000P_I2C_ADDRESS 24 -#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE)) +#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && \ + defined(MODULE)) extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg); -- cgit v1.2.1 From f91294d37a1824c4487b041dc1b4aefbef5fc76e Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 9 Mar 2009 02:39:58 -0300 Subject: V4L/DVB (10904): remove dib0070_ctrl_agc_filter from dib0070.h This function prototype is defined but the function itself does not exist. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dib0070.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h index 21f2c5161af4..9670f5d20cfb 100644 --- a/drivers/media/dvb/frontends/dib0070.h +++ b/drivers/media/dvb/frontends/dib0070.h @@ -58,6 +58,4 @@ static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe) } #endif -extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open); - #endif -- cgit v1.2.1 From cae78ed599c348999a318ace0fcc3ff0277c8fa4 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 13 Jan 2009 04:40:36 -0300 Subject: V4L/DVB (10925): add support for LG Electronics LGDT3305 ATSC/QAM-B Demodulator Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 8 + drivers/media/dvb/frontends/Makefile | 1 + drivers/media/dvb/frontends/lgdt3305.c | 1087 ++++++++++++++++++++++++++++++++ drivers/media/dvb/frontends/lgdt3305.h | 85 +++ 4 files changed, 1181 insertions(+) create mode 100644 drivers/media/dvb/frontends/lgdt3305.c create mode 100644 drivers/media/dvb/frontends/lgdt3305.h (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 2887d3398fb8..5c78f6329d68 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -419,6 +419,14 @@ config DVB_LGDT3304 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. +config DVB_LGDT3305 + tristate "LG Electronics LGDT3305 based" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want + to support this frontend. + config DVB_S5H1409 tristate "Samsung S5H1409 based" depends on DVB_CORE && I2C diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 1e3866b2fd2e..2a250399b555 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o obj-$(CONFIG_DVB_S5H1420) += s5h1420.o obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o obj-$(CONFIG_DVB_LGDT3304) += lgdt3304.o +obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o obj-$(CONFIG_DVB_CX24123) += cx24123.o obj-$(CONFIG_DVB_LNBP21) += lnbp21.o obj-$(CONFIG_DVB_ISL6405) += isl6405.o diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c new file mode 100644 index 000000000000..698c88b0749c --- /dev/null +++ b/drivers/media/dvb/frontends/lgdt3305.c @@ -0,0 +1,1087 @@ +/* + * Support for LGDT3305 - VSB/QAM + * + * Copyright (C) 2008, 2009 Michael Krufky + * + * 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 "dvb_math.h" +#include "lgdt3305.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))"); + +#define DBG_INFO 1 +#define DBG_REG 2 + +#define lg_printk(kern, fmt, arg...) \ + printk(kern "%s: " fmt, __func__, ##arg) + +#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3305: " fmt, ##arg) +#define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg) +#define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg) +#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \ + lg_printk(KERN_DEBUG, fmt, ##arg) +#define lg_reg(fmt, arg...) if (debug & DBG_REG) \ + lg_printk(KERN_DEBUG, fmt, ##arg) + +#define lg_fail(ret) \ +({ \ + int __ret; \ + __ret = (ret < 0); \ + if (__ret) \ + lg_err("error %d on line %d\n", ret, __LINE__); \ + __ret; \ +}) + +struct lgdt3305_state { + struct i2c_adapter *i2c_adap; + const struct lgdt3305_config *cfg; + + struct dvb_frontend frontend; + + fe_modulation_t current_modulation; + u32 current_frequency; + u32 snr; +}; + +/* ------------------------------------------------------------------------ */ + +#define LGDT3305_GEN_CTRL_1 0x0000 +#define LGDT3305_GEN_CTRL_2 0x0001 +#define LGDT3305_GEN_CTRL_3 0x0002 +#define LGDT3305_GEN_STATUS 0x0003 +#define LGDT3305_GEN_CONTROL 0x0007 +#define LGDT3305_GEN_CTRL_4 0x000a +#define LGDT3305_DGTL_AGC_REF_1 0x0012 +#define LGDT3305_DGTL_AGC_REF_2 0x0013 +#define LGDT3305_CR_CTR_FREQ_1 0x0106 +#define LGDT3305_CR_CTR_FREQ_2 0x0107 +#define LGDT3305_CR_CTR_FREQ_3 0x0108 +#define LGDT3305_CR_CTR_FREQ_4 0x0109 +#define LGDT3305_CR_MSE_1 0x011b +#define LGDT3305_CR_MSE_2 0x011c +#define LGDT3305_CR_LOCK_STATUS 0x011d +#define LGDT3305_CR_CTRL_7 0x0126 +#define LGDT3305_AGC_POWER_REF_1 0x0300 +#define LGDT3305_AGC_POWER_REF_2 0x0301 +#define LGDT3305_AGC_DELAY_PT_1 0x0302 +#define LGDT3305_AGC_DELAY_PT_2 0x0303 +#define LGDT3305_RFAGC_LOOP_FLTR_BW_1 0x0306 +#define LGDT3305_RFAGC_LOOP_FLTR_BW_2 0x0307 +#define LGDT3305_IFBW_1 0x0308 +#define LGDT3305_IFBW_2 0x0309 +#define LGDT3305_AGC_CTRL_1 0x030c +#define LGDT3305_AGC_CTRL_4 0x0314 +#define LGDT3305_EQ_MSE_1 0x0413 +#define LGDT3305_EQ_MSE_2 0x0414 +#define LGDT3305_EQ_MSE_3 0x0415 +#define LGDT3305_PT_MSE_1 0x0417 +#define LGDT3305_PT_MSE_2 0x0418 +#define LGDT3305_PT_MSE_3 0x0419 +#define LGDT3305_FEC_BLOCK_CTRL 0x0504 +#define LGDT3305_FEC_LOCK_STATUS 0x050a +#define LGDT3305_FEC_PKT_ERR_1 0x050c +#define LGDT3305_FEC_PKT_ERR_2 0x050d +#define LGDT3305_TP_CTRL_1 0x050e +#define LGDT3305_BERT_PERIOD 0x0801 +#define LGDT3305_BERT_ERROR_COUNT_1 0x080a +#define LGDT3305_BERT_ERROR_COUNT_2 0x080b +#define LGDT3305_BERT_ERROR_COUNT_3 0x080c +#define LGDT3305_BERT_ERROR_COUNT_4 0x080d + +static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val) +{ + int ret; + u8 buf[] = { reg >> 8, reg & 0xff, val }; + struct i2c_msg msg = { + .addr = state->cfg->i2c_addr, .flags = 0, + .buf = buf, .len = 3, + }; + + lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val); + + ret = i2c_transfer(state->i2c_adap, &msg, 1); + + if (ret != 1) { + lg_err("error (addr %02x %02x <- %02x, err = %i)\n", + msg.buf[0], msg.buf[1], msg.buf[2], ret); + if (ret < 0) + return ret; + else + return -EREMOTEIO; + } + return 0; +} + +static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val) +{ + int ret; + u8 reg_buf[] = { reg >> 8, reg & 0xff }; + struct i2c_msg msg[] = { + { .addr = state->cfg->i2c_addr, + .flags = 0, .buf = reg_buf, .len = 2 }, + { .addr = state->cfg->i2c_addr, + .flags = I2C_M_RD, .buf = val, .len = 1 }, + }; + + lg_reg("reg: 0x%04x\n", reg); + + ret = i2c_transfer(state->i2c_adap, msg, 2); + + if (ret != 2) { + lg_err("error (addr %02x reg %04x error (ret == %i)\n", + state->cfg->i2c_addr, reg, ret); + if (ret < 0) + return ret; + else + return -EREMOTEIO; + } + return 0; +} + +#define read_reg(state, reg) \ +({ \ + u8 __val; \ + int ret = lgdt3305_read_reg(state, reg, &__val); \ + if (lg_fail(ret)) \ + __val = 0; \ + __val; \ +}) + +static int lgdt3305_set_reg_bit(struct lgdt3305_state *state, + u16 reg, int bit, int onoff) +{ + u8 val; + int ret; + + lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff); + + ret = lgdt3305_read_reg(state, reg, &val); + if (lg_fail(ret)) + goto fail; + + val &= ~(1 << bit); + val |= (onoff & 1) << bit; + + ret = lgdt3305_write_reg(state, reg, val); +fail: + return ret; +} + +struct lgdt3305_reg { + u16 reg; + u8 val; +}; + +static int lgdt3305_write_regs(struct lgdt3305_state *state, + struct lgdt3305_reg *regs, int len) +{ + int i, ret; + + lg_reg("writing %d registers...\n", len); + + for (i = 0; i < len - 1; i++) { + ret = lgdt3305_write_reg(state, regs[i].reg, regs[i].val); + if (lg_fail(ret)) + return ret; + } + return 0; +} + +/* ------------------------------------------------------------------------ */ + +static int lgdt3305_soft_reset(struct lgdt3305_state *state) +{ + int ret; + + lg_dbg("\n"); + + ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 0); + if (lg_fail(ret)) + goto fail; + + msleep(20); + ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 1); +fail: + return ret; +} + +static inline int lgdt3305_mpeg_mode(struct lgdt3305_state *state, + enum lgdt3305_mpeg_mode mode) +{ + lg_dbg("(%d)\n", mode); + return lgdt3305_set_reg_bit(state, LGDT3305_TP_CTRL_1, 5, mode); +} + +static int lgdt3305_mpeg_mode_polarity(struct lgdt3305_state *state, + enum lgdt3305_tp_clock_edge edge, + enum lgdt3305_tp_valid_polarity valid) +{ + u8 val; + int ret; + + lg_dbg("edge = %d, valid = %d\n", edge, valid); + + ret = lgdt3305_read_reg(state, LGDT3305_TP_CTRL_1, &val); + if (lg_fail(ret)) + goto fail; + + val &= ~0x09; + + if (edge) + val |= 0x08; + if (valid) + val |= 0x01; + + ret = lgdt3305_write_reg(state, LGDT3305_TP_CTRL_1, val); + if (lg_fail(ret)) + goto fail; + + ret = lgdt3305_soft_reset(state); +fail: + return ret; +} + +static int lgdt3305_set_modulation(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + u8 opermode; + int ret; + + lg_dbg("\n"); + + ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_1, &opermode); + if (lg_fail(ret)) + goto fail; + + opermode &= ~0x03; + + switch (param->u.vsb.modulation) { + case VSB_8: + opermode |= 0x03; + break; + case QAM_64: + opermode |= 0x00; + break; + case QAM_256: + opermode |= 0x01; + break; + default: + return -EINVAL; + } + ret = lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_1, opermode); +fail: + return ret; +} + +static int lgdt3305_set_filter_extension(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + int val; + + switch (param->u.vsb.modulation) { + case VSB_8: + val = 0; + break; + case QAM_64: + case QAM_256: + val = 1; + break; + default: + return -EINVAL; + } + lg_dbg("val = %d\n", val); + + return lgdt3305_set_reg_bit(state, 0x043f, 2, val); +} + +/* ------------------------------------------------------------------------ */ + +static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + u16 agc_ref; + + switch (param->u.vsb.modulation) { + case VSB_8: + agc_ref = 0x32c4; + break; + case QAM_64: + agc_ref = 0x2a00; + break; + case QAM_256: + agc_ref = 0x2a80; + break; + default: + return -EINVAL; + } + + lg_dbg("agc ref: 0x%04x\n", agc_ref); + + lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_1, agc_ref >> 8); + lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_2, agc_ref & 0xff); + + return 0; +} + +static int lgdt3305_rfagc_loop(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + u16 ifbw, rfbw, agcdelay; + + switch (param->u.vsb.modulation) { + case VSB_8: + agcdelay = 0x04c0; + rfbw = 0x8000; + ifbw = 0x8000; + break; + case QAM_64: + case QAM_256: + agcdelay = 0x046b; + rfbw = 0x8889; + ifbw = 0x8888; + break; + default: + return -EINVAL; + } + + if (state->cfg->rf_agc_loop) { + lg_dbg("agcdelay: 0x%04x, rfbw: 0x%04x\n", agcdelay, rfbw); + + /* rf agc loop filter bandwidth */ + lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_1, + agcdelay >> 8); + lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_2, + agcdelay & 0xff); + + lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_1, + rfbw >> 8); + lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_2, + rfbw & 0xff); + } else { + lg_dbg("ifbw: 0x%04x\n", ifbw); + + /* if agc loop filter bandwidth */ + lgdt3305_write_reg(state, LGDT3305_IFBW_1, ifbw >> 8); + lgdt3305_write_reg(state, LGDT3305_IFBW_2, ifbw & 0xff); + } + + return 0; +} + +static int lgdt3305_agc_setup(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + int lockdten, acqen; + + switch (param->u.vsb.modulation) { + case VSB_8: + lockdten = 0; + acqen = 0; + break; + case QAM_64: + case QAM_256: + lockdten = 1; + acqen = 1; + break; + default: + return -EINVAL; + } + + lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen); + + /* control agc function */ + lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1); + lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen); + + return lgdt3305_rfagc_loop(state, param); +} + +static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + u16 usref = 0; + + switch (param->u.vsb.modulation) { + case VSB_8: + if (state->cfg->usref_8vsb) + usref = state->cfg->usref_8vsb; + break; + case QAM_64: + if (state->cfg->usref_qam64) + usref = state->cfg->usref_qam64; + break; + case QAM_256: + if (state->cfg->usref_qam256) + usref = state->cfg->usref_qam256; + break; + default: + return -EINVAL; + } + + if (usref) { + lg_dbg("set manual mode: 0x%04x\n", usref); + + lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 3, 1); + + lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_1, + 0xff & (usref >> 8)); + lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_2, + 0xff & (usref >> 0)); + } + return 0; +} + +/* ------------------------------------------------------------------------ */ + +static int lgdt3305_spectral_inversion(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param, + int inversion) +{ + int ret; + + lg_dbg("(%d)\n", inversion); + + switch (param->u.vsb.modulation) { + case VSB_8: + ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7, + inversion ? 0xf9 : 0x79); + break; + case QAM_64: + case QAM_256: + ret = lgdt3305_write_reg(state, LGDT3305_FEC_BLOCK_CTRL, + inversion ? 0xfd : 0xff); + break; + default: + ret = -EINVAL; + } + return ret; +} + +static int lgdt3305_set_if(struct lgdt3305_state *state, + struct dvb_frontend_parameters *param) +{ + u16 if_freq_khz; + u8 nco1, nco2, nco3, nco4; + u64 nco; + + switch (param->u.vsb.modulation) { + case VSB_8: + if_freq_khz = state->cfg->vsb_if_khz; + break; + case QAM_64: + case QAM_256: + if_freq_khz = state->cfg->qam_if_khz; + break; + default: + return -EINVAL; + } + + nco = if_freq_khz / 10; + +#define LGDT3305_64BIT_DIVISION_ENABLED 0 + /* FIXME: 64bit division disabled to avoid linking error: + * WARNING: "__udivdi3" [lgdt3305.ko] undefined! + */ + switch (param->u.vsb.modulation) { + case VSB_8: +#if LGDT3305_64BIT_DIVISION_ENABLED + nco <<= 24; + nco /= 625; +#else + nco *= ((1 << 24) / 625); +#endif + break; + case QAM_64: + case QAM_256: +#if LGDT3305_64BIT_DIVISION_ENABLED + nco <<= 28; + nco /= 625; +#else + nco *= ((1 << 28) / 625); +#endif + break; + default: + return -EINVAL; + } + + nco1 = (nco >> 24) & 0x3f; + nco1 |= 0x40; + nco2 = (nco >> 16) & 0xff; + nco3 = (nco >> 8) & 0xff; + nco4 = nco & 0xff; + + lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, nco1); + lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, nco2); + lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, nco3); + lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, nco4); + + lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n", + if_freq_khz, nco1, nco2, nco3, nco4); + + return 0; +} + +/* ------------------------------------------------------------------------ */ + +static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + + if (state->cfg->deny_i2c_rptr) + return 0; + + lg_dbg("(%d)\n", enable); + + return lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_2, 5, + enable ? 0 : 1); +} + +static int lgdt3305_sleep(struct dvb_frontend *fe) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + u8 gen_ctrl_3, gen_ctrl_4; + + lg_dbg("\n"); + + gen_ctrl_3 = read_reg(state, LGDT3305_GEN_CTRL_3); + gen_ctrl_4 = read_reg(state, LGDT3305_GEN_CTRL_4); + + /* hold in software reset while sleeping */ + gen_ctrl_3 &= ~0x01; + /* tristate the IF-AGC pin */ + gen_ctrl_3 |= 0x02; + /* tristate the RF-AGC pin */ + gen_ctrl_3 |= 0x04; + + /* disable vsb/qam module */ + gen_ctrl_4 &= ~0x01; + /* disable adc module */ + gen_ctrl_4 &= ~0x02; + + lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_3, gen_ctrl_3); + lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_4, gen_ctrl_4); + + return 0; +} + +static int lgdt3305_init(struct dvb_frontend *fe) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + int ret; + + static struct lgdt3305_reg lgdt3305_init_data[] = { + { .reg = LGDT3305_GEN_CTRL_1, + .val = 0x03, }, + { .reg = LGDT3305_GEN_CTRL_2, + .val = 0xb0, }, + { .reg = LGDT3305_GEN_CTRL_3, + .val = 0x01, }, + { .reg = LGDT3305_GEN_CONTROL, + .val = 0x6f, }, + { .reg = LGDT3305_GEN_CTRL_4, + .val = 0x03, }, + { .reg = LGDT3305_DGTL_AGC_REF_1, + .val = 0x32, }, + { .reg = LGDT3305_DGTL_AGC_REF_2, + .val = 0xc4, }, + { .reg = LGDT3305_CR_CTR_FREQ_1, + .val = 0x00, }, + { .reg = LGDT3305_CR_CTR_FREQ_2, + .val = 0x00, }, + { .reg = LGDT3305_CR_CTR_FREQ_3, + .val = 0x00, }, + { .reg = LGDT3305_CR_CTR_FREQ_4, + .val = 0x00, }, + { .reg = LGDT3305_CR_CTRL_7, + .val = 0x79, }, + { .reg = LGDT3305_AGC_POWER_REF_1, + .val = 0x32, }, + { .reg = LGDT3305_AGC_POWER_REF_2, + .val = 0xc4, }, + { .reg = LGDT3305_AGC_DELAY_PT_1, + .val = 0x0d, }, + { .reg = LGDT3305_AGC_DELAY_PT_2, + .val = 0x30, }, + { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1, + .val = 0x80, }, + { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2, + .val = 0x00, }, + { .reg = LGDT3305_IFBW_1, + .val = 0x80, }, + { .reg = LGDT3305_IFBW_2, + .val = 0x00, }, + { .reg = LGDT3305_AGC_CTRL_1, + .val = 0x30, }, + { .reg = LGDT3305_AGC_CTRL_4, + .val = 0x61, }, + { .reg = LGDT3305_FEC_BLOCK_CTRL, + .val = 0xff, }, + { .reg = LGDT3305_TP_CTRL_1, + .val = 0x1b, }, + }; + + lg_dbg("\n"); + + ret = lgdt3305_write_regs(state, lgdt3305_init_data, + ARRAY_SIZE(lgdt3305_init_data)); + if (lg_fail(ret)) + goto fail; + + ret = lgdt3305_soft_reset(state); +fail: + return ret; +} + +static int lgdt3305_set_parameters(struct dvb_frontend *fe, + struct dvb_frontend_parameters *param) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + int ret; + + lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation); + + if (fe->ops.tuner_ops.set_params) { + ret = fe->ops.tuner_ops.set_params(fe, param); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + if (lg_fail(ret)) + goto fail; + state->current_frequency = param->frequency; + } + + ret = lgdt3305_set_modulation(state, param); + if (lg_fail(ret)) + goto fail; + + ret = lgdt3305_passband_digital_agc(state, param); + if (lg_fail(ret)) + goto fail; + ret = lgdt3305_set_agc_power_ref(state, param); + if (lg_fail(ret)) + goto fail; + ret = lgdt3305_agc_setup(state, param); + if (lg_fail(ret)) + goto fail; + + /* low if */ + ret = lgdt3305_write_reg(state, LGDT3305_GEN_CONTROL, 0x2f); + if (lg_fail(ret)) + goto fail; + ret = lgdt3305_set_reg_bit(state, LGDT3305_CR_CTR_FREQ_1, 6, 1); + if (lg_fail(ret)) + goto fail; + + ret = lgdt3305_set_if(state, param); + if (lg_fail(ret)) + goto fail; + ret = lgdt3305_spectral_inversion(state, param, + state->cfg->spectral_inversion + ? 1 : 0); + if (lg_fail(ret)) + goto fail; + + ret = lgdt3305_set_filter_extension(state, param); + if (lg_fail(ret)) + goto fail; + + state->current_modulation = param->u.vsb.modulation; + + ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode); + if (lg_fail(ret)) + goto fail; + + /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */ + ret = lgdt3305_mpeg_mode_polarity(state, + state->cfg->tpclk_edge, + state->cfg->tpvalid_polarity); +fail: + return ret; +} + +static int lgdt3305_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *param) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + + lg_dbg("\n"); + + param->u.vsb.modulation = state->current_modulation; + param->frequency = state->current_frequency; + return 0; +} + +/* ------------------------------------------------------------------------ */ + +static int lgdt3305_read_cr_lock_status(struct lgdt3305_state *state, + int *locked) +{ + u8 val; + int ret; + char *cr_lock_state = ""; + + *locked = 0; + + ret = lgdt3305_read_reg(state, LGDT3305_CR_LOCK_STATUS, &val); + if (lg_fail(ret)) + goto fail; + + switch (state->current_modulation) { + case QAM_256: + case QAM_64: + if (val & (1 << 1)) + *locked = 1; + + switch (val & 0x07) { + case 0: + cr_lock_state = "QAM UNLOCK"; + break; + case 4: + cr_lock_state = "QAM 1stLock"; + break; + case 6: + cr_lock_state = "QAM 2ndLock"; + break; + case 7: + cr_lock_state = "QAM FinalLock"; + break; + default: + cr_lock_state = "CLOCKQAM-INVALID!"; + break; + } + break; + case VSB_8: + if (val & (1 << 7)) { + *locked = 1; + cr_lock_state = "CLOCKVSB"; + } + break; + default: + ret = -EINVAL; + } + lg_dbg("(%d) %s\n", *locked, cr_lock_state); +fail: + return ret; +} + +static int lgdt3305_read_fec_lock_status(struct lgdt3305_state *state, + int *locked) +{ + u8 val; + int ret, mpeg_lock, fec_lock, viterbi_lock; + + *locked = 0; + + switch (state->current_modulation) { + case QAM_256: + case QAM_64: + ret = lgdt3305_read_reg(state, + LGDT3305_FEC_LOCK_STATUS, &val); + if (lg_fail(ret)) + goto fail; + + mpeg_lock = (val & (1 << 0)) ? 1 : 0; + fec_lock = (val & (1 << 2)) ? 1 : 0; + viterbi_lock = (val & (1 << 3)) ? 1 : 0; + + *locked = mpeg_lock && fec_lock && viterbi_lock; + + lg_dbg("(%d) %s%s%s\n", *locked, + mpeg_lock ? "mpeg lock " : "", + fec_lock ? "fec lock " : "", + viterbi_lock ? "viterbi lock" : ""); + break; + case VSB_8: + default: + ret = -EINVAL; + } +fail: + return ret; +} + +static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + u8 val; + int ret, signal, inlock, nofecerr, snrgood, + cr_lock, fec_lock, sync_lock; + + *status = 0; + + ret = lgdt3305_read_reg(state, LGDT3305_GEN_STATUS, &val); + if (lg_fail(ret)) + goto fail; + + signal = (val & (1 << 4)) ? 1 : 0; + inlock = (val & (1 << 3)) ? 0 : 1; + sync_lock = (val & (1 << 2)) ? 1 : 0; + nofecerr = (val & (1 << 1)) ? 1 : 0; + snrgood = (val & (1 << 0)) ? 1 : 0; + + lg_dbg("%s%s%s%s%s\n", + signal ? "SIGNALEXIST " : "", + inlock ? "INLOCK " : "", + sync_lock ? "SYNCLOCK " : "", + nofecerr ? "NOFECERR " : "", + snrgood ? "SNRGOOD " : ""); + + ret = lgdt3305_read_cr_lock_status(state, &cr_lock); + if (lg_fail(ret)) + goto fail; + + if (signal) + *status |= FE_HAS_SIGNAL; + if (cr_lock) + *status |= FE_HAS_CARRIER; + if (nofecerr) + *status |= FE_HAS_VITERBI; + if (sync_lock) + *status |= FE_HAS_SYNC; + + switch (state->current_modulation) { + case QAM_256: + case QAM_64: + ret = lgdt3305_read_fec_lock_status(state, &fec_lock); + if (lg_fail(ret)) + goto fail; + + if (fec_lock) + *status |= FE_HAS_LOCK; + break; + case VSB_8: + if (inlock) + *status |= FE_HAS_LOCK; + break; + default: + ret = -EINVAL; + } +fail: + return ret; +} + +/* ------------------------------------------------------------------------ */ + +/* borrowed from lgdt330x.c */ +static u32 calculate_snr(u32 mse, u32 c) +{ + if (mse == 0) /* no signal */ + return 0; + + mse = intlog10(mse); + if (mse > c) { + /* Negative SNR, which is possible, but realisticly the + demod will lose lock before the signal gets this bad. The + API only allows for unsigned values, so just return 0 */ + return 0; + } + return 10*(c - mse); +} + +static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + u32 noise; /* noise value */ + u32 c; /* per-modulation SNR calculation constant */ + + switch (state->current_modulation) { + case VSB_8: +#ifdef USE_PTMSE + /* Use Phase Tracker Mean-Square Error Register */ + /* SNR for ranges from -13.11 to +44.08 */ + noise = ((read_reg(state, LGDT3305_PT_MSE_1) & 0x07) << 16) | + (read_reg(state, LGDT3305_PT_MSE_2) << 8) | + (read_reg(state, LGDT3305_PT_MSE_3) & 0xff); + c = 73957994; /* log10(25*32^2)*2^24 */ +#else + /* Use Equalizer Mean-Square Error Register */ + /* SNR for ranges from -16.12 to +44.08 */ + noise = ((read_reg(state, LGDT3305_EQ_MSE_1) & 0x0f) << 16) | + (read_reg(state, LGDT3305_EQ_MSE_2) << 8) | + (read_reg(state, LGDT3305_EQ_MSE_3) & 0xff); + c = 73957994; /* log10(25*32^2)*2^24 */ +#endif + break; + case QAM_64: + case QAM_256: + noise = (read_reg(state, LGDT3305_CR_MSE_1) << 8) | + (read_reg(state, LGDT3305_CR_MSE_2) & 0xff); + + c = (state->current_modulation == QAM_64) ? + 97939837 : 98026066; + /* log10(688128)*2^24 and log10(696320)*2^24 */ + break; + default: + return -EINVAL; + } + state->snr = calculate_snr(noise, c); + /*report SNR in dB * 10 */ + *snr = (state->snr / ((1 << 24) / 10)); + lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise, + state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16); + + return 0; +} + +static int lgdt3305_read_signal_strength(struct dvb_frontend *fe, + u16 *strength) +{ + /* borrowed from lgdt330x.c + * + * Calculate strength from SNR up to 35dB + * Even though the SNR can go higher than 35dB, + * there is some comfort factor in having a range of + * strong signals that can show at 100% + */ + struct lgdt3305_state *state = fe->demodulator_priv; + u16 snr; + int ret; + + *strength = 0; + + ret = fe->ops.read_snr(fe, &snr); + if (lg_fail(ret)) + goto fail; + /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */ + /* scale the range 0 - 35*2^24 into 0 - 65535 */ + if (state->snr >= 8960 * 0x10000) + *strength = 0xffff; + else + *strength = state->snr / 8960; +fail: + return ret; +} + +/* ------------------------------------------------------------------------ */ + +static int lgdt3305_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + *ber = 0; + return 0; +} + +static int lgdt3305_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + + *ucblocks = + (read_reg(state, LGDT3305_FEC_PKT_ERR_1) << 8) | + (read_reg(state, LGDT3305_FEC_PKT_ERR_2) & 0xff); + + return 0; +} + +static int lgdt3305_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings + *fe_tune_settings) +{ + fe_tune_settings->min_delay_ms = 500; + lg_dbg("\n"); + return 0; +} + +static void lgdt3305_release(struct dvb_frontend *fe) +{ + struct lgdt3305_state *state = fe->demodulator_priv; + lg_dbg("\n"); + kfree(state); +} + +static struct dvb_frontend_ops lgdt3305_ops; + +struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, + struct i2c_adapter *i2c_adap) +{ + struct lgdt3305_state *state = NULL; + int ret; + u8 val; + + lg_dbg("(%d-%04x)\n", + i2c_adap ? i2c_adapter_id(i2c_adap) : 0, + config ? config->i2c_addr : 0); + + state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL); + if (state == NULL) + goto fail; + + state->cfg = config; + state->i2c_adap = i2c_adap; + + memcpy(&state->frontend.ops, &lgdt3305_ops, + sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + + /* verify that we're talking to a lg dt3305 */ + ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val); + if ((lg_fail(ret)) | (val == 0)) + goto fail; + ret = lgdt3305_write_reg(state, 0x0808, 0x80); + if (lg_fail(ret)) + goto fail; + ret = lgdt3305_read_reg(state, 0x0808, &val); + if ((lg_fail(ret)) | (val != 0x80)) + goto fail; + ret = lgdt3305_write_reg(state, 0x0808, 0x00); + if (lg_fail(ret)) + goto fail; + + state->current_frequency = -1; + state->current_modulation = -1; + + return &state->frontend; +fail: + lg_warn("unable to detect LGDT3305 hardware\n"); + state->frontend.demodulator_priv = NULL; + kfree(state); + return NULL; +} +EXPORT_SYMBOL(lgdt3305_attach); + +static struct dvb_frontend_ops lgdt3305_ops = { + .info = { + .name = "LG Electronics LGDT3305 VSB/QAM Frontend", + .type = FE_ATSC, + .frequency_min = 54000000, + .frequency_max = 858000000, + .frequency_stepsize = 62500, + .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB + }, + .i2c_gate_ctrl = lgdt3305_i2c_gate_ctrl, + .init = lgdt3305_init, + .sleep = lgdt3305_sleep, + .set_frontend = lgdt3305_set_parameters, + .get_frontend = lgdt3305_get_frontend, + .get_tune_settings = lgdt3305_get_tune_settings, + .read_status = lgdt3305_read_status, + .read_ber = lgdt3305_read_ber, + .read_signal_strength = lgdt3305_read_signal_strength, + .read_snr = lgdt3305_read_snr, + .read_ucblocks = lgdt3305_read_ucblocks, + .release = lgdt3305_release, +}; + +MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver"); +MODULE_AUTHOR("Michael Krufky"); +MODULE_LICENSE("GPL"); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/drivers/media/dvb/frontends/lgdt3305.h b/drivers/media/dvb/frontends/lgdt3305.h new file mode 100644 index 000000000000..4fa6e52d1fe8 --- /dev/null +++ b/drivers/media/dvb/frontends/lgdt3305.h @@ -0,0 +1,85 @@ +/* + * Support for LGDT3305 - VSB/QAM + * + * Copyright (C) 2008, 2009 Michael Krufky + * + * 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 _LGDT3305_H_ +#define _LGDT3305_H_ + +#include +#include "dvb_frontend.h" + + +enum lgdt3305_mpeg_mode { + LGDT3305_MPEG_PARALLEL = 0, + LGDT3305_MPEG_SERIAL = 1, +}; + +enum lgdt3305_tp_clock_edge { + LGDT3305_TPCLK_RISING_EDGE = 0, + LGDT3305_TPCLK_FALLING_EDGE = 1, +}; + +enum lgdt3305_tp_valid_polarity { + LGDT3305_TP_VALID_LOW = 0, + LGDT3305_TP_VALID_HIGH = 1, +}; + +struct lgdt3305_config { + u8 i2c_addr; + + /* user defined IF frequency in KHz */ + u16 qam_if_khz; + u16 vsb_if_khz; + + /* AGC Power reference - defaults are used if left unset */ + u16 usref_8vsb; /* default: 0x32c4 */ + u16 usref_qam64; /* default: 0x5400 */ + u16 usref_qam256; /* default: 0x2a80 */ + + /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */ + int deny_i2c_rptr:1; + + /* spectral inversion - 0:disabled 1:enabled */ + int spectral_inversion:1; + + /* use RF AGC loop - 0:disabled 1:enabled */ + int rf_agc_loop:1; + + enum lgdt3305_mpeg_mode mpeg_mode; + enum lgdt3305_tp_clock_edge tpclk_edge; + enum lgdt3305_tp_valid_polarity tpvalid_polarity; +}; + +#if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \ + defined(MODULE)) +extern +struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, + struct i2c_adapter *i2c_adap); +#else +static inline +struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, + struct i2c_adapter *i2c_adap) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_LGDT3305 */ + +#endif /* _LGDT3305_H_ */ -- cgit v1.2.1 From 1c12148bdcc6a978ab6a9930d40ddfb9d26e9e82 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 11 Mar 2009 01:45:44 -0300 Subject: V4L/DVB (10968): lgdt3305: add email address to MODULE_AUTHOR Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/lgdt3305.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c index 698c88b0749c..729a30f99d4b 100644 --- a/drivers/media/dvb/frontends/lgdt3305.c +++ b/drivers/media/dvb/frontends/lgdt3305.c @@ -1077,7 +1077,7 @@ static struct dvb_frontend_ops lgdt3305_ops = { }; MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver"); -MODULE_AUTHOR("Michael Krufky"); +MODULE_AUTHOR("Michael Krufky "); MODULE_LICENSE("GPL"); /* -- cgit v1.2.1 From 60ce3c471fdc4f5a173a393710138717b639e3c1 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 11 Mar 2009 01:47:53 -0300 Subject: V4L/DVB (10969): lgdt3305: add missing space in comment small whitespace cleanup - space missing after the * Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/lgdt3305.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c index 729a30f99d4b..f5f77117ec34 100644 --- a/drivers/media/dvb/frontends/lgdt3305.c +++ b/drivers/media/dvb/frontends/lgdt3305.c @@ -931,7 +931,7 @@ static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr) return -EINVAL; } state->snr = calculate_snr(noise, c); - /*report SNR in dB * 10 */ + /* report SNR in dB * 10 */ *snr = (state->snr / ((1 << 24) / 10)); lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise, state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16); -- cgit v1.2.1 From 0290152c0f0f4a1c3d6e2b6064780d0cc288d8a4 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 11 Mar 2009 01:46:44 -0300 Subject: V4L/DVB (10970): lgdt3305: add MODULE_VERSION We'll start off with MODULE_VERSION("0.1") Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/lgdt3305.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c index f5f77117ec34..0ad820b08ca5 100644 --- a/drivers/media/dvb/frontends/lgdt3305.c +++ b/drivers/media/dvb/frontends/lgdt3305.c @@ -1079,6 +1079,7 @@ static struct dvb_frontend_ops lgdt3305_ops = { MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver"); MODULE_AUTHOR("Michael Krufky "); MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1"); /* * Local variables: -- cgit v1.2.1 From 9f9cd8f18c7faabf6dc144c198f6ee30429d3da0 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 12 Mar 2009 10:12:16 -0300 Subject: V4L/DVB (10984): lgdt3305: avoid OOPS in error path of lgdt3305_attach Setting state->frontend.demodulator_priv to NULL in the event of a kzalloc error will result in an OOPS. Just remove that line. Thanks to Matthias Schwarzott for pointing this out. Cc: Matthias Schwarzott Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/lgdt3305.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c index 0ad820b08ca5..d92d0557a80b 100644 --- a/drivers/media/dvb/frontends/lgdt3305.c +++ b/drivers/media/dvb/frontends/lgdt3305.c @@ -1047,7 +1047,6 @@ struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, return &state->frontend; fail: lg_warn("unable to detect LGDT3305 hardware\n"); - state->frontend.demodulator_priv = NULL; kfree(state); return NULL; } -- cgit v1.2.1 From 11a84143b27303095b035931350e9233b538c4e3 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sun, 15 Mar 2009 07:28:45 -0300 Subject: V4L/DVB (11054): Shorten some lines in stv0900 to less then 81 characters Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_core.c | 41 ++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index 3cc6626fe633..5c8835ed7338 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -656,13 +656,18 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, dprintk(KERN_INFO "%s\n", __func__); - dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF); + dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF, + F0900_P2_LOCK_DEFINITIF); if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) { - dmd_reg(noise_field1, F0900_P1_NOSPLHT_NORMED1, F0900_P2_NOSPLHT_NORMED1); - dmd_reg(noise_field0, F0900_P1_NOSPLHT_NORMED0, F0900_P2_NOSPLHT_NORMED0); + dmd_reg(noise_field1, F0900_P1_NOSPLHT_NORMED1, + F0900_P2_NOSPLHT_NORMED1); + dmd_reg(noise_field0, F0900_P1_NOSPLHT_NORMED0, + F0900_P2_NOSPLHT_NORMED0); } else { - dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1, F0900_P2_NOSDATAT_NORMED1); - dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0, F0900_P1_NOSDATAT_NORMED0); + dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1, + F0900_P2_NOSDATAT_NORMED1); + dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0, + F0900_P1_NOSDATAT_NORMED0); } if (stv0900_get_bits(i_params, lock_flag_field)) { @@ -670,27 +675,34 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, regval = 0; msleep(5); for (i = 0; i < 16; i++) { - regval += MAKEWORD(stv0900_get_bits(i_params, noise_field1), - stv0900_get_bits(i_params, noise_field0)); + regval += MAKEWORD(stv0900_get_bits(i_params, + noise_field1), + stv0900_get_bits(i_params, + noise_field0)); msleep(1); } regval /= 16; imin = 0; imax = lookup->size - 1; - if (INRANGE(lookup->table[imin].regval, regval, lookup->table[imax].regval)) { + if (INRANGE(lookup->table[imin].regval, + regval, + lookup->table[imax].regval)) { while ((imax - imin) > 1) { i = (imax + imin) >> 1; - - if (INRANGE(lookup->table[imin].regval, regval, lookup->table[i].regval)) + if (INRANGE(lookup->table[imin].regval, + regval, + lookup->table[i].regval)) imax = i; else imin = i; } c_n = ((regval - lookup->table[imin].regval) - * (lookup->table[imax].realval - lookup->table[imin].realval) - / (lookup->table[imax].regval - lookup->table[imin].regval)) + * (lookup->table[imax].realval + - lookup->table[imin].realval) + / (lookup->table[imax].regval + - lookup->table[imin].regval)) + lookup->table[imin].realval; } else if (regval < lookup->table[imin].regval) c_n = 1000; @@ -702,7 +714,10 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr) { - *snr = (16383 / 1030) * (30 + stv0900_carr_get_quality(fe, (const struct stv0900_table *)&stv0900_s2_cn)); + *snr = stv0900_carr_get_quality(fe, + (const struct stv0900_table *)&stv0900_s2_cn); + *snr += 30; + *snr *= (16383 / 1030); return 0; } -- cgit v1.2.1 From 5765348cd41c17c797765174d479508ecfbd43de Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Sun, 15 Mar 2009 07:31:45 -0300 Subject: V4L/DVB (11055): Fix typo in stv0900 Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index 5c8835ed7338..da414b12247f 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -667,7 +667,7 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1, F0900_P2_NOSDATAT_NORMED1); dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0, - F0900_P1_NOSDATAT_NORMED0); + F0900_P2_NOSDATAT_NORMED0); } if (stv0900_get_bits(i_params, lock_flag_field)) { -- cgit v1.2.1 From e9d4a6d5ef58a700d3add96ffb984741c6e34fff Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Tue, 17 Mar 2009 18:21:18 -0300 Subject: V4L/DVB (11057): Fix CiMax stability in Netup Dual DVB-S2 CI It appears TS discontinuity about one per 10 hrs if CAM used. Patch to fix it. Signed-off-by: Abylay Ospan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0900_core.c | 2 +- drivers/media/dvb/frontends/stv0900_init.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index da414b12247f..8499bcf7f251 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -250,7 +250,7 @@ enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params) } msleep(3); - for (i = 0; i < 180; i++) + for (i = 0; i < 182; i++) stv0900_write_reg(i_params, STV0900_InitVal[i][0], STV0900_InitVal[i][1]); if (stv0900_read_reg(i_params, R0900_MID) >= 0x20) { diff --git a/drivers/media/dvb/frontends/stv0900_init.h b/drivers/media/dvb/frontends/stv0900_init.h index fa8dbe197bd6..ff388b47a4e3 100644 --- a/drivers/media/dvb/frontends/stv0900_init.h +++ b/drivers/media/dvb/frontends/stv0900_init.h @@ -217,7 +217,7 @@ static const struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoo { STV0900_32APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B, 0x1E, 0x3A, 0x3D, 0x2A, 0x2D } }; -static const u16 STV0900_InitVal[180][2] = { +static const u16 STV0900_InitVal[182][2] = { { R0900_OUTCFG , 0x00 }, { R0900_MODECFG , 0xff }, { R0900_AGCRF1CFG , 0x11 }, @@ -396,6 +396,8 @@ static const u16 STV0900_InitVal[180][2] = { { R0900_DATA72CFG , 0x52 }, { R0900_P1_TSCFGM , 0xc0 }, { R0900_P2_TSCFGM , 0xc0 }, + { R0900_P1_TSCFGH , 0xe0 }, /* DVB-CI timings */ + { R0900_P2_TSCFGH , 0xe0 }, /* DVB-CI timings */ { R0900_P1_TSSPEED , 0x40 }, { R0900_P2_TSSPEED , 0x40 }, }; -- cgit v1.2.1 From f56738cd81690dcaec92307b1a7f9f5f69af15b1 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 02:59:30 -0300 Subject: V4L/DVB (11060): au8522: rename the au8522.c source file Rename the au8522.c file to au8522_dig.c so that more source files can be added to the driver while preserving the original name of au8522.ko Thanks to Michael Krufky and Steven Toth for providing sample hardware, engineering level support, and testing. Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Makefile | 1 + drivers/media/dvb/frontends/au8522.c | 874 ------------------------------- drivers/media/dvb/frontends/au8522_dig.c | 874 +++++++++++++++++++++++++++++++ 3 files changed, 875 insertions(+), 874 deletions(-) delete mode 100644 drivers/media/dvb/frontends/au8522.c create mode 100644 drivers/media/dvb/frontends/au8522_dig.c (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 2a250399b555..742826523df5 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -8,6 +8,7 @@ EXTRA_CFLAGS += -Idrivers/media/common/tuners/ s921-objs := s921_module.o s921_core.o stb0899-objs = stb0899_drv.o stb0899_algo.o stv0900-objs = stv0900_core.o stv0900_sw.o +au8522-objs = au8522_dig.o obj-$(CONFIG_DVB_PLL) += dvb-pll.o obj-$(CONFIG_DVB_STV0299) += stv0299.o diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c deleted file mode 100644 index eabf9a68e7ec..000000000000 --- a/drivers/media/dvb/frontends/au8522.c +++ /dev/null @@ -1,874 +0,0 @@ -/* - Auvitek AU8522 QAM/8VSB demodulator driver - - Copyright (C) 2008 Steven Toth - - 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 "au8522.h" - -struct au8522_state { - - struct i2c_adapter *i2c; - - /* configuration settings */ - const struct au8522_config *config; - - struct dvb_frontend frontend; - - u32 current_frequency; - fe_modulation_t current_modulation; - - u32 fe_status; - unsigned int led_state; -}; - -static int debug; - -#define dprintk(arg...) do { \ - if (debug) \ - printk(arg); \ - } while (0) - -/* 16 bit registers, 8 bit values */ -static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) -{ - int ret; - u8 buf [] = { reg >> 8, reg & 0xff, data }; - - struct i2c_msg msg = { .addr = state->config->demod_address, - .flags = 0, .buf = buf, .len = 3 }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static u8 au8522_readreg(struct au8522_state *state, u16 reg) -{ - int ret; - u8 b0 [] = { reg >> 8, reg & 0xff }; - u8 b1 [] = { 0 }; - - struct i2c_msg msg [] = { - { .addr = state->config->demod_address, .flags = 0, - .buf = b0, .len = 2 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, - .buf = b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - printk(KERN_ERR "%s: readreg error (ret == %i)\n", - __func__, ret); - return b1[0]; -} - -static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct au8522_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, enable); - - if (enable) - return au8522_writereg(state, 0x106, 1); - else - return au8522_writereg(state, 0x106, 0); -} - -struct mse2snr_tab { - u16 val; - u16 data; -}; - -/* VSB SNR lookup table */ -static struct mse2snr_tab vsb_mse2snr_tab[] = { - { 0, 270 }, - { 2, 250 }, - { 3, 240 }, - { 5, 230 }, - { 7, 220 }, - { 9, 210 }, - { 12, 200 }, - { 13, 195 }, - { 15, 190 }, - { 17, 185 }, - { 19, 180 }, - { 21, 175 }, - { 24, 170 }, - { 27, 165 }, - { 31, 160 }, - { 32, 158 }, - { 33, 156 }, - { 36, 152 }, - { 37, 150 }, - { 39, 148 }, - { 40, 146 }, - { 41, 144 }, - { 43, 142 }, - { 44, 140 }, - { 48, 135 }, - { 50, 130 }, - { 43, 142 }, - { 53, 125 }, - { 56, 120 }, - { 256, 115 }, -}; - -/* QAM64 SNR lookup table */ -static struct mse2snr_tab qam64_mse2snr_tab[] = { - { 15, 0 }, - { 16, 290 }, - { 17, 288 }, - { 18, 286 }, - { 19, 284 }, - { 20, 282 }, - { 21, 281 }, - { 22, 279 }, - { 23, 277 }, - { 24, 275 }, - { 25, 273 }, - { 26, 271 }, - { 27, 269 }, - { 28, 268 }, - { 29, 266 }, - { 30, 264 }, - { 31, 262 }, - { 32, 260 }, - { 33, 259 }, - { 34, 258 }, - { 35, 256 }, - { 36, 255 }, - { 37, 254 }, - { 38, 252 }, - { 39, 251 }, - { 40, 250 }, - { 41, 249 }, - { 42, 248 }, - { 43, 246 }, - { 44, 245 }, - { 45, 244 }, - { 46, 242 }, - { 47, 241 }, - { 48, 240 }, - { 50, 239 }, - { 51, 238 }, - { 53, 237 }, - { 54, 236 }, - { 56, 235 }, - { 57, 234 }, - { 59, 233 }, - { 60, 232 }, - { 62, 231 }, - { 63, 230 }, - { 65, 229 }, - { 67, 228 }, - { 68, 227 }, - { 70, 226 }, - { 71, 225 }, - { 73, 224 }, - { 74, 223 }, - { 76, 222 }, - { 78, 221 }, - { 80, 220 }, - { 82, 219 }, - { 85, 218 }, - { 88, 217 }, - { 90, 216 }, - { 92, 215 }, - { 93, 214 }, - { 94, 212 }, - { 95, 211 }, - { 97, 210 }, - { 99, 209 }, - { 101, 208 }, - { 102, 207 }, - { 104, 206 }, - { 107, 205 }, - { 111, 204 }, - { 114, 203 }, - { 118, 202 }, - { 122, 201 }, - { 125, 200 }, - { 128, 199 }, - { 130, 198 }, - { 132, 197 }, - { 256, 190 }, -}; - -/* QAM256 SNR lookup table */ -static struct mse2snr_tab qam256_mse2snr_tab[] = { - { 16, 0 }, - { 17, 400 }, - { 18, 398 }, - { 19, 396 }, - { 20, 394 }, - { 21, 392 }, - { 22, 390 }, - { 23, 388 }, - { 24, 386 }, - { 25, 384 }, - { 26, 382 }, - { 27, 380 }, - { 28, 379 }, - { 29, 378 }, - { 30, 377 }, - { 31, 376 }, - { 32, 375 }, - { 33, 374 }, - { 34, 373 }, - { 35, 372 }, - { 36, 371 }, - { 37, 370 }, - { 38, 362 }, - { 39, 354 }, - { 40, 346 }, - { 41, 338 }, - { 42, 330 }, - { 43, 328 }, - { 44, 326 }, - { 45, 324 }, - { 46, 322 }, - { 47, 320 }, - { 48, 319 }, - { 49, 318 }, - { 50, 317 }, - { 51, 316 }, - { 52, 315 }, - { 53, 314 }, - { 54, 313 }, - { 55, 312 }, - { 56, 311 }, - { 57, 310 }, - { 58, 308 }, - { 59, 306 }, - { 60, 304 }, - { 61, 302 }, - { 62, 300 }, - { 63, 298 }, - { 65, 295 }, - { 68, 294 }, - { 70, 293 }, - { 73, 292 }, - { 76, 291 }, - { 78, 290 }, - { 79, 289 }, - { 81, 288 }, - { 82, 287 }, - { 83, 286 }, - { 84, 285 }, - { 85, 284 }, - { 86, 283 }, - { 88, 282 }, - { 89, 281 }, - { 256, 280 }, -}; - -static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse, - u16 *snr) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < sz; i++) { - if (mse < tab[i].val) { - *snr = tab[i].data; - ret = 0; - break; - } - } - dprintk("%s() snr=%d\n", __func__, *snr); - return ret; -} - -static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq) -{ - struct au8522_state *state = fe->demodulator_priv; - u8 r0b5, r0b6, r0b7; - char *ifmhz; - - switch (if_freq) { - case AU8522_IF_3_25MHZ: - ifmhz = "3.25"; - r0b5 = 0x00; - r0b6 = 0x3d; - r0b7 = 0xa0; - break; - case AU8522_IF_4MHZ: - ifmhz = "4.00"; - r0b5 = 0x00; - r0b6 = 0x4b; - r0b7 = 0xd9; - break; - case AU8522_IF_6MHZ: - ifmhz = "6.00"; - r0b5 = 0xfb; - r0b6 = 0x8e; - r0b7 = 0x39; - break; - default: - dprintk("%s() IF Frequency not supported\n", __func__); - return -EINVAL; - } - dprintk("%s() %s MHz\n", __func__, ifmhz); - au8522_writereg(state, 0x80b5, r0b5); - au8522_writereg(state, 0x80b6, r0b6); - au8522_writereg(state, 0x80b7, r0b7); - - return 0; -} - -/* VSB Modulation table */ -static struct { - u16 reg; - u16 data; -} VSB_mod_tab[] = { - { 0x8090, 0x84 }, - { 0x4092, 0x11 }, - { 0x2005, 0x00 }, - { 0x8091, 0x80 }, - { 0x80a3, 0x0c }, - { 0x80a4, 0xe8 }, - { 0x8081, 0xc4 }, - { 0x80a5, 0x40 }, - { 0x80a7, 0x40 }, - { 0x80a6, 0x67 }, - { 0x8262, 0x20 }, - { 0x821c, 0x30 }, - { 0x80d8, 0x1a }, - { 0x8227, 0xa0 }, - { 0x8121, 0xff }, - { 0x80a8, 0xf0 }, - { 0x80a9, 0x05 }, - { 0x80aa, 0x77 }, - { 0x80ab, 0xf0 }, - { 0x80ac, 0x05 }, - { 0x80ad, 0x77 }, - { 0x80ae, 0x41 }, - { 0x80af, 0x66 }, - { 0x821b, 0xcc }, - { 0x821d, 0x80 }, - { 0x80a4, 0xe8 }, - { 0x8231, 0x13 }, -}; - -/* QAM Modulation table */ -static struct { - u16 reg; - u16 data; -} QAM_mod_tab[] = { - { 0x80a3, 0x09 }, - { 0x80a4, 0x00 }, - { 0x8081, 0xc4 }, - { 0x80a5, 0x40 }, - { 0x80aa, 0x77 }, - { 0x80ad, 0x77 }, - { 0x80a6, 0x67 }, - { 0x8262, 0x20 }, - { 0x821c, 0x30 }, - { 0x80b8, 0x3e }, - { 0x80b9, 0xf0 }, - { 0x80ba, 0x01 }, - { 0x80bb, 0x18 }, - { 0x80bc, 0x50 }, - { 0x80bd, 0x00 }, - { 0x80be, 0xea }, - { 0x80bf, 0xef }, - { 0x80c0, 0xfc }, - { 0x80c1, 0xbd }, - { 0x80c2, 0x1f }, - { 0x80c3, 0xfc }, - { 0x80c4, 0xdd }, - { 0x80c5, 0xaf }, - { 0x80c6, 0x00 }, - { 0x80c7, 0x38 }, - { 0x80c8, 0x30 }, - { 0x80c9, 0x05 }, - { 0x80ca, 0x4a }, - { 0x80cb, 0xd0 }, - { 0x80cc, 0x01 }, - { 0x80cd, 0xd9 }, - { 0x80ce, 0x6f }, - { 0x80cf, 0xf9 }, - { 0x80d0, 0x70 }, - { 0x80d1, 0xdf }, - { 0x80d2, 0xf7 }, - { 0x80d3, 0xc2 }, - { 0x80d4, 0xdf }, - { 0x80d5, 0x02 }, - { 0x80d6, 0x9a }, - { 0x80d7, 0xd0 }, - { 0x8250, 0x0d }, - { 0x8251, 0xcd }, - { 0x8252, 0xe0 }, - { 0x8253, 0x05 }, - { 0x8254, 0xa7 }, - { 0x8255, 0xff }, - { 0x8256, 0xed }, - { 0x8257, 0x5b }, - { 0x8258, 0xae }, - { 0x8259, 0xe6 }, - { 0x825a, 0x3d }, - { 0x825b, 0x0f }, - { 0x825c, 0x0d }, - { 0x825d, 0xea }, - { 0x825e, 0xf2 }, - { 0x825f, 0x51 }, - { 0x8260, 0xf5 }, - { 0x8261, 0x06 }, - { 0x821a, 0x00 }, - { 0x8546, 0x40 }, - { 0x8210, 0x26 }, - { 0x8211, 0xf6 }, - { 0x8212, 0x84 }, - { 0x8213, 0x02 }, - { 0x8502, 0x01 }, - { 0x8121, 0x04 }, - { 0x8122, 0x04 }, - { 0x852e, 0x10 }, - { 0x80a4, 0xca }, - { 0x80a7, 0x40 }, - { 0x8526, 0x01 }, -}; - -static int au8522_enable_modulation(struct dvb_frontend *fe, - fe_modulation_t m) -{ - struct au8522_state *state = fe->demodulator_priv; - int i; - - dprintk("%s(0x%08x)\n", __func__, m); - - switch (m) { - case VSB_8: - dprintk("%s() VSB_8\n", __func__); - for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++) - au8522_writereg(state, - VSB_mod_tab[i].reg, - VSB_mod_tab[i].data); - au8522_set_if(fe, state->config->vsb_if); - break; - case QAM_64: - case QAM_256: - dprintk("%s() QAM 64/256\n", __func__); - for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++) - au8522_writereg(state, - QAM_mod_tab[i].reg, - QAM_mod_tab[i].data); - au8522_set_if(fe, state->config->qam_if); - break; - default: - dprintk("%s() Invalid modulation\n", __func__); - return -EINVAL; - } - - state->current_modulation = m; - - return 0; -} - -/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int au8522_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct au8522_state *state = fe->demodulator_priv; - int ret = -EINVAL; - - dprintk("%s(frequency=%d)\n", __func__, p->frequency); - - if ((state->current_frequency == p->frequency) && - (state->current_modulation == p->u.vsb.modulation)) - return 0; - - au8522_enable_modulation(fe, p->u.vsb.modulation); - - /* Allow the demod to settle */ - msleep(100); - - 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, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - if (ret < 0) - return ret; - - state->current_frequency = p->frequency; - - return 0; -} - -/* Reset the demod hardware and reset all of the configuration registers - to a default state. */ -static int au8522_init(struct dvb_frontend *fe) -{ - struct au8522_state *state = fe->demodulator_priv; - dprintk("%s()\n", __func__); - - au8522_writereg(state, 0xa4, 1 << 5); - - au8522_i2c_gate_ctrl(fe, 1); - - return 0; -} - -static int au8522_led_gpio_enable(struct au8522_state *state, int onoff) -{ - struct au8522_led_config *led_config = state->config->led_cfg; - u8 val; - - /* bail out if we cant control an LED */ - if (!led_config || !led_config->gpio_output || - !led_config->gpio_output_enable || !led_config->gpio_output_disable) - return 0; - - val = au8522_readreg(state, 0x4000 | - (led_config->gpio_output & ~0xc000)); - if (onoff) { - /* enable GPIO output */ - val &= ~((led_config->gpio_output_enable >> 8) & 0xff); - val |= (led_config->gpio_output_enable & 0xff); - } else { - /* disable GPIO output */ - val &= ~((led_config->gpio_output_disable >> 8) & 0xff); - val |= (led_config->gpio_output_disable & 0xff); - } - return au8522_writereg(state, 0x8000 | - (led_config->gpio_output & ~0xc000), val); -} - -/* led = 0 | off - * led = 1 | signal ok - * led = 2 | signal strong - * led < 0 | only light led if leds are currently off - */ -static int au8522_led_ctrl(struct au8522_state *state, int led) -{ - struct au8522_led_config *led_config = state->config->led_cfg; - int i, ret = 0; - - /* bail out if we cant control an LED */ - if (!led_config || !led_config->gpio_leds || - !led_config->num_led_states || !led_config->led_states) - return 0; - - if (led < 0) { - /* if LED is already lit, then leave it as-is */ - if (state->led_state) - return 0; - else - led *= -1; - } - - /* toggle LED if changing state */ - if (state->led_state != led) { - u8 val; - - dprintk("%s: %d\n", __func__, led); - - au8522_led_gpio_enable(state, 1); - - val = au8522_readreg(state, 0x4000 | - (led_config->gpio_leds & ~0xc000)); - - /* start with all leds off */ - for (i = 0; i < led_config->num_led_states; i++) - val &= ~led_config->led_states[i]; - - /* set selected LED state */ - if (led < led_config->num_led_states) - val |= led_config->led_states[led]; - else if (led_config->num_led_states) - val |= - led_config->led_states[led_config->num_led_states - 1]; - - ret = au8522_writereg(state, 0x8000 | - (led_config->gpio_leds & ~0xc000), val); - if (ret < 0) - return ret; - - state->led_state = led; - - if (led == 0) - au8522_led_gpio_enable(state, 0); - } - - return 0; -} - -static int au8522_sleep(struct dvb_frontend *fe) -{ - struct au8522_state *state = fe->demodulator_priv; - dprintk("%s()\n", __func__); - - /* turn off led */ - au8522_led_ctrl(state, 0); - - state->current_frequency = 0; - - return 0; -} - -static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct au8522_state *state = fe->demodulator_priv; - u8 reg; - u32 tuner_status = 0; - - *status = 0; - - if (state->current_modulation == VSB_8) { - dprintk("%s() Checking VSB_8\n", __func__); - reg = au8522_readreg(state, 0x4088); - if ((reg & 0x03) == 0x03) - *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; - } else { - dprintk("%s() Checking QAM\n", __func__); - reg = au8522_readreg(state, 0x4541); - if (reg & 0x80) - *status |= FE_HAS_VITERBI; - if (reg & 0x20) - *status |= FE_HAS_LOCK | FE_HAS_SYNC; - } - - switch (state->config->status_mode) { - case AU8522_DEMODLOCKING: - dprintk("%s() DEMODLOCKING\n", __func__); - if (*status & FE_HAS_VITERBI) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - case AU8522_TUNERLOCKING: - /* Get the tuner status */ - dprintk("%s() TUNERLOCKING\n", __func__); - if (fe->ops.tuner_ops.get_status) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - fe->ops.tuner_ops.get_status(fe, &tuner_status); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - if (tuner_status) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - } - state->fe_status = *status; - - if (*status & FE_HAS_LOCK) - /* turn on LED, if it isn't on already */ - au8522_led_ctrl(state, -1); - else - /* turn off LED */ - au8522_led_ctrl(state, 0); - - dprintk("%s() status 0x%08x\n", __func__, *status); - - return 0; -} - -static int au8522_led_status(struct au8522_state *state, const u16 *snr) -{ - struct au8522_led_config *led_config = state->config->led_cfg; - int led; - u16 strong; - - /* bail out if we cant control an LED */ - if (!led_config) - return 0; - - if (0 == (state->fe_status & FE_HAS_LOCK)) - return au8522_led_ctrl(state, 0); - else if (state->current_modulation == QAM_256) - strong = led_config->qam256_strong; - else if (state->current_modulation == QAM_64) - strong = led_config->qam64_strong; - else /* (state->current_modulation == VSB_8) */ - strong = led_config->vsb8_strong; - - if (*snr >= strong) - led = 2; - else - led = 1; - - if ((state->led_state) && - (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10)) - /* snr didn't change enough to bother - * changing the color of the led */ - return 0; - - return au8522_led_ctrl(state, led); -} - -static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct au8522_state *state = fe->demodulator_priv; - int ret = -EINVAL; - - dprintk("%s()\n", __func__); - - if (state->current_modulation == QAM_256) - ret = au8522_mse2snr_lookup(qam256_mse2snr_tab, - ARRAY_SIZE(qam256_mse2snr_tab), - au8522_readreg(state, 0x4522), - snr); - else if (state->current_modulation == QAM_64) - ret = au8522_mse2snr_lookup(qam64_mse2snr_tab, - ARRAY_SIZE(qam64_mse2snr_tab), - au8522_readreg(state, 0x4522), - snr); - else /* VSB_8 */ - ret = au8522_mse2snr_lookup(vsb_mse2snr_tab, - ARRAY_SIZE(vsb_mse2snr_tab), - au8522_readreg(state, 0x4311), - snr); - - if (state->config->led_cfg) - au8522_led_status(state, snr); - - return ret; -} - -static int au8522_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - return au8522_read_snr(fe, signal_strength); -} - -static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct au8522_state *state = fe->demodulator_priv; - - if (state->current_modulation == VSB_8) - *ucblocks = au8522_readreg(state, 0x4087); - else - *ucblocks = au8522_readreg(state, 0x4543); - - return 0; -} - -static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - return au8522_read_ucblocks(fe, ber); -} - -static int au8522_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct au8522_state *state = fe->demodulator_priv; - - p->frequency = state->current_frequency; - p->u.vsb.modulation = state->current_modulation; - - return 0; -} - -static int au8522_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void au8522_release(struct dvb_frontend *fe) -{ - struct au8522_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops au8522_ops; - -struct dvb_frontend *au8522_attach(const struct au8522_config *config, - struct i2c_adapter *i2c) -{ - struct au8522_state *state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &au8522_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - if (au8522_init(&state->frontend) != 0) { - printk(KERN_ERR "%s: Failed to initialize correctly\n", - __func__); - goto error; - } - - /* Note: Leaving the I2C gate open here. */ - au8522_i2c_gate_ctrl(&state->frontend, 1); - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(au8522_attach); - -static struct dvb_frontend_ops au8522_ops = { - - .info = { - .name = "Auvitek AU8522 QAM/8VSB Frontend", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - - .init = au8522_init, - .sleep = au8522_sleep, - .i2c_gate_ctrl = au8522_i2c_gate_ctrl, - .set_frontend = au8522_set_frontend, - .get_frontend = au8522_get_frontend, - .get_tune_settings = au8522_get_tune_settings, - .read_status = au8522_read_status, - .read_ber = au8522_read_ber, - .read_signal_strength = au8522_read_signal_strength, - .read_snr = au8522_read_snr, - .read_ucblocks = au8522_read_ucblocks, - .release = au8522_release, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - -MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c new file mode 100644 index 000000000000..eabf9a68e7ec --- /dev/null +++ b/drivers/media/dvb/frontends/au8522_dig.c @@ -0,0 +1,874 @@ +/* + Auvitek AU8522 QAM/8VSB demodulator driver + + Copyright (C) 2008 Steven Toth + + 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 "au8522.h" + +struct au8522_state { + + struct i2c_adapter *i2c; + + /* configuration settings */ + const struct au8522_config *config; + + struct dvb_frontend frontend; + + u32 current_frequency; + fe_modulation_t current_modulation; + + u32 fe_status; + unsigned int led_state; +}; + +static int debug; + +#define dprintk(arg...) do { \ + if (debug) \ + printk(arg); \ + } while (0) + +/* 16 bit registers, 8 bit values */ +static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) +{ + int ret; + u8 buf [] = { reg >> 8, reg & 0xff, data }; + + struct i2c_msg msg = { .addr = state->config->demod_address, + .flags = 0, .buf = buf, .len = 3 }; + + ret = i2c_transfer(state->i2c, &msg, 1); + + if (ret != 1) + printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " + "ret == %i)\n", __func__, reg, data, ret); + + return (ret != 1) ? -1 : 0; +} + +static u8 au8522_readreg(struct au8522_state *state, u16 reg) +{ + int ret; + u8 b0 [] = { reg >> 8, reg & 0xff }; + u8 b1 [] = { 0 }; + + struct i2c_msg msg [] = { + { .addr = state->config->demod_address, .flags = 0, + .buf = b0, .len = 2 }, + { .addr = state->config->demod_address, .flags = I2C_M_RD, + .buf = b1, .len = 1 } }; + + ret = i2c_transfer(state->i2c, msg, 2); + + if (ret != 2) + printk(KERN_ERR "%s: readreg error (ret == %i)\n", + __func__, ret); + return b1[0]; +} + +static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct au8522_state *state = fe->demodulator_priv; + + dprintk("%s(%d)\n", __func__, enable); + + if (enable) + return au8522_writereg(state, 0x106, 1); + else + return au8522_writereg(state, 0x106, 0); +} + +struct mse2snr_tab { + u16 val; + u16 data; +}; + +/* VSB SNR lookup table */ +static struct mse2snr_tab vsb_mse2snr_tab[] = { + { 0, 270 }, + { 2, 250 }, + { 3, 240 }, + { 5, 230 }, + { 7, 220 }, + { 9, 210 }, + { 12, 200 }, + { 13, 195 }, + { 15, 190 }, + { 17, 185 }, + { 19, 180 }, + { 21, 175 }, + { 24, 170 }, + { 27, 165 }, + { 31, 160 }, + { 32, 158 }, + { 33, 156 }, + { 36, 152 }, + { 37, 150 }, + { 39, 148 }, + { 40, 146 }, + { 41, 144 }, + { 43, 142 }, + { 44, 140 }, + { 48, 135 }, + { 50, 130 }, + { 43, 142 }, + { 53, 125 }, + { 56, 120 }, + { 256, 115 }, +}; + +/* QAM64 SNR lookup table */ +static struct mse2snr_tab qam64_mse2snr_tab[] = { + { 15, 0 }, + { 16, 290 }, + { 17, 288 }, + { 18, 286 }, + { 19, 284 }, + { 20, 282 }, + { 21, 281 }, + { 22, 279 }, + { 23, 277 }, + { 24, 275 }, + { 25, 273 }, + { 26, 271 }, + { 27, 269 }, + { 28, 268 }, + { 29, 266 }, + { 30, 264 }, + { 31, 262 }, + { 32, 260 }, + { 33, 259 }, + { 34, 258 }, + { 35, 256 }, + { 36, 255 }, + { 37, 254 }, + { 38, 252 }, + { 39, 251 }, + { 40, 250 }, + { 41, 249 }, + { 42, 248 }, + { 43, 246 }, + { 44, 245 }, + { 45, 244 }, + { 46, 242 }, + { 47, 241 }, + { 48, 240 }, + { 50, 239 }, + { 51, 238 }, + { 53, 237 }, + { 54, 236 }, + { 56, 235 }, + { 57, 234 }, + { 59, 233 }, + { 60, 232 }, + { 62, 231 }, + { 63, 230 }, + { 65, 229 }, + { 67, 228 }, + { 68, 227 }, + { 70, 226 }, + { 71, 225 }, + { 73, 224 }, + { 74, 223 }, + { 76, 222 }, + { 78, 221 }, + { 80, 220 }, + { 82, 219 }, + { 85, 218 }, + { 88, 217 }, + { 90, 216 }, + { 92, 215 }, + { 93, 214 }, + { 94, 212 }, + { 95, 211 }, + { 97, 210 }, + { 99, 209 }, + { 101, 208 }, + { 102, 207 }, + { 104, 206 }, + { 107, 205 }, + { 111, 204 }, + { 114, 203 }, + { 118, 202 }, + { 122, 201 }, + { 125, 200 }, + { 128, 199 }, + { 130, 198 }, + { 132, 197 }, + { 256, 190 }, +}; + +/* QAM256 SNR lookup table */ +static struct mse2snr_tab qam256_mse2snr_tab[] = { + { 16, 0 }, + { 17, 400 }, + { 18, 398 }, + { 19, 396 }, + { 20, 394 }, + { 21, 392 }, + { 22, 390 }, + { 23, 388 }, + { 24, 386 }, + { 25, 384 }, + { 26, 382 }, + { 27, 380 }, + { 28, 379 }, + { 29, 378 }, + { 30, 377 }, + { 31, 376 }, + { 32, 375 }, + { 33, 374 }, + { 34, 373 }, + { 35, 372 }, + { 36, 371 }, + { 37, 370 }, + { 38, 362 }, + { 39, 354 }, + { 40, 346 }, + { 41, 338 }, + { 42, 330 }, + { 43, 328 }, + { 44, 326 }, + { 45, 324 }, + { 46, 322 }, + { 47, 320 }, + { 48, 319 }, + { 49, 318 }, + { 50, 317 }, + { 51, 316 }, + { 52, 315 }, + { 53, 314 }, + { 54, 313 }, + { 55, 312 }, + { 56, 311 }, + { 57, 310 }, + { 58, 308 }, + { 59, 306 }, + { 60, 304 }, + { 61, 302 }, + { 62, 300 }, + { 63, 298 }, + { 65, 295 }, + { 68, 294 }, + { 70, 293 }, + { 73, 292 }, + { 76, 291 }, + { 78, 290 }, + { 79, 289 }, + { 81, 288 }, + { 82, 287 }, + { 83, 286 }, + { 84, 285 }, + { 85, 284 }, + { 86, 283 }, + { 88, 282 }, + { 89, 281 }, + { 256, 280 }, +}; + +static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse, + u16 *snr) +{ + int i, ret = -EINVAL; + dprintk("%s()\n", __func__); + + for (i = 0; i < sz; i++) { + if (mse < tab[i].val) { + *snr = tab[i].data; + ret = 0; + break; + } + } + dprintk("%s() snr=%d\n", __func__, *snr); + return ret; +} + +static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq) +{ + struct au8522_state *state = fe->demodulator_priv; + u8 r0b5, r0b6, r0b7; + char *ifmhz; + + switch (if_freq) { + case AU8522_IF_3_25MHZ: + ifmhz = "3.25"; + r0b5 = 0x00; + r0b6 = 0x3d; + r0b7 = 0xa0; + break; + case AU8522_IF_4MHZ: + ifmhz = "4.00"; + r0b5 = 0x00; + r0b6 = 0x4b; + r0b7 = 0xd9; + break; + case AU8522_IF_6MHZ: + ifmhz = "6.00"; + r0b5 = 0xfb; + r0b6 = 0x8e; + r0b7 = 0x39; + break; + default: + dprintk("%s() IF Frequency not supported\n", __func__); + return -EINVAL; + } + dprintk("%s() %s MHz\n", __func__, ifmhz); + au8522_writereg(state, 0x80b5, r0b5); + au8522_writereg(state, 0x80b6, r0b6); + au8522_writereg(state, 0x80b7, r0b7); + + return 0; +} + +/* VSB Modulation table */ +static struct { + u16 reg; + u16 data; +} VSB_mod_tab[] = { + { 0x8090, 0x84 }, + { 0x4092, 0x11 }, + { 0x2005, 0x00 }, + { 0x8091, 0x80 }, + { 0x80a3, 0x0c }, + { 0x80a4, 0xe8 }, + { 0x8081, 0xc4 }, + { 0x80a5, 0x40 }, + { 0x80a7, 0x40 }, + { 0x80a6, 0x67 }, + { 0x8262, 0x20 }, + { 0x821c, 0x30 }, + { 0x80d8, 0x1a }, + { 0x8227, 0xa0 }, + { 0x8121, 0xff }, + { 0x80a8, 0xf0 }, + { 0x80a9, 0x05 }, + { 0x80aa, 0x77 }, + { 0x80ab, 0xf0 }, + { 0x80ac, 0x05 }, + { 0x80ad, 0x77 }, + { 0x80ae, 0x41 }, + { 0x80af, 0x66 }, + { 0x821b, 0xcc }, + { 0x821d, 0x80 }, + { 0x80a4, 0xe8 }, + { 0x8231, 0x13 }, +}; + +/* QAM Modulation table */ +static struct { + u16 reg; + u16 data; +} QAM_mod_tab[] = { + { 0x80a3, 0x09 }, + { 0x80a4, 0x00 }, + { 0x8081, 0xc4 }, + { 0x80a5, 0x40 }, + { 0x80aa, 0x77 }, + { 0x80ad, 0x77 }, + { 0x80a6, 0x67 }, + { 0x8262, 0x20 }, + { 0x821c, 0x30 }, + { 0x80b8, 0x3e }, + { 0x80b9, 0xf0 }, + { 0x80ba, 0x01 }, + { 0x80bb, 0x18 }, + { 0x80bc, 0x50 }, + { 0x80bd, 0x00 }, + { 0x80be, 0xea }, + { 0x80bf, 0xef }, + { 0x80c0, 0xfc }, + { 0x80c1, 0xbd }, + { 0x80c2, 0x1f }, + { 0x80c3, 0xfc }, + { 0x80c4, 0xdd }, + { 0x80c5, 0xaf }, + { 0x80c6, 0x00 }, + { 0x80c7, 0x38 }, + { 0x80c8, 0x30 }, + { 0x80c9, 0x05 }, + { 0x80ca, 0x4a }, + { 0x80cb, 0xd0 }, + { 0x80cc, 0x01 }, + { 0x80cd, 0xd9 }, + { 0x80ce, 0x6f }, + { 0x80cf, 0xf9 }, + { 0x80d0, 0x70 }, + { 0x80d1, 0xdf }, + { 0x80d2, 0xf7 }, + { 0x80d3, 0xc2 }, + { 0x80d4, 0xdf }, + { 0x80d5, 0x02 }, + { 0x80d6, 0x9a }, + { 0x80d7, 0xd0 }, + { 0x8250, 0x0d }, + { 0x8251, 0xcd }, + { 0x8252, 0xe0 }, + { 0x8253, 0x05 }, + { 0x8254, 0xa7 }, + { 0x8255, 0xff }, + { 0x8256, 0xed }, + { 0x8257, 0x5b }, + { 0x8258, 0xae }, + { 0x8259, 0xe6 }, + { 0x825a, 0x3d }, + { 0x825b, 0x0f }, + { 0x825c, 0x0d }, + { 0x825d, 0xea }, + { 0x825e, 0xf2 }, + { 0x825f, 0x51 }, + { 0x8260, 0xf5 }, + { 0x8261, 0x06 }, + { 0x821a, 0x00 }, + { 0x8546, 0x40 }, + { 0x8210, 0x26 }, + { 0x8211, 0xf6 }, + { 0x8212, 0x84 }, + { 0x8213, 0x02 }, + { 0x8502, 0x01 }, + { 0x8121, 0x04 }, + { 0x8122, 0x04 }, + { 0x852e, 0x10 }, + { 0x80a4, 0xca }, + { 0x80a7, 0x40 }, + { 0x8526, 0x01 }, +}; + +static int au8522_enable_modulation(struct dvb_frontend *fe, + fe_modulation_t m) +{ + struct au8522_state *state = fe->demodulator_priv; + int i; + + dprintk("%s(0x%08x)\n", __func__, m); + + switch (m) { + case VSB_8: + dprintk("%s() VSB_8\n", __func__); + for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++) + au8522_writereg(state, + VSB_mod_tab[i].reg, + VSB_mod_tab[i].data); + au8522_set_if(fe, state->config->vsb_if); + break; + case QAM_64: + case QAM_256: + dprintk("%s() QAM 64/256\n", __func__); + for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++) + au8522_writereg(state, + QAM_mod_tab[i].reg, + QAM_mod_tab[i].data); + au8522_set_if(fe, state->config->qam_if); + break; + default: + dprintk("%s() Invalid modulation\n", __func__); + return -EINVAL; + } + + state->current_modulation = m; + + return 0; +} + +/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ +static int au8522_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct au8522_state *state = fe->demodulator_priv; + int ret = -EINVAL; + + dprintk("%s(frequency=%d)\n", __func__, p->frequency); + + if ((state->current_frequency == p->frequency) && + (state->current_modulation == p->u.vsb.modulation)) + return 0; + + au8522_enable_modulation(fe, p->u.vsb.modulation); + + /* Allow the demod to settle */ + msleep(100); + + 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, p); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + + if (ret < 0) + return ret; + + state->current_frequency = p->frequency; + + return 0; +} + +/* Reset the demod hardware and reset all of the configuration registers + to a default state. */ +static int au8522_init(struct dvb_frontend *fe) +{ + struct au8522_state *state = fe->demodulator_priv; + dprintk("%s()\n", __func__); + + au8522_writereg(state, 0xa4, 1 << 5); + + au8522_i2c_gate_ctrl(fe, 1); + + return 0; +} + +static int au8522_led_gpio_enable(struct au8522_state *state, int onoff) +{ + struct au8522_led_config *led_config = state->config->led_cfg; + u8 val; + + /* bail out if we cant control an LED */ + if (!led_config || !led_config->gpio_output || + !led_config->gpio_output_enable || !led_config->gpio_output_disable) + return 0; + + val = au8522_readreg(state, 0x4000 | + (led_config->gpio_output & ~0xc000)); + if (onoff) { + /* enable GPIO output */ + val &= ~((led_config->gpio_output_enable >> 8) & 0xff); + val |= (led_config->gpio_output_enable & 0xff); + } else { + /* disable GPIO output */ + val &= ~((led_config->gpio_output_disable >> 8) & 0xff); + val |= (led_config->gpio_output_disable & 0xff); + } + return au8522_writereg(state, 0x8000 | + (led_config->gpio_output & ~0xc000), val); +} + +/* led = 0 | off + * led = 1 | signal ok + * led = 2 | signal strong + * led < 0 | only light led if leds are currently off + */ +static int au8522_led_ctrl(struct au8522_state *state, int led) +{ + struct au8522_led_config *led_config = state->config->led_cfg; + int i, ret = 0; + + /* bail out if we cant control an LED */ + if (!led_config || !led_config->gpio_leds || + !led_config->num_led_states || !led_config->led_states) + return 0; + + if (led < 0) { + /* if LED is already lit, then leave it as-is */ + if (state->led_state) + return 0; + else + led *= -1; + } + + /* toggle LED if changing state */ + if (state->led_state != led) { + u8 val; + + dprintk("%s: %d\n", __func__, led); + + au8522_led_gpio_enable(state, 1); + + val = au8522_readreg(state, 0x4000 | + (led_config->gpio_leds & ~0xc000)); + + /* start with all leds off */ + for (i = 0; i < led_config->num_led_states; i++) + val &= ~led_config->led_states[i]; + + /* set selected LED state */ + if (led < led_config->num_led_states) + val |= led_config->led_states[led]; + else if (led_config->num_led_states) + val |= + led_config->led_states[led_config->num_led_states - 1]; + + ret = au8522_writereg(state, 0x8000 | + (led_config->gpio_leds & ~0xc000), val); + if (ret < 0) + return ret; + + state->led_state = led; + + if (led == 0) + au8522_led_gpio_enable(state, 0); + } + + return 0; +} + +static int au8522_sleep(struct dvb_frontend *fe) +{ + struct au8522_state *state = fe->demodulator_priv; + dprintk("%s()\n", __func__); + + /* turn off led */ + au8522_led_ctrl(state, 0); + + state->current_frequency = 0; + + return 0; +} + +static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct au8522_state *state = fe->demodulator_priv; + u8 reg; + u32 tuner_status = 0; + + *status = 0; + + if (state->current_modulation == VSB_8) { + dprintk("%s() Checking VSB_8\n", __func__); + reg = au8522_readreg(state, 0x4088); + if ((reg & 0x03) == 0x03) + *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; + } else { + dprintk("%s() Checking QAM\n", __func__); + reg = au8522_readreg(state, 0x4541); + if (reg & 0x80) + *status |= FE_HAS_VITERBI; + if (reg & 0x20) + *status |= FE_HAS_LOCK | FE_HAS_SYNC; + } + + switch (state->config->status_mode) { + case AU8522_DEMODLOCKING: + dprintk("%s() DEMODLOCKING\n", __func__); + if (*status & FE_HAS_VITERBI) + *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; + break; + case AU8522_TUNERLOCKING: + /* Get the tuner status */ + dprintk("%s() TUNERLOCKING\n", __func__); + if (fe->ops.tuner_ops.get_status) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + fe->ops.tuner_ops.get_status(fe, &tuner_status); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + if (tuner_status) + *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; + break; + } + state->fe_status = *status; + + if (*status & FE_HAS_LOCK) + /* turn on LED, if it isn't on already */ + au8522_led_ctrl(state, -1); + else + /* turn off LED */ + au8522_led_ctrl(state, 0); + + dprintk("%s() status 0x%08x\n", __func__, *status); + + return 0; +} + +static int au8522_led_status(struct au8522_state *state, const u16 *snr) +{ + struct au8522_led_config *led_config = state->config->led_cfg; + int led; + u16 strong; + + /* bail out if we cant control an LED */ + if (!led_config) + return 0; + + if (0 == (state->fe_status & FE_HAS_LOCK)) + return au8522_led_ctrl(state, 0); + else if (state->current_modulation == QAM_256) + strong = led_config->qam256_strong; + else if (state->current_modulation == QAM_64) + strong = led_config->qam64_strong; + else /* (state->current_modulation == VSB_8) */ + strong = led_config->vsb8_strong; + + if (*snr >= strong) + led = 2; + else + led = 1; + + if ((state->led_state) && + (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10)) + /* snr didn't change enough to bother + * changing the color of the led */ + return 0; + + return au8522_led_ctrl(state, led); +} + +static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct au8522_state *state = fe->demodulator_priv; + int ret = -EINVAL; + + dprintk("%s()\n", __func__); + + if (state->current_modulation == QAM_256) + ret = au8522_mse2snr_lookup(qam256_mse2snr_tab, + ARRAY_SIZE(qam256_mse2snr_tab), + au8522_readreg(state, 0x4522), + snr); + else if (state->current_modulation == QAM_64) + ret = au8522_mse2snr_lookup(qam64_mse2snr_tab, + ARRAY_SIZE(qam64_mse2snr_tab), + au8522_readreg(state, 0x4522), + snr); + else /* VSB_8 */ + ret = au8522_mse2snr_lookup(vsb_mse2snr_tab, + ARRAY_SIZE(vsb_mse2snr_tab), + au8522_readreg(state, 0x4311), + snr); + + if (state->config->led_cfg) + au8522_led_status(state, snr); + + return ret; +} + +static int au8522_read_signal_strength(struct dvb_frontend *fe, + u16 *signal_strength) +{ + return au8522_read_snr(fe, signal_strength); +} + +static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct au8522_state *state = fe->demodulator_priv; + + if (state->current_modulation == VSB_8) + *ucblocks = au8522_readreg(state, 0x4087); + else + *ucblocks = au8522_readreg(state, 0x4543); + + return 0; +} + +static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + return au8522_read_ucblocks(fe, ber); +} + +static int au8522_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct au8522_state *state = fe->demodulator_priv; + + p->frequency = state->current_frequency; + p->u.vsb.modulation = state->current_modulation; + + return 0; +} + +static int au8522_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *tune) +{ + tune->min_delay_ms = 1000; + return 0; +} + +static void au8522_release(struct dvb_frontend *fe) +{ + struct au8522_state *state = fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops au8522_ops; + +struct dvb_frontend *au8522_attach(const struct au8522_config *config, + struct i2c_adapter *i2c) +{ + struct au8522_state *state = NULL; + + /* allocate memory for the internal state */ + state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL); + if (state == NULL) + goto error; + + /* setup the state */ + state->config = config; + state->i2c = i2c; + /* create dvb_frontend */ + memcpy(&state->frontend.ops, &au8522_ops, + sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + + if (au8522_init(&state->frontend) != 0) { + printk(KERN_ERR "%s: Failed to initialize correctly\n", + __func__); + goto error; + } + + /* Note: Leaving the I2C gate open here. */ + au8522_i2c_gate_ctrl(&state->frontend, 1); + + return &state->frontend; + +error: + kfree(state); + return NULL; +} +EXPORT_SYMBOL(au8522_attach); + +static struct dvb_frontend_ops au8522_ops = { + + .info = { + .name = "Auvitek AU8522 QAM/8VSB Frontend", + .type = FE_ATSC, + .frequency_min = 54000000, + .frequency_max = 858000000, + .frequency_stepsize = 62500, + .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB + }, + + .init = au8522_init, + .sleep = au8522_sleep, + .i2c_gate_ctrl = au8522_i2c_gate_ctrl, + .set_frontend = au8522_set_frontend, + .get_frontend = au8522_get_frontend, + .get_tune_settings = au8522_get_tune_settings, + .read_status = au8522_read_status, + .read_ber = au8522_read_ber, + .read_signal_strength = au8522_read_signal_strength, + .read_snr = au8522_read_snr, + .read_ucblocks = au8522_read_ucblocks, + .release = au8522_release, +}; + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Enable verbose debug messages"); + +MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver"); +MODULE_AUTHOR("Steven Toth"); +MODULE_LICENSE("GPL"); -- cgit v1.2.1 From 0c44bf362fc1f0dc927b814184d9b877a2f507cf Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 02:59:56 -0300 Subject: V4L/DVB (11061): au8522: move shared state and common functions into a separate header files Move the au8522 state structure, as well as exposing functions needed by the analog side of the demodulator into a common header file. Thanks to Michael Krufky and Steven Toth for providing sample hardware, engineering level support, and testing. Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522_dig.c | 25 +++----------- drivers/media/dvb/frontends/au8522_priv.h | 57 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 drivers/media/dvb/frontends/au8522_priv.h (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index eabf9a68e7ec..8082547c73e2 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c @@ -27,22 +27,7 @@ #include #include "dvb_frontend.h" #include "au8522.h" - -struct au8522_state { - - struct i2c_adapter *i2c; - - /* configuration settings */ - const struct au8522_config *config; - - struct dvb_frontend frontend; - - u32 current_frequency; - fe_modulation_t current_modulation; - - u32 fe_status; - unsigned int led_state; -}; +#include "au8522_priv.h" static int debug; @@ -52,7 +37,7 @@ static int debug; } while (0) /* 16 bit registers, 8 bit values */ -static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) +int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) { int ret; u8 buf [] = { reg >> 8, reg & 0xff, data }; @@ -69,7 +54,7 @@ static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) return (ret != 1) ? -1 : 0; } -static u8 au8522_readreg(struct au8522_state *state, u16 reg) +u8 au8522_readreg(struct au8522_state *state, u16 reg) { int ret; u8 b0 [] = { reg >> 8, reg & 0xff }; @@ -528,7 +513,7 @@ static int au8522_set_frontend(struct dvb_frontend *fe, /* Reset the demod hardware and reset all of the configuration registers to a default state. */ -static int au8522_init(struct dvb_frontend *fe) +int au8522_init(struct dvb_frontend *fe) { struct au8522_state *state = fe->demodulator_priv; dprintk("%s()\n", __func__); @@ -624,7 +609,7 @@ static int au8522_led_ctrl(struct au8522_state *state, int led) return 0; } -static int au8522_sleep(struct dvb_frontend *fe) +int au8522_sleep(struct dvb_frontend *fe) { struct au8522_state *state = fe->demodulator_priv; dprintk("%s()\n", __func__); diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h new file mode 100644 index 000000000000..569675d295d5 --- /dev/null +++ b/drivers/media/dvb/frontends/au8522_priv.h @@ -0,0 +1,57 @@ +/* + Auvitek AU8522 QAM/8VSB demodulator driver + + Copyright (C) 2008 Steven Toth + Copyright (C) 2008 Devin Heitmueller + Copyright (C) 2005-2008 Auvitek International, Ltd. + + 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 +#include +#include "dvb_frontend.h" +#include "au8522.h" +#include "tuner-i2c.h" + +struct au8522_state { + struct i2c_adapter *i2c; + + /* configuration settings */ + const struct au8522_config *config; + + struct dvb_frontend frontend; + + u32 current_frequency; + fe_modulation_t current_modulation; + + u32 fe_status; + unsigned int led_state; +}; + +/* These are routines shared by both the VSB/QAM demodulator and the analog + decoder */ +int au8522_writereg(struct au8522_state *state, u16 reg, u8 data); +u8 au8522_readreg(struct au8522_state *state, u16 reg); +int au8522_init(struct dvb_frontend *fe); +int au8522_sleep(struct dvb_frontend *fe); -- cgit v1.2.1 From 083a17317be27a0f33d999b4360320b322a8b55b Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 03:00:19 -0300 Subject: V4L/DVB (11062): au8522: fix register read/write high bits For the i2c messages to read and write registers, the two high order bits of the first byte dictates whether it is a read or a write operation. Thanks to Michael Krufky and Steven Toth for providing sample hardware, engineering level support, and testing. Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522_dig.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index 8082547c73e2..17bdbe2c67e6 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c @@ -40,7 +40,7 @@ static int debug; int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) { int ret; - u8 buf [] = { reg >> 8, reg & 0xff, data }; + u8 buf [] = { (reg >> 8) | 0x80, reg & 0xff, data }; struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 }; @@ -57,7 +57,7 @@ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) u8 au8522_readreg(struct au8522_state *state, u16 reg) { int ret; - u8 b0 [] = { reg >> 8, reg & 0xff }; + u8 b0 [] = { (reg >> 8) | 0x40, reg & 0xff }; u8 b1 [] = { 0 }; struct i2c_msg msg [] = { -- cgit v1.2.1 From 7bf63eda681e095ca3c39d075354053107febf80 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 03:00:34 -0300 Subject: V4L/DVB (11063): au8522: power down the digital demod when not in use When the au8522 is idle, put the chip into a low power mode (reduces power consumption from 450ma to 346ma) Thanks to Michael Krufky and Steven Toth for providing sample hardware, engineering level support, and testing. Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522_dig.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index 17bdbe2c67e6..fa3ecbed1e58 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c @@ -617,6 +617,9 @@ int au8522_sleep(struct dvb_frontend *fe) /* turn off led */ au8522_led_ctrl(state, 0); + /* Power down the chip */ + au8522_writereg(state, 0xa4, 1 << 5); + state->current_frequency = 0; return 0; -- cgit v1.2.1 From 209fdf66b8699a6b2998b58e572d67230dae507f Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 03:00:36 -0300 Subject: V4L/DVB (11064): au8522: make use of hybrid framework so analog/digital demod can share state Make use of the hybrid tuner framework so the analog and digital parts of the au8522 demodulator can make use of the same shared state. Thanks to Michael Krufky and Steven Toth for providing sample hardware, engineering level support, and testing. Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522_dig.c | 45 ++++++++++++++++++++++++++----- drivers/media/dvb/frontends/au8522_priv.h | 8 ++++++ 2 files changed, 46 insertions(+), 7 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index fa3ecbed1e58..b04346687c68 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c @@ -31,6 +31,10 @@ static int debug; +/* Despite the name "hybrid_tuner", the framework works just as well for + hybrid demodulators as well... */ +static LIST_HEAD(hybrid_tuner_instance_list); + #define dprintk(arg...) do { \ if (debug) \ printk(arg); \ @@ -786,23 +790,50 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe, return 0; } +static struct dvb_frontend_ops au8522_ops; + +int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, + u8 client_address) +{ + return hybrid_tuner_request_state(struct au8522_state, (*state), + hybrid_tuner_instance_list, + i2c, client_address, "au8522"); +} + +void au8522_release_state(struct au8522_state *state) +{ + if (state != NULL) + hybrid_tuner_release_state(state); +} + + static void au8522_release(struct dvb_frontend *fe) { struct au8522_state *state = fe->demodulator_priv; - kfree(state); + au8522_release_state(state); } -static struct dvb_frontend_ops au8522_ops; - struct dvb_frontend *au8522_attach(const struct au8522_config *config, struct i2c_adapter *i2c) { struct au8522_state *state = NULL; + int instance; /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL); - if (state == NULL) - goto error; + instance = au8522_get_state(&state, i2c, config->demod_address); + switch (instance) { + case 0: + dprintk("%s state allocation failed\n", __func__); + break; + case 1: + /* new demod instance */ + dprintk("%s using new instance\n", __func__); + break; + default: + /* existing demod instance */ + dprintk("%s using existing instance\n", __func__); + break; + } /* setup the state */ state->config = config; @@ -824,7 +855,7 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config, return &state->frontend; error: - kfree(state); + au8522_release_state(state); return NULL; } EXPORT_SYMBOL(au8522_attach); diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h index 569675d295d5..98b09caa2123 100644 --- a/drivers/media/dvb/frontends/au8522_priv.h +++ b/drivers/media/dvb/frontends/au8522_priv.h @@ -37,6 +37,10 @@ struct au8522_state { struct i2c_adapter *i2c; + /* Used for sharing of the state between analog and digital mode */ + struct tuner_i2c_props i2c_props; + struct list_head hybrid_tuner_instance_list; + /* configuration settings */ const struct au8522_config *config; @@ -55,3 +59,7 @@ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data); u8 au8522_readreg(struct au8522_state *state, u16 reg); int au8522_init(struct dvb_frontend *fe); int au8522_sleep(struct dvb_frontend *fe); + +int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, + u8 client_address); +void au8522_release_state(struct au8522_state *state); -- cgit v1.2.1 From 968cf78285ef03672ae514e9ad7a60919eb97551 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 03:00:38 -0300 Subject: V4L/DVB (11065): au8522: add support for analog side of demodulator Add support for the analog functionality in the au8522 analog/digital demodulator Thanks to Michael Krufky and Steven Toth for providing sample hardware, engineering level support, and testing. Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky [mchehab: renamed drivers/media/video/au8522_decoder.c as drivers/media/dvb/frontends/au8522_decoder.c to avoid breaking bisect] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Makefile | 2 +- drivers/media/dvb/frontends/au8522.h | 16 + drivers/media/dvb/frontends/au8522_decoder.c | 839 +++++++++++++++++++++++++++ drivers/media/dvb/frontends/au8522_priv.h | 347 +++++++++++ 4 files changed, 1203 insertions(+), 1 deletion(-) create mode 100644 drivers/media/dvb/frontends/au8522_decoder.c (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 742826523df5..65a336aa1db6 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -8,7 +8,7 @@ EXTRA_CFLAGS += -Idrivers/media/common/tuners/ s921-objs := s921_module.o s921_core.o stb0899-objs = stb0899_drv.o stb0899_algo.o stv0900-objs = stv0900_core.o stv0900_sw.o -au8522-objs = au8522_dig.o +au8522-objs = au8522_dig.o au8522_decoder.o obj-$(CONFIG_DVB_PLL) += dvb-pll.o obj-$(CONFIG_DVB_STV0299) += stv0299.o diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb/frontends/au8522.h index 7b94f554a093..565dcf31af57 100644 --- a/drivers/media/dvb/frontends/au8522.h +++ b/drivers/media/dvb/frontends/au8522.h @@ -74,6 +74,22 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config, } #endif /* CONFIG_DVB_AU8522 */ +/* Other modes may need to be added later */ +enum au8522_video_input { + AU8522_COMPOSITE_CH1 = 1, + AU8522_COMPOSITE_CH2, + AU8522_COMPOSITE_CH3, + AU8522_COMPOSITE_CH4, + AU8522_COMPOSITE_CH4_SIF, + AU8522_SVIDEO_CH13, + AU8522_SVIDEO_CH24, +}; + +enum au8522_audio_input { + AU8522_AUDIO_NONE, + AU8522_AUDIO_SIF, +}; + #endif /* __AU8522_H__ */ /* diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c new file mode 100644 index 000000000000..e2927c145cd8 --- /dev/null +++ b/drivers/media/dvb/frontends/au8522_decoder.c @@ -0,0 +1,839 @@ +/* + * Auvitek AU8522 QAM/8VSB demodulator driver and video decoder + * + * Copyright (C) 2009 Devin Heitmueller + * Copyright (C) 2005-2008 Auvitek International, Ltd. + * + * 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. + */ + +/* Developer notes: + * + * VBI support is not yet working + * Saturation and hue setting are not yet working + * Enough is implemented here for CVBS and S-Video inputs, but the actual + * analog demodulator code isn't implemented (not needed for xc5000 since it + * has its own demodulator and outputs CVBS) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "au8522.h" +#include "au8522_priv.h" + +MODULE_AUTHOR("Devin Heitmueller"); +MODULE_LICENSE("GPL"); + +static int au8522_analog_debug; + +static unsigned short normal_i2c[] = { 0x8e >> 1, I2C_CLIENT_END }; + +module_param_named(analog_debug, au8522_analog_debug, int, 0644); + +MODULE_PARM_DESC(analog_debug, + "Analog debugging messages [0=Off (default) 1=On]"); + +I2C_CLIENT_INSMOD; + +struct au8522_register_config { + u16 reg_name; + u8 reg_val[8]; +}; + + +/* Video Decoder Filter Coefficients + The values are as follows from left to right + 0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13" +*/ +struct au8522_register_config filter_coef[] = { + {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00}}, + {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00}}, + {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00}}, + {AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00}}, + {AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00}}, + {AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00}}, + {AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00}}, + {AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00}}, + {AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00}}, + {AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40}}, + {AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09}}, + {AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38}}, + {AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff}}, + {AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7}}, + {AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf}}, + {AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06}}, + {AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30}}, + {AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01}}, + {AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd}}, + {AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf}}, + {AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7}}, + {AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb}}, + {AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0}}, + {AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f}}, + {AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8}}, + {AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb}}, + {AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5}}, + {AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e}}, + {AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15}}, + {AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34}}, + +}; +#define NUM_FILTER_COEF (sizeof (filter_coef) / sizeof(struct au8522_register_config)) + + +/* Registers 0x060b through 0x0652 are the LP Filter coefficients + The values are as follows from left to right + 0="SIF" 1="ATVRF/ATVRF13" + Note: the "ATVRF/ATVRF13" mode has never been tested +*/ +struct au8522_register_config lpfilter_coef[] = { + {0x060b, {0x21, 0x0b}}, + {0x060c, {0xad, 0xad}}, + {0x060d, {0x70, 0xf0}}, + {0x060e, {0xea, 0xe9}}, + {0x060f, {0xdd, 0xdd}}, + {0x0610, {0x08, 0x64}}, + {0x0611, {0x60, 0x60}}, + {0x0612, {0xf8, 0xb2}}, + {0x0613, {0x01, 0x02}}, + {0x0614, {0xe4, 0xb4}}, + {0x0615, {0x19, 0x02}}, + {0x0616, {0xae, 0x2e}}, + {0x0617, {0xee, 0xc5}}, + {0x0618, {0x56, 0x56}}, + {0x0619, {0x30, 0x58}}, + {0x061a, {0xf9, 0xf8}}, + {0x061b, {0x24, 0x64}}, + {0x061c, {0x07, 0x07}}, + {0x061d, {0x30, 0x30}}, + {0x061e, {0xa9, 0xed}}, + {0x061f, {0x09, 0x0b}}, + {0x0620, {0x42, 0xc2}}, + {0x0621, {0x1d, 0x2a}}, + {0x0622, {0xd6, 0x56}}, + {0x0623, {0x95, 0x8b}}, + {0x0624, {0x2b, 0x2b}}, + {0x0625, {0x30, 0x24}}, + {0x0626, {0x3e, 0x3e}}, + {0x0627, {0x62, 0xe2}}, + {0x0628, {0xe9, 0xf5}}, + {0x0629, {0x99, 0x19}}, + {0x062a, {0xd4, 0x11}}, + {0x062b, {0x03, 0x04}}, + {0x062c, {0xb5, 0x85}}, + {0x062d, {0x1e, 0x20}}, + {0x062e, {0x2a, 0xea}}, + {0x062f, {0xd7, 0xd2}}, + {0x0630, {0x15, 0x15}}, + {0x0631, {0xa3, 0xa9}}, + {0x0632, {0x1f, 0x1f}}, + {0x0633, {0xf9, 0xd1}}, + {0x0634, {0xc0, 0xc3}}, + {0x0635, {0x4d, 0x8d}}, + {0x0636, {0x21, 0x31}}, + {0x0637, {0x83, 0x83}}, + {0x0638, {0x08, 0x8c}}, + {0x0639, {0x19, 0x19}}, + {0x063a, {0x45, 0xa5}}, + {0x063b, {0xef, 0xec}}, + {0x063c, {0x8a, 0x8a}}, + {0x063d, {0xf4, 0xf6}}, + {0x063e, {0x8f, 0x8f}}, + {0x063f, {0x44, 0x0c}}, + {0x0640, {0xef, 0xf0}}, + {0x0641, {0x66, 0x66}}, + {0x0642, {0xcc, 0xd2}}, + {0x0643, {0x41, 0x41}}, + {0x0644, {0x63, 0x93}}, + {0x0645, {0x8e, 0x8e}}, + {0x0646, {0xa2, 0x42}}, + {0x0647, {0x7b, 0x7b}}, + {0x0648, {0x04, 0x04}}, + {0x0649, {0x00, 0x00}}, + {0x064a, {0x40, 0x40}}, + {0x064b, {0x8c, 0x98}}, + {0x064c, {0x00, 0x00}}, + {0x064d, {0x63, 0xc3}}, + {0x064e, {0x04, 0x04}}, + {0x064f, {0x20, 0x20}}, + {0x0650, {0x00, 0x00}}, + {0x0651, {0x40 ,0x40}}, + {0x0652, {0x01, 0x01}}, +}; +#define NUM_LPFILTER_COEF (sizeof (lpfilter_coef) / sizeof(struct au8522_register_config)) + +static inline struct au8522_state *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct au8522_state, sd); +} + +static void setup_vbi(struct au8522_state *state, int aud_input) +{ + int i; + + /* These are set to zero regardless of what mode we're in */ + au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H,0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H,0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H,0x00); + + /* Setup the VBI registers */ + for (i = 0x30; i < 0x60; i++) { + au8522_writereg(state, i, 0x40); + } + /* For some reason, every register is 0x40 except register 0x44 + (confirmed via the HVR-950q USB capture) */ + au8522_writereg(state, 0x44, 0x60); + + /* Enable VBI (we always do this regardless of whether the user is + viewing closed caption info) */ + au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, + AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON); + +} + +static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode) +{ + int i; + int filter_coef_type; + + /* Provide reasonable defaults for picture tuning values */ + au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07); + au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed); + state->brightness = 0xed - 128; + au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79); + state->contrast = 0x79; + au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80); + au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80); + au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00); + au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00); + + /* Other decoder registers */ + au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00); + + if (input_mode == 0x23) { + /* S-Video input mapping */ + au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04); + } else { + /* All other modes (CVBS/ATVRF etc.) */ + au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00); + } + + au8522_writereg(state, AU8522_TVDEC_PGA_REG012H, + AU8522_TVDEC_PGA_REG012H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_MODE_REG015H, + AU8522_TVDEC_COMB_MODE_REG015H_CVBS); + au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H, + AU8522_TVDED_DBG_MODE_REG060H_CVBS); + au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H, + AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13); + au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H, + AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13); + au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H, + AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS); + au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H, + AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR1_REG065H, + AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR2_REG066H, + AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR3_REG067H, + AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_NOTCH_THR_REG068H, + AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR1_REG069H, + AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR2_REG06AH, + AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH, + AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH, + AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH, + AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH, + AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS); + au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH, + AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H, + AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS); + au8522_writereg(state, AU8522_REG071H, AU8522_REG071H_CVBS); + au8522_writereg(state, AU8522_REG072H, AU8522_REG072H_CVBS); + au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H, + AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS); + au8522_writereg(state, AU8522_REG074H, AU8522_REG074H_CVBS); + au8522_writereg(state, AU8522_REG075H, AU8522_REG075H_CVBS); + au8522_writereg(state, AU8522_TVDEC_DCAGC_CTRL_REG077H, + AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS); + au8522_writereg(state, AU8522_TVDEC_PIC_START_ADJ_REG078H, + AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS); + au8522_writereg(state, AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H, + AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS); + au8522_writereg(state, AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH, + AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS); + au8522_writereg(state, AU8522_TVDEC_INTRP_CTRL_REG07BH, + AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS); + au8522_writereg(state, AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H, + AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS); + au8522_writereg(state, AU8522_TOREGAAGC_REG0E5H, + AU8522_TOREGAAGC_REG0E5H_CVBS); + au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS); + + setup_vbi(state, 0); + + if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 || + input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) { + /* Despite what the table says, for the HVR-950q we still need + to be in CVBS mode for the S-Video input (reason uknown). */ + /* filter_coef_type = 3; */ + filter_coef_type = 5; + } else { + filter_coef_type = 5; + } + + /* Load the Video Decoder Filter Coefficients */ + for (i = 0; i < NUM_FILTER_COEF; i++) { + au8522_writereg(state, filter_coef[i].reg_name, + filter_coef[i].reg_val[filter_coef_type]); + } + + /* It's not clear what these registers are for, but they are always + set to the same value regardless of what mode we're in */ + au8522_writereg(state, AU8522_REG42EH, 0x87); + au8522_writereg(state, AU8522_REG42FH, 0xa2); + au8522_writereg(state, AU8522_REG430H, 0xbf); + au8522_writereg(state, AU8522_REG431H, 0xcb); + au8522_writereg(state, AU8522_REG432H, 0xa1); + au8522_writereg(state, AU8522_REG433H, 0x41); + au8522_writereg(state, AU8522_REG434H, 0x88); + au8522_writereg(state, AU8522_REG435H, 0xc2); + au8522_writereg(state, AU8522_REG436H, 0x3c); +} + +static void au8522_setup_cvbs_mode(struct au8522_state *state) +{ + /* here we're going to try the pre-programmed route */ + au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H, + AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS); + + au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00); + au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e); + au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10); + + au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, + AU8522_INPUT_CONTROL_REG081H_CVBS_CH1); + + setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1); + + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); +} + +static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state) +{ + /* here we're going to try the pre-programmed route */ + au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H, + AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS); + + /* It's not clear why they turn off the PGA before enabling the clamp + control, but the Windows trace does it so we will too... */ + au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00); + + /* Enable clamping control */ + au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e); + + /* Turn on the PGA */ + au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10); + + /* Set input mode to CVBS on channel 4 with SIF audio input enabled */ + au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, + AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF); + + setup_decoder_defaults(state, + AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF); + + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); +} + +static void au8522_setup_svideo_mode(struct au8522_state *state) +{ + au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H, + AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO); + + /* Set input to Y on Channe1, C on Channel 3 */ + au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, + AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13); + + /* Disable clamping control (required for S-video) */ + au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00); + + setup_decoder_defaults(state, + AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13); + + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); +} + +/* ----------------------------------------------------------------------- */ + +static void disable_audio_input(struct au8522_state *state) +{ + /* This can probably be optimized */ + au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00); + au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00); + au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00); + au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80); + au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84); + + au8522_writereg(state, AU8522_ENA_USB_REG101H, 0x00); + au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F); + au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F); + au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO); + au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x40); + + au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x11); + msleep(5); + au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x00); + + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04); + au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03); + au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02); + + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); +} + +/* 0=disable, 1=SIF */ +static void set_audio_input(struct au8522_state *state, int aud_input) +{ + int i; + + /* Note that this function needs to be used in conjunction with setting + the input routing via register 0x81 */ + + if (aud_input == AU8522_AUDIO_NONE) { + disable_audio_input(state); + return; + } + + if (aud_input != AU8522_AUDIO_SIF) { + /* The caller asked for a mode we don't currently support */ + printk("Unsupported audio mode requested! mode=%d\n", + aud_input); + return; + } + + /* Load the Audio Decoder Filter Coefficients */ + for (i = 0; i < NUM_LPFILTER_COEF; i++) { + au8522_writereg(state, lpfilter_coef[i].reg_name, + lpfilter_coef[i].reg_val[0]); + } + + /* Setup audio */ + au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00); + au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00); + au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00); + au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80); + au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84); + msleep(150); + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00); + msleep(1); + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d); + msleep(50); + au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F); + au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F); + au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff); + msleep(80); + au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F); + au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F); + au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO); + au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82); + msleep(70); + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09); + au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03); + au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2); +} + +/* ----------------------------------------------------------------------- */ + +static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct au8522_state *state = to_state(sd); + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + state->brightness = ctrl->value; + au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, + ctrl->value - 128); + break; + case V4L2_CID_CONTRAST: + state->contrast = ctrl->value; + au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, + ctrl->value); + break; + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + case V4L2_CID_AUDIO_VOLUME: + case V4L2_CID_AUDIO_BASS: + case V4L2_CID_AUDIO_TREBLE: + case V4L2_CID_AUDIO_BALANCE: + case V4L2_CID_AUDIO_MUTE: + /* Not yet implemented */ + default: + return -EINVAL; + } + + return 0; +} + +static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct au8522_state *state = to_state(sd); + + /* Note that we are using values cached in the state structure instead + of reading the registers due to issues with i2c reads not working + properly/consistently yet on the HVR-950q */ + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = state->brightness; + break; + case V4L2_CID_CONTRAST: + ctrl->value = state->contrast; + break; + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + case V4L2_CID_AUDIO_VOLUME: + case V4L2_CID_AUDIO_BASS: + case V4L2_CID_AUDIO_TREBLE: + case V4L2_CID_AUDIO_BALANCE: + case V4L2_CID_AUDIO_MUTE: + /* Not yet supported */ + default: + return -EINVAL; + } + + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static int au8522_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +{ + switch (fmt->type) { + default: + return -EINVAL; + } + return 0; +} + +static int au8522_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +{ + switch (fmt->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + /* Not yet implemented */ + break; + default: + return -EINVAL; + } + + return 0; +} + +/* ----------------------------------------------------------------------- */ + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int au8522_g_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct au8522_state *state = to_state(sd); + + if (!v4l2_chip_match_i2c_client(client, ®->match)) + return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + reg->val = au8522_readreg(state, reg->reg & 0xffff); + return 0; +} + +static int au8522_s_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct au8522_state *state = to_state(sd); + + if (!v4l2_chip_match_i2c_client(client, ®->match)) + return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + au8522_writereg(state, reg->reg, reg->val & 0xff); + return 0; +} +#endif + +static int au8522_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct au8522_state *state = to_state(sd); + + if (enable) { + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + 0x01); + msleep(1); + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS); + } else { + /* This does not completely power down the device + (it only reduces it from around 140ma to 80ma) */ + au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, + 1 << 5); + } + return 0; +} + +static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) +{ + switch (qc->id) { + case V4L2_CID_CONTRAST: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, + AU8522_TVDEC_CONTRAST_REG00BH_CVBS); + case V4L2_CID_BRIGHTNESS: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + /* Not yet implemented */ + default: + break; + } + + return -EINVAL; +} + +static int au8522_reset(struct v4l2_subdev *sd, u32 val) +{ + struct au8522_state *state = to_state(sd); + + au8522_writereg(state, 0xa4, 1 << 5); + + return 0; +} + +static int au8522_s_video_routing(struct v4l2_subdev *sd, + const struct v4l2_routing *route) +{ + struct au8522_state *state = to_state(sd); + + au8522_reset(sd, 0); + + /* Jam open the i2c gate to the tuner. We do this here to handle the + case where the user went into digital mode (causing the gate to be + closed), and then came back to analog mode */ + au8522_writereg(state, 0x106, 1); + + if (route->input == AU8522_COMPOSITE_CH1) { + au8522_setup_cvbs_mode(state); + } else if (route->input == AU8522_SVIDEO_CH13) { + au8522_setup_svideo_mode(state); + } else if (route->input == AU8522_COMPOSITE_CH4_SIF) { + au8522_setup_cvbs_tuner_mode(state); + } else { + printk("au8522 mode not currently supported\n"); + return -EINVAL; + } + return 0; +} + +static int au8522_s_audio_routing(struct v4l2_subdev *sd, + const struct v4l2_routing *route) +{ + struct au8522_state *state = to_state(sd); + set_audio_input(state, route->input); + return 0; +} + +static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) +{ + int val = 0; + struct au8522_state *state = to_state(sd); + u8 lock_status; + + /* Interrogate the decoder to see if we are getting a real signal */ + lock_status = au8522_readreg(state, 0x00); + if (lock_status == 0xa2) + vt->signal = 0x01; + else + vt->signal = 0x00; + + vt->capability |= + V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | + V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; + + val = V4L2_TUNER_SUB_MONO; + vt->rxsubchans = val; + vt->audmode = V4L2_TUNER_MODE_STEREO; + return 0; +} + +static int au8522_g_chip_ident(struct v4l2_subdev *sd, + struct v4l2_dbg_chip_ident *chip) +{ + struct au8522_state *state = to_state(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + + return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev); +} + +static int au8522_log_status(struct v4l2_subdev *sd) +{ + /* FIXME: Add some status info here */ + return 0; +} + +static int au8522_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} + +/* ----------------------------------------------------------------------- */ + +static const struct v4l2_subdev_core_ops au8522_core_ops = { + .log_status = au8522_log_status, + .g_chip_ident = au8522_g_chip_ident, + .g_ctrl = au8522_g_ctrl, + .s_ctrl = au8522_s_ctrl, + .queryctrl = au8522_queryctrl, + .reset = au8522_reset, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .g_register = au8522_g_register, + .s_register = au8522_s_register, +#endif +}; + +static const struct v4l2_subdev_tuner_ops au8522_tuner_ops = { + .g_tuner = au8522_g_tuner, +}; + +static const struct v4l2_subdev_audio_ops au8522_audio_ops = { + .s_routing = au8522_s_audio_routing, +}; + +static const struct v4l2_subdev_video_ops au8522_video_ops = { + .s_routing = au8522_s_video_routing, + .g_fmt = au8522_g_fmt, + .s_fmt = au8522_s_fmt, + .s_stream = au8522_s_stream, +}; + +static const struct v4l2_subdev_ops au8522_ops = { + .core = &au8522_core_ops, + .tuner = &au8522_tuner_ops, + .audio = &au8522_audio_ops, + .video = &au8522_video_ops, +}; + +/* ----------------------------------------------------------------------- */ + +static int au8522_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct au8522_state *state; + struct v4l2_subdev *sd; + int instance; + struct au8522_config *demod_config; + + /* Check if the adapter supports the needed features */ + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + return -EIO; + } + + /* allocate memory for the internal state */ + instance = au8522_get_state(&state, client->adapter, client->addr); + switch (instance) { + case 0: + printk("au8522_decoder allocation failed\n"); + return -EIO; + case 1: + /* new demod instance */ + printk("au8522_decoder creating new instance...\n"); + break; + default: + /* existing demod instance */ + printk("au8522_decoder attaching to existing instance...\n"); + break; + } + + demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL); + demod_config->demod_address = 0x8e >> 1; + + state->config = demod_config; + state->i2c = client->adapter; + + sd = &state->sd; + v4l2_i2c_subdev_init(sd, client, &au8522_ops); + + state->c = client; + state->vid_input = AU8522_COMPOSITE_CH1; + state->aud_input = AU8522_AUDIO_NONE; + state->id = 8522; + state->rev = 0; + + /* Jam open the i2c gate to the tuner */ + au8522_writereg(state, 0x106, 1); + + return 0; +} + +static int au8522_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + v4l2_device_unregister_subdev(sd); + au8522_release_state(to_state(sd)); + return 0; +} + +static const struct i2c_device_id au8522_id[] = { + {"au8522", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, au8522_id); + +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "au8522", + .driverid = I2C_DRIVERID_AU8522, + .command = au8522_command, + .probe = au8522_probe, + .remove = au8522_remove, + .id_table = au8522_id, +}; diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h index 98b09caa2123..f328f2b3ad3d 100644 --- a/drivers/media/dvb/frontends/au8522_priv.h +++ b/drivers/media/dvb/frontends/au8522_priv.h @@ -35,6 +35,7 @@ #include "tuner-i2c.h" struct au8522_state { + struct i2c_client *c; struct i2c_adapter *i2c; /* Used for sharing of the state between analog and digital mode */ @@ -51,6 +52,16 @@ struct au8522_state { u32 fe_status; unsigned int led_state; + + /* Analog settings */ + struct v4l2_subdev sd; + v4l2_std_id std; + int vid_input; + int aud_input; + u32 id; + u32 rev; + u8 brightness; + u8 contrast; }; /* These are routines shared by both the VSB/QAM demodulator and the analog @@ -63,3 +74,339 @@ int au8522_sleep(struct dvb_frontend *fe); int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, u8 client_address); void au8522_release_state(struct au8522_state *state); + +/* REGISTERS */ +#define AU8522_INPUT_CONTROL_REG081H 0x081 +#define AU8522_PGA_CONTROL_REG082H 0x082 +#define AU8522_CLAMPING_CONTROL_REG083H 0x083 + +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H 0x0A3 +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H 0x0A4 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H 0x0A5 +#define AU8522_AGC_CONTROL_RANGE_REG0A6H 0x0A6 +#define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H 0x0A7 +#define AU8522_TUNER_AGC_RF_STOP_REG0A8H 0x0A8 +#define AU8522_TUNER_AGC_RF_START_REG0A9H 0x0A9 +#define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH 0x0AA +#define AU8522_TUNER_AGC_IF_STOP_REG0ABH 0x0AB +#define AU8522_TUNER_AGC_IF_START_REG0ACH 0x0AC +#define AU8522_TUNER_AGC_IF_DEFAULT_REG0ADH 0x0AD +#define AU8522_TUNER_AGC_STEP_REG0AEH 0x0AE +#define AU8522_TUNER_GAIN_STEP_REG0AFH 0x0AF + +/* Receiver registers */ +#define AU8522_FRMREGTHRD1_REG0B0H 0x0B0 +#define AU8522_FRMREGAGC1H_REG0B1H 0x0B1 +#define AU8522_FRMREGSHIFT1_REG0B2H 0x0B2 +#define AU8522_TOREGAGC1_REG0B3H 0x0B3 +#define AU8522_TOREGASHIFT1_REG0B4H 0x0B4 +#define AU8522_FRMREGBBH_REG0B5H 0x0B5 +#define AU8522_FRMREGBBM_REG0B6H 0x0B6 +#define AU8522_FRMREGBBL_REG0B7H 0x0B7 +/* 0xB8 TO 0xD7 are the filter coefficients */ +#define AU8522_FRMREGTHRD2_REG0D8H 0x0D8 +#define AU8522_FRMREGAGC2H_REG0D9H 0x0D9 +#define AU8522_TOREGAGC2_REG0DAH 0x0DA +#define AU8522_TOREGSHIFT2_REG0DBH 0x0DB +#define AU8522_FRMREGPILOTH_REG0DCH 0x0DC +#define AU8522_FRMREGPILOTM_REG0DDH 0x0DD +#define AU8522_FRMREGPILOTL_REG0DEH 0x0DE +#define AU8522_TOREGFREQ_REG0DFH 0x0DF + +#define AU8522_RX_PGA_RFOUT_REG0EBH 0x0EB +#define AU8522_RX_PGA_IFOUT_REG0ECH 0x0EC +#define AU8522_RX_PGA_PGAOUT_REG0EDH 0x0ED + +#define AU8522_CHIP_MODE_REG0FEH 0x0FE + +/* I2C bus control registers */ +#define AU8522_I2C_CONTROL_REG0_REG090H 0x090 +#define AU8522_I2C_CONTROL_REG1_REG091H 0x091 +#define AU8522_I2C_STATUS_REG092H 0x092 +#define AU8522_I2C_WR_DATA0_REG093H 0x093 +#define AU8522_I2C_WR_DATA1_REG094H 0x094 +#define AU8522_I2C_WR_DATA2_REG095H 0x095 +#define AU8522_I2C_WR_DATA3_REG096H 0x096 +#define AU8522_I2C_WR_DATA4_REG097H 0x097 +#define AU8522_I2C_WR_DATA5_REG098H 0x098 +#define AU8522_I2C_WR_DATA6_REG099H 0x099 +#define AU8522_I2C_WR_DATA7_REG09AH 0x09A +#define AU8522_I2C_RD_DATA0_REG09BH 0x09B +#define AU8522_I2C_RD_DATA1_REG09CH 0x09C +#define AU8522_I2C_RD_DATA2_REG09DH 0x09D +#define AU8522_I2C_RD_DATA3_REG09EH 0x09E +#define AU8522_I2C_RD_DATA4_REG09FH 0x09F +#define AU8522_I2C_RD_DATA5_REG0A0H 0x0A0 +#define AU8522_I2C_RD_DATA6_REG0A1H 0x0A1 +#define AU8522_I2C_RD_DATA7_REG0A2H 0x0A2 + +#define AU8522_ENA_USB_REG101H 0x101 + +#define AU8522_I2S_CTRL_0_REG110H 0x110 +#define AU8522_I2S_CTRL_1_REG111H 0x111 +#define AU8522_I2S_CTRL_2_REG112H 0x112 + +#define AU8522_FRMREGFFECONTROL_REG121H 0x121 +#define AU8522_FRMREGDFECONTROL_REG122H 0x122 + +#define AU8522_CARRFREQOFFSET0_REG201H 0x201 +#define AU8522_CARRFREQOFFSET1_REG202H 0x202 + +#define AU8522_DECIMATION_GAIN_REG21AH 0x21A +#define AU8522_FRMREGIFSLP_REG21BH 0x21B +#define AU8522_FRMREGTHRDL2_REG21CH 0x21C +#define AU8522_FRMREGSTEP3DB_REG21DH 0x21D +#define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH 0x21E +#define AU8522_FRMREGPLLMODE_REG21FH 0x21F +#define AU8522_FRMREGCSTHRD_REG220H 0x220 +#define AU8522_FRMREGCRLOCKDMAX_REG221H 0x221 +#define AU8522_FRMREGCRPERIODMASK_REG222H 0x222 +#define AU8522_FRMREGCRLOCK0THH_REG223H 0x223 +#define AU8522_FRMREGCRLOCK1THH_REG224H 0x224 +#define AU8522_FRMREGCRLOCK0THL_REG225H 0x225 +#define AU8522_FRMREGCRLOCK1THL_REG226H 0x226 +#define AU_FRMREGPLLACQPHASESCL_REG227H 0x227 +#define AU8522_FRMREGFREQFBCTRL_REG228H 0x228 + +/* Analog TV Decoder */ +#define AU8522_TVDEC_STATUS_REG000H 0x000 +#define AU8522_TVDEC_INT_STATUS_REG001H 0x001 +#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 0x002 +#define AU8522_TVDEC_SHARPNESSREG009H 0x009 +#define AU8522_TVDEC_BRIGHTNESS_REG00AH 0x00A +#define AU8522_TVDEC_CONTRAST_REG00BH 0x00B +#define AU8522_TVDEC_SATURATION_CB_REG00CH 0x00C +#define AU8522_TVDEC_SATURATION_CR_REG00DH 0x00D +#define AU8522_TVDEC_HUE_H_REG00EH 0x00E +#define AU8522_TVDEC_HUE_L_REG00FH 0x00F +#define AU8522_TVDEC_INT_MASK_REG010H 0x010 +#define AU8522_VIDEO_MODE_REG011H 0x011 +#define AU8522_TVDEC_PGA_REG012H 0x012 +#define AU8522_TVDEC_COMB_MODE_REG015H 0x015 +#define AU8522_REG016H 0x016 +#define AU8522_TVDED_DBG_MODE_REG060H 0x060 +#define AU8522_TVDEC_FORMAT_CTRL1_REG061H 0x061 +#define AU8522_TVDEC_FORMAT_CTRL2_REG062H 0x062 +#define AU8522_TVDEC_VCR_DET_LLIM_REG063H 0x063 +#define AU8522_TVDEC_VCR_DET_HLIM_REG064H 0x064 +#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H 0x065 +#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H 0x066 +#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H 0x067 +#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H 0x068 +#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H 0x069 +#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH 0x06A +#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH 0x06B +#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH 0x06C +#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 0x06D +#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH 0x06E +#define AU8522_TVDEC_UV_SEP_THR_REG06FH 0x06F +#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H 0x070 +#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H 0x073 +#define AU8522_TVDEC_DCAGC_CTRL_REG077H 0x077 +#define AU8522_TVDEC_PIC_START_ADJ_REG078H 0x078 +#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H 0x079 +#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH 0x07A +#define AU8522_TVDEC_INTRP_CTRL_REG07BH 0x07B +#define AU8522_TVDEC_PLL_STATUS_REG07EH 0x07E +#define AU8522_TVDEC_FSC_FREQ_REG07FH 0x07F + +#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H 0x0E4 +#define AU8522_TOREGAAGC_REG0E5H 0x0E5 + +#define AU8522_TVDEC_CHROMA_AGC_REG401H 0x401 +#define AU8522_TVDEC_CHROMA_SFT_REG402H 0x402 +#define AU8522_FILTER_COEF_R410 0x410 +#define AU8522_FILTER_COEF_R411 0x411 +#define AU8522_FILTER_COEF_R412 0x412 +#define AU8522_FILTER_COEF_R413 0x413 +#define AU8522_FILTER_COEF_R414 0x414 +#define AU8522_FILTER_COEF_R415 0x415 +#define AU8522_FILTER_COEF_R416 0x416 +#define AU8522_FILTER_COEF_R417 0x417 +#define AU8522_FILTER_COEF_R418 0x418 +#define AU8522_FILTER_COEF_R419 0x419 +#define AU8522_FILTER_COEF_R41A 0x41A +#define AU8522_FILTER_COEF_R41B 0x41B +#define AU8522_FILTER_COEF_R41C 0x41C +#define AU8522_FILTER_COEF_R41D 0x41D +#define AU8522_FILTER_COEF_R41E 0x41E +#define AU8522_FILTER_COEF_R41F 0x41F +#define AU8522_FILTER_COEF_R420 0x420 +#define AU8522_FILTER_COEF_R421 0x421 +#define AU8522_FILTER_COEF_R422 0x422 +#define AU8522_FILTER_COEF_R423 0x423 +#define AU8522_FILTER_COEF_R424 0x424 +#define AU8522_FILTER_COEF_R425 0x425 +#define AU8522_FILTER_COEF_R426 0x426 +#define AU8522_FILTER_COEF_R427 0x427 +#define AU8522_FILTER_COEF_R428 0x428 +#define AU8522_FILTER_COEF_R429 0x429 +#define AU8522_FILTER_COEF_R42A 0x42A +#define AU8522_FILTER_COEF_R42B 0x42B +#define AU8522_FILTER_COEF_R42C 0x42C +#define AU8522_FILTER_COEF_R42D 0x42D + +/* VBI Control Registers */ +#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H 0x004 +#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H 0x005 +#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H 0x006 +#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H 0x007 +#define AU8522_TVDEC_VBI_CTRL_H_REG017H 0x017 +#define AU8522_TVDEC_VBI_CTRL_L_REG018H 0x018 +#define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H 0x019 +#define AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH 0x01A +#define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH 0x01B +#define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH 0x01C +#define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH 0x01E +#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH 0x01F +#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H 0x020 +#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 0x021 +#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H 0x022 +#define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H 0x023 + +#define AU8522_REG071H 0x071 +#define AU8522_REG072H 0x072 +#define AU8522_REG074H 0x074 +#define AU8522_REG075H 0x075 + +/* Digital Demodulator Registers */ +#define AU8522_FRAME_COUNT0_REG084H 0x084 +#define AU8522_RS_STATUS_G0_REG085H 0x085 +#define AU8522_RS_STATUS_B0_REG086H 0x086 +#define AU8522_RS_STATUS_E_REG087H 0x087 +#define AU8522_DEMODULATION_STATUS_REG088H 0x088 +#define AU8522_TOREGTRESTATUS_REG0E6H 0x0E6 +#define AU8522_TSPORT_CONTROL_REG10BH 0x10B +#define AU8522_TSTHES_REG10CH 0x10C +#define AU8522_FRMREGDFEKEEP_REG301H 0x301 +#define AU8522_DFE_AVERAGE_REG302H 0x302 +#define AU8522_FRMREGEQLERRWIN_REG303H 0x303 +#define AU8522_FRMREGFFEKEEP_REG304H 0x304 +#define AU8522_FRMREGDFECONTROL1_REG305H 0x305 +#define AU8522_FRMREGEQLERRLOW_REG306H 0x306 + +#define AU8522_REG42EH 0x42E +#define AU8522_REG42FH 0x42F +#define AU8522_REG430H 0x430 +#define AU8522_REG431H 0x431 +#define AU8522_REG432H 0x432 +#define AU8522_REG433H 0x433 +#define AU8522_REG434H 0x434 +#define AU8522_REG435H 0x435 +#define AU8522_REG436H 0x436 + +/* GPIO Registers */ +#define AU8522_GPIO_CONTROL_REG0E0H 0x0E0 +#define AU8522_GPIO_STATUS_REG0E1H 0x0E1 +#define AU8522_GPIO_DATA_REG0E2H 0x0E2 + +/* Audio Control Registers */ +#define AU8522_AUDIOAGC_REG0EEH 0x0EE +#define AU8522_AUDIO_STATUS_REG0F0H 0x0F0 +#define AU8522_AUDIO_MODE_REG0F1H 0x0F1 +#define AU8522_AUDIO_VOLUME_L_REG0F2H 0x0F2 +#define AU8522_AUDIO_VOLUME_R_REG0F3H 0x0F3 +#define AU8522_AUDIO_VOLUME_REG0F4H 0x0F4 +#define AU8522_FRMREGAUPHASE_REG0F7H 0x0F7 +#define AU8522_REG0F9H 0x0F9 + +#define AU8522_AUDIOAGC2_REG605H 0x605 +#define AU8522_AUDIOFREQ_REG606H 0x606 + + +/**************************************************************/ + +#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4 +#define AU8522_INPUT_CONTROL_REG081H_ATVRF 0xC4 +#define AU8522_INPUT_CONTROL_REG081H_ATVRF13 0xC4 +#define AU8522_INPUT_CONTROL_REG081H_J83B64 0xC4 +#define AU8522_INPUT_CONTROL_REG081H_J83B256 0xC4 +#define AU8522_INPUT_CONTROL_REG081H_CVBS 0x20 +#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1 0xA2 +#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2 0xA0 +#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3 0x69 +#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4 0x68 +#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF 0x28 +/* CH1 AS Y,CH3 AS C */ +#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 0x23 +/* CH2 AS Y,CH4 AS C */ +#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24 0x20 +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC 0x0C +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64 0x09 +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256 0x09 +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS 0x12 +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF 0x1A +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13 0x1A +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO 0x02 + +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR 0x00 +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO 0x9C +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS 0x9D +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC 0xE8 +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 0xCA +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64 0xCA +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF 0xDD +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13 0xDD +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL 0xDD +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM 0xDD + +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC 0x80 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 0x80 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64 0x80 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC 0x40 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256 0x40 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64 0x40 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR 0x00 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF 0x01 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13 0x01 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO 0x04 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS 0x01 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM 0x03 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS 0x09 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL 0x01 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM 0x01 + +/* STILL NEED TO BE REFACTORED @@@@@@@@@@@@@@ */ +#define AU8522_TVDEC_CONTRAST_REG00BH_CVBS 0x79 +#define AU8522_TVDEC_SATURATION_CB_REG00CH_CVBS 0x80 +#define AU8522_TVDEC_SATURATION_CR_REG00DH_CVBS 0x80 +#define AU8522_TVDEC_HUE_H_REG00EH_CVBS 0x00 +#define AU8522_TVDEC_HUE_L_REG00FH_CVBS 0x00 +#define AU8522_TVDEC_PGA_REG012H_CVBS 0x0F +#define AU8522_TVDEC_COMB_MODE_REG015H_CVBS 0x00 +#define AU8522_REG016H_CVBS 0x00 +#define AU8522_TVDED_DBG_MODE_REG060H_CVBS 0x00 +#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS 0x0B +#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13 0x03 +#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13 0x00 +#define AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS 0x19 +#define AU8522_REG0F9H_AUDIO 0x20 +#define AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS 0xA7 +#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS 0x0A +#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS 0x32 +#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS 0x19 +#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS 0x23 +#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS 0x41 +#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS 0x0A +#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS 0x32 +#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS 0x34 +#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS 0x05 +#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS 0x6E +#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS 0x0F +#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS 0x80 +#define AU8522_REG071H_CVBS 0x18 +#define AU8522_REG072H_CVBS 0x30 +#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS 0xF0 +#define AU8522_REG074H_CVBS 0x80 +#define AU8522_REG075H_CVBS 0xF0 +#define AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS 0xFB +#define AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS 0x04 +#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS 0x00 +#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS 0x00 +#define AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS 0xEE +#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS 0xFE +#define AU8522_TOREGAAGC_REG0E5H_CVBS 0x00 +#define AU8522_TVDEC_VBI6A_REG035H_CVBS 0x40 + +/* Enables Closed captioning */ +#define AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON 0x21 -- cgit v1.2.1 From 4ff5ed44f84aed6727ec226853a1c6b03c36db5e Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 03:00:45 -0300 Subject: V4L/DVB (11069): au8522: add mutex protecting use of hybrid state Access using the hybrid state framework requires the list to be protected by a mutex. Thanks to Michael Krufky for reporting this during a code review. Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522_dig.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index b04346687c68..7e24b914dbe5 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c @@ -34,6 +34,7 @@ static int debug; /* Despite the name "hybrid_tuner", the framework works just as well for hybrid demodulators as well... */ static LIST_HEAD(hybrid_tuner_instance_list); +static DEFINE_MUTEX(au8522_list_mutex); #define dprintk(arg...) do { \ if (debug) \ @@ -795,15 +796,23 @@ static struct dvb_frontend_ops au8522_ops; int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, u8 client_address) { - return hybrid_tuner_request_state(struct au8522_state, (*state), - hybrid_tuner_instance_list, - i2c, client_address, "au8522"); + int ret; + + mutex_lock(&au8522_list_mutex); + ret = hybrid_tuner_request_state(struct au8522_state, (*state), + hybrid_tuner_instance_list, + i2c, client_address, "au8522"); + mutex_unlock(&au8522_list_mutex); + + return ret; } void au8522_release_state(struct au8522_state *state) { + mutex_lock(&au8522_list_mutex); if (state != NULL) hybrid_tuner_release_state(state); + mutex_unlock(&au8522_list_mutex); } -- cgit v1.2.1 From d9109bef4b4f501eee94ae68bf876f765d5c6941 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 03:00:58 -0300 Subject: V4L/DVB (11076): au0828: make g_chip_ident call work properly Make the g_chip_ident call work for the au0828/au8522. Discovered when testing with the v4l2_compliance tool Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky [mchehab@redhat.com: fix merge conflict, due to a path change for analog demod] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522_decoder.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c index e2927c145cd8..564636389bae 100644 --- a/drivers/media/dvb/frontends/au8522_decoder.c +++ b/drivers/media/dvb/frontends/au8522_decoder.c @@ -636,6 +636,7 @@ static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) break; } + qc->type = 0; return -EINVAL; } -- cgit v1.2.1 From 62899a28008d635f25c3408b4cc46021f0cb34d3 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sun, 15 Mar 2009 18:48:52 -0300 Subject: V4L/DVB (11085): au0828/au8522: Codingstyle fixes Take a pass over all of the au0828/au8522 files and cleanup all the codingstyle issues. This patch does not make *any* functional change to the code. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522_decoder.c | 233 ++++++++++++++------------- drivers/media/dvb/frontends/au8522_dig.c | 14 +- 2 files changed, 126 insertions(+), 121 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c index 564636389bae..2ad84c236ec7 100644 --- a/drivers/media/dvb/frontends/au8522_decoder.c +++ b/drivers/media/dvb/frontends/au8522_decoder.c @@ -67,39 +67,40 @@ struct au8522_register_config { 0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13" */ struct au8522_register_config filter_coef[] = { - {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00}}, - {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00}}, - {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00}}, - {AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00}}, - {AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00}}, - {AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00}}, - {AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00}}, - {AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00}}, - {AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00}}, - {AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40}}, - {AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09}}, - {AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38}}, - {AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff}}, - {AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7}}, - {AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf}}, - {AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06}}, - {AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30}}, - {AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01}}, - {AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd}}, - {AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf}}, - {AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7}}, - {AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb}}, - {AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0}}, - {AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f}}, - {AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8}}, - {AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb}}, - {AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5}}, - {AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e}}, - {AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15}}, - {AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34}}, + {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00} }, + {AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40} }, + {AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09} }, + {AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38} }, + {AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff} }, + {AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7} }, + {AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf} }, + {AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06} }, + {AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30} }, + {AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01} }, + {AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd} }, + {AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf} }, + {AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7} }, + {AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb} }, + {AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0} }, + {AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f} }, + {AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8} }, + {AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb} }, + {AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5} }, + {AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e} }, + {AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15} }, + {AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34} }, }; -#define NUM_FILTER_COEF (sizeof (filter_coef) / sizeof(struct au8522_register_config)) +#define NUM_FILTER_COEF (sizeof(filter_coef)\ + / sizeof(struct au8522_register_config)) /* Registers 0x060b through 0x0652 are the LP Filter coefficients @@ -108,80 +109,81 @@ struct au8522_register_config filter_coef[] = { Note: the "ATVRF/ATVRF13" mode has never been tested */ struct au8522_register_config lpfilter_coef[] = { - {0x060b, {0x21, 0x0b}}, - {0x060c, {0xad, 0xad}}, - {0x060d, {0x70, 0xf0}}, - {0x060e, {0xea, 0xe9}}, - {0x060f, {0xdd, 0xdd}}, - {0x0610, {0x08, 0x64}}, - {0x0611, {0x60, 0x60}}, - {0x0612, {0xf8, 0xb2}}, - {0x0613, {0x01, 0x02}}, - {0x0614, {0xe4, 0xb4}}, - {0x0615, {0x19, 0x02}}, - {0x0616, {0xae, 0x2e}}, - {0x0617, {0xee, 0xc5}}, - {0x0618, {0x56, 0x56}}, - {0x0619, {0x30, 0x58}}, - {0x061a, {0xf9, 0xf8}}, - {0x061b, {0x24, 0x64}}, - {0x061c, {0x07, 0x07}}, - {0x061d, {0x30, 0x30}}, - {0x061e, {0xa9, 0xed}}, - {0x061f, {0x09, 0x0b}}, - {0x0620, {0x42, 0xc2}}, - {0x0621, {0x1d, 0x2a}}, - {0x0622, {0xd6, 0x56}}, - {0x0623, {0x95, 0x8b}}, - {0x0624, {0x2b, 0x2b}}, - {0x0625, {0x30, 0x24}}, - {0x0626, {0x3e, 0x3e}}, - {0x0627, {0x62, 0xe2}}, - {0x0628, {0xe9, 0xf5}}, - {0x0629, {0x99, 0x19}}, - {0x062a, {0xd4, 0x11}}, - {0x062b, {0x03, 0x04}}, - {0x062c, {0xb5, 0x85}}, - {0x062d, {0x1e, 0x20}}, - {0x062e, {0x2a, 0xea}}, - {0x062f, {0xd7, 0xd2}}, - {0x0630, {0x15, 0x15}}, - {0x0631, {0xa3, 0xa9}}, - {0x0632, {0x1f, 0x1f}}, - {0x0633, {0xf9, 0xd1}}, - {0x0634, {0xc0, 0xc3}}, - {0x0635, {0x4d, 0x8d}}, - {0x0636, {0x21, 0x31}}, - {0x0637, {0x83, 0x83}}, - {0x0638, {0x08, 0x8c}}, - {0x0639, {0x19, 0x19}}, - {0x063a, {0x45, 0xa5}}, - {0x063b, {0xef, 0xec}}, - {0x063c, {0x8a, 0x8a}}, - {0x063d, {0xf4, 0xf6}}, - {0x063e, {0x8f, 0x8f}}, - {0x063f, {0x44, 0x0c}}, - {0x0640, {0xef, 0xf0}}, - {0x0641, {0x66, 0x66}}, - {0x0642, {0xcc, 0xd2}}, - {0x0643, {0x41, 0x41}}, - {0x0644, {0x63, 0x93}}, - {0x0645, {0x8e, 0x8e}}, - {0x0646, {0xa2, 0x42}}, - {0x0647, {0x7b, 0x7b}}, - {0x0648, {0x04, 0x04}}, - {0x0649, {0x00, 0x00}}, - {0x064a, {0x40, 0x40}}, - {0x064b, {0x8c, 0x98}}, - {0x064c, {0x00, 0x00}}, - {0x064d, {0x63, 0xc3}}, - {0x064e, {0x04, 0x04}}, - {0x064f, {0x20, 0x20}}, - {0x0650, {0x00, 0x00}}, - {0x0651, {0x40 ,0x40}}, - {0x0652, {0x01, 0x01}}, + {0x060b, {0x21, 0x0b} }, + {0x060c, {0xad, 0xad} }, + {0x060d, {0x70, 0xf0} }, + {0x060e, {0xea, 0xe9} }, + {0x060f, {0xdd, 0xdd} }, + {0x0610, {0x08, 0x64} }, + {0x0611, {0x60, 0x60} }, + {0x0612, {0xf8, 0xb2} }, + {0x0613, {0x01, 0x02} }, + {0x0614, {0xe4, 0xb4} }, + {0x0615, {0x19, 0x02} }, + {0x0616, {0xae, 0x2e} }, + {0x0617, {0xee, 0xc5} }, + {0x0618, {0x56, 0x56} }, + {0x0619, {0x30, 0x58} }, + {0x061a, {0xf9, 0xf8} }, + {0x061b, {0x24, 0x64} }, + {0x061c, {0x07, 0x07} }, + {0x061d, {0x30, 0x30} }, + {0x061e, {0xa9, 0xed} }, + {0x061f, {0x09, 0x0b} }, + {0x0620, {0x42, 0xc2} }, + {0x0621, {0x1d, 0x2a} }, + {0x0622, {0xd6, 0x56} }, + {0x0623, {0x95, 0x8b} }, + {0x0624, {0x2b, 0x2b} }, + {0x0625, {0x30, 0x24} }, + {0x0626, {0x3e, 0x3e} }, + {0x0627, {0x62, 0xe2} }, + {0x0628, {0xe9, 0xf5} }, + {0x0629, {0x99, 0x19} }, + {0x062a, {0xd4, 0x11} }, + {0x062b, {0x03, 0x04} }, + {0x062c, {0xb5, 0x85} }, + {0x062d, {0x1e, 0x20} }, + {0x062e, {0x2a, 0xea} }, + {0x062f, {0xd7, 0xd2} }, + {0x0630, {0x15, 0x15} }, + {0x0631, {0xa3, 0xa9} }, + {0x0632, {0x1f, 0x1f} }, + {0x0633, {0xf9, 0xd1} }, + {0x0634, {0xc0, 0xc3} }, + {0x0635, {0x4d, 0x8d} }, + {0x0636, {0x21, 0x31} }, + {0x0637, {0x83, 0x83} }, + {0x0638, {0x08, 0x8c} }, + {0x0639, {0x19, 0x19} }, + {0x063a, {0x45, 0xa5} }, + {0x063b, {0xef, 0xec} }, + {0x063c, {0x8a, 0x8a} }, + {0x063d, {0xf4, 0xf6} }, + {0x063e, {0x8f, 0x8f} }, + {0x063f, {0x44, 0x0c} }, + {0x0640, {0xef, 0xf0} }, + {0x0641, {0x66, 0x66} }, + {0x0642, {0xcc, 0xd2} }, + {0x0643, {0x41, 0x41} }, + {0x0644, {0x63, 0x93} }, + {0x0645, {0x8e, 0x8e} }, + {0x0646, {0xa2, 0x42} }, + {0x0647, {0x7b, 0x7b} }, + {0x0648, {0x04, 0x04} }, + {0x0649, {0x00, 0x00} }, + {0x064a, {0x40, 0x40} }, + {0x064b, {0x8c, 0x98} }, + {0x064c, {0x00, 0x00} }, + {0x064d, {0x63, 0xc3} }, + {0x064e, {0x04, 0x04} }, + {0x064f, {0x20, 0x20} }, + {0x0650, {0x00, 0x00} }, + {0x0651, {0x40, 0x40} }, + {0x0652, {0x01, 0x01} }, }; -#define NUM_LPFILTER_COEF (sizeof (lpfilter_coef) / sizeof(struct au8522_register_config)) +#define NUM_LPFILTER_COEF (sizeof(lpfilter_coef)\ + / sizeof(struct au8522_register_config)) static inline struct au8522_state *to_state(struct v4l2_subdev *sd) { @@ -202,14 +204,17 @@ static void setup_vbi(struct au8522_state *state, int aud_input) au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00); au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00); au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H,0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H,0x00); - au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H,0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H, + 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H, + 0x00); + au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H, + 0x00); /* Setup the VBI registers */ - for (i = 0x30; i < 0x60; i++) { + for (i = 0x30; i < 0x60; i++) au8522_writereg(state, i, 0x40); - } + /* For some reason, every register is 0x40 except register 0x44 (confirmed via the HVR-950q USB capture) */ au8522_writereg(state, 0x44, 0x60); @@ -448,7 +453,7 @@ static void set_audio_input(struct au8522_state *state, int aud_input) if (aud_input != AU8522_AUDIO_SIF) { /* The caller asked for a mode we don't currently support */ - printk("Unsupported audio mode requested! mode=%d\n", + printk(KERN_ERR "Unsupported audio mode requested! mode=%d\n", aud_input); return; } @@ -668,7 +673,7 @@ static int au8522_s_video_routing(struct v4l2_subdev *sd, } else if (route->input == AU8522_COMPOSITE_CH4_SIF) { au8522_setup_cvbs_tuner_mode(state); } else { - printk("au8522 mode not currently supported\n"); + printk(KERN_ERR "au8522 mode not currently supported\n"); return -EINVAL; } return 0; @@ -782,15 +787,15 @@ static int au8522_probe(struct i2c_client *client, instance = au8522_get_state(&state, client->adapter, client->addr); switch (instance) { case 0: - printk("au8522_decoder allocation failed\n"); + printk(KERN_ERR "au8522_decoder allocation failed\n"); return -EIO; case 1: /* new demod instance */ - printk("au8522_decoder creating new instance...\n"); + printk(KERN_INFO "au8522_decoder creating new instance...\n"); break; default: /* existing demod instance */ - printk("au8522_decoder attaching to existing instance...\n"); + printk(KERN_INFO "au8522_decoder attach existing instance.\n"); break; } diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index 7e24b914dbe5..35731258bb0a 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c @@ -36,16 +36,16 @@ static int debug; static LIST_HEAD(hybrid_tuner_instance_list); static DEFINE_MUTEX(au8522_list_mutex); -#define dprintk(arg...) do { \ - if (debug) \ - printk(arg); \ +#define dprintk(arg...)\ + do { if (debug)\ + printk(arg);\ } while (0) /* 16 bit registers, 8 bit values */ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) { int ret; - u8 buf [] = { (reg >> 8) | 0x80, reg & 0xff, data }; + u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data }; struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 }; @@ -62,10 +62,10 @@ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) u8 au8522_readreg(struct au8522_state *state, u16 reg) { int ret; - u8 b0 [] = { (reg >> 8) | 0x40, reg & 0xff }; - u8 b1 [] = { 0 }; + u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff }; + u8 b1[] = { 0 }; - struct i2c_msg msg [] = { + struct i2c_msg msg[] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 }, { .addr = state->config->demod_address, .flags = I2C_M_RD, -- cgit v1.2.1 From baadd7925c98968c94e9657272d91957a3ad0a41 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sun, 15 Mar 2009 20:05:51 -0300 Subject: V4L/DVB (11089): au8522: finish conversion to v4l2_device/subdev Per Hans Verkuil instruction, remove the au8522_command and replace v4l2-i2c-drv-legacy.h with v4l2-i2c-drv.h Thanks to Hans Verkuil for reviewing the au8522 analog support. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522_decoder.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c index 2ad84c236ec7..c9d0eecfbe3c 100644 --- a/drivers/media/dvb/frontends/au8522_decoder.c +++ b/drivers/media/dvb/frontends/au8522_decoder.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include "au8522.h" #include "au8522_priv.h" @@ -725,11 +725,6 @@ static int au8522_log_status(struct v4l2_subdev *sd) return 0; } -static int au8522_command(struct i2c_client *client, unsigned cmd, void *arg) -{ - return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); -} - /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops au8522_core_ops = { @@ -838,7 +833,6 @@ MODULE_DEVICE_TABLE(i2c, au8522_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "au8522", .driverid = I2C_DRIVERID_AU8522, - .command = au8522_command, .probe = au8522_probe, .remove = au8522_remove, .id_table = au8522_id, -- cgit v1.2.1 From 235f0e4348cc57d5a5fe36d07530ecf6541eeae5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Mar 2009 16:39:07 -0300 Subject: V4L/DVB (11100): au8522: fix compilation warning. normal_i2c and I2C_CLIENT_INSMOD are only necessary for kernels < 2.6.22. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522_decoder.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c index c9d0eecfbe3c..2617f680bd5f 100644 --- a/drivers/media/dvb/frontends/au8522_decoder.c +++ b/drivers/media/dvb/frontends/au8522_decoder.c @@ -47,15 +47,12 @@ MODULE_LICENSE("GPL"); static int au8522_analog_debug; -static unsigned short normal_i2c[] = { 0x8e >> 1, I2C_CLIENT_END }; module_param_named(analog_debug, au8522_analog_debug, int, 0644); MODULE_PARM_DESC(analog_debug, "Analog debugging messages [0=Off (default) 1=On]"); -I2C_CLIENT_INSMOD; - struct au8522_register_config { u16 reg_name; u8 reg_val[8]; -- cgit v1.2.1 From 6a39a38e338527effb2703e76aedd856cc7b3683 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 19 Mar 2009 21:03:09 -0300 Subject: V4L/DVB (11110): au8522/au0828: Fix Kconfig dependencies au8522 is now dependent of V4L2, as reported by Randy Dunlap : au8522_decoder.c:(.text+0x199898): undefined reference to `v4l2_ctrl_query_fill' au8522_decoder.c:(.text+0x1998b3): undefined reference to `v4l2_ctrl_query_fill' au8522_decoder.c:(.text+0x199944): undefined reference to `v4l2_device_unregister_subdev' au8522_decoder.c:(.text+0x19997c): undefined reference to `v4l2_chip_ident_i2c_client' au8522_decoder.c:(.text+0x199f1e): undefined reference to `v4l2_i2c_subdev_init' Cc: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 5c78f6329d68..a206cee23f73 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -437,7 +437,7 @@ config DVB_S5H1409 config DVB_AU8522 tristate "Auvitek AU8522 based" - depends on DVB_CORE && I2C + depends on DVB_CORE && I2C && VIDEO_V4L2 default m if DVB_FE_CUSTOMISE help An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want -- cgit v1.2.1 From dcd241c384357e5c146299d45d2ee2f4ad439723 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 19 Mar 2009 21:41:08 -0300 Subject: V4L/DVB (11111): dvb_dummy_fe: Fix compilation breakage As reported by Randy Dunlap : ERROR: "dvb_dummy_fe_ofdm_attach" [drivers/media/video/cx231xx/cx231xx-dvb.ko] undefined! This happens since cx231xx DVB part still misses the frontend modules. So, the dummy frontend were used for development. The proper fix is to implement the DVB modules there, as they will be required. While this won't happen, lets allow the compilation with or without the dummy FE testing module. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dvb_dummy_fe.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.h b/drivers/media/dvb/frontends/dvb_dummy_fe.h index 8210f19d56ce..1fcb987d6386 100644 --- a/drivers/media/dvb/frontends/dvb_dummy_fe.h +++ b/drivers/media/dvb/frontends/dvb_dummy_fe.h @@ -25,8 +25,27 @@ #include #include "dvb_frontend.h" +#if defined(CONFIG_DVB_DUMMY_FE) || (defined(CONFIG_DVB_DUMMY_FE_MODULE) && \ +defined(MODULE)) extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void); extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void); extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void); +#else +static inline struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +static inline struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +static inline struct dvb_frontend *dvb_dummy_fe_qam_attach(void) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_DUMMY_FE */ #endif // DVB_DUMMY_FE_H -- cgit v1.2.1 From 378a2793eb5e1e6bcd44f85d368ad6962c8ce1ee Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 25 Mar 2009 16:48:15 -0300 Subject: V4L/DVB (11215): zl10353: add support for Intel CE6230 and Intel CE6231 Add chip IDs and configuration registers needed for Intel CE6230 and Intel CE6231. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/zl10353.c | 8 +++++++- drivers/media/dvb/frontends/zl10353.h | 4 ++++ drivers/media/dvb/frontends/zl10353_priv.h | 8 +++++++- 3 files changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index b150ed306696..148b6f7f6cb2 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c @@ -572,6 +572,10 @@ static int zl10353_init(struct dvb_frontend *fe) zl10353_dump_regs(fe); if (state->config.parallel_ts) zl10353_reset_attach[2] &= ~0x20; + if (state->config.clock_ctl_1) + zl10353_reset_attach[3] = state->config.clock_ctl_1; + if (state->config.pll_0) + zl10353_reset_attach[4] = state->config.pll_0; /* Do a "hard" reset if not already done */ if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] || @@ -614,6 +618,7 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, struct i2c_adapter *i2c) { struct zl10353_state *state = NULL; + int id; /* allocate memory for the internal state */ state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL); @@ -625,7 +630,8 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, memcpy(&state->config, config, sizeof(struct zl10353_config)); /* check if the demod is there */ - if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353) + id = zl10353_read_register(state, CHIP_ID); + if ((id != ID_ZL10353) && (id != ID_CE6230) && (id != ID_CE6231)) goto error; /* create dvb_frontend */ diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h index 2287bac46243..6e3ca9eed048 100644 --- a/drivers/media/dvb/frontends/zl10353.h +++ b/drivers/media/dvb/frontends/zl10353.h @@ -41,6 +41,10 @@ struct zl10353_config /* set if i2c_gate_ctrl disable is required */ u8 disable_i2c_gate_ctrl:1; + + /* clock control registers (0x51-0x54) */ + u8 clock_ctl_1; /* default: 0x46 */ + u8 pll_0; /* default: 0x15 */ }; #if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE)) diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h index 055ff1f7e349..e0dd1d3e09dd 100644 --- a/drivers/media/dvb/frontends/zl10353_priv.h +++ b/drivers/media/dvb/frontends/zl10353_priv.h @@ -22,7 +22,9 @@ #ifndef _ZL10353_PRIV_ #define _ZL10353_PRIV_ -#define ID_ZL10353 0x14 +#define ID_ZL10353 0x14 /* Zarlink ZL10353 */ +#define ID_CE6230 0x18 /* Intel CE6230 */ +#define ID_CE6231 0x19 /* Intel CE6231 */ #define msb(x) (((x) >> 8) & 0xff) #define lsb(x) ((x) & 0xff) @@ -50,6 +52,10 @@ enum zl10353_reg_addr { TPS_RECEIVED_0 = 0x1E, TPS_CURRENT_1 = 0x1F, TPS_CURRENT_0 = 0x20, + CLOCK_CTL_0 = 0x51, + CLOCK_CTL_1 = 0x52, + PLL_0 = 0x53, + PLL_1 = 0x54, RESET = 0x55, AGC_TARGET = 0x56, MCLK_RATIO = 0x5C, -- cgit v1.2.1 From 997fb78e73f3dce23c6fa773128583e1fa15d164 Mon Sep 17 00:00:00 2001 From: Artem Makhutov Date: Thu, 26 Mar 2009 06:45:53 -0300 Subject: V4L/DVB (11248): Remove debug output from stb6100_cfg.h This patch removes the debug output from stb6100_cfg.h as it is flooding the syslog with tuning data during normal operation. Signed-off-by: Artem Makhutov Acked-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stb6100_cfg.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/stb6100_cfg.h b/drivers/media/dvb/frontends/stb6100_cfg.h index d3133405dc03..6314d18c797a 100644 --- a/drivers/media/dvb/frontends/stb6100_cfg.h +++ b/drivers/media/dvb/frontends/stb6100_cfg.h @@ -36,7 +36,6 @@ static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency) return err; } *frequency = t_state.frequency; - printk("%s: Frequency=%d\n", __func__, t_state.frequency); } return 0; } @@ -59,7 +58,6 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency) return err; } } - printk("%s: Frequency=%d\n", __func__, t_state.frequency); return 0; } @@ -81,7 +79,6 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) } *bandwidth = t_state.bandwidth; } - printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth); return 0; } @@ -103,6 +100,5 @@ static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) return err; } } - printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth); return 0; } -- cgit v1.2.1 From 1662070a593b5a862b5bf8c843ebfab0deb058a6 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 28 Feb 2009 10:19:30 -0300 Subject: V4L/DVB (11284): Fix i2c code of flexcop-driver for rare revisions This patch adds a workaround in the i2c-code of the flexcop-driver to fix support for SkyStar2 rev 2.7. There are not many devices out there, that's why this bug was not revealed earlier. Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/itd1000_priv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/itd1000_priv.h b/drivers/media/dvb/frontends/itd1000_priv.h index 8cdc54e57903..08ca851223c9 100644 --- a/drivers/media/dvb/frontends/itd1000_priv.h +++ b/drivers/media/dvb/frontends/itd1000_priv.h @@ -31,7 +31,7 @@ struct itd1000_state { /* ugly workaround for flexcop's incapable i2c-controller * FIXME, if possible */ - u8 shadow[255]; + u8 shadow[256]; }; enum itd1000_register { -- cgit v1.2.1 From 73722dddbd73f20799e84708f59d1cddf429dac9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 30 Mar 2009 07:08:30 -0300 Subject: V4L/DVB (11314): au8522: remove unused I2C_DRIVERID I2C_DRIVERIDs are no longer needed with v4l2_subdev and will be removed from the kernel soon. Cc: Devin Heitmueller Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522_decoder.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media/dvb/frontends') diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c index 2617f680bd5f..d63e1527dc88 100644 --- a/drivers/media/dvb/frontends/au8522_decoder.c +++ b/drivers/media/dvb/frontends/au8522_decoder.c @@ -829,7 +829,6 @@ MODULE_DEVICE_TABLE(i2c, au8522_id); static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "au8522", - .driverid = I2C_DRIVERID_AU8522, .probe = au8522_probe, .remove = au8522_remove, .id_table = au8522_id, -- cgit v1.2.1