diff options
Diffstat (limited to 'drivers/media/dvb/frontends')
157 files changed, 0 insertions, 67029 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig deleted file mode 100644 index 23e4cffeba3..00000000000 --- a/drivers/media/dvb/frontends/Kconfig +++ /dev/null @@ -1,530 +0,0 @@ -config DVB_FE_CUSTOMISE - bool "Customise the frontend modules to build" - depends on DVB_CORE - default N - help - 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 - -config DVB_STB0899 - tristate "STB0899 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S/S2/DSS Multistandard demodulator. Say Y when you want - to support this demodulator based frontends - -config DVB_STB6100 - tristate "STB6100 based tuners" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A Silicon tuner from ST used in conjunction with the STB0899 - demodulator. Say Y when you want to support this tuner. - -comment "DVB-S (satellite) frontends" - depends on DVB_CORE - -config DVB_CX24110 - tristate "Conexant CX24110 based" - 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_CX24123 - tristate "Conexant CX24123 based" - 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_MT312 - tristate "Zarlink VP310/MT312/ZL10313 based" - 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_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 - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_STV0288 - tristate "ST STV0288 based" - 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_STB6000 - tristate "ST STB6000 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_STV0299 - tristate "ST STV0299 based" - 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_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_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 - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_TDA10086 - tristate "Philips TDA10086 based" - 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_TDA8261 - tristate "Philips TDA8261 based" - 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_VES1X93 - tristate "VLSI VES1893 or VES1993 based" - 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_TUNER_ITD1000 - tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS" - 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_TUNER_CX24113 - tristate "Conexant CX24113/CX24128 tuner for DVB-S/DSS" - 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_TDA826X - tristate "Philips TDA826X 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_TUA6100 - tristate "Infineon TUA6100 PLL" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S PLL chip. - -config DVB_CX24116 - tristate "Conexant CX24116 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S/S2 tuner module. Say Y when you want to support this frontend. - -config DVB_SI21XX - tristate "Silicon Labs SI21XX based" - 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. - -comment "DVB-T (terrestrial) frontends" - depends on DVB_CORE - -config DVB_SP8870 - tristate "Spase sp8870 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - - This driver needs external firmware. Please use the command - "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to - download/extract it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - -config DVB_SP887X - tristate "Spase sp887x based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - - This driver needs external firmware. Please use the command - "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to - download/extract it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - -config DVB_CX22700 - tristate "Conexant CX22700 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - -config DVB_CX22702 - tristate "Conexant cx22702 demodulator (OFDM)" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - -config DVB_DRX397XD - tristate "Micronas DRX3975D/DRX3977D based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - - TODO: - This driver needs external firmware. Please use the command - "<kerneldir>/Documentation/dvb/get_dvb_firmware drx397xD" to - download/extract them, and then copy them to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - -config DVB_L64781 - tristate "LSI L64781" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - -config DVB_TDA1004X - tristate "Philips TDA10045H/TDA10046H based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - - This driver needs external firmware. Please use the commands - "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", - "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to - download/extract them, and then copy them to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - -config DVB_NXT6000 - tristate "NxtWave Communications NXT6000 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - -config DVB_MT352 - tristate "Zarlink MT352 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - -config DVB_ZL10353 - tristate "Zarlink ZL10353 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - -config DVB_DIB3000MB - tristate "DiBcom 3000M-B" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Designed for mobile usage. Say Y when you want - to support this frontend. - -config DVB_DIB3000MC - tristate "DiBcom 3000P/M-C" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Designed for mobile usage. Say Y when you want - to support this frontend. - -config DVB_DIB7000M - tristate "DiBcom 7000MA/MB/PA/PB/MC" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Designed for mobile usage. Say Y when you want - to support this frontend. - -config DVB_DIB7000P - tristate "DiBcom 7000PC" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Designed for mobile usage. Say Y when you want - to support this frontend. - -config DVB_TDA10048 - tristate "Philips TDA10048HN based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - 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 - -config DVB_VES1820 - tristate "VLSI VES1820 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-C tuner module. Say Y when you want to support this frontend. - -config DVB_TDA10021 - tristate "Philips TDA10021 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-C tuner module. Say Y when you want to support this frontend. - -config DVB_TDA10023 - tristate "Philips TDA10023 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-C tuner module. Say Y when you want to support this frontend. - -config DVB_STV0297 - tristate "ST STV0297 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-C tuner module. Say Y when you want to support this frontend. - -comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends" - depends on DVB_CORE - -config DVB_NXT200X - tristate "NxtWave Communications NXT2002/NXT2004 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. - - This driver needs external firmware. Please use the commands - "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" and - "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to - download/extract them, and then copy them to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - -config DVB_OR51211 - tristate "Oren OR51211 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An ATSC 8VSB tuner module. Say Y when you want to support this frontend. - - This driver needs external firmware. Please use the command - "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to - download it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - -config DVB_OR51132 - tristate "Oren OR51132 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. - - This driver needs external firmware. Please use the commands - "<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_vsb" and/or - "<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_qam" to - download firmwares for 8VSB and QAM64/256, respectively. Copy them to - /usr/lib/hotplug/firmware or /lib/firmware (depending on - configuration of firmware hotplug). - -config DVB_BCM3510 - tristate "Broadcom BCM3510" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to - support this frontend. - -config DVB_LGDT330X - tristate "LG Electronics LGDT3302/LGDT3303 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_LGDT3304 - tristate "LG Electronics LGDT3304" - 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_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 - 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_AU8522 - tristate "Auvitek AU8522 based" - 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 - to support this frontend. - -config DVB_S5H1411 - tristate "Samsung S5H1411 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. - -comment "ISDB-T (terrestrial) frontends" - depends on DVB_CORE - -config DVB_S921 - tristate "Sharp S921 tuner" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module. - Say Y when you want to support this frontend. - -comment "Digital terrestrial only tuners/PLL" - depends on DVB_CORE - -config DVB_PLL - tristate "Generic I2C PLL based tuners" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - This module drives a number of tuners based on PLL chips with a - common I2C interface. Say Y when you want to support these tuners. - -config DVB_TUNER_DIB0070 - tristate "DiBcom DiB0070 silicon base-band tuner" - depends on I2C - default m if DVB_FE_CUSTOMISE - help - A driver for the silicon baseband tuner DiB0070 from DiBcom. - This device is only used inside a SiP called together with a - demodulator for now. - -comment "SEC control devices for DVB-S" - depends on DVB_CORE - -config DVB_LNBP21 - tristate "LNBP21/LNBH24 SEC controllers" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An SEC control chips. - -config DVB_ISL6405 - tristate "ISL6405 SEC controller" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An SEC control chip. - -config DVB_ISL6421 - tristate "ISL6421 SEC controller" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An SEC control chip. - -config DVB_LGS8GL5 - tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DMB-TH tuner module. Say Y when you want to support this frontend. - -config DVB_LGS8GXX - tristate "Legend Silicon LGS8913/LGS8GL5/LGS8GXX DMB-TH demodulator" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DMB-TH tuner module. Say Y when you want to support this frontend. - -comment "Tools to develop new frontends" - -config DVB_DUMMY_FE - tristate "Dummy frontend driver" - default n -endmenu - -endif diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile deleted file mode 100644 index bc2b00abd10..00000000000 --- a/drivers/media/dvb/frontends/Makefile +++ /dev/null @@ -1,74 +0,0 @@ -# -# Makefile for the kernel DVB frontend device drivers. -# - -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -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_decoder.o - -obj-$(CONFIG_DVB_PLL) += dvb-pll.o -obj-$(CONFIG_DVB_STV0299) += stv0299.o -obj-$(CONFIG_DVB_STB0899) += stb0899.o -obj-$(CONFIG_DVB_STB6100) += stb6100.o -obj-$(CONFIG_DVB_SP8870) += sp8870.o -obj-$(CONFIG_DVB_CX22700) += cx22700.o -obj-$(CONFIG_DVB_CX24110) += cx24110.o -obj-$(CONFIG_DVB_TDA8083) += tda8083.o -obj-$(CONFIG_DVB_L64781) += l64781.o -obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o -obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o -obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o -obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o -obj-$(CONFIG_DVB_MT312) += mt312.o -obj-$(CONFIG_DVB_VES1820) += ves1820.o -obj-$(CONFIG_DVB_VES1X93) += ves1x93.o -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 -obj-$(CONFIG_DVB_TDA10021) += tda10021.o -obj-$(CONFIG_DVB_TDA10023) += tda10023.o -obj-$(CONFIG_DVB_STV0297) += stv0297.o -obj-$(CONFIG_DVB_NXT200X) += nxt200x.o -obj-$(CONFIG_DVB_OR51211) += or51211.o -obj-$(CONFIG_DVB_OR51132) += or51132.o -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 -obj-$(CONFIG_DVB_ISL6421) += isl6421.o -obj-$(CONFIG_DVB_TDA10086) += tda10086.o -obj-$(CONFIG_DVB_TDA826X) += tda826x.o -obj-$(CONFIG_DVB_TDA8261) += tda8261.o -obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o -obj-$(CONFIG_DVB_TUA6100) += tua6100.o -obj-$(CONFIG_DVB_S5H1409) += s5h1409.o -obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o -obj-$(CONFIG_DVB_AU8522) += au8522.o -obj-$(CONFIG_DVB_TDA10048) += tda10048.o -obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o -obj-$(CONFIG_DVB_S5H1411) += s5h1411.o -obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o -obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o -obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o -obj-$(CONFIG_DVB_AF9013) += af9013.o -obj-$(CONFIG_DVB_CX24116) += cx24116.o -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 -obj-$(CONFIG_DVB_STV0900) += stv0900.o - diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c deleted file mode 100644 index b2b50fb4cfd..00000000000 --- a/drivers/media/dvb/frontends/af9013.c +++ /dev/null @@ -1,1685 +0,0 @@ -/* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> - * - * Thanks to Afatech who kindly provided information. - * - * 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 <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/firmware.h> - -#include "dvb_frontend.h" -#include "af9013_priv.h" -#include "af9013.h" - -int af9013_debug; - -struct af9013_state { - struct i2c_adapter *i2c; - struct dvb_frontend frontend; - - struct af9013_config config; - - u16 signal_strength; - u32 ber; - u32 ucblocks; - u16 snr; - u32 frequency; - unsigned long next_statistics_check; -}; - -static u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; - -static int af9013_write_regs(struct af9013_state *state, u8 mbox, u16 reg, - u8 *val, u8 len) -{ - u8 buf[3+len]; - struct i2c_msg msg = { - .addr = state->config.demod_address, - .flags = 0, - .len = sizeof(buf), - .buf = buf }; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - buf[2] = mbox; - memcpy(&buf[3], val, len); - - if (i2c_transfer(state->i2c, &msg, 1) != 1) { - warn("I2C write failed reg:%04x len:%d", reg, len); - return -EREMOTEIO; - } - return 0; -} - -static int af9013_write_ofdm_regs(struct af9013_state *state, u16 reg, u8 *val, - u8 len) -{ - u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(0 << 6)|(0 << 7); - return af9013_write_regs(state, mbox, reg, val, len); -} - -static int af9013_write_ofsm_regs(struct af9013_state *state, u16 reg, u8 *val, - u8 len) -{ - u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(1 << 6)|(1 << 7); - return af9013_write_regs(state, mbox, reg, val, len); -} - -/* write single register */ -static int af9013_write_reg(struct af9013_state *state, u16 reg, u8 val) -{ - return af9013_write_ofdm_regs(state, reg, &val, 1); -} - -/* read single register */ -static int af9013_read_reg(struct af9013_state *state, u16 reg, u8 *val) -{ - u8 obuf[3] = { reg >> 8, reg & 0xff, 0 }; - u8 ibuf[1]; - struct i2c_msg msg[2] = { - { - .addr = state->config.demod_address, - .flags = 0, - .len = sizeof(obuf), - .buf = obuf - }, { - .addr = state->config.demod_address, - .flags = I2C_M_RD, - .len = sizeof(ibuf), - .buf = ibuf - } - }; - - if (i2c_transfer(state->i2c, msg, 2) != 2) { - warn("I2C read failed reg:%04x", reg); - return -EREMOTEIO; - } - *val = ibuf[0]; - return 0; -} - -static int af9013_write_reg_bits(struct af9013_state *state, u16 reg, u8 pos, - u8 len, u8 val) -{ - int ret; - u8 tmp, mask; - - ret = af9013_read_reg(state, reg, &tmp); - if (ret) - return ret; - - mask = regmask[len - 1] << pos; - tmp = (tmp & ~mask) | ((val << pos) & mask); - - return af9013_write_reg(state, reg, tmp); -} - -static int af9013_read_reg_bits(struct af9013_state *state, u16 reg, u8 pos, - u8 len, u8 *val) -{ - int ret; - u8 tmp; - - ret = af9013_read_reg(state, reg, &tmp); - if (ret) - return ret; - *val = (tmp >> pos) & regmask[len - 1]; - return 0; -} - -static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) -{ - int ret; - u8 pos; - u16 addr; - deb_info("%s: gpio:%d gpioval:%02x\n", __func__, gpio, gpioval); - -/* GPIO0 & GPIO1 0xd735 - GPIO2 & GPIO3 0xd736 */ - - switch (gpio) { - case 0: - case 1: - addr = 0xd735; - break; - case 2: - case 3: - addr = 0xd736; - break; - - default: - err("invalid gpio:%d\n", gpio); - ret = -EINVAL; - goto error; - }; - - switch (gpio) { - case 0: - case 2: - pos = 0; - break; - case 1: - case 3: - default: - pos = 4; - break; - }; - - ret = af9013_write_reg_bits(state, addr, pos, 4, gpioval); - -error: - return ret; -} - -static u32 af913_div(u32 a, u32 b, u32 x) -{ - u32 r = 0, c = 0, i; - deb_info("%s: a:%d b:%d x:%d\n", __func__, a, b, x); - - if (a > b) { - c = a / b; - a = a - c * b; - } - - for (i = 0; i < x; i++) { - if (a >= b) { - r += 1; - a -= b; - } - a <<= 1; - r <<= 1; - } - r = (c << (u32)x) + r; - - deb_info("%s: a:%d b:%d x:%d r:%d r:%x\n", __func__, a, b, x, r, r); - return r; -} - -static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw) -{ - int ret = 0; - u8 i = 0; - u8 buf[24]; - u32 uninitialized_var(ns_coeff1_2048nu); - u32 uninitialized_var(ns_coeff1_8191nu); - u32 uninitialized_var(ns_coeff1_8192nu); - u32 uninitialized_var(ns_coeff1_8193nu); - u32 uninitialized_var(ns_coeff2_2k); - u32 uninitialized_var(ns_coeff2_8k); - - deb_info("%s: adc_clock:%d bw:%d\n", __func__, - state->config.adc_clock, bw); - - switch (state->config.adc_clock) { - case 28800: /* 28.800 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x01e79e7a; - ns_coeff1_8191nu = 0x0079eb6e; - ns_coeff1_8192nu = 0x0079e79e; - ns_coeff1_8193nu = 0x0079e3cf; - ns_coeff2_2k = 0x00f3cf3d; - ns_coeff2_8k = 0x003cf3cf; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x0238e38e; - ns_coeff1_8191nu = 0x008e3d55; - ns_coeff1_8192nu = 0x008e38e4; - ns_coeff1_8193nu = 0x008e3472; - ns_coeff2_2k = 0x011c71c7; - ns_coeff2_8k = 0x00471c72; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x028a28a3; - ns_coeff1_8191nu = 0x00a28f3d; - ns_coeff1_8192nu = 0x00a28a29; - ns_coeff1_8193nu = 0x00a28514; - ns_coeff2_2k = 0x01451451; - ns_coeff2_8k = 0x00514514; - break; - default: - ret = -EINVAL; - } - break; - case 20480: /* 20.480 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x02adb6dc; - ns_coeff1_8191nu = 0x00ab7313; - ns_coeff1_8192nu = 0x00ab6db7; - ns_coeff1_8193nu = 0x00ab685c; - ns_coeff2_2k = 0x0156db6e; - ns_coeff2_8k = 0x0055b6dc; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x03200001; - ns_coeff1_8191nu = 0x00c80640; - ns_coeff1_8192nu = 0x00c80000; - ns_coeff1_8193nu = 0x00c7f9c0; - ns_coeff2_2k = 0x01900000; - ns_coeff2_8k = 0x00640000; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x03924926; - ns_coeff1_8191nu = 0x00e4996e; - ns_coeff1_8192nu = 0x00e49249; - ns_coeff1_8193nu = 0x00e48b25; - ns_coeff2_2k = 0x01c92493; - ns_coeff2_8k = 0x00724925; - break; - default: - ret = -EINVAL; - } - break; - case 28000: /* 28.000 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x01f58d10; - ns_coeff1_8191nu = 0x007d672f; - ns_coeff1_8192nu = 0x007d6344; - ns_coeff1_8193nu = 0x007d5f59; - ns_coeff2_2k = 0x00fac688; - ns_coeff2_8k = 0x003eb1a2; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x02492492; - ns_coeff1_8191nu = 0x00924db7; - ns_coeff1_8192nu = 0x00924925; - ns_coeff1_8193nu = 0x00924492; - ns_coeff2_2k = 0x01249249; - ns_coeff2_8k = 0x00492492; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x029cbc15; - ns_coeff1_8191nu = 0x00a7343f; - ns_coeff1_8192nu = 0x00a72f05; - ns_coeff1_8193nu = 0x00a729cc; - ns_coeff2_2k = 0x014e5e0a; - ns_coeff2_8k = 0x00539783; - break; - default: - ret = -EINVAL; - } - break; - case 25000: /* 25.000 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x0231bcb5; - ns_coeff1_8191nu = 0x008c7391; - ns_coeff1_8192nu = 0x008c6f2d; - ns_coeff1_8193nu = 0x008c6aca; - ns_coeff2_2k = 0x0118de5b; - ns_coeff2_8k = 0x00463797; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x028f5c29; - ns_coeff1_8191nu = 0x00a3dc29; - ns_coeff1_8192nu = 0x00a3d70a; - ns_coeff1_8193nu = 0x00a3d1ec; - ns_coeff2_2k = 0x0147ae14; - ns_coeff2_8k = 0x0051eb85; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x02ecfb9d; - ns_coeff1_8191nu = 0x00bb44c1; - ns_coeff1_8192nu = 0x00bb3ee7; - ns_coeff1_8193nu = 0x00bb390d; - ns_coeff2_2k = 0x01767dce; - ns_coeff2_8k = 0x005d9f74; - break; - default: - ret = -EINVAL; - } - break; - default: - err("invalid xtal"); - return -EINVAL; - } - if (ret) { - err("invalid bandwidth"); - return ret; - } - - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x00ff0000) >> 16); - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff2_2k & 0x01c00000) >> 22); - buf[i++] = (u8) ((ns_coeff2_2k & 0x003fc000) >> 14); - buf[i++] = (u8) ((ns_coeff2_2k & 0x00003fc0) >> 6); - buf[i++] = (u8) ((ns_coeff2_2k & 0x0000003f)); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x00ffc000) >> 16); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x00ffc000) >> 16); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x00ffc000) >> 16); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff2_8k & 0x01c00000) >> 22); - buf[i++] = (u8) ((ns_coeff2_8k & 0x003fc000) >> 14); - buf[i++] = (u8) ((ns_coeff2_8k & 0x00003fc0) >> 6); - buf[i++] = (u8) ((ns_coeff2_8k & 0x0000003f)); - - deb_info("%s: coeff:", __func__); - debug_dump(buf, sizeof(buf), deb_info); - - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, 0xae00 + i, buf[i]); - if (ret) - break; - } - - return ret; -} - -static int af9013_set_adc_ctrl(struct af9013_state *state) -{ - int ret; - u8 buf[3], tmp, i; - u32 adc_cw; - - deb_info("%s: adc_clock:%d\n", __func__, state->config.adc_clock); - - /* adc frequency type */ - switch (state->config.adc_clock) { - case 28800: /* 28.800 MHz */ - tmp = 0; - break; - case 20480: /* 20.480 MHz */ - tmp = 1; - break; - case 28000: /* 28.000 MHz */ - tmp = 2; - break; - case 25000: /* 25.000 MHz */ - tmp = 3; - break; - default: - err("invalid xtal"); - return -EINVAL; - } - - adc_cw = af913_div(state->config.adc_clock*1000, 1000000ul, 19ul); - - buf[0] = (u8) ((adc_cw & 0x000000ff)); - buf[1] = (u8) ((adc_cw & 0x0000ff00) >> 8); - buf[2] = (u8) ((adc_cw & 0x00ff0000) >> 16); - - deb_info("%s: adc_cw:", __func__); - debug_dump(buf, sizeof(buf), deb_info); - - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, 0xd180 + i, buf[i]); - if (ret) - goto error; - } - ret = af9013_write_reg_bits(state, 0x9bd2, 0, 4, tmp); -error: - return ret; -} - -static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw) -{ - int ret; - u16 addr; - u8 buf[3], i, j; - u32 adc_freq, freq_cw; - s8 bfs_spec_inv; - int if_sample_freq; - - for (j = 0; j < 3; j++) { - if (j == 0) { - addr = 0xd140; /* fcw normal */ - bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1; - } else if (j == 1) { - addr = 0x9be7; /* fcw dummy ram */ - bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1; - } else { - addr = 0x9bea; /* fcw inverted */ - bfs_spec_inv = state->config.rf_spec_inv ? 1 : -1; - } - - adc_freq = state->config.adc_clock * 1000; - if_sample_freq = state->config.tuner_if * 1000; - - /* TDA18271 uses different sampling freq for every bw */ - if (state->config.tuner == AF9013_TUNER_TDA18271) { - switch (bw) { - case BANDWIDTH_6_MHZ: - if_sample_freq = 3300000; /* 3.3 MHz */ - break; - case BANDWIDTH_7_MHZ: - if_sample_freq = 3800000; /* 3.8 MHz */ - break; - case BANDWIDTH_8_MHZ: - default: - if_sample_freq = 4300000; /* 4.3 MHz */ - break; - } - } - - while (if_sample_freq > (adc_freq / 2)) - if_sample_freq = if_sample_freq - adc_freq; - - if (if_sample_freq >= 0) - bfs_spec_inv = bfs_spec_inv * (-1); - else - if_sample_freq = if_sample_freq * (-1); - - freq_cw = af913_div(if_sample_freq, adc_freq, 23ul); - - if (bfs_spec_inv == -1) - freq_cw = 0x00800000 - freq_cw; - - buf[0] = (u8) ((freq_cw & 0x000000ff)); - buf[1] = (u8) ((freq_cw & 0x0000ff00) >> 8); - buf[2] = (u8) ((freq_cw & 0x007f0000) >> 16); - - - deb_info("%s: freq_cw:", __func__); - debug_dump(buf, sizeof(buf), deb_info); - - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, addr++, buf[i]); - if (ret) - goto error; - } - } -error: - return ret; -} - -static int af9013_set_ofdm_params(struct af9013_state *state, - struct dvb_ofdm_parameters *params, u8 *auto_mode) -{ - int ret; - u8 i, buf[3] = {0, 0, 0}; - *auto_mode = 0; /* set if parameters are requested to auto set */ - - switch (params->transmission_mode) { - case TRANSMISSION_MODE_AUTO: - *auto_mode = 1; - case TRANSMISSION_MODE_2K: - break; - case TRANSMISSION_MODE_8K: - buf[0] |= (1 << 0); - break; - default: - return -EINVAL; - } - - switch (params->guard_interval) { - case GUARD_INTERVAL_AUTO: - *auto_mode = 1; - case GUARD_INTERVAL_1_32: - break; - case GUARD_INTERVAL_1_16: - buf[0] |= (1 << 2); - break; - case GUARD_INTERVAL_1_8: - buf[0] |= (2 << 2); - break; - case GUARD_INTERVAL_1_4: - buf[0] |= (3 << 2); - break; - default: - return -EINVAL; - } - - switch (params->hierarchy_information) { - case HIERARCHY_AUTO: - *auto_mode = 1; - case HIERARCHY_NONE: - break; - case HIERARCHY_1: - buf[0] |= (1 << 4); - break; - case HIERARCHY_2: - buf[0] |= (2 << 4); - break; - case HIERARCHY_4: - buf[0] |= (3 << 4); - break; - default: - return -EINVAL; - }; - - switch (params->constellation) { - case QAM_AUTO: - *auto_mode = 1; - case QPSK: - break; - case QAM_16: - buf[1] |= (1 << 6); - break; - case QAM_64: - buf[1] |= (2 << 6); - break; - default: - return -EINVAL; - } - - /* Use HP. How and which case we can switch to LP? */ - buf[1] |= (1 << 4); - - switch (params->code_rate_HP) { - case FEC_AUTO: - *auto_mode = 1; - case FEC_1_2: - break; - case FEC_2_3: - buf[2] |= (1 << 0); - break; - case FEC_3_4: - buf[2] |= (2 << 0); - break; - case FEC_5_6: - buf[2] |= (3 << 0); - break; - case FEC_7_8: - buf[2] |= (4 << 0); - break; - default: - return -EINVAL; - } - - switch (params->code_rate_LP) { - case FEC_AUTO: - /* if HIERARCHY_NONE and FEC_NONE then LP FEC is set to FEC_AUTO - by dvb_frontend.c for compatibility */ - if (params->hierarchy_information != HIERARCHY_NONE) - *auto_mode = 1; - case FEC_1_2: - break; - case FEC_2_3: - buf[2] |= (1 << 3); - break; - case FEC_3_4: - buf[2] |= (2 << 3); - break; - case FEC_5_6: - buf[2] |= (3 << 3); - break; - case FEC_7_8: - buf[2] |= (4 << 3); - break; - case FEC_NONE: - if (params->hierarchy_information == HIERARCHY_AUTO) - break; - default: - return -EINVAL; - } - - switch (params->bandwidth) { - case BANDWIDTH_6_MHZ: - break; - case BANDWIDTH_7_MHZ: - buf[1] |= (1 << 2); - break; - case BANDWIDTH_8_MHZ: - buf[1] |= (2 << 2); - break; - default: - return -EINVAL; - } - - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, 0xd3c0 + i, buf[i]); - if (ret) - break; - } - - return ret; -} - -static int af9013_reset(struct af9013_state *state, u8 sleep) -{ - int ret; - u8 tmp, i; - deb_info("%s\n", __func__); - - /* enable OFDM reset */ - ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 1); - if (ret) - goto error; - - /* start reset mechanism */ - ret = af9013_write_reg(state, 0xaeff, 1); - if (ret) - goto error; - - /* reset is done when bit 1 is set */ - for (i = 0; i < 150; i++) { - ret = af9013_read_reg_bits(state, 0xd417, 1, 1, &tmp); - if (ret) - goto error; - if (tmp) - break; /* reset done */ - msleep(10); - } - if (!tmp) - return -ETIMEDOUT; - - /* don't clear reset when going to sleep */ - if (!sleep) { - /* clear OFDM reset */ - ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0); - if (ret) - goto error; - - /* disable OFDM reset */ - ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0); - } -error: - return ret; -} - -static int af9013_power_ctrl(struct af9013_state *state, u8 onoff) -{ - int ret; - deb_info("%s: onoff:%d\n", __func__, onoff); - - if (onoff) { - /* power on */ - ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 0); - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0); - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0); - } else { - /* power off */ - ret = af9013_reset(state, 1); - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 1); - } -error: - return ret; -} - -static int af9013_lock_led(struct af9013_state *state, u8 onoff) -{ - deb_info("%s: onoff:%d\n", __func__, onoff); - - return af9013_write_reg_bits(state, 0xd730, 0, 1, onoff); -} - -static int af9013_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 auto_mode; /* auto set TPS */ - - deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency, - params->u.ofdm.bandwidth); - - state->frequency = params->frequency; - - /* program CFOE coefficients */ - ret = af9013_set_coeff(state, params->u.ofdm.bandwidth); - if (ret) - goto error; - - /* program frequency control */ - ret = af9013_set_freq_ctrl(state, params->u.ofdm.bandwidth); - if (ret) - goto error; - - /* clear TPS lock flag (inverted flag) */ - ret = af9013_write_reg_bits(state, 0xd330, 3, 1, 1); - if (ret) - goto error; - - /* clear MPEG2 lock flag */ - ret = af9013_write_reg_bits(state, 0xd507, 6, 1, 0); - if (ret) - goto error; - - /* empty channel function */ - ret = af9013_write_reg_bits(state, 0x9bfe, 0, 1, 0); - if (ret) - goto error; - - /* empty DVB-T channel function */ - ret = af9013_write_reg_bits(state, 0x9bc2, 0, 1, 0); - if (ret) - goto error; - - /* program tuner */ - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, params); - - /* program TPS and bandwidth, check if auto mode needed */ - ret = af9013_set_ofdm_params(state, ¶ms->u.ofdm, &auto_mode); - if (ret) - goto error; - - if (auto_mode) { - /* clear easy mode flag */ - ret = af9013_write_reg(state, 0xaefd, 0); - deb_info("%s: auto TPS\n", __func__); - } else { - /* set easy mode flag */ - ret = af9013_write_reg(state, 0xaefd, 1); - if (ret) - goto error; - ret = af9013_write_reg(state, 0xaefe, 0); - deb_info("%s: manual TPS\n", __func__); - } - if (ret) - goto error; - - /* everything is set, lets try to receive channel - OFSM GO! */ - ret = af9013_write_reg(state, 0xffff, 0); - if (ret) - goto error; - -error: - return ret; -} - -static int af9013_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 i, buf[3]; - deb_info("%s\n", __func__); - - /* read TPS registers */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0xd3c0 + i, &buf[i]); - if (ret) - goto error; - } - - switch ((buf[1] >> 6) & 3) { - case 0: - p->u.ofdm.constellation = QPSK; - break; - case 1: - p->u.ofdm.constellation = QAM_16; - break; - case 2: - p->u.ofdm.constellation = QAM_64; - break; - } - - switch ((buf[0] >> 0) & 3) { - case 0: - p->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; - break; - case 1: - p->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - } - - switch ((buf[0] >> 2) & 3) { - case 0: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; - break; - } - - switch ((buf[0] >> 4) & 7) { - case 0: - p->u.ofdm.hierarchy_information = HIERARCHY_NONE; - break; - case 1: - p->u.ofdm.hierarchy_information = HIERARCHY_1; - break; - case 2: - p->u.ofdm.hierarchy_information = HIERARCHY_2; - break; - case 3: - p->u.ofdm.hierarchy_information = HIERARCHY_4; - break; - } - - switch ((buf[2] >> 0) & 7) { - case 0: - p->u.ofdm.code_rate_HP = FEC_1_2; - break; - case 1: - p->u.ofdm.code_rate_HP = FEC_2_3; - break; - case 2: - p->u.ofdm.code_rate_HP = FEC_3_4; - break; - case 3: - p->u.ofdm.code_rate_HP = FEC_5_6; - break; - case 4: - p->u.ofdm.code_rate_HP = FEC_7_8; - break; - } - - switch ((buf[2] >> 3) & 7) { - case 0: - p->u.ofdm.code_rate_LP = FEC_1_2; - break; - case 1: - p->u.ofdm.code_rate_LP = FEC_2_3; - break; - case 2: - p->u.ofdm.code_rate_LP = FEC_3_4; - break; - case 3: - p->u.ofdm.code_rate_LP = FEC_5_6; - break; - case 4: - p->u.ofdm.code_rate_LP = FEC_7_8; - break; - } - - switch ((buf[1] >> 2) & 3) { - case 0: - p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - break; - case 1: - p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; - break; - case 2: - p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; - break; - } - - p->inversion = INVERSION_AUTO; - p->frequency = state->frequency; - -error: - return ret; -} - -static int af9013_update_ber_unc(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 buf[3], i; - u32 error_bit_count = 0; - u32 total_bit_count = 0; - u32 abort_packet_count = 0; - - state->ber = 0; - - /* check if error bit count is ready */ - ret = af9013_read_reg_bits(state, 0xd391, 4, 1, &buf[0]); - if (ret) - goto error; - if (!buf[0]) - goto exit; - - /* get RSD packet abort count */ - for (i = 0; i < 2; i++) { - ret = af9013_read_reg(state, 0xd38a + i, &buf[i]); - if (ret) - goto error; - } - abort_packet_count = (buf[1] << 8) + buf[0]; - - /* get error bit count */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0xd387 + i, &buf[i]); - if (ret) - goto error; - } - error_bit_count = (buf[2] << 16) + (buf[1] << 8) + buf[0]; - error_bit_count = error_bit_count - abort_packet_count * 8 * 8; - - /* get used RSD counting period (10000 RSD packets used) */ - for (i = 0; i < 2; i++) { - ret = af9013_read_reg(state, 0xd385 + i, &buf[i]); - if (ret) - goto error; - } - total_bit_count = (buf[1] << 8) + buf[0]; - total_bit_count = total_bit_count - abort_packet_count; - total_bit_count = total_bit_count * 204 * 8; - - if (total_bit_count) - state->ber = error_bit_count * 1000000000 / total_bit_count; - - state->ucblocks += abort_packet_count; - - deb_info("%s: err bits:%d total bits:%d abort count:%d\n", __func__, - error_bit_count, total_bit_count, abort_packet_count); - - /* set BER counting range */ - ret = af9013_write_reg(state, 0xd385, 10000 & 0xff); - if (ret) - goto error; - ret = af9013_write_reg(state, 0xd386, 10000 >> 8); - if (ret) - goto error; - /* reset and start BER counter */ - ret = af9013_write_reg_bits(state, 0xd391, 4, 1, 1); - if (ret) - goto error; - -exit: -error: - return ret; -} - -static int af9013_update_snr(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 buf[3], i, len; - u32 quant = 0; - struct snr_table *uninitialized_var(snr_table); - - /* check if quantizer ready (for snr) */ - ret = af9013_read_reg_bits(state, 0xd2e1, 3, 1, &buf[0]); - if (ret) - goto error; - if (buf[0]) { - /* quantizer ready - read it */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0xd2e3 + i, &buf[i]); - if (ret) - goto error; - } - quant = (buf[2] << 16) + (buf[1] << 8) + buf[0]; - - /* read current constellation */ - ret = af9013_read_reg(state, 0xd3c1, &buf[0]); - if (ret) - goto error; - - switch ((buf[0] >> 6) & 3) { - case 0: - len = ARRAY_SIZE(qpsk_snr_table); - snr_table = qpsk_snr_table; - break; - case 1: - len = ARRAY_SIZE(qam16_snr_table); - snr_table = qam16_snr_table; - break; - case 2: - len = ARRAY_SIZE(qam64_snr_table); - snr_table = qam64_snr_table; - break; - default: - len = 0; - break; - } - - if (len) { - for (i = 0; i < len; i++) { - if (quant < snr_table[i].val) { - state->snr = snr_table[i].snr * 10; - break; - } - } - } - - /* set quantizer super frame count */ - ret = af9013_write_reg(state, 0xd2e2, 1); - if (ret) - goto error; - - /* check quantizer availability */ - for (i = 0; i < 10; i++) { - msleep(10); - ret = af9013_read_reg_bits(state, 0xd2e6, 0, 1, - &buf[0]); - if (ret) - goto error; - if (!buf[0]) - break; - } - - /* reset quantizer */ - ret = af9013_write_reg_bits(state, 0xd2e1, 3, 1, 1); - if (ret) - goto error; - } - -error: - return ret; -} - -static int af9013_update_signal_strength(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 tmp0; - u8 rf_gain, rf_50, rf_80, if_gain, if_50, if_80; - int signal_strength; - - deb_info("%s\n", __func__); - - state->signal_strength = 0; - - ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, &tmp0); - if (ret) - goto error; - if (tmp0) { - ret = af9013_read_reg(state, 0x9bbd, &rf_50); - if (ret) - goto error; - ret = af9013_read_reg(state, 0x9bd0, &rf_80); - if (ret) - goto error; - ret = af9013_read_reg(state, 0x9be2, &if_50); - if (ret) - goto error; - ret = af9013_read_reg(state, 0x9be4, &if_80); - if (ret) - goto error; - ret = af9013_read_reg(state, 0xd07c, &rf_gain); - if (ret) - goto error; - ret = af9013_read_reg(state, 0xd07d, &if_gain); - if (ret) - goto error; - signal_strength = (0xffff / (9 * (rf_50 + if_50) - \ - 11 * (rf_80 + if_80))) * (10 * (rf_gain + if_gain) - \ - 11 * (rf_80 + if_80)); - if (signal_strength < 0) - signal_strength = 0; - else if (signal_strength > 0xffff) - signal_strength = 0xffff; - - state->signal_strength = signal_strength; - } - -error: - return ret; -} - -static int af9013_update_statistics(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - - if (time_before(jiffies, state->next_statistics_check)) - return 0; - - /* set minimum statistic update interval */ - state->next_statistics_check = jiffies + msecs_to_jiffies(1200); - - ret = af9013_update_signal_strength(fe); - if (ret) - goto error; - ret = af9013_update_snr(fe); - if (ret) - goto error; - ret = af9013_update_ber_unc(fe); - if (ret) - goto error; - -error: - return ret; -} - -static int af9013_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *fesettings) -{ - fesettings->min_delay_ms = 800; - fesettings->step_size = 0; - fesettings->max_drift = 0; - - return 0; -} - -static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret = 0; - u8 tmp; - *status = 0; - - /* TPS lock */ - ret = af9013_read_reg_bits(state, 0xd330, 3, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL; - - /* MPEG2 lock */ - ret = af9013_read_reg_bits(state, 0xd507, 6, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_SYNC | FE_HAS_LOCK; - - if (!(*status & FE_HAS_SIGNAL)) { - /* AGC lock */ - ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_SIGNAL; - } - - if (!(*status & FE_HAS_CARRIER)) { - /* CFO lock */ - ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_CARRIER; - } - - if (!(*status & FE_HAS_CARRIER)) { - /* SFOE lock */ - ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_CARRIER; - } - - ret = af9013_update_statistics(fe); - -error: - return ret; -} - - -static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *ber = state->ber; - return ret; -} - -static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *strength = state->signal_strength; - return ret; -} - -static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *snr = state->snr; - return ret; -} - -static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *ucblocks = state->ucblocks; - return ret; -} - -static int af9013_sleep(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - deb_info("%s\n", __func__); - - ret = af9013_lock_led(state, 0); - if (ret) - goto error; - - ret = af9013_power_ctrl(state, 0); -error: - return ret; -} - -static int af9013_init(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret, i, len; - u8 tmp0, tmp1; - struct regdesc *init; - deb_info("%s\n", __func__); - - /* reset OFDM */ - ret = af9013_reset(state, 0); - if (ret) - goto error; - - /* power on */ - ret = af9013_power_ctrl(state, 1); - if (ret) - goto error; - - /* enable ADC */ - ret = af9013_write_reg(state, 0xd73a, 0xa4); - if (ret) - goto error; - - /* write API version to firmware */ - for (i = 0; i < sizeof(state->config.api_version); i++) { - ret = af9013_write_reg(state, 0x9bf2 + i, - state->config.api_version[i]); - if (ret) - goto error; - } - - /* program ADC control */ - ret = af9013_set_adc_ctrl(state); - if (ret) - goto error; - - /* set I2C master clock */ - ret = af9013_write_reg(state, 0xd416, 0x14); - if (ret) - goto error; - - /* set 16 embx */ - ret = af9013_write_reg_bits(state, 0xd700, 1, 1, 1); - if (ret) - goto error; - - /* set no trigger */ - ret = af9013_write_reg_bits(state, 0xd700, 2, 1, 0); - if (ret) - goto error; - - /* set read-update bit for constellation */ - ret = af9013_write_reg_bits(state, 0xd371, 1, 1, 1); - if (ret) - goto error; - - /* enable FEC monitor */ - ret = af9013_write_reg_bits(state, 0xd392, 1, 1, 1); - if (ret) - goto error; - - /* load OFSM settings */ - deb_info("%s: load ofsm settings\n", __func__); - len = ARRAY_SIZE(ofsm_init); - init = ofsm_init; - for (i = 0; i < len; i++) { - ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos, - init[i].len, init[i].val); - if (ret) - goto error; - } - - /* load tuner specific settings */ - deb_info("%s: load tuner specific settings\n", __func__); - switch (state->config.tuner) { - case AF9013_TUNER_MXL5003D: - len = ARRAY_SIZE(tuner_init_mxl5003d); - init = tuner_init_mxl5003d; - break; - case AF9013_TUNER_MXL5005D: - case AF9013_TUNER_MXL5005R: - len = ARRAY_SIZE(tuner_init_mxl5005); - init = tuner_init_mxl5005; - break; - case AF9013_TUNER_ENV77H11D5: - len = ARRAY_SIZE(tuner_init_env77h11d5); - init = tuner_init_env77h11d5; - break; - case AF9013_TUNER_MT2060: - len = ARRAY_SIZE(tuner_init_mt2060); - init = tuner_init_mt2060; - break; - case AF9013_TUNER_MC44S803: - len = ARRAY_SIZE(tuner_init_mc44s803); - init = tuner_init_mc44s803; - break; - case AF9013_TUNER_QT1010: - case AF9013_TUNER_QT1010A: - len = ARRAY_SIZE(tuner_init_qt1010); - init = tuner_init_qt1010; - break; - case AF9013_TUNER_MT2060_2: - len = ARRAY_SIZE(tuner_init_mt2060_2); - init = tuner_init_mt2060_2; - break; - case AF9013_TUNER_TDA18271: - len = ARRAY_SIZE(tuner_init_tda18271); - init = tuner_init_tda18271; - break; - case AF9013_TUNER_UNKNOWN: - default: - len = ARRAY_SIZE(tuner_init_unknown); - init = tuner_init_unknown; - break; - } - - for (i = 0; i < len; i++) { - ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos, - init[i].len, init[i].val); - if (ret) - goto error; - } - - /* set TS mode */ - deb_info("%s: setting ts mode\n", __func__); - tmp0 = 0; /* parallel mode */ - tmp1 = 0; /* serial mode */ - switch (state->config.output_mode) { - case AF9013_OUTPUT_MODE_PARALLEL: - tmp0 = 1; - break; - case AF9013_OUTPUT_MODE_SERIAL: - tmp1 = 1; - break; - case AF9013_OUTPUT_MODE_USB: - /* usb mode for AF9015 */ - default: - break; - } - ret = af9013_write_reg_bits(state, 0xd500, 1, 1, tmp0); /* parallel */ - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd500, 2, 1, tmp1); /* serial */ - if (ret) - goto error; - - /* enable lock led */ - ret = af9013_lock_led(state, 1); - if (ret) - goto error; - -error: - return ret; -} - -static struct dvb_frontend_ops af9013_ops; - -static int af9013_download_firmware(struct af9013_state *state) -{ - int i, len, packets, remainder, ret; - const struct firmware *fw; - u16 addr = 0x5100; /* firmware start address */ - u16 checksum = 0; - u8 val; - u8 fw_params[4]; - u8 *data; - u8 *fw_file = AF9013_DEFAULT_FIRMWARE; - - msleep(100); - /* check whether firmware is already running */ - ret = af9013_read_reg(state, 0x98be, &val); - if (ret) - goto error; - else - deb_info("%s: firmware status:%02x\n", __func__, val); - - if (val == 0x0c) /* fw is running, no need for download */ - goto exit; - - info("found a '%s' in cold state, will try to load a firmware", - af9013_ops.info.name); - - /* request the firmware, this will block and timeout */ - ret = request_firmware(&fw, fw_file, &state->i2c->dev); - if (ret) { - err("did not find the firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details" \ - " on firmware-problems. (%d)", - fw_file, ret); - goto error; - } - - info("downloading firmware from file '%s'", fw_file); - - /* calc checksum */ - for (i = 0; i < fw->size; i++) - checksum += fw->data[i]; - - fw_params[0] = checksum >> 8; - fw_params[1] = checksum & 0xff; - fw_params[2] = fw->size >> 8; - fw_params[3] = fw->size & 0xff; - - /* write fw checksum & size */ - ret = af9013_write_ofsm_regs(state, 0x50fc, - fw_params, sizeof(fw_params)); - if (ret) - goto error_release; - - #define FW_PACKET_MAX_DATA 16 - - packets = fw->size / FW_PACKET_MAX_DATA; - remainder = fw->size % FW_PACKET_MAX_DATA; - len = FW_PACKET_MAX_DATA; - for (i = 0; i <= packets; i++) { - if (i == packets) /* set size of the last packet */ - len = remainder; - - data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); - ret = af9013_write_ofsm_regs(state, addr, data, len); - addr += FW_PACKET_MAX_DATA; - - if (ret) { - err("firmware download failed at %d with %d", i, ret); - goto error_release; - } - } - - /* request boot firmware */ - ret = af9013_write_reg(state, 0xe205, 1); - if (ret) - goto error_release; - - for (i = 0; i < 15; i++) { - msleep(100); - - /* check firmware status */ - ret = af9013_read_reg(state, 0x98be, &val); - if (ret) - goto error_release; - - deb_info("%s: firmware status:%02x\n", __func__, val); - - if (val == 0x0c || val == 0x04) /* success or fail */ - break; - } - - if (val == 0x04) { - err("firmware did not run"); - ret = -1; - } else if (val != 0x0c) { - err("firmware boot timeout"); - ret = -1; - } - -error_release: - release_firmware(fw); -error: -exit: - if (!ret) - info("found a '%s' in warm state.", af9013_ops.info.name); - return ret; -} - -static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - int ret; - struct af9013_state *state = fe->demodulator_priv; - deb_info("%s: enable:%d\n", __func__, enable); - - if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) - ret = af9013_write_reg_bits(state, 0xd417, 3, 1, enable); - else - ret = af9013_write_reg_bits(state, 0xd607, 2, 1, enable); - - return ret; -} - -static void af9013_release(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops af9013_ops; - -struct dvb_frontend *af9013_attach(const struct af9013_config *config, - struct i2c_adapter *i2c) -{ - int ret; - struct af9013_state *state = NULL; - u8 buf[3], i; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct af9013_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->i2c = i2c; - memcpy(&state->config, config, sizeof(struct af9013_config)); - - /* chip version */ - ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]); - if (ret) - goto error; - - /* ROM version */ - for (i = 0; i < 2; i++) { - ret = af9013_read_reg(state, 0x116b + i, &buf[i]); - if (ret) - goto error; - } - deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__, - buf[2], buf[0], buf[1]); - - /* download firmware */ - if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) { - ret = af9013_download_firmware(state); - if (ret) - goto error; - } - - /* firmware version */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0x5103 + i, &buf[i]); - if (ret) - goto error; - } - info("firmware version:%d.%d.%d", buf[0], buf[1], buf[2]); - - /* settings for mp2if */ - if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) { - /* AF9015 split PSB to 1.5k + 0.5k */ - ret = af9013_write_reg_bits(state, 0xd50b, 2, 1, 1); - } else { - /* AF9013 change the output bit to data7 */ - ret = af9013_write_reg_bits(state, 0xd500, 3, 1, 1); - if (ret) - goto error; - /* AF9013 set mpeg to full speed */ - ret = af9013_write_reg_bits(state, 0xd502, 4, 1, 1); - } - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd520, 4, 1, 1); - if (ret) - goto error; - - /* set GPIOs */ - for (i = 0; i < sizeof(state->config.gpio); i++) { - ret = af9013_set_gpio(state, i, state->config.gpio[i]); - if (ret) - goto error; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &af9013_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - return &state->frontend; -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(af9013_attach); - -static struct dvb_frontend_ops af9013_ops = { - .info = { - .name = "Afatech AF9013 DVB-T", - .type = FE_OFDM, - .frequency_min = 174000000, - .frequency_max = 862000000, - .frequency_stepsize = 250000, - .frequency_tolerance = 0, - .caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | - FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | - FE_CAN_RECOVER | - FE_CAN_MUTE_TS - }, - - .release = af9013_release, - .init = af9013_init, - .sleep = af9013_sleep, - .i2c_gate_ctrl = af9013_i2c_gate_ctrl, - - .set_frontend = af9013_set_frontend, - .get_frontend = af9013_get_frontend, - - .get_tune_settings = af9013_get_tune_settings, - - .read_status = af9013_read_status, - .read_ber = af9013_read_ber, - .read_signal_strength = af9013_read_signal_strength, - .read_snr = af9013_read_snr, - .read_ucblocks = af9013_read_ucblocks, -}; - -module_param_named(debug, af9013_debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); -MODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb/frontends/af9013.h deleted file mode 100644 index 28b90c91c76..00000000000 --- a/drivers/media/dvb/frontends/af9013.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> - * - * Thanks to Afatech who kindly provided information. - * - * 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 _AF9013_H_ -#define _AF9013_H_ - -#include <linux/dvb/frontend.h> - -enum af9013_ts_mode { - AF9013_OUTPUT_MODE_PARALLEL, - AF9013_OUTPUT_MODE_SERIAL, - AF9013_OUTPUT_MODE_USB, /* only for AF9015 */ -}; - -enum af9013_tuner { - AF9013_TUNER_MXL5003D = 3, /* MaxLinear */ - AF9013_TUNER_MXL5005D = 13, /* MaxLinear */ - AF9013_TUNER_MXL5005R = 30, /* MaxLinear */ - AF9013_TUNER_ENV77H11D5 = 129, /* Panasonic */ - AF9013_TUNER_MT2060 = 130, /* Microtune */ - AF9013_TUNER_MC44S803 = 133, /* Freescale */ - AF9013_TUNER_QT1010 = 134, /* Quantek */ - AF9013_TUNER_UNKNOWN = 140, /* for can tuners ? */ - AF9013_TUNER_MT2060_2 = 147, /* Microtune */ - AF9013_TUNER_TDA18271 = 156, /* NXP */ - AF9013_TUNER_QT1010A = 162, /* Quantek */ -}; - -/* AF9013/5 GPIOs (mostly guessed) - demod#1-gpio#0 - set demod#2 i2c-addr for dual devices - demod#1-gpio#1 - xtal setting (?) - demod#1-gpio#3 - tuner#1 - demod#2-gpio#0 - tuner#2 - demod#2-gpio#1 - xtal setting (?) -*/ -#define AF9013_GPIO_ON (1 << 0) -#define AF9013_GPIO_EN (1 << 1) -#define AF9013_GPIO_O (1 << 2) -#define AF9013_GPIO_I (1 << 3) - -#define AF9013_GPIO_LO (AF9013_GPIO_ON|AF9013_GPIO_EN) -#define AF9013_GPIO_HI (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O) - -#define AF9013_GPIO_TUNER_ON (AF9013_GPIO_ON|AF9013_GPIO_EN) -#define AF9013_GPIO_TUNER_OFF (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O) - -struct af9013_config { - /* demodulator's I2C address */ - u8 demod_address; - - /* frequencies in kHz */ - u32 adc_clock; - - /* tuner ID */ - u8 tuner; - - /* tuner IF */ - u16 tuner_if; - - /* TS data output mode */ - u8 output_mode:2; - - /* RF spectrum inversion */ - u8 rf_spec_inv:1; - - /* API version */ - u8 api_version[4]; - - /* GPIOs */ - u8 gpio[4]; -}; - - -#if defined(CONFIG_DVB_AF9013) || \ - (defined(CONFIG_DVB_AF9013_MODULE) && defined(MODULE)) -extern struct dvb_frontend *af9013_attach(const struct af9013_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *af9013_attach( -const struct af9013_config *config, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_AF9013 */ - -#endif /* _AF9013_H_ */ diff --git a/drivers/media/dvb/frontends/af9013_priv.h b/drivers/media/dvb/frontends/af9013_priv.h deleted file mode 100644 index 163e251d0b7..00000000000 --- a/drivers/media/dvb/frontends/af9013_priv.h +++ /dev/null @@ -1,869 +0,0 @@ -/* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> - * - * Thanks to Afatech who kindly provided information. - * - * 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 _AF9013_PRIV_ -#define _AF9013_PRIV_ - -#define LOG_PREFIX "af9013" -extern int af9013_debug; - -#define dprintk(var, level, args...) \ - do { if ((var & level)) printk(args); } while (0) - -#define debug_dump(b, l, func) {\ - int loop_; \ - for (loop_ = 0; loop_ < l; loop_++) \ - func("%02x ", b[loop_]); \ - func("\n");\ -} - -#define deb_info(args...) dprintk(af9013_debug, 0x01, args) - -#undef err -#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg) -#undef info -#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) -#undef warn -#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg) - -#define AF9013_DEFAULT_FIRMWARE "dvb-fe-af9013.fw" - -struct regdesc { - u16 addr; - u8 pos:4; - u8 len:4; - u8 val; -}; - -struct snr_table { - u32 val; - u8 snr; -}; - -/* QPSK SNR lookup table */ -static struct snr_table qpsk_snr_table[] = { - { 0x0b4771, 0 }, - { 0x0c1aed, 1 }, - { 0x0d0d27, 2 }, - { 0x0e4d19, 3 }, - { 0x0e5da8, 4 }, - { 0x107097, 5 }, - { 0x116975, 6 }, - { 0x1252d9, 7 }, - { 0x131fa4, 8 }, - { 0x13d5e1, 9 }, - { 0x148e53, 10 }, - { 0x15358b, 11 }, - { 0x15dd29, 12 }, - { 0x168112, 13 }, - { 0x170b61, 14 }, - { 0xffffff, 15 }, -}; - -/* QAM16 SNR lookup table */ -static struct snr_table qam16_snr_table[] = { - { 0x05eb62, 5 }, - { 0x05fecf, 6 }, - { 0x060b80, 7 }, - { 0x062501, 8 }, - { 0x064865, 9 }, - { 0x069604, 10 }, - { 0x06f356, 11 }, - { 0x07706a, 12 }, - { 0x0804d3, 13 }, - { 0x089d1a, 14 }, - { 0x093e3d, 15 }, - { 0x09e35d, 16 }, - { 0x0a7c3c, 17 }, - { 0x0afaf8, 18 }, - { 0x0b719d, 19 }, - { 0xffffff, 20 }, -}; - -/* QAM64 SNR lookup table */ -static struct snr_table qam64_snr_table[] = { - { 0x03109b, 12 }, - { 0x0310d4, 13 }, - { 0x031920, 14 }, - { 0x0322d0, 15 }, - { 0x0339fc, 16 }, - { 0x0364a1, 17 }, - { 0x038bcc, 18 }, - { 0x03c7d3, 19 }, - { 0x0408cc, 20 }, - { 0x043bed, 21 }, - { 0x048061, 22 }, - { 0x04be95, 23 }, - { 0x04fa7d, 24 }, - { 0x052405, 25 }, - { 0x05570d, 26 }, - { 0xffffff, 27 }, -}; - -static struct regdesc ofsm_init[] = { - { 0xd73a, 0, 8, 0xa1 }, - { 0xd73b, 0, 8, 0x1f }, - { 0xd73c, 4, 4, 0x0a }, - { 0xd732, 3, 1, 0x00 }, - { 0xd731, 4, 2, 0x03 }, - { 0xd73d, 7, 1, 0x01 }, - { 0xd740, 0, 1, 0x00 }, - { 0xd740, 1, 1, 0x00 }, - { 0xd740, 2, 1, 0x00 }, - { 0xd740, 3, 1, 0x01 }, - { 0xd3c1, 4, 1, 0x01 }, - { 0xd3a2, 0, 8, 0x00 }, - { 0xd3a3, 0, 8, 0x04 }, - { 0xd305, 0, 8, 0x32 }, - { 0xd306, 0, 8, 0x10 }, - { 0xd304, 0, 8, 0x04 }, - { 0x9112, 0, 1, 0x01 }, - { 0x911d, 0, 1, 0x01 }, - { 0x911a, 0, 1, 0x01 }, - { 0x911b, 0, 1, 0x01 }, - { 0x9bce, 0, 4, 0x02 }, - { 0x9116, 0, 1, 0x01 }, - { 0x9bd1, 0, 1, 0x01 }, - { 0xd2e0, 0, 8, 0xd0 }, - { 0xd2e9, 0, 4, 0x0d }, - { 0xd38c, 0, 8, 0xfc }, - { 0xd38d, 0, 8, 0x00 }, - { 0xd38e, 0, 8, 0x7e }, - { 0xd38f, 0, 8, 0x00 }, - { 0xd390, 0, 8, 0x2f }, - { 0xd145, 4, 1, 0x01 }, - { 0xd1a9, 4, 1, 0x01 }, - { 0xd158, 5, 3, 0x01 }, - { 0xd159, 0, 6, 0x06 }, - { 0xd167, 0, 8, 0x00 }, - { 0xd168, 0, 4, 0x07 }, - { 0xd1c3, 5, 3, 0x00 }, - { 0xd1c4, 0, 6, 0x00 }, - { 0xd1c5, 0, 7, 0x10 }, - { 0xd1c6, 0, 3, 0x02 }, - { 0xd080, 2, 5, 0x03 }, - { 0xd081, 4, 4, 0x09 }, - { 0xd098, 4, 4, 0x0f }, - { 0xd098, 0, 4, 0x03 }, - { 0xdbc0, 3, 1, 0x01 }, - { 0xdbc0, 4, 1, 0x01 }, - { 0xdbc7, 0, 8, 0x08 }, - { 0xdbc8, 4, 4, 0x00 }, - { 0xdbc9, 0, 5, 0x01 }, - { 0xd280, 0, 8, 0xe0 }, - { 0xd281, 0, 8, 0xff }, - { 0xd282, 0, 8, 0xff }, - { 0xd283, 0, 8, 0xc3 }, - { 0xd284, 0, 8, 0xff }, - { 0xd285, 0, 4, 0x01 }, - { 0xd0f0, 0, 7, 0x1a }, - { 0xd0f1, 4, 1, 0x01 }, - { 0xd0f2, 0, 8, 0x0c }, - { 0xd103, 0, 4, 0x08 }, - { 0xd0f8, 0, 7, 0x20 }, - { 0xd111, 5, 1, 0x00 }, - { 0xd111, 6, 1, 0x00 }, - { 0x910b, 0, 8, 0x0a }, - { 0x9115, 0, 8, 0x02 }, - { 0x910c, 0, 8, 0x02 }, - { 0x910d, 0, 8, 0x08 }, - { 0x910e, 0, 8, 0x0a }, - { 0x9bf6, 0, 8, 0x06 }, - { 0x9bf8, 0, 8, 0x02 }, - { 0x9bf7, 0, 8, 0x05 }, - { 0x9bf9, 0, 8, 0x0f }, - { 0x9bfc, 0, 8, 0x13 }, - { 0x9bd3, 0, 8, 0xff }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, -}; - -/* Panasonic ENV77H11D5 tuner init - AF9013_TUNER_ENV77H11D5 = 129 */ -static struct regdesc tuner_init_env77h11d5[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x03 }, - { 0x9bbe, 0, 8, 0x01 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x00 }, - { 0x9be3, 0, 8, 0x00 }, - { 0xd015, 0, 8, 0x50 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0xdf }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x44 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0xeb }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0xf4 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bba, 0, 8, 0xf9 }, - { 0x9bc3, 0, 8, 0xdf }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0xeb }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bc9, 0, 8, 0x52 }, - { 0xd011, 0, 8, 0x3c }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0xf7 }, - { 0xd014, 0, 2, 0x02 }, - { 0xd040, 0, 8, 0x0b }, - { 0xd041, 0, 2, 0x02 }, - { 0xd042, 0, 8, 0x4d }, - { 0xd043, 0, 2, 0x00 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, -}; - -/* Microtune MT2060 tuner init - AF9013_TUNER_MT2060 = 130 */ -static struct regdesc tuner_init_mt2060[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x07 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x00 }, - { 0x9be3, 0, 8, 0x00 }, - { 0x9bbe, 0, 1, 0x00 }, - { 0x9bcc, 0, 1, 0x00 }, - { 0x9bb9, 0, 8, 0x75 }, - { 0x9bcd, 0, 8, 0x24 }, - { 0x9bff, 0, 8, 0x30 }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x32 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x36 }, - { 0xd00d, 0, 2, 0x03 }, - { 0xd00a, 0, 8, 0x35 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x07 }, - { 0x9bc8, 0, 8, 0x90 }, - { 0x9bc3, 0, 8, 0x0f }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x36 }, - { 0x9bc6, 0, 8, 0x03 }, - { 0x9bba, 0, 8, 0xc9 }, - { 0x9bc9, 0, 8, 0x79 }, - { 0xd011, 0, 8, 0x10 }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0x45 }, - { 0xd014, 0, 2, 0x03 }, - { 0xd040, 0, 8, 0x98 }, - { 0xd041, 0, 2, 0x00 }, - { 0xd042, 0, 8, 0xcf }, - { 0xd043, 0, 2, 0x03 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0xcc }, - { 0x9be4, 0, 8, 0xa0 }, - { 0x9bbd, 0, 8, 0x8e }, - { 0x9be2, 0, 8, 0x4d }, - { 0x9bee, 0, 1, 0x01 }, -}; - -/* Microtune MT2060 tuner init - AF9013_TUNER_MT2060_2 = 147 */ -static struct regdesc tuner_init_mt2060_2[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x06 }, - { 0x9bbe, 0, 8, 0x01 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x32 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x36 }, - { 0xd00d, 0, 2, 0x03 }, - { 0xd00a, 0, 8, 0x35 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x07 }, - { 0x9bc8, 0, 8, 0x90 }, - { 0x9bc3, 0, 8, 0x0f }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x36 }, - { 0x9bc6, 0, 8, 0x03 }, - { 0x9bba, 0, 8, 0xc9 }, - { 0x9bc9, 0, 8, 0x79 }, - { 0xd011, 0, 8, 0x10 }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0x45 }, - { 0xd014, 0, 2, 0x03 }, - { 0xd040, 0, 8, 0x98 }, - { 0xd041, 0, 2, 0x00 }, - { 0xd042, 0, 8, 0xcf }, - { 0xd043, 0, 2, 0x03 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 8, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x96 }, - { 0xd054, 0, 8, 0x46 }, - { 0xd045, 7, 1, 0x00 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, -}; - -/* MaxLinear MXL5003 tuner init - AF9013_TUNER_MXL5003D = 3 */ -static struct regdesc tuner_init_mxl5003d[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x09 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x00 }, - { 0x9be3, 0, 8, 0x00 }, - { 0x9bfc, 0, 8, 0x0f }, - { 0x9bf6, 0, 8, 0x01 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0xd015, 0, 8, 0x33 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x40 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x6c }, - { 0xd007, 0, 2, 0x00 }, - { 0xd00c, 0, 8, 0x3d }, - { 0xd00d, 0, 2, 0x00 }, - { 0xd00a, 0, 8, 0x45 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x07 }, - { 0x9bc8, 0, 8, 0x52 }, - { 0x9bc3, 0, 8, 0x0f }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x3d }, - { 0x9bc6, 0, 8, 0x00 }, - { 0x9bba, 0, 8, 0xa2 }, - { 0x9bc9, 0, 8, 0xa0 }, - { 0xd011, 0, 8, 0x56 }, - { 0xd012, 0, 2, 0x00 }, - { 0xd013, 0, 8, 0x50 }, - { 0xd014, 0, 2, 0x00 }, - { 0xd040, 0, 8, 0x56 }, - { 0xd041, 0, 2, 0x00 }, - { 0xd042, 0, 8, 0x50 }, - { 0xd043, 0, 2, 0x00 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 8, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, -}; - -/* MaxLinear MXL5005 tuner init - AF9013_TUNER_MXL5005D = 13 - AF9013_TUNER_MXL5005R = 30 */ -static struct regdesc tuner_init_mxl5005[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x07 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x01 }, - { 0x9be3, 0, 8, 0x01 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x28 }, - { 0x9bff, 0, 8, 0x24 }, - { 0xd015, 0, 8, 0x40 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x40 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x73 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0xfa }, - { 0xd00d, 0, 2, 0x01 }, - { 0xd00a, 0, 8, 0xff }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x23 }, - { 0x9bc8, 0, 8, 0x55 }, - { 0x9bc3, 0, 8, 0x01 }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0xfa }, - { 0x9bc6, 0, 8, 0x01 }, - { 0x9bba, 0, 8, 0xff }, - { 0x9bc9, 0, 8, 0xff }, - { 0x9bd3, 0, 8, 0x95 }, - { 0xd011, 0, 8, 0x70 }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0xfb }, - { 0xd014, 0, 2, 0x01 }, - { 0xd040, 0, 8, 0x70 }, - { 0xd041, 0, 2, 0x01 }, - { 0xd042, 0, 8, 0xfb }, - { 0xd043, 0, 2, 0x01 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0x93 }, - { 0x9be4, 0, 8, 0xfe }, - { 0x9bbd, 0, 8, 0x63 }, - { 0x9be2, 0, 8, 0xfe }, - { 0x9bee, 0, 1, 0x01 }, -}; - -/* Quantek QT1010 tuner init - AF9013_TUNER_QT1010 = 134 - AF9013_TUNER_QT1010A = 162 */ -static struct regdesc tuner_init_qt1010[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x09 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x01 }, - { 0x9be3, 0, 8, 0x01 }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x28 }, - { 0x9bff, 0, 8, 0x20 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x99 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x0f }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0x50 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x00 }, - { 0x9bc8, 0, 8, 0x00 }, - { 0x9bc3, 0, 8, 0x0f }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x0f }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bba, 0, 8, 0xc5 }, - { 0x9bc9, 0, 8, 0xff }, - { 0xd011, 0, 8, 0x58 }, - { 0xd012, 0, 2, 0x02 }, - { 0xd013, 0, 8, 0x89 }, - { 0xd014, 0, 2, 0x01 }, - { 0xd040, 0, 8, 0x58 }, - { 0xd041, 0, 2, 0x02 }, - { 0xd042, 0, 8, 0x89 }, - { 0xd043, 0, 2, 0x01 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0xcd }, - { 0x9be4, 0, 8, 0xbb }, - { 0x9bbd, 0, 8, 0x93 }, - { 0x9be2, 0, 8, 0x80 }, - { 0x9bee, 0, 1, 0x01 }, -}; - -/* Freescale MC44S803 tuner init - AF9013_TUNER_MC44S803 = 133 */ -static struct regdesc tuner_init_mc44s803[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x06 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x00 }, - { 0x9be3, 0, 8, 0x00 }, - { 0x9bf6, 0, 8, 0x01 }, - { 0x9bf8, 0, 8, 0x02 }, - { 0x9bf9, 0, 8, 0x02 }, - { 0x9bfc, 0, 8, 0x1f }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x24 }, - { 0x9bff, 0, 8, 0x24 }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x01 }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x7b }, - { 0xd007, 0, 2, 0x00 }, - { 0xd00c, 0, 8, 0x7c }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0xfe }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x08 }, - { 0x9bc8, 0, 8, 0x9a }, - { 0x9bc3, 0, 8, 0x01 }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x7c }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bba, 0, 8, 0xfc }, - { 0x9bc9, 0, 8, 0xaa }, - { 0xd011, 0, 8, 0x6b }, - { 0xd012, 0, 2, 0x00 }, - { 0xd013, 0, 8, 0x88 }, - { 0xd014, 0, 2, 0x02 }, - { 0xd040, 0, 8, 0x6b }, - { 0xd041, 0, 2, 0x00 }, - { 0xd042, 0, 8, 0x7c }, - { 0xd043, 0, 2, 0x02 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0x9e }, - { 0x9be4, 0, 8, 0xff }, - { 0x9bbd, 0, 8, 0x9e }, - { 0x9be2, 0, 8, 0x25 }, - { 0x9bee, 0, 1, 0x01 }, - { 0xd73b, 3, 1, 0x00 }, -}; - -/* unknown, probably for tin can tuner, tuner init - AF9013_TUNER_UNKNOWN = 140 */ -static struct regdesc tuner_init_unknown[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x02 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x01 }, - { 0x9be3, 0, 8, 0x01 }, - { 0xd1a0, 1, 1, 0x00 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x18 }, - { 0x9bff, 0, 8, 0x2c }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0xdf }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x44 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x00 }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0xf6 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bba, 0, 8, 0xf9 }, - { 0x9bc8, 0, 8, 0xaa }, - { 0x9bc3, 0, 8, 0xdf }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x00 }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bc9, 0, 8, 0xf0 }, - { 0xd011, 0, 8, 0x3c }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0xf7 }, - { 0xd014, 0, 2, 0x02 }, - { 0xd040, 0, 8, 0x0b }, - { 0xd041, 0, 2, 0x02 }, - { 0xd042, 0, 8, 0x4d }, - { 0xd043, 0, 2, 0x00 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, -}; - -/* NXP TDA18271 tuner init - AF9013_TUNER_TDA18271 = 156 */ -static struct regdesc tuner_init_tda18271[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x04 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x01 }, - { 0x9be3, 0, 8, 0x01 }, - { 0xd1a0, 1, 1, 0x00 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x18 }, - { 0x9bff, 0, 8, 0x2c }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0xdf }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x44 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x00 }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0xf6 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bba, 0, 8, 0xf9 }, - { 0x9bc8, 0, 8, 0xaa }, - { 0x9bc3, 0, 8, 0xdf }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x00 }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bc9, 0, 8, 0xf0 }, - { 0xd011, 0, 8, 0x3c }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0xf7 }, - { 0xd014, 0, 2, 0x02 }, - { 0xd040, 0, 8, 0x0b }, - { 0xd041, 0, 2, 0x02 }, - { 0xd042, 0, 8, 0x4d }, - { 0xd043, 0, 2, 0x00 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0xa8 }, - { 0x9be4, 0, 8, 0x7f }, - { 0x9bbd, 0, 8, 0xa8 }, - { 0x9be2, 0, 8, 0x20 }, - { 0x9bee, 0, 1, 0x01 }, -}; - -#endif /* _AF9013_PRIV_ */ diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb/frontends/au8522.h deleted file mode 100644 index 565dcf31af5..00000000000 --- a/drivers/media/dvb/frontends/au8522.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - Auvitek AU8522 QAM/8VSB demodulator driver - - Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> - - 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 __AU8522_H__ -#define __AU8522_H__ - -#include <linux/dvb/frontend.h> - -enum au8522_if_freq { - AU8522_IF_6MHZ = 0, - AU8522_IF_4MHZ, - AU8522_IF_3_25MHZ, -}; - -struct au8522_led_config { - u16 vsb8_strong; - u16 qam64_strong; - u16 qam256_strong; - - u16 gpio_output; - /* unset hi bits, set low bits */ - u16 gpio_output_enable; - u16 gpio_output_disable; - - u16 gpio_leds; - u8 *led_states; - unsigned int num_led_states; -}; - -struct au8522_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* Return lock status based on tuner lock, or demod lock */ -#define AU8522_TUNERLOCKING 0 -#define AU8522_DEMODLOCKING 1 - u8 status_mode; - - struct au8522_led_config *led_cfg; - - enum au8522_if_freq vsb_if; - enum au8522_if_freq qam_if; -}; - -#if defined(CONFIG_DVB_AU8522) || \ - (defined(CONFIG_DVB_AU8522_MODULE) && defined(MODULE)) -extern struct dvb_frontend *au8522_attach(const struct au8522_config *config, - struct i2c_adapter *i2c); -#else -static inline -struct dvb_frontend *au8522_attach(const struct au8522_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#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__ */ - -/* - * Local variables: - * c-basic-offset: 8 - */ diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c deleted file mode 100644 index 9e9a75576a1..00000000000 --- a/drivers/media/dvb/frontends/au8522_decoder.c +++ /dev/null @@ -1,835 +0,0 @@ -/* - * Auvitek AU8522 QAM/8VSB demodulator driver and video decoder - * - * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org> - * 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 <linux/kernel.h> -#include <linux/slab.h> -#include <linux/videodev2.h> -#include <linux/i2c.h> -#include <linux/delay.h> -#include <media/v4l2-common.h> -#include <media/v4l2-chip-ident.h> -#include <media/v4l2-i2c-drv.h> -#include <media/v4l2-device.h> -#include "au8522.h" -#include "au8522_priv.h" - -MODULE_AUTHOR("Devin Heitmueller"); -MODULE_LICENSE("GPL"); - -static int au8522_analog_debug; - - -module_param_named(analog_debug, au8522_analog_debug, int, 0644); - -MODULE_PARM_DESC(analog_debug, - "Analog debugging messages [0=Off (default) 1=On]"); - -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(KERN_ERR "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; - } - - qc->type = 0; - 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, - u32 input, u32 output, u32 config) -{ - 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 (input == AU8522_COMPOSITE_CH1) { - au8522_setup_cvbs_mode(state); - } else if (input == AU8522_SVIDEO_CH13) { - au8522_setup_svideo_mode(state); - } else if (input == AU8522_COMPOSITE_CH4_SIF) { - au8522_setup_cvbs_tuner_mode(state); - } else { - printk(KERN_ERR "au8522 mode not currently supported\n"); - return -EINVAL; - } - return 0; -} - -static int au8522_s_audio_routing(struct v4l2_subdev *sd, - u32 input, u32 output, u32 config) -{ - struct au8522_state *state = to_state(sd); - set_audio_input(state, 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 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(KERN_ERR "au8522_decoder allocation failed\n"); - return -EIO; - case 1: - /* new demod instance */ - printk(KERN_INFO "au8522_decoder creating new instance...\n"); - break; - default: - /* existing demod instance */ - printk(KERN_INFO "au8522_decoder attach 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", - .probe = au8522_probe, - .remove = au8522_remove, - .id_table = au8522_id, -}; diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c deleted file mode 100644 index 35731258bb0..00000000000 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ /dev/null @@ -1,902 +0,0 @@ -/* - Auvitek AU8522 QAM/8VSB demodulator driver - - Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> - - 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 <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "au8522.h" -#include "au8522_priv.h" - -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)\ - 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 }; - - 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; -} - -u8 au8522_readreg(struct au8522_state *state, u16 reg) -{ - int ret; - u8 b0[] = { (reg >> 8) | 0x40, 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. */ -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; -} - -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); - - /* Power down the chip */ - au8522_writereg(state, 0xa4, 1 << 5); - - 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 struct dvb_frontend_ops au8522_ops; - -int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, - u8 client_address) -{ - 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); -} - - -static void au8522_release(struct dvb_frontend *fe) -{ - struct au8522_state *state = fe->demodulator_priv; - au8522_release_state(state); -} - -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 */ - 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; - 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: - au8522_release_state(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_priv.h b/drivers/media/dvb/frontends/au8522_priv.h deleted file mode 100644 index f328f2b3ad3..00000000000 --- a/drivers/media/dvb/frontends/au8522_priv.h +++ /dev/null @@ -1,412 +0,0 @@ -/* - Auvitek AU8522 QAM/8VSB demodulator driver - - Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> - Copyright (C) 2008 Devin Heitmueller <dheitmueller@linuxtv.org> - 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 <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/videodev2.h> -#include <media/v4l2-device.h> -#include <linux/i2c.h> -#include "dvb_frontend.h" -#include "au8522.h" -#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 */ - struct tuner_i2c_props i2c_props; - struct list_head hybrid_tuner_instance_list; - - /* 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; - - /* 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 - 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); - -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 diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c deleted file mode 100644 index cf5e576dfdc..00000000000 --- a/drivers/media/dvb/frontends/bcm3510.c +++ /dev/null @@ -1,854 +0,0 @@ -/* - * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC) - * - * Copyright (C) 2001-5, B2C2 inc. - * - * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de> - * - * This driver is "hard-coded" to be used with the 1st generation of - * Technisat/B2C2's Air2PC ATSC PCI/USB cards/boxes. The pll-programming - * (Panasonic CT10S) is located here, which is actually wrong. Unless there is - * another device with a BCM3510, this is no problem. - * - * The driver works also with QAM64 DVB-C, but had an unreasonable high - * UNC. (Tested with the Air2PC ATSC 1st generation) - * - * You'll need a firmware for this driver in order to get it running. It is - * called "dvb-fe-bcm3510-01.fw". - * - * 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 <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/firmware.h> -#include <linux/jiffies.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/mutex.h> - -#include "dvb_frontend.h" -#include "bcm3510.h" -#include "bcm3510_priv.h" - -struct bcm3510_state { - - struct i2c_adapter* i2c; - const struct bcm3510_config* config; - struct dvb_frontend frontend; - - /* demodulator private data */ - struct mutex hab_mutex; - u8 firmware_loaded:1; - - unsigned long next_status_check; - unsigned long status_check_interval; - struct bcm3510_hab_cmd_status1 status1; - struct bcm3510_hab_cmd_status2 status2; -}; - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c (|-able))."); - -#define dprintk(level,x...) if (level & debug) printk(x) -#define dbufout(b,l,m) {\ - int i; \ - for (i = 0; i < l; i++) \ - m("%02x ",b[i]); \ -} -#define deb_info(args...) dprintk(0x01,args) -#define deb_i2c(args...) dprintk(0x02,args) -#define deb_hab(args...) dprintk(0x04,args) - -/* transfer functions */ -static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len) -{ - u8 b[256]; - int err; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = len + 1 }; - - b[0] = reg; - memcpy(&b[1],buf,len); - - deb_i2c("i2c wr %02x: ",reg); - dbufout(buf,len,deb_i2c); - deb_i2c("\n"); - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - - deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n", - __func__, state->config->demod_address, reg, err); - return -EREMOTEIO; - } - - return 0; -} - -static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len) -{ - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, .buf = ®, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } - }; - int err; - - memset(buf,0,len); - - if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) { - deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n", - __func__, state->config->demod_address, reg, err); - return -EREMOTEIO; - } - deb_i2c("i2c rd %02x: ",reg); - dbufout(buf,len,deb_i2c); - deb_i2c("\n"); - - return 0; -} - -static int bcm3510_writeB(struct bcm3510_state *state, u8 reg, bcm3510_register_value v) -{ - return bcm3510_writebytes(state,reg,&v.raw,1); -} - -static int bcm3510_readB(struct bcm3510_state *state, u8 reg, bcm3510_register_value *v) -{ - return bcm3510_readbytes(state,reg,&v->raw,1); -} - -/* Host Access Buffer transfers */ -static int bcm3510_hab_get_response(struct bcm3510_state *st, u8 *buf, int len) -{ - bcm3510_register_value v; - int ret,i; - - v.HABADR_a6.HABADR = 0; - if ((ret = bcm3510_writeB(st,0xa6,v)) < 0) - return ret; - - for (i = 0; i < len; i++) { - if ((ret = bcm3510_readB(st,0xa7,&v)) < 0) - return ret; - buf[i] = v.HABDATA_a7; - } - return 0; -} - -static int bcm3510_hab_send_request(struct bcm3510_state *st, u8 *buf, int len) -{ - bcm3510_register_value v,hab; - int ret,i; - unsigned long t; - -/* Check if any previous HAB request still needs to be serviced by the - * Aquisition Processor before sending new request */ - if ((ret = bcm3510_readB(st,0xa8,&v)) < 0) - return ret; - if (v.HABSTAT_a8.HABR) { - deb_info("HAB is running already - clearing it.\n"); - v.HABSTAT_a8.HABR = 0; - bcm3510_writeB(st,0xa8,v); -// return -EBUSY; - } - -/* Send the start HAB Address (automatically incremented after write of - * HABDATA) and write the HAB Data */ - hab.HABADR_a6.HABADR = 0; - if ((ret = bcm3510_writeB(st,0xa6,hab)) < 0) - return ret; - - for (i = 0; i < len; i++) { - hab.HABDATA_a7 = buf[i]; - if ((ret = bcm3510_writeB(st,0xa7,hab)) < 0) - return ret; - } - -/* Set the HABR bit to indicate AP request in progress (LBHABR allows HABR to - * be written) */ - v.raw = 0; v.HABSTAT_a8.HABR = 1; v.HABSTAT_a8.LDHABR = 1; - if ((ret = bcm3510_writeB(st,0xa8,v)) < 0) - return ret; - -/* Polling method: Wait until the AP finishes processing the HAB request */ - t = jiffies + 1*HZ; - while (time_before(jiffies, t)) { - deb_info("waiting for HAB to complete\n"); - msleep(10); - if ((ret = bcm3510_readB(st,0xa8,&v)) < 0) - return ret; - - if (!v.HABSTAT_a8.HABR) - return 0; - } - - deb_info("send_request execution timed out.\n"); - return -ETIMEDOUT; -} - -static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *obuf, u8 olen, u8 *ibuf, u8 ilen) -{ - u8 ob[olen+2],ib[ilen+2]; - int ret = 0; - - ob[0] = cmd; - ob[1] = msgid; - memcpy(&ob[2],obuf,olen); - - deb_hab("hab snd: "); - dbufout(ob,olen+2,deb_hab); - deb_hab("\n"); - - if (mutex_lock_interruptible(&st->hab_mutex) < 0) - return -EAGAIN; - - if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 || - (ret = bcm3510_hab_get_response(st, ib, ilen+2)) < 0) - goto error; - - deb_hab("hab get: "); - dbufout(ib,ilen+2,deb_hab); - deb_hab("\n"); - - memcpy(ibuf,&ib[2],ilen); -error: - mutex_unlock(&st->hab_mutex); - return ret; -} - -#if 0 -/* not needed, we use a semaphore to prevent HAB races */ -static int bcm3510_is_ap_ready(struct bcm3510_state *st) -{ - bcm3510_register_value ap,hab; - int ret; - - if ((ret = bcm3510_readB(st,0xa8,&hab)) < 0 || - (ret = bcm3510_readB(st,0xa2,&ap) < 0)) - return ret; - - if (ap.APSTAT1_a2.RESET || ap.APSTAT1_a2.IDLE || ap.APSTAT1_a2.STOP || hab.HABSTAT_a8.HABR) { - deb_info("AP is busy\n"); - return -EBUSY; - } - - return 0; -} -#endif - -static int bcm3510_bert_reset(struct bcm3510_state *st) -{ - bcm3510_register_value b; - int ret; - - if ((ret = bcm3510_readB(st,0xfa,&b)) < 0) - return ret; - - b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); - b.BERCTL_fa.RESYNC = 1; bcm3510_writeB(st,0xfa,b); - b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); - b.BERCTL_fa.CNTCTL = 1; b.BERCTL_fa.BITCNT = 1; bcm3510_writeB(st,0xfa,b); - - /* clear residual bit counter TODO */ - return 0; -} - -static int bcm3510_refresh_state(struct bcm3510_state *st) -{ - if (time_after(jiffies,st->next_status_check)) { - bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS1, NULL,0, (u8 *)&st->status1, sizeof(st->status1)); - bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS2, NULL,0, (u8 *)&st->status2, sizeof(st->status2)); - st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000; - } - return 0; -} - -static int bcm3510_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct bcm3510_state* st = fe->demodulator_priv; - bcm3510_refresh_state(st); - - *status = 0; - if (st->status1.STATUS1.RECEIVER_LOCK) - *status |= FE_HAS_LOCK | FE_HAS_SYNC; - - if (st->status1.STATUS1.FEC_LOCK) - *status |= FE_HAS_VITERBI; - - if (st->status1.STATUS1.OUT_PLL_LOCK) - *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; - - if (*status & FE_HAS_LOCK) - st->status_check_interval = 1500; - else /* more frequently checks if no lock has been achieved yet */ - st->status_check_interval = 500; - - deb_info("real_status: %02x\n",*status); - return 0; -} - -static int bcm3510_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct bcm3510_state* st = fe->demodulator_priv; - bcm3510_refresh_state(st); - - *ber = (st->status2.LDBER0 << 16) | (st->status2.LDBER1 << 8) | st->status2.LDBER2; - return 0; -} - -static int bcm3510_read_unc(struct dvb_frontend* fe, u32* unc) -{ - struct bcm3510_state* st = fe->demodulator_priv; - bcm3510_refresh_state(st); - *unc = (st->status2.LDUERC0 << 8) | st->status2.LDUERC1; - return 0; -} - -static int bcm3510_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct bcm3510_state* st = fe->demodulator_priv; - s32 t; - - bcm3510_refresh_state(st); - t = st->status2.SIGNAL; - - if (t > 190) - t = 190; - if (t < 90) - t = 90; - - t -= 90; - t = t * 0xff / 100; - /* normalize if necessary */ - *strength = (t << 8) | t; - return 0; -} - -static int bcm3510_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct bcm3510_state* st = fe->demodulator_priv; - bcm3510_refresh_state(st); - - *snr = st->status1.SNR_EST0*1000 + ((st->status1.SNR_EST1*1000) >> 8); - return 0; -} - -/* tuner frontend programming */ -static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a) -{ - struct bcm3510_hab_cmd_tune c; - memset(&c,0,sizeof(struct bcm3510_hab_cmd_tune)); - -/* I2C Mode disabled, set 16 control / Data pairs */ - c.length = 0x10; - c.clock_width = 0; -/* CS1, CS0, DATA, CLK bits control the tuner RF_AGC_SEL pin is set to - * logic high (as Configuration) */ - c.misc = 0x10; -/* Set duration of the initial state of TUNCTL = 3.34 micro Sec */ - c.TUNCTL_state = 0x40; - -/* PRESCALER DEVIDE RATIO | BC1_2_3_4; (band switch), 1stosc REFERENCE COUNTER REF_S12 and REF_S11 */ - c.ctl_dat[0].ctrl.size = BITS_8; - c.ctl_dat[0].data = 0x80 | bc; - -/* Control DATA pin, 1stosc REFERENCE COUNTER REF_S10 to REF_S3 */ - c.ctl_dat[1].ctrl.size = BITS_8; - c.ctl_dat[1].data = 4; - -/* set CONTROL BIT 1 to 1, 1stosc REFERENCE COUNTER REF_S2 to REF_S1 */ - c.ctl_dat[2].ctrl.size = BITS_3; - c.ctl_dat[2].data = 0x20; - -/* control CS0 pin, pulse byte ? */ - c.ctl_dat[3].ctrl.size = BITS_3; - c.ctl_dat[3].ctrl.clk_off = 1; - c.ctl_dat[3].ctrl.cs0 = 1; - c.ctl_dat[3].data = 0x40; - -/* PGM_S18 to PGM_S11 */ - c.ctl_dat[4].ctrl.size = BITS_8; - c.ctl_dat[4].data = n >> 3; - -/* PGM_S10 to PGM_S8, SWL_S7 to SWL_S3 */ - c.ctl_dat[5].ctrl.size = BITS_8; - c.ctl_dat[5].data = ((n & 0x7) << 5) | (a >> 2); - -/* SWL_S2 and SWL_S1, set CONTROL BIT 2 to 0 */ - c.ctl_dat[6].ctrl.size = BITS_3; - c.ctl_dat[6].data = (a << 6) & 0xdf; - -/* control CS0 pin, pulse byte ? */ - c.ctl_dat[7].ctrl.size = BITS_3; - c.ctl_dat[7].ctrl.clk_off = 1; - c.ctl_dat[7].ctrl.cs0 = 1; - c.ctl_dat[7].data = 0x40; - -/* PRESCALER DEVIDE RATIO, 2ndosc REFERENCE COUNTER REF_S12 and REF_S11 */ - c.ctl_dat[8].ctrl.size = BITS_8; - c.ctl_dat[8].data = 0x80; - -/* 2ndosc REFERENCE COUNTER REF_S10 to REF_S3 */ - c.ctl_dat[9].ctrl.size = BITS_8; - c.ctl_dat[9].data = 0x10; - -/* set CONTROL BIT 1 to 1, 2ndosc REFERENCE COUNTER REF_S2 to REF_S1 */ - c.ctl_dat[10].ctrl.size = BITS_3; - c.ctl_dat[10].data = 0x20; - -/* pulse byte */ - c.ctl_dat[11].ctrl.size = BITS_3; - c.ctl_dat[11].ctrl.clk_off = 1; - c.ctl_dat[11].ctrl.cs1 = 1; - c.ctl_dat[11].data = 0x40; - -/* PGM_S18 to PGM_S11 */ - c.ctl_dat[12].ctrl.size = BITS_8; - c.ctl_dat[12].data = 0x2a; - -/* PGM_S10 to PGM_S8 and SWL_S7 to SWL_S3 */ - c.ctl_dat[13].ctrl.size = BITS_8; - c.ctl_dat[13].data = 0x8e; - -/* SWL_S2 and SWL_S1 and set CONTROL BIT 2 to 0 */ - c.ctl_dat[14].ctrl.size = BITS_3; - c.ctl_dat[14].data = 0; - -/* Pulse Byte */ - c.ctl_dat[15].ctrl.size = BITS_3; - c.ctl_dat[15].ctrl.clk_off = 1; - c.ctl_dat[15].ctrl.cs1 = 1; - c.ctl_dat[15].data = 0x40; - - return bcm3510_do_hab_cmd(st,CMD_TUNE, MSGID_TUNE,(u8 *) &c,sizeof(c), NULL, 0); -} - -static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq) -{ - u8 bc,a; - u16 n; - s32 YIntercept,Tfvco1; - - freq /= 1000; - - deb_info("%dkHz:",freq); - /* set Band Switch */ - if (freq <= 168000) - bc = 0x1c; - else if (freq <= 378000) - bc = 0x2c; - else - bc = 0x30; - - if (freq >= 470000) { - freq -= 470001; - YIntercept = 18805; - } else if (freq >= 90000) { - freq -= 90001; - YIntercept = 15005; - } else if (freq >= 76000){ - freq -= 76001; - YIntercept = 14865; - } else { - freq -= 54001; - YIntercept = 14645; - } - - Tfvco1 = (((freq/6000)*60 + YIntercept)*4)/10; - - n = Tfvco1 >> 6; - a = Tfvco1 & 0x3f; - - deb_info(" BC1_2_3_4: %x, N: %x A: %x\n", bc, n, a); - if (n >= 16 && n <= 2047) - return bcm3510_tuner_cmd(st,bc,n,a); - - return -EINVAL; -} - -static int bcm3510_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) -{ - struct bcm3510_state* st = fe->demodulator_priv; - struct bcm3510_hab_cmd_ext_acquire cmd; - struct bcm3510_hab_cmd_bert_control bert; - int ret; - - memset(&cmd,0,sizeof(cmd)); - switch (p->u.vsb.modulation) { - case QAM_256: - cmd.ACQUIRE0.MODE = 0x1; - cmd.ACQUIRE1.SYM_RATE = 0x1; - cmd.ACQUIRE1.IF_FREQ = 0x1; - break; - case QAM_64: - cmd.ACQUIRE0.MODE = 0x2; - cmd.ACQUIRE1.SYM_RATE = 0x2; - cmd.ACQUIRE1.IF_FREQ = 0x1; - break; -/* case QAM_256: - cmd.ACQUIRE0.MODE = 0x3; - break; - case QAM_128: - cmd.ACQUIRE0.MODE = 0x4; - break; - case QAM_64: - cmd.ACQUIRE0.MODE = 0x5; - break; - case QAM_32: - cmd.ACQUIRE0.MODE = 0x6; - break; - case QAM_16: - cmd.ACQUIRE0.MODE = 0x7; - break;*/ - case VSB_8: - cmd.ACQUIRE0.MODE = 0x8; - cmd.ACQUIRE1.SYM_RATE = 0x0; - cmd.ACQUIRE1.IF_FREQ = 0x0; - break; - case VSB_16: - cmd.ACQUIRE0.MODE = 0x9; - cmd.ACQUIRE1.SYM_RATE = 0x0; - cmd.ACQUIRE1.IF_FREQ = 0x0; - default: - return -EINVAL; - }; - cmd.ACQUIRE0.OFFSET = 0; - cmd.ACQUIRE0.NTSCSWEEP = 1; - cmd.ACQUIRE0.FA = 1; - cmd.ACQUIRE0.BW = 0; - -/* if (enableOffset) { - cmd.IF_OFFSET0 = xx; - cmd.IF_OFFSET1 = xx; - - cmd.SYM_OFFSET0 = xx; - cmd.SYM_OFFSET1 = xx; - if (enableNtscSweep) { - cmd.NTSC_OFFSET0; - cmd.NTSC_OFFSET1; - } - } */ - bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0); - -/* doing it with different MSGIDs, data book and source differs */ - bert.BE = 0; - bert.unused = 0; - bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0); - bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0); - - bcm3510_bert_reset(st); - - if ((ret = bcm3510_set_freq(st,p->frequency)) < 0) - return ret; - - memset(&st->status1,0,sizeof(st->status1)); - memset(&st->status2,0,sizeof(st->status2)); - st->status_check_interval = 500; - -/* Give the AP some time */ - msleep(200); - - return 0; -} - -static int bcm3510_sleep(struct dvb_frontend* fe) -{ - return 0; -} - -static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s) -{ - s->min_delay_ms = 1000; - s->step_size = 0; - s->max_drift = 0; - return 0; -} - -static void bcm3510_release(struct dvb_frontend* fe) -{ - struct bcm3510_state* state = fe->demodulator_priv; - kfree(state); -} - -/* firmware download: - * firmware file is build up like this: - * 16bit addr, 16bit length, 8byte of length - */ -#define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw" - -static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, const u8 *b, - u16 len) -{ - int ret = 0,i; - bcm3510_register_value vH, vL,vD; - - vH.MADRH_a9 = addr >> 8; - vL.MADRL_aa = addr; - if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret; - if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret; - - for (i = 0; i < len; i++) { - vD.MDATA_ab = b[i]; - if ((ret = bcm3510_writeB(st,0xab,vD)) < 0) - return ret; - } - - return 0; -} - -static int bcm3510_download_firmware(struct dvb_frontend* fe) -{ - struct bcm3510_state* st = fe->demodulator_priv; - const struct firmware *fw; - u16 addr,len; - const u8 *b; - int ret,i; - - deb_info("requesting firmware\n"); - if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) { - err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret); - return ret; - } - deb_info("got firmware: %zd\n",fw->size); - - b = fw->data; - for (i = 0; i < fw->size;) { - addr = le16_to_cpu( *( (u16 *)&b[i] ) ); - len = le16_to_cpu( *( (u16 *)&b[i+2] ) ); - deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size); - if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) { - err("firmware download failed: %d\n",ret); - return ret; - } - i += 4 + len; - } - release_firmware(fw); - deb_info("firmware download successfully completed\n"); - return 0; -} - -static int bcm3510_check_firmware_version(struct bcm3510_state *st) -{ - struct bcm3510_hab_cmd_get_version_info ver; - bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver)); - - deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n", - ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version); - - if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION && - ver.config_version == BCM3510_DEF_CONFIG_VERSION && - ver.demod_version == BCM3510_DEF_DEMOD_VERSION) - return 0; - - deb_info("version check failed\n"); - return -ENODEV; -} - -/* (un)resetting the AP */ -static int bcm3510_reset(struct bcm3510_state *st) -{ - int ret; - unsigned long t; - bcm3510_register_value v; - - bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1; - if ((ret = bcm3510_writeB(st,0xa0,v)) < 0) - return ret; - - t = jiffies + 3*HZ; - while (time_before(jiffies, t)) { - msleep(10); - if ((ret = bcm3510_readB(st,0xa2,&v)) < 0) - return ret; - - if (v.APSTAT1_a2.RESET) - return 0; - } - deb_info("reset timed out\n"); - return -ETIMEDOUT; -} - -static int bcm3510_clear_reset(struct bcm3510_state *st) -{ - bcm3510_register_value v; - int ret; - unsigned long t; - - v.raw = 0; - if ((ret = bcm3510_writeB(st,0xa0,v)) < 0) - return ret; - - t = jiffies + 3*HZ; - while (time_before(jiffies, t)) { - msleep(10); - if ((ret = bcm3510_readB(st,0xa2,&v)) < 0) - return ret; - - /* verify that reset is cleared */ - if (!v.APSTAT1_a2.RESET) - return 0; - } - deb_info("reset clear timed out\n"); - return -ETIMEDOUT; -} - -static int bcm3510_init_cold(struct bcm3510_state *st) -{ - int ret; - bcm3510_register_value v; - - /* read Acquisation Processor status register and check it is not in RUN mode */ - if ((ret = bcm3510_readB(st,0xa2,&v)) < 0) - return ret; - if (v.APSTAT1_a2.RUN) { - deb_info("AP is already running - firmware already loaded.\n"); - return 0; - } - - deb_info("reset?\n"); - if ((ret = bcm3510_reset(st)) < 0) - return ret; - - deb_info("tristate?\n"); - /* tri-state */ - v.TSTCTL_2e.CTL = 0; - if ((ret = bcm3510_writeB(st,0x2e,v)) < 0) - return ret; - - deb_info("firmware?\n"); - if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 || - (ret = bcm3510_clear_reset(st)) < 0) - return ret; - - /* anything left here to Let the acquisition processor begin execution at program counter 0000 ??? */ - - return 0; -} - -static int bcm3510_init(struct dvb_frontend* fe) -{ - struct bcm3510_state* st = fe->demodulator_priv; - bcm3510_register_value j; - struct bcm3510_hab_cmd_set_agc c; - int ret; - - if ((ret = bcm3510_readB(st,0xca,&j)) < 0) - return ret; - - deb_info("JDEC: %02x\n",j.raw); - - switch (j.JDEC_ca.JDEC) { - case JDEC_WAIT_AT_RAM: - deb_info("attempting to download firmware\n"); - if ((ret = bcm3510_init_cold(st)) < 0) - return ret; - case JDEC_EEPROM_LOAD_WAIT: /* fall-through is wanted */ - deb_info("firmware is loaded\n"); - bcm3510_check_firmware_version(st); - break; - default: - return -ENODEV; - } - - memset(&c,0,1); - c.SEL = 1; - bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0); - - return 0; -} - - -static struct dvb_frontend_ops bcm3510_ops; - -struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config, - struct i2c_adapter *i2c) -{ - struct bcm3510_state* state = NULL; - int ret; - bcm3510_register_value v; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct bcm3510_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - - state->config = config; - state->i2c = i2c; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - mutex_init(&state->hab_mutex); - - if ((ret = bcm3510_readB(state,0xe0,&v)) < 0) - goto error; - - deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER); - - if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) && /* cold */ - (v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0)) /* warm */ - goto error; - - info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER); - - bcm3510_reset(state); - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(bcm3510_attach); - -static struct dvb_frontend_ops bcm3510_ops = { - - .info = { - .name = "Broadcom BCM3510 VSB/QAM frontend", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 803000000, - /* stepsize is just a guess */ - .frequency_stepsize = 0, - .caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_8VSB | FE_CAN_16VSB | - FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 - }, - - .release = bcm3510_release, - - .init = bcm3510_init, - .sleep = bcm3510_sleep, - - .set_frontend = bcm3510_set_frontend, - .get_tune_settings = bcm3510_get_tune_settings, - - .read_status = bcm3510_read_status, - .read_ber = bcm3510_read_ber, - .read_signal_strength = bcm3510_read_signal_strength, - .read_snr = bcm3510_read_snr, - .read_ucblocks = bcm3510_read_unc, -}; - -MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver"); -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb/frontends/bcm3510.h deleted file mode 100644 index f4575c0cc44..00000000000 --- a/drivers/media/dvb/frontends/bcm3510.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC) - * - * Copyright (C) 2001-5, B2C2 inc. - * - * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de> - * - * 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 BCM3510_H -#define BCM3510_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -struct bcm3510_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* request firmware for device */ - int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); -}; - -#if defined(CONFIG_DVB_BCM3510) || (defined(CONFIG_DVB_BCM3510_MODULE) && defined(MODULE)) -extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_BCM3510 - -#endif diff --git a/drivers/media/dvb/frontends/bcm3510_priv.h b/drivers/media/dvb/frontends/bcm3510_priv.h deleted file mode 100644 index 3bb1bc2a04f..00000000000 --- a/drivers/media/dvb/frontends/bcm3510_priv.h +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC) - * - * Copyright (C) 2001-5, B2C2 inc. - * - * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de> - * - * 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 __BCM3510_PRIV_H__ -#define __BCM3510_PRIV_H__ - -#define PACKED __attribute__((packed)) - -#undef err -#define err(format, arg...) printk(KERN_ERR "bcm3510: " format "\n" , ## arg) -#undef info -#define info(format, arg...) printk(KERN_INFO "bcm3510: " format "\n" , ## arg) -#undef warn -#define warn(format, arg...) printk(KERN_WARNING "bcm3510: " format "\n" , ## arg) - - -#define PANASONIC_FIRST_IF_BASE_IN_KHz 1407500 -#define BCM3510_SYMBOL_RATE 5381000 - -typedef union { - u8 raw; - - struct { - u8 CTL :8; - } TSTCTL_2e; - - u8 LDCERC_4e; - u8 LDUERC_4f; - u8 LD_BER0_65; - u8 LD_BER1_66; - u8 LD_BER2_67; - u8 LD_BER3_68; - - struct { - u8 RESET :1; - u8 IDLE :1; - u8 STOP :1; - u8 HIRQ0 :1; - u8 HIRQ1 :1; - u8 na0 :1; - u8 HABAV :1; - u8 na1 :1; - } HCTL1_a0; - - struct { - u8 na0 :1; - u8 IDLMSK :1; - u8 STMSK :1; - u8 I0MSK :1; - u8 I1MSK :1; - u8 na1 :1; - u8 HABMSK :1; - u8 na2 :1; - } HCTLMSK_a1; - - struct { - u8 RESET :1; - u8 IDLE :1; - u8 STOP :1; - u8 RUN :1; - u8 HABAV :1; - u8 MEMAV :1; - u8 ALDONE :1; - u8 REIRQ :1; - } APSTAT1_a2; - - struct { - u8 RSTMSK :1; - u8 IMSK :1; - u8 SMSK :1; - u8 RMSK :1; - u8 HABMSK :1; - u8 MAVMSK :1; - u8 ALDMSK :1; - u8 REMSK :1; - } APMSK1_a3; - - u8 APSTAT2_a4; - u8 APMSK2_a5; - - struct { - u8 HABADR :7; - u8 na :1; - } HABADR_a6; - - u8 HABDATA_a7; - - struct { - u8 HABR :1; - u8 LDHABR :1; - u8 APMSK :1; - u8 HMSK :1; - u8 LDMSK :1; - u8 na :3; - } HABSTAT_a8; - - u8 MADRH_a9; - u8 MADRL_aa; - u8 MDATA_ab; - - struct { -#define JDEC_WAIT_AT_RAM 0x7 -#define JDEC_EEPROM_LOAD_WAIT 0x4 - u8 JDEC :3; - u8 na :5; - } JDEC_ca; - - struct { - u8 REV :4; - u8 LAYER :4; - } REVID_e0; - - struct { - u8 unk0 :1; - u8 CNTCTL :1; - u8 BITCNT :1; - u8 unk1 :1; - u8 RESYNC :1; - u8 unk2 :3; - } BERCTL_fa; - - struct { - u8 CSEL0 :1; - u8 CLKED0 :1; - u8 CSEL1 :1; - u8 CLKED1 :1; - u8 CLKLEV :1; - u8 SPIVAR :1; - u8 na :2; - } TUNSET_fc; - - struct { - u8 CLK :1; - u8 DATA :1; - u8 CS0 :1; - u8 CS1 :1; - u8 AGCSEL :1; - u8 na0 :1; - u8 TUNSEL :1; - u8 na1 :1; - } TUNCTL_fd; - - u8 TUNSEL0_fe; - u8 TUNSEL1_ff; - -} bcm3510_register_value; - -/* HAB commands */ - -/* version */ -#define CMD_GET_VERSION_INFO 0x3D -#define MSGID_GET_VERSION_INFO 0x15 -struct bcm3510_hab_cmd_get_version_info { - u8 microcode_version; - u8 script_version; - u8 config_version; - u8 demod_version; -} PACKED; - -#define BCM3510_DEF_MICROCODE_VERSION 0x0E -#define BCM3510_DEF_SCRIPT_VERSION 0x06 -#define BCM3510_DEF_CONFIG_VERSION 0x01 -#define BCM3510_DEF_DEMOD_VERSION 0xB1 - -/* acquire */ -#define CMD_ACQUIRE 0x38 - -#define MSGID_EXT_TUNER_ACQUIRE 0x0A -struct bcm3510_hab_cmd_ext_acquire { - struct { - u8 MODE :4; - u8 BW :1; - u8 FA :1; - u8 NTSCSWEEP :1; - u8 OFFSET :1; - } PACKED ACQUIRE0; /* control_byte */ - - struct { - u8 IF_FREQ :3; - u8 zero0 :1; - u8 SYM_RATE :3; - u8 zero1 :1; - } PACKED ACQUIRE1; /* sym_if */ - - u8 IF_OFFSET0; /* IF_Offset_10hz */ - u8 IF_OFFSET1; - u8 SYM_OFFSET0; /* SymbolRateOffset */ - u8 SYM_OFFSET1; - u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */ - u8 NTSC_OFFSET1; -} PACKED; - -#define MSGID_INT_TUNER_ACQUIRE 0x0B -struct bcm3510_hab_cmd_int_acquire { - struct { - u8 MODE :4; - u8 BW :1; - u8 FA :1; - u8 NTSCSWEEP :1; - u8 OFFSET :1; - } PACKED ACQUIRE0; /* control_byte */ - - struct { - u8 IF_FREQ :3; - u8 zero0 :1; - u8 SYM_RATE :3; - u8 zero1 :1; - } PACKED ACQUIRE1; /* sym_if */ - - u8 TUNER_FREQ0; - u8 TUNER_FREQ1; - u8 TUNER_FREQ2; - u8 TUNER_FREQ3; - u8 IF_OFFSET0; /* IF_Offset_10hz */ - u8 IF_OFFSET1; - u8 SYM_OFFSET0; /* SymbolRateOffset */ - u8 SYM_OFFSET1; - u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */ - u8 NTSC_OFFSET1; -} PACKED; - -/* modes */ -#define BCM3510_QAM16 = 0x01 -#define BCM3510_QAM32 = 0x02 -#define BCM3510_QAM64 = 0x03 -#define BCM3510_QAM128 = 0x04 -#define BCM3510_QAM256 = 0x05 -#define BCM3510_8VSB = 0x0B -#define BCM3510_16VSB = 0x0D - -/* IF_FREQS */ -#define BCM3510_IF_TERRESTRIAL 0x0 -#define BCM3510_IF_CABLE 0x1 -#define BCM3510_IF_USE_CMD 0x7 - -/* SYM_RATE */ -#define BCM3510_SR_8VSB 0x0 /* 5381119 s/sec */ -#define BCM3510_SR_256QAM 0x1 /* 5360537 s/sec */ -#define BCM3510_SR_16QAM 0x2 /* 5056971 s/sec */ -#define BCM3510_SR_MISC 0x3 /* 5000000 s/sec */ -#define BCM3510_SR_USE_CMD 0x7 - -/* special symbol rate */ -#define CMD_SET_VALUE_NOT_LISTED 0x2d -#define MSGID_SET_SYMBOL_RATE_NOT_LISTED 0x0c -struct bcm3510_hab_cmd_set_sr_not_listed { - u8 HOST_SYM_RATE0; - u8 HOST_SYM_RATE1; - u8 HOST_SYM_RATE2; - u8 HOST_SYM_RATE3; -} PACKED; - -/* special IF */ -#define MSGID_SET_IF_FREQ_NOT_LISTED 0x0d -struct bcm3510_hab_cmd_set_if_freq_not_listed { - u8 HOST_IF_FREQ0; - u8 HOST_IF_FREQ1; - u8 HOST_IF_FREQ2; - u8 HOST_IF_FREQ3; -} PACKED; - -/* auto reacquire */ -#define CMD_AUTO_PARAM 0x2a -#define MSGID_AUTO_REACQUIRE 0x0e -struct bcm3510_hab_cmd_auto_reacquire { - u8 ACQ :1; /* on/off*/ - u8 unused :7; -} PACKED; - -#define MSGID_SET_RF_AGC_SEL 0x12 -struct bcm3510_hab_cmd_set_agc { - u8 LVL :1; - u8 unused :6; - u8 SEL :1; -} PACKED; - -#define MSGID_SET_AUTO_INVERSION 0x14 -struct bcm3510_hab_cmd_auto_inversion { - u8 AI :1; - u8 unused :7; -} PACKED; - - -/* bert control */ -#define CMD_STATE_CONTROL 0x12 -#define MSGID_BERT_CONTROL 0x0e -#define MSGID_BERT_SET 0xfa -struct bcm3510_hab_cmd_bert_control { - u8 BE :1; - u8 unused :7; -} PACKED; - -#define MSGID_TRI_STATE 0x2e -struct bcm3510_hab_cmd_tri_state { - u8 RE :1; /* a/d ram port pins */ - u8 PE :1; /* baud clock pin */ - u8 AC :1; /* a/d clock pin */ - u8 BE :1; /* baud clock pin */ - u8 unused :4; -} PACKED; - - -/* tune */ -#define CMD_TUNE 0x38 -#define MSGID_TUNE 0x16 -struct bcm3510_hab_cmd_tune_ctrl_data_pair { - struct { -#define BITS_8 0x07 -#define BITS_7 0x06 -#define BITS_6 0x05 -#define BITS_5 0x04 -#define BITS_4 0x03 -#define BITS_3 0x02 -#define BITS_2 0x01 -#define BITS_1 0x00 - u8 size :3; - u8 unk :2; - u8 clk_off :1; - u8 cs0 :1; - u8 cs1 :1; - - } PACKED ctrl; - - u8 data; -} PACKED; - -struct bcm3510_hab_cmd_tune { - u8 length; - u8 clock_width; - u8 misc; - u8 TUNCTL_state; - - struct bcm3510_hab_cmd_tune_ctrl_data_pair ctl_dat[16]; -} PACKED; - -#define CMD_STATUS 0x38 -#define MSGID_STATUS1 0x08 -struct bcm3510_hab_cmd_status1 { - struct { - u8 EQ_MODE :4; - u8 reserved :2; - u8 QRE :1; /* if QSE and the spectrum is inversed */ - u8 QSE :1; /* automatic spectral inversion */ - } PACKED STATUS0; - - struct { - u8 RECEIVER_LOCK :1; - u8 FEC_LOCK :1; - u8 OUT_PLL_LOCK :1; - u8 reserved :5; - } PACKED STATUS1; - - struct { - u8 reserved :2; - u8 BW :1; - u8 NTE :1; /* NTSC filter sweep enabled */ - u8 AQI :1; /* currently acquiring */ - u8 FA :1; /* fast acquisition */ - u8 ARI :1; /* auto reacquire */ - u8 TI :1; /* programming the tuner */ - } PACKED STATUS2; - u8 STATUS3; - u8 SNR_EST0; - u8 SNR_EST1; - u8 TUNER_FREQ0; - u8 TUNER_FREQ1; - u8 TUNER_FREQ2; - u8 TUNER_FREQ3; - u8 SYM_RATE0; - u8 SYM_RATE1; - u8 SYM_RATE2; - u8 SYM_RATE3; - u8 SYM_OFFSET0; - u8 SYM_OFFSET1; - u8 SYM_ERROR0; - u8 SYM_ERROR1; - u8 IF_FREQ0; - u8 IF_FREQ1; - u8 IF_FREQ2; - u8 IF_FREQ3; - u8 IF_OFFSET0; - u8 IF_OFFSET1; - u8 IF_ERROR0; - u8 IF_ERROR1; - u8 NTSC_FILTER0; - u8 NTSC_FILTER1; - u8 NTSC_FILTER2; - u8 NTSC_FILTER3; - u8 NTSC_OFFSET0; - u8 NTSC_OFFSET1; - u8 NTSC_ERROR0; - u8 NTSC_ERROR1; - u8 INT_AGC_LEVEL0; - u8 INT_AGC_LEVEL1; - u8 EXT_AGC_LEVEL0; - u8 EXT_AGC_LEVEL1; -} PACKED; - -#define MSGID_STATUS2 0x14 -struct bcm3510_hab_cmd_status2 { - struct { - u8 EQ_MODE :4; - u8 reserved :2; - u8 QRE :1; - u8 QSR :1; - } PACKED STATUS0; - struct { - u8 RL :1; - u8 FL :1; - u8 OL :1; - u8 reserved :5; - } PACKED STATUS1; - u8 SYMBOL_RATE0; - u8 SYMBOL_RATE1; - u8 SYMBOL_RATE2; - u8 SYMBOL_RATE3; - u8 LDCERC0; - u8 LDCERC1; - u8 LDCERC2; - u8 LDCERC3; - u8 LDUERC0; - u8 LDUERC1; - u8 LDUERC2; - u8 LDUERC3; - u8 LDBER0; - u8 LDBER1; - u8 LDBER2; - u8 LDBER3; - struct { - u8 MODE_TYPE :4; /* acquire mode 0 */ - u8 reservd :4; - } MODE_TYPE; - u8 SNR_EST0; - u8 SNR_EST1; - u8 SIGNAL; -} PACKED; - -#define CMD_SET_RF_BW_NOT_LISTED 0x3f -#define MSGID_SET_RF_BW_NOT_LISTED 0x11 -/* TODO */ - -#endif diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb/frontends/bsbe1.h deleted file mode 100644 index 5e431ebd089..00000000000 --- a/drivers/media/dvb/frontends/bsbe1.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * bsbe1.h - ALPS BSBE1 tuner support - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef BSBE1_H -#define BSBE1_H - -static u8 alps_bsbe1_inittab[] = { - 0x01, 0x15, /* XTAL = 4MHz, VCO = 352 MHz */ - 0x02, 0x30, /* MCLK = 88 MHz */ - 0x03, 0x00, /* ACR output 0 */ - 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x05, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x00, /* DAC output 0 */ - 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ - 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1/OP0 normal, val = 1 (LNB power on) */ - 0x0d, 0x82, /* DC offset compensation = on, beta_agc1 = 2 */ - 0x0f, 0x92, /* AGC1R */ - 0x10, 0x34, /* AGC2O */ - 0x11, 0x84, /* TLSR */ - 0x12, 0xb9, /* CFD */ - 0x15, 0xc9, /* lock detector threshold */ - 0x28, 0x00, /* out imp: normal, type: parallel, FEC mode: QPSK */ - 0x33, 0xfc, /* RS control */ - 0x34, 0x93, /* count viterbi bit errors per 2E18 bytes */ - 0xff, 0xff -}; - - -static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - - if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } - else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } - else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } - else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } - else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } - else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } - - stv0299_writereg(fe, 0x13, aclk); - stv0299_writereg(fe, 0x14, bclk); - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, (ratio ) & 0xf0); - - return 0; -} - -static int alps_bsbe1_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) -{ - int ret; - u8 data[4]; - u32 div; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - struct i2c_adapter *i2c = fe->tuner_priv; - - if ((params->frequency < 950000) || (params->frequency > 2150000)) - return -EINVAL; - - div = params->frequency / 1000; - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x80 | ((div & 0x18000) >> 10) | 0x1; - data[3] = 0xe0; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - ret = i2c_transfer(i2c, &msg, 1); - return (ret != 1) ? -EIO : 0; -} - -static struct stv0299_config alps_bsbe1_config = { - .demod_address = 0x68, - .inittab = alps_bsbe1_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .min_delay_ms = 100, - .set_symbol_rate = alps_bsbe1_set_symbol_rate, -}; - -#endif diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb/frontends/bsru6.h deleted file mode 100644 index 45a6dfd8ebb..00000000000 --- a/drivers/media/dvb/frontends/bsru6.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * bsru6.h - ALPS BSRU6 tuner support (moved from budget-ci.c) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef BSRU6_H -#define BSRU6_H - -static u8 alps_bsru6_inittab[] = { - 0x01, 0x15, - 0x02, 0x00, - 0x03, 0x00, - 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x40, /* DAC not used, set to high impendance mode */ - 0x07, 0x00, /* DAC LSB */ - 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ - 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ - 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ - 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ - 0x10, 0x3f, // AGC2 0x3d - 0x11, 0x84, - 0x12, 0xb9, - 0x15, 0xc9, // lock detector threshold - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 - 0x29, 0x1e, // 1/2 threshold - 0x2a, 0x14, // 2/3 threshold - 0x2b, 0x0f, // 3/4 threshold - 0x2c, 0x09, // 5/6 threshold - 0x2d, 0x05, // 7/8 threshold - 0x2e, 0x01, - 0x31, 0x1f, // test all FECs - 0x32, 0x19, // viterbi and synchro search - 0x33, 0xfc, // rs control - 0x34, 0x93, // error control - 0x0f, 0x52, - 0xff, 0xff -}; - -static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - - if (srate < 1500000) { - aclk = 0xb7; - bclk = 0x47; - } else if (srate < 3000000) { - aclk = 0xb7; - bclk = 0x4b; - } else if (srate < 7000000) { - aclk = 0xb7; - bclk = 0x4f; - } else if (srate < 14000000) { - aclk = 0xb7; - bclk = 0x53; - } else if (srate < 30000000) { - aclk = 0xb6; - bclk = 0x53; - } else if (srate < 45000000) { - aclk = 0xb4; - bclk = 0x51; - } - - stv0299_writereg(fe, 0x13, aclk); - stv0299_writereg(fe, 0x14, bclk); - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, ratio & 0xf0); - - return 0; -} - -static int alps_bsru6_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - u8 buf[4]; - u32 div; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - struct i2c_adapter *i2c = fe->tuner_priv; - - if ((params->frequency < 950000) || (params->frequency > 2150000)) - return -EINVAL; - - div = (params->frequency + (125 - 1)) / 125; // round correctly - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; - buf[3] = 0xC4; - - if (params->frequency > 1530000) - buf[3] = 0xc0; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(i2c, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct stv0299_config alps_bsru6_config = { - .demod_address = 0x68, - .inittab = alps_bsru6_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP1, - .min_delay_ms = 100, - .set_symbol_rate = alps_bsru6_set_symbol_rate, -}; - -#endif diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c deleted file mode 100644 index ace5cb17165..00000000000 --- a/drivers/media/dvb/frontends/cx22700.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - Conexant cx22700 DVB OFDM demodulator driver - - Copyright (C) 2001-2002 Convergence Integrated Media GmbH - Holger Waechtler <holger@convergence.de> - - 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 <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include "dvb_frontend.h" -#include "cx22700.h" - - -struct cx22700_state { - - struct i2c_adapter* i2c; - - const struct cx22700_config* config; - - struct dvb_frontend frontend; -}; - - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "cx22700: " args); \ - } while (0) - -static u8 init_tab [] = { - 0x04, 0x10, - 0x05, 0x09, - 0x06, 0x00, - 0x08, 0x04, - 0x09, 0x00, - 0x0a, 0x01, - 0x15, 0x40, - 0x16, 0x10, - 0x17, 0x87, - 0x18, 0x17, - 0x1a, 0x10, - 0x25, 0x04, - 0x2e, 0x00, - 0x39, 0x00, - 0x3a, 0x04, - 0x45, 0x08, - 0x46, 0x02, - 0x47, 0x05, -}; - - -static int cx22700_writereg (struct cx22700_state* state, u8 reg, u8 data) -{ - int ret; - u8 buf [] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - - dprintk ("%s\n", __func__); - - ret = i2c_transfer (state->i2c, &msg, 1); - - if (ret != 1) - printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", - __func__, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static int cx22700_readreg (struct cx22700_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - dprintk ("%s\n", __func__); - - ret = i2c_transfer (state->i2c, msg, 2); - - if (ret != 2) return -EIO; - - return b1[0]; -} - -static int cx22700_set_inversion (struct cx22700_state* state, int inversion) -{ - u8 val; - - dprintk ("%s\n", __func__); - - switch (inversion) { - case INVERSION_AUTO: - return -EOPNOTSUPP; - case INVERSION_ON: - val = cx22700_readreg (state, 0x09); - return cx22700_writereg (state, 0x09, val | 0x01); - case INVERSION_OFF: - val = cx22700_readreg (state, 0x09); - return cx22700_writereg (state, 0x09, val & 0xfe); - default: - return -EINVAL; - } -} - -static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_parameters *p) -{ - static const u8 qam_tab [4] = { 0, 1, 0, 2 }; - static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 }; - u8 val; - - dprintk ("%s\n", __func__); - - if (p->code_rate_HP < FEC_1_2 || p->code_rate_HP > FEC_7_8) - return -EINVAL; - - if (p->code_rate_LP < FEC_1_2 || p->code_rate_LP > FEC_7_8) - return -EINVAL; - - if (p->code_rate_HP == FEC_4_5 || p->code_rate_LP == FEC_4_5) - return -EINVAL; - - if (p->guard_interval < GUARD_INTERVAL_1_32 || - p->guard_interval > GUARD_INTERVAL_1_4) - return -EINVAL; - - if (p->transmission_mode != TRANSMISSION_MODE_2K && - p->transmission_mode != TRANSMISSION_MODE_8K) - return -EINVAL; - - if (p->constellation != QPSK && - p->constellation != QAM_16 && - p->constellation != QAM_64) - return -EINVAL; - - if (p->hierarchy_information < HIERARCHY_NONE || - p->hierarchy_information > HIERARCHY_4) - return -EINVAL; - - if (p->bandwidth < BANDWIDTH_8_MHZ && p->bandwidth > BANDWIDTH_6_MHZ) - return -EINVAL; - - if (p->bandwidth == BANDWIDTH_7_MHZ) - cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 | 0x10)); - else - cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 & ~0x10)); - - val = qam_tab[p->constellation - QPSK]; - val |= p->hierarchy_information - HIERARCHY_NONE; - - cx22700_writereg (state, 0x04, val); - - val = fec_tab[p->code_rate_HP - FEC_1_2] << 3; - val |= fec_tab[p->code_rate_LP - FEC_1_2]; - - cx22700_writereg (state, 0x05, val); - - val = (p->guard_interval - GUARD_INTERVAL_1_32) << 2; - val |= p->transmission_mode - TRANSMISSION_MODE_2K; - - cx22700_writereg (state, 0x06, val); - - cx22700_writereg (state, 0x08, 0x04 | 0x02); /* use user tps parameters */ - cx22700_writereg (state, 0x08, 0x04); /* restart aquisition */ - - return 0; -} - -static int cx22700_get_tps (struct cx22700_state* state, struct dvb_ofdm_parameters *p) -{ - static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 }; - static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4, - FEC_5_6, FEC_7_8 }; - u8 val; - - dprintk ("%s\n", __func__); - - if (!(cx22700_readreg(state, 0x07) & 0x20)) /* tps valid? */ - return -EAGAIN; - - val = cx22700_readreg (state, 0x01); - - if ((val & 0x7) > 4) - p->hierarchy_information = HIERARCHY_AUTO; - else - p->hierarchy_information = HIERARCHY_NONE + (val & 0x7); - - if (((val >> 3) & 0x3) > 2) - p->constellation = QAM_AUTO; - else - p->constellation = qam_tab[(val >> 3) & 0x3]; - - val = cx22700_readreg (state, 0x02); - - if (((val >> 3) & 0x07) > 4) - p->code_rate_HP = FEC_AUTO; - else - p->code_rate_HP = fec_tab[(val >> 3) & 0x07]; - - if ((val & 0x07) > 4) - p->code_rate_LP = FEC_AUTO; - else - p->code_rate_LP = fec_tab[val & 0x07]; - - val = cx22700_readreg (state, 0x03); - - p->guard_interval = GUARD_INTERVAL_1_32 + ((val >> 6) & 0x3); - p->transmission_mode = TRANSMISSION_MODE_2K + ((val >> 5) & 0x1); - - return 0; -} - -static int cx22700_init (struct dvb_frontend* fe) - -{ struct cx22700_state* state = fe->demodulator_priv; - int i; - - dprintk("cx22700_init: init chip\n"); - - cx22700_writereg (state, 0x00, 0x02); /* soft reset */ - cx22700_writereg (state, 0x00, 0x00); - - msleep(10); - - for (i=0; i<sizeof(init_tab); i+=2) - cx22700_writereg (state, init_tab[i], init_tab[i+1]); - - cx22700_writereg (state, 0x00, 0x01); - - return 0; -} - -static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct cx22700_state* state = fe->demodulator_priv; - - u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9) - | (cx22700_readreg (state, 0x0e) << 1); - u8 sync = cx22700_readreg (state, 0x07); - - *status = 0; - - if (rs_ber < 0xff00) - *status |= FE_HAS_SIGNAL; - - if (sync & 0x20) - *status |= FE_HAS_CARRIER; - - if (sync & 0x10) - *status |= FE_HAS_VITERBI; - - if (sync & 0x10) - *status |= FE_HAS_SYNC; - - if (*status == 0x0f) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct cx22700_state* state = fe->demodulator_priv; - - *ber = cx22700_readreg (state, 0x0c) & 0x7f; - cx22700_writereg (state, 0x0c, 0x00); - - return 0; -} - -static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) -{ - struct cx22700_state* state = fe->demodulator_priv; - - u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9) - | (cx22700_readreg (state, 0x0e) << 1); - *signal_strength = ~rs_ber; - - return 0; -} - -static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct cx22700_state* state = fe->demodulator_priv; - - u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9) - | (cx22700_readreg (state, 0x0e) << 1); - *snr = ~rs_ber; - - return 0; -} - -static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct cx22700_state* state = fe->demodulator_priv; - - *ucblocks = cx22700_readreg (state, 0x0f); - cx22700_writereg (state, 0x0f, 0x00); - - return 0; -} - -static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx22700_state* state = fe->demodulator_priv; - - cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/ - cx22700_writereg (state, 0x00, 0x00); - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - cx22700_set_inversion (state, p->inversion); - cx22700_set_tps (state, &p->u.ofdm); - cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */ - cx22700_writereg (state, 0x00, 0x01); /* restart acquire */ - - return 0; -} - -static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx22700_state* state = fe->demodulator_priv; - u8 reg09 = cx22700_readreg (state, 0x09); - - p->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF; - return cx22700_get_tps (state, &p->u.ofdm); -} - -static int cx22700_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct cx22700_state* state = fe->demodulator_priv; - - if (enable) { - return cx22700_writereg(state, 0x0a, 0x00); - } else { - return cx22700_writereg(state, 0x0a, 0x01); - } -} - -static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 150; - fesettings->step_size = 166667; - fesettings->max_drift = 166667*2; - return 0; -} - -static void cx22700_release(struct dvb_frontend* fe) -{ - struct cx22700_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops cx22700_ops; - -struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, - struct i2c_adapter* i2c) -{ - struct cx22700_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct cx22700_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* check if the demod is there */ - if (cx22700_readreg(state, 0x07) < 0) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx22700_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops cx22700_ops = { - - .info = { - .name = "Conexant CX22700 DVB-T", - .type = FE_OFDM, - .frequency_min = 470000000, - .frequency_max = 860000000, - .frequency_stepsize = 166667, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_RECOVER - }, - - .release = cx22700_release, - - .init = cx22700_init, - .i2c_gate_ctrl = cx22700_i2c_gate_ctrl, - - .set_frontend = cx22700_set_frontend, - .get_frontend = cx22700_get_frontend, - .get_tune_settings = cx22700_get_tune_settings, - - .read_status = cx22700_read_status, - .read_ber = cx22700_read_ber, - .read_signal_strength = cx22700_read_signal_strength, - .read_snr = cx22700_read_snr, - .read_ucblocks = cx22700_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Conexant CX22700 DVB-T Demodulator driver"); -MODULE_AUTHOR("Holger Waechtler"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(cx22700_attach); diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h deleted file mode 100644 index 4757a930ca0..00000000000 --- a/drivers/media/dvb/frontends/cx22700.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Conexant CX22700 DVB OFDM demodulator driver - - Copyright (C) 2001-2002 Convergence Integrated Media GmbH - Holger Waechtler <holger@convergence.de> - - 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 CX22700_H -#define CX22700_H - -#include <linux/dvb/frontend.h> - -struct cx22700_config -{ - /* the demodulator's i2c address */ - u8 demod_address; -}; - -#if defined(CONFIG_DVB_CX22700) || (defined(CONFIG_DVB_CX22700_MODULE) && defined(MODULE)) -extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_CX22700 - -#endif // CX22700_H diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c deleted file mode 100644 index 5d1abe34bdd..00000000000 --- a/drivers/media/dvb/frontends/cx22702.c +++ /dev/null @@ -1,641 +0,0 @@ -/* - Conexant 22702 DVB OFDM demodulator driver - - based on: - Alps TDMB7 DVB OFDM demodulator driver - - Copyright (C) 2001-2002 Convergence Integrated Media GmbH - Holger Waechtler <holger@convergence.de> - - Copyright (C) 2004 Steven Toth <stoth@linuxtv.org> - - 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 <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "cx22702.h" - -struct cx22702_state { - - struct i2c_adapter *i2c; - - /* configuration settings */ - const struct cx22702_config *config; - - struct dvb_frontend frontend; - - /* previous uncorrected block counter */ - u8 prevUCBlocks; -}; - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - -#define dprintk if (debug) printk - -/* Register values to initialise the demod */ -static u8 init_tab[] = { - 0x00, 0x00, /* Stop aquisition */ - 0x0B, 0x06, - 0x09, 0x01, - 0x0D, 0x41, - 0x16, 0x32, - 0x20, 0x0A, - 0x21, 0x17, - 0x24, 0x3e, - 0x26, 0xff, - 0x27, 0x10, - 0x28, 0x00, - 0x29, 0x00, - 0x2a, 0x10, - 0x2b, 0x00, - 0x2c, 0x10, - 0x2d, 0x00, - 0x48, 0xd4, - 0x49, 0x56, - 0x6b, 0x1e, - 0xc8, 0x02, - 0xf9, 0x00, - 0xfa, 0x00, - 0xfb, 0x00, - 0xfc, 0x00, - 0xfd, 0x00, -}; - -static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { - .addr = state->config->demod_address, .flags = 0, - .buf = buf, .len = 2 }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - printk(KERN_ERR - "%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", - __func__, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static u8 cx22702_readreg(struct cx22702_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, - .buf = b0, .len = 1 }, - { .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 cx22702_set_inversion(struct cx22702_state *state, int inversion) -{ - u8 val; - - switch (inversion) { - case INVERSION_AUTO: - return -EOPNOTSUPP; - case INVERSION_ON: - val = cx22702_readreg(state, 0x0C); - return cx22702_writereg(state, 0x0C, val | 0x01); - case INVERSION_OFF: - val = cx22702_readreg(state, 0x0C); - return cx22702_writereg(state, 0x0C, val & 0xfe); - default: - return -EINVAL; - } - -} - -/* Retrieve the demod settings */ -static int cx22702_get_tps(struct cx22702_state *state, - struct dvb_ofdm_parameters *p) -{ - u8 val; - - /* Make sure the TPS regs are valid */ - if (!(cx22702_readreg(state, 0x0A) & 0x20)) - return -EAGAIN; - - val = cx22702_readreg(state, 0x01); - switch ((val & 0x18) >> 3) { - case 0: - p->constellation = QPSK; - break; - case 1: - p->constellation = QAM_16; - break; - case 2: - p->constellation = QAM_64; - break; - } - switch (val & 0x07) { - case 0: - p->hierarchy_information = HIERARCHY_NONE; - break; - case 1: - p->hierarchy_information = HIERARCHY_1; - break; - case 2: - p->hierarchy_information = HIERARCHY_2; - break; - case 3: - p->hierarchy_information = HIERARCHY_4; - break; - } - - - val = cx22702_readreg(state, 0x02); - switch ((val & 0x38) >> 3) { - case 0: - p->code_rate_HP = FEC_1_2; - break; - case 1: - p->code_rate_HP = FEC_2_3; - break; - case 2: - p->code_rate_HP = FEC_3_4; - break; - case 3: - p->code_rate_HP = FEC_5_6; - break; - case 4: - p->code_rate_HP = FEC_7_8; - break; - } - switch (val & 0x07) { - case 0: - p->code_rate_LP = FEC_1_2; - break; - case 1: - p->code_rate_LP = FEC_2_3; - break; - case 2: - p->code_rate_LP = FEC_3_4; - break; - case 3: - p->code_rate_LP = FEC_5_6; - break; - case 4: - p->code_rate_LP = FEC_7_8; - break; - } - - val = cx22702_readreg(state, 0x03); - switch ((val & 0x0c) >> 2) { - case 0: - p->guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - p->guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - p->guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - p->guard_interval = GUARD_INTERVAL_1_4; - break; - } - switch (val & 0x03) { - case 0: - p->transmission_mode = TRANSMISSION_MODE_2K; - break; - case 1: - p->transmission_mode = TRANSMISSION_MODE_8K; - break; - } - - return 0; -} - -static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct cx22702_state *state = fe->demodulator_priv; - dprintk("%s(%d)\n", __func__, enable); - if (enable) - return cx22702_writereg(state, 0x0D, - cx22702_readreg(state, 0x0D) & 0xfe); - else - return cx22702_writereg(state, 0x0D, - cx22702_readreg(state, 0x0D) | 1); -} - -/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int cx22702_set_tps(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - u8 val; - struct cx22702_state *state = fe->demodulator_priv; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* set inversion */ - cx22702_set_inversion(state, p->inversion); - - /* set bandwidth */ - switch (p->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20); - break; - case BANDWIDTH_7_MHZ: - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10); - break; - case BANDWIDTH_8_MHZ: - cx22702_writereg(state, 0x0C, - cx22702_readreg(state, 0x0C) & 0xcf); - break; - default: - dprintk("%s: invalid bandwidth\n", __func__); - return -EINVAL; - } - - p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */ - - /* use auto configuration? */ - if ((p->u.ofdm.hierarchy_information == HIERARCHY_AUTO) || - (p->u.ofdm.constellation == QAM_AUTO) || - (p->u.ofdm.code_rate_HP == FEC_AUTO) || - (p->u.ofdm.code_rate_LP == FEC_AUTO) || - (p->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO) || - (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO)) { - - /* TPS Source - use hardware driven values */ - cx22702_writereg(state, 0x06, 0x10); - cx22702_writereg(state, 0x07, 0x9); - cx22702_writereg(state, 0x08, 0xC1); - cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) - & 0xfc); - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40); - cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */ - dprintk("%s: Autodetecting\n", __func__); - return 0; - } - - /* manually programmed values */ - val = 0; - switch (p->u.ofdm.constellation) { - case QPSK: - val = (val & 0xe7); - break; - case QAM_16: - val = (val & 0xe7) | 0x08; - break; - case QAM_64: - val = (val & 0xe7) | 0x10; - break; - default: - dprintk("%s: invalid constellation\n", __func__); - return -EINVAL; - } - switch (p->u.ofdm.hierarchy_information) { - case HIERARCHY_NONE: - val = (val & 0xf8); - break; - case HIERARCHY_1: - val = (val & 0xf8) | 1; - break; - case HIERARCHY_2: - val = (val & 0xf8) | 2; - break; - case HIERARCHY_4: - val = (val & 0xf8) | 3; - break; - default: - dprintk("%s: invalid hierarchy\n", __func__); - return -EINVAL; - } - cx22702_writereg(state, 0x06, val); - - val = 0; - switch (p->u.ofdm.code_rate_HP) { - case FEC_NONE: - case FEC_1_2: - val = (val & 0xc7); - break; - case FEC_2_3: - val = (val & 0xc7) | 0x08; - break; - case FEC_3_4: - val = (val & 0xc7) | 0x10; - break; - case FEC_5_6: - val = (val & 0xc7) | 0x18; - break; - case FEC_7_8: - val = (val & 0xc7) | 0x20; - break; - default: - dprintk("%s: invalid code_rate_HP\n", __func__); - return -EINVAL; - } - switch (p->u.ofdm.code_rate_LP) { - case FEC_NONE: - case FEC_1_2: - val = (val & 0xf8); - break; - case FEC_2_3: - val = (val & 0xf8) | 1; - break; - case FEC_3_4: - val = (val & 0xf8) | 2; - break; - case FEC_5_6: - val = (val & 0xf8) | 3; - break; - case FEC_7_8: - val = (val & 0xf8) | 4; - break; - default: - dprintk("%s: invalid code_rate_LP\n", __func__); - return -EINVAL; - } - cx22702_writereg(state, 0x07, val); - - val = 0; - switch (p->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_32: - val = (val & 0xf3); - break; - case GUARD_INTERVAL_1_16: - val = (val & 0xf3) | 0x04; - break; - case GUARD_INTERVAL_1_8: - val = (val & 0xf3) | 0x08; - break; - case GUARD_INTERVAL_1_4: - val = (val & 0xf3) | 0x0c; - break; - default: - dprintk("%s: invalid guard_interval\n", __func__); - return -EINVAL; - } - switch (p->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: - val = (val & 0xfc); - break; - case TRANSMISSION_MODE_8K: - val = (val & 0xfc) | 1; - break; - default: - dprintk("%s: invalid transmission_mode\n", __func__); - return -EINVAL; - } - cx22702_writereg(state, 0x08, val); - cx22702_writereg(state, 0x0B, - (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02); - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40); - - /* Begin channel aquisition */ - cx22702_writereg(state, 0x00, 0x01); - - return 0; -} - -/* Reset the demod hardware and reset all of the configuration registers - to a default state. */ -static int cx22702_init(struct dvb_frontend *fe) -{ - int i; - struct cx22702_state *state = fe->demodulator_priv; - - cx22702_writereg(state, 0x00, 0x02); - - msleep(10); - - for (i = 0; i < ARRAY_SIZE(init_tab); i += 2) - cx22702_writereg(state, init_tab[i], init_tab[i + 1]); - - cx22702_writereg(state, 0xf8, (state->config->output_mode << 1) - & 0x02); - - cx22702_i2c_gate_ctrl(fe, 0); - - return 0; -} - -static int cx22702_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct cx22702_state *state = fe->demodulator_priv; - u8 reg0A; - u8 reg23; - - *status = 0; - - reg0A = cx22702_readreg(state, 0x0A); - reg23 = cx22702_readreg(state, 0x23); - - dprintk("%s: status demod=0x%02x agc=0x%02x\n" - , __func__, reg0A, reg23); - - if (reg0A & 0x10) { - *status |= FE_HAS_LOCK; - *status |= FE_HAS_VITERBI; - *status |= FE_HAS_SYNC; - } - - if (reg0A & 0x20) - *status |= FE_HAS_CARRIER; - - if (reg23 < 0xf0) - *status |= FE_HAS_SIGNAL; - - return 0; -} - -static int cx22702_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct cx22702_state *state = fe->demodulator_priv; - - if (cx22702_readreg(state, 0xE4) & 0x02) { - /* Realtime statistics */ - *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 - | (cx22702_readreg(state, 0xDF) & 0x7F); - } else { - /* Averagtine statistics */ - *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 - | cx22702_readreg(state, 0xDF); - } - - return 0; -} - -static int cx22702_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - struct cx22702_state *state = fe->demodulator_priv; - - u16 rs_ber = 0; - rs_ber = cx22702_readreg(state, 0x23); - *signal_strength = (rs_ber << 8) | rs_ber; - - return 0; -} - -static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct cx22702_state *state = fe->demodulator_priv; - - u16 rs_ber = 0; - if (cx22702_readreg(state, 0xE4) & 0x02) { - /* Realtime statistics */ - rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 - | (cx22702_readreg(state, 0xDF) & 0x7F); - } else { - /* Averagine statistics */ - rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 8 - | cx22702_readreg(state, 0xDF); - } - *snr = ~rs_ber; - - return 0; -} - -static int cx22702_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct cx22702_state *state = fe->demodulator_priv; - - u8 _ucblocks; - - /* RS Uncorrectable Packet Count then reset */ - _ucblocks = cx22702_readreg(state, 0xE3); - if (state->prevUCBlocks < _ucblocks) - *ucblocks = (_ucblocks - state->prevUCBlocks); - else - *ucblocks = state->prevUCBlocks - _ucblocks; - state->prevUCBlocks = _ucblocks; - - return 0; -} - -static int cx22702_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx22702_state *state = fe->demodulator_priv; - - u8 reg0C = cx22702_readreg(state, 0x0C); - - p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF; - return cx22702_get_tps(state, &p->u.ofdm); -} - -static int cx22702_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void cx22702_release(struct dvb_frontend *fe) -{ - struct cx22702_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops cx22702_ops; - -struct dvb_frontend *cx22702_attach(const struct cx22702_config *config, - struct i2c_adapter *i2c) -{ - struct cx22702_state *state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->prevUCBlocks = 0; - - /* check if the demod is there */ - if (cx22702_readreg(state, 0x1f) != 0x3) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx22702_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(cx22702_attach); - -static struct dvb_frontend_ops cx22702_ops = { - - .info = { - .name = "Conexant CX22702 DVB-T", - .type = FE_OFDM, - .frequency_min = 177000000, - .frequency_max = 858000000, - .frequency_stepsize = 166666, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER - }, - - .release = cx22702_release, - - .init = cx22702_init, - .i2c_gate_ctrl = cx22702_i2c_gate_ctrl, - - .set_frontend = cx22702_set_tps, - .get_frontend = cx22702_get_frontend, - .get_tune_settings = cx22702_get_tune_settings, - - .read_status = cx22702_read_status, - .read_ber = cx22702_read_ber, - .read_signal_strength = cx22702_read_signal_strength, - .read_snr = cx22702_read_snr, - .read_ucblocks = cx22702_read_ucblocks, -}; - -MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h deleted file mode 100644 index f154e1f428e..00000000000 --- a/drivers/media/dvb/frontends/cx22702.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Conexant 22702 DVB OFDM demodulator driver - - based on: - Alps TDMB7 DVB OFDM demodulator driver - - Copyright (C) 2001-2002 Convergence Integrated Media GmbH - Holger Waechtler <holger@convergence.de> - - Copyright (C) 2004 Steven Toth <stoth@linuxtv.org> - - 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 CX22702_H -#define CX22702_H - -#include <linux/dvb/frontend.h> - -struct cx22702_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* serial/parallel output */ -#define CX22702_PARALLEL_OUTPUT 0 -#define CX22702_SERIAL_OUTPUT 1 - u8 output_mode; -}; - -#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) \ - && defined(MODULE)) -extern struct dvb_frontend *cx22702_attach( - const struct cx22702_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *cx22702_attach( - const struct cx22702_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c deleted file mode 100644 index 87ae29db024..00000000000 --- a/drivers/media/dvb/frontends/cx24110.c +++ /dev/null @@ -1,667 +0,0 @@ - /* - cx24110 - Single Chip Satellite Channel Receiver driver module - - Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on - work - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - - 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 <linux/slab.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> - -#include "dvb_frontend.h" -#include "cx24110.h" - - -struct cx24110_state { - - struct i2c_adapter* i2c; - - const struct cx24110_config* config; - - struct dvb_frontend frontend; - - u32 lastber; - u32 lastbler; - u32 lastesn0; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "cx24110: " args); \ - } while (0) - -static struct {u8 reg; u8 data;} cx24110_regdata[]= - /* Comments beginning with @ denote this value should - be the default */ - {{0x09,0x01}, /* SoftResetAll */ - {0x09,0x00}, /* release reset */ - {0x01,0xe8}, /* MSB of code rate 27.5MS/s */ - {0x02,0x17}, /* middle byte " */ - {0x03,0x29}, /* LSB " */ - {0x05,0x03}, /* @ DVB mode, standard code rate 3/4 */ - {0x06,0xa5}, /* @ PLL 60MHz */ - {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */ - {0x0a,0x00}, /* @ partial chip disables, do not set */ - {0x0b,0x01}, /* set output clock in gapped mode, start signal low - active for first byte */ - {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */ - {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */ - {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1 - to avoid starting the BER counter. Reset the - CRC test bit. Finite counting selected */ - {0x15,0xff}, /* @ size of the limited time window for RS BER - estimation. It is <value>*256 RS blocks, this - gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ - {0x16,0x00}, /* @ enable all RS output ports */ - {0x17,0x04}, /* @ time window allowed for the RS to sync */ - {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned - for automatically */ - /* leave the current code rate and normalization - registers as they are after reset... */ - {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting - only once */ - {0x23,0x18}, /* @ size of the limited time window for Viterbi BER - estimation. It is <value>*65536 channel bits, i.e. - approx. 38ms at 27.5MS/s, rate 3/4 */ - {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */ - /* leave front-end AGC parameters at default values */ - /* leave decimation AGC parameters at default values */ - {0x35,0x40}, /* disable all interrupts. They are not connected anyway */ - {0x36,0xff}, /* clear all interrupt pending flags */ - {0x37,0x00}, /* @ fully enable AutoAcqq state machine */ - {0x38,0x07}, /* @ enable fade recovery, but not autostart AutoAcq */ - /* leave the equalizer parameters on their default values */ - /* leave the final AGC parameters on their default values */ - {0x41,0x00}, /* @ MSB of front-end derotator frequency */ - {0x42,0x00}, /* @ middle bytes " */ - {0x43,0x00}, /* @ LSB " */ - /* leave the carrier tracking loop parameters on default */ - /* leave the bit timing loop parameters at gefault */ - {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */ - /* the cx24108 data sheet for symbol rates above 15MS/s */ - {0x57,0x00}, /* @ Filter sigma delta enabled, positive */ - {0x61,0x95}, /* GPIO pins 1-4 have special function */ - {0x62,0x05}, /* GPIO pin 5 has special function, pin 6 is GPIO */ - {0x63,0x00}, /* All GPIO pins use CMOS output characteristics */ - {0x64,0x20}, /* GPIO 6 is input, all others are outputs */ - {0x6d,0x30}, /* tuner auto mode clock freq 62kHz */ - {0x70,0x15}, /* use auto mode, tuner word is 21 bits long */ - {0x73,0x00}, /* @ disable several demod bypasses */ - {0x74,0x00}, /* @ " */ - {0x75,0x00} /* @ " */ - /* the remaining registers are for SEC */ - }; - - -static int cx24110_writereg (struct cx24110_state* state, int reg, int data) -{ - u8 buf [] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - int err; - - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - dprintk ("%s: writereg error (err == %i, reg == 0x%02x," - " data == 0x%02x)\n", __func__, err, reg, data); - return -EREMOTEIO; - } - - return 0; -} - -static int cx24110_readreg (struct cx24110_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) return ret; - - return b1[0]; -} - -static int cx24110_set_inversion (struct cx24110_state* state, fe_spectral_inversion_t inversion) -{ -/* fixme (low): error handling */ - - switch (inversion) { - case INVERSION_OFF: - cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1); - /* AcqSpectrInvDis on. No idea why someone should want this */ - cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)&0xf7); - /* Initial value 0 at start of acq */ - cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)&0xef); - /* current value 0 */ - /* The cx24110 manual tells us this reg is read-only. - But what the heck... set it ayways */ - break; - case INVERSION_ON: - cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1); - /* AcqSpectrInvDis on. No idea why someone should want this */ - cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)|0x08); - /* Initial value 1 at start of acq */ - cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)|0x10); - /* current value 1 */ - break; - case INVERSION_AUTO: - cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xfe); - /* AcqSpectrInvDis off. Leave initial & current states as is */ - break; - default: - return -EINVAL; - } - - return 0; -} - -static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec) -{ -/* fixme (low): error handling */ - - static const int rate[]={-1,1,2,3,5,7,-1}; - static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1}; - static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1}; - - /* Well, the AutoAcq engine of the cx24106 and 24110 automatically - searches all enabled viterbi rates, and can handle non-standard - rates as well. */ - - if (fec>FEC_AUTO) - fec=FEC_AUTO; - - if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */ - cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xdf); - /* clear AcqVitDis bit */ - cx24110_writereg(state,0x18,0xae); - /* allow all DVB standard code rates */ - cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|0x3); - /* set nominal Viterbi rate 3/4 */ - cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|0x3); - /* set current Viterbi rate 3/4 */ - cx24110_writereg(state,0x1a,0x05); cx24110_writereg(state,0x1b,0x06); - /* set the puncture registers for code rate 3/4 */ - return 0; - } else { - cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x20); - /* set AcqVitDis bit */ - if(rate[fec]>0) { - cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|rate[fec]); - /* set nominal Viterbi rate */ - cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|rate[fec]); - /* set current Viterbi rate */ - cx24110_writereg(state,0x1a,g1[fec]); - cx24110_writereg(state,0x1b,g2[fec]); - /* not sure if this is the right way: I always used AutoAcq mode */ - } else - return -EOPNOTSUPP; -/* fixme (low): which is the correct return code? */ - }; - return 0; -} - -static fe_code_rate_t cx24110_get_fec (struct cx24110_state* state) -{ - int i; - - i=cx24110_readreg(state,0x22)&0x0f; - if(!(i&0x08)) { - return FEC_1_2 + i - 1; - } else { -/* fixme (low): a special code rate has been selected. In theory, we need to - return a denominator value, a numerator value, and a pair of puncture - maps to correctly describe this mode. But this should never happen in - practice, because it cannot be set by cx24110_get_fec. */ - return FEC_NONE; - } -} - -static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) -{ -/* fixme (low): add error handling */ - u32 ratio; - u32 tmp, fclk, BDRI; - - static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; - int i; - - dprintk("cx24110 debug: entering %s(%d)\n",__func__,srate); - if (srate>90999000UL/2) - srate=90999000UL/2; - if (srate<500000) - srate=500000; - - for(i = 0; (i < ARRAY_SIZE(bands)) && (srate>bands[i]); i++) - ; - /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz, - and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult, - R06[3:0] PLLphaseDetGain */ - tmp=cx24110_readreg(state,0x07)&0xfc; - if(srate<90999000UL/4) { /* sample rate 45MHz*/ - cx24110_writereg(state,0x07,tmp); - cx24110_writereg(state,0x06,0x78); - fclk=90999000UL/2; - } else if(srate<60666000UL/2) { /* sample rate 60MHz */ - cx24110_writereg(state,0x07,tmp|0x1); - cx24110_writereg(state,0x06,0xa5); - fclk=60666000UL; - } else if(srate<80888000UL/2) { /* sample rate 80MHz */ - cx24110_writereg(state,0x07,tmp|0x2); - cx24110_writereg(state,0x06,0x87); - fclk=80888000UL; - } else { /* sample rate 90MHz */ - cx24110_writereg(state,0x07,tmp|0x3); - cx24110_writereg(state,0x06,0x78); - fclk=90999000UL; - }; - dprintk("cx24110 debug: fclk %d Hz\n",fclk); - /* we need to divide two integers with approx. 27 bits in 32 bit - arithmetic giving a 25 bit result */ - /* the maximum dividend is 90999000/2, 0x02b6446c, this number is - also the most complex divisor. Hence, the dividend has, - assuming 32bit unsigned arithmetic, 6 clear bits on top, the - divisor 2 unused bits at the bottom. Also, the quotient is - always less than 1/2. Borrowed from VES1893.c, of course */ - - tmp=srate<<6; - BDRI=fclk>>2; - ratio=(tmp/BDRI); - - tmp=(tmp%BDRI)<<8; - ratio=(ratio<<8)+(tmp/BDRI); - - tmp=(tmp%BDRI)<<8; - ratio=(ratio<<8)+(tmp/BDRI); - - tmp=(tmp%BDRI)<<1; - ratio=(ratio<<1)+(tmp/BDRI); - - dprintk("srate= %d (range %d, up to %d)\n", srate,i,bands[i]); - dprintk("fclk = %d\n", fclk); - dprintk("ratio= %08x\n", ratio); - - cx24110_writereg(state, 0x1, (ratio>>16)&0xff); - cx24110_writereg(state, 0x2, (ratio>>8)&0xff); - cx24110_writereg(state, 0x3, (ratio)&0xff); - - return 0; - -} - -static int _cx24110_pll_write (struct dvb_frontend* fe, u8 *buf, int len) -{ - struct cx24110_state *state = fe->demodulator_priv; - - if (len != 3) - return -EINVAL; - -/* tuner data is 21 bits long, must be left-aligned in data */ -/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */ -/* FIXME (low): add error handling, avoid infinite loops if HW fails... */ - - cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */ - cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */ - - /* if the auto tuner writer is still busy, clear it out */ - while (cx24110_readreg(state,0x6d)&0x80) - cx24110_writereg(state,0x72,0); - - /* write the topmost 8 bits */ - cx24110_writereg(state,0x72,buf[0]); - - /* wait for the send to be completed */ - while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) - ; - - /* send another 8 bytes */ - cx24110_writereg(state,0x72,buf[1]); - while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) - ; - - /* and the topmost 5 bits of this byte */ - cx24110_writereg(state,0x72,buf[2]); - while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) - ; - - /* now strobe the enable line once */ - cx24110_writereg(state,0x6d,0x32); - cx24110_writereg(state,0x6d,0x30); - - return 0; -} - -static int cx24110_initfe(struct dvb_frontend* fe) -{ - struct cx24110_state *state = fe->demodulator_priv; -/* fixme (low): error handling */ - int i; - - dprintk("%s: init chip\n", __func__); - - for(i = 0; i < ARRAY_SIZE(cx24110_regdata); i++) { - cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data); - }; - - return 0; -} - -static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct cx24110_state *state = fe->demodulator_priv; - - switch (voltage) { - case SEC_VOLTAGE_13: - return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0xc0); - case SEC_VOLTAGE_18: - return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0x40); - default: - return -EINVAL; - }; -} - -static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) -{ - int rv, bit; - struct cx24110_state *state = fe->demodulator_priv; - unsigned long timeout; - - if (burst == SEC_MINI_A) - bit = 0x00; - else if (burst == SEC_MINI_B) - bit = 0x08; - else - return -EINVAL; - - rv = cx24110_readreg(state, 0x77); - if (!(rv & 0x04)) - cx24110_writereg(state, 0x77, rv | 0x04); - - rv = cx24110_readreg(state, 0x76); - cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit)); - timeout = jiffies + msecs_to_jiffies(100); - while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40)) - ; /* wait for LNB ready */ - - return 0; -} - -static int cx24110_send_diseqc_msg(struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd *cmd) -{ - int i, rv; - struct cx24110_state *state = fe->demodulator_priv; - unsigned long timeout; - - if (cmd->msg_len < 3 || cmd->msg_len > 6) - return -EINVAL; /* not implemented */ - - for (i = 0; i < cmd->msg_len; i++) - cx24110_writereg(state, 0x79 + i, cmd->msg[i]); - - rv = cx24110_readreg(state, 0x77); - if (rv & 0x04) { - cx24110_writereg(state, 0x77, rv & ~0x04); - msleep(30); /* reportedly fixes switching problems */ - } - - rv = cx24110_readreg(state, 0x76); - - cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3)); - timeout = jiffies + msecs_to_jiffies(100); - while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40)) - ; /* wait for LNB ready */ - - return 0; -} - -static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct cx24110_state *state = fe->demodulator_priv; - - int sync = cx24110_readreg (state, 0x55); - - *status = 0; - - if (sync & 0x10) - *status |= FE_HAS_SIGNAL; - - if (sync & 0x08) - *status |= FE_HAS_CARRIER; - - sync = cx24110_readreg (state, 0x08); - - if (sync & 0x40) - *status |= FE_HAS_VITERBI; - - if (sync & 0x20) - *status |= FE_HAS_SYNC; - - if ((sync & 0x60) == 0x60) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct cx24110_state *state = fe->demodulator_priv; - - /* fixme (maybe): value range is 16 bit. Scale? */ - if(cx24110_readreg(state,0x24)&0x10) { - /* the Viterbi error counter has finished one counting window */ - cx24110_writereg(state,0x24,0x04); /* select the ber reg */ - state->lastber=cx24110_readreg(state,0x25)| - (cx24110_readreg(state,0x26)<<8); - cx24110_writereg(state,0x24,0x04); /* start new count window */ - cx24110_writereg(state,0x24,0x14); - } - *ber = state->lastber; - - return 0; -} - -static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) -{ - struct cx24110_state *state = fe->demodulator_priv; - -/* no provision in hardware. Read the frontend AGC accumulator. No idea how to scale this, but I know it is 2s complement */ - u8 signal = cx24110_readreg (state, 0x27)+128; - *signal_strength = (signal << 8) | signal; - - return 0; -} - -static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct cx24110_state *state = fe->demodulator_priv; - - /* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */ - if(cx24110_readreg(state,0x6a)&0x80) { - /* the Es/N0 error counter has finished one counting window */ - state->lastesn0=cx24110_readreg(state,0x69)| - (cx24110_readreg(state,0x68)<<8); - cx24110_writereg(state,0x6a,0x84); /* start new count window */ - } - *snr = state->lastesn0; - - return 0; -} - -static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct cx24110_state *state = fe->demodulator_priv; - u32 lastbyer; - - if(cx24110_readreg(state,0x10)&0x40) { - /* the RS error counter has finished one counting window */ - cx24110_writereg(state,0x10,0x60); /* select the byer reg */ - lastbyer=cx24110_readreg(state,0x12)| - (cx24110_readreg(state,0x13)<<8)| - (cx24110_readreg(state,0x14)<<16); - cx24110_writereg(state,0x10,0x70); /* select the bler reg */ - state->lastbler=cx24110_readreg(state,0x12)| - (cx24110_readreg(state,0x13)<<8)| - (cx24110_readreg(state,0x14)<<16); - cx24110_writereg(state,0x10,0x20); /* start new count window */ - } - *ucblocks = state->lastbler; - - return 0; -} - -static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx24110_state *state = fe->demodulator_priv; - - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - cx24110_set_inversion (state, p->inversion); - cx24110_set_fec (state, p->u.qpsk.fec_inner); - cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate); - cx24110_writereg(state,0x04,0x05); /* start aquisition */ - - return 0; -} - -static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx24110_state *state = fe->demodulator_priv; - s32 afc; unsigned sclk; - -/* cannot read back tuner settings (freq). Need to have some private storage */ - - sclk = cx24110_readreg (state, 0x07) & 0x03; -/* ok, real AFC (FEDR) freq. is afc/2^24*fsamp, fsamp=45/60/80/90MHz. - * Need 64 bit arithmetic. Is thiss possible in the kernel? */ - if (sclk==0) sclk=90999000L/2L; - else if (sclk==1) sclk=60666000L; - else if (sclk==2) sclk=80888000L; - else sclk=90999000L; - sclk>>=8; - afc = sclk*(cx24110_readreg (state, 0x44)&0x1f)+ - ((sclk*cx24110_readreg (state, 0x45))>>8)+ - ((sclk*cx24110_readreg (state, 0x46))>>16); - - p->frequency += afc; - p->inversion = (cx24110_readreg (state, 0x22) & 0x10) ? - INVERSION_ON : INVERSION_OFF; - p->u.qpsk.fec_inner = cx24110_get_fec (state); - - return 0; -} - -static int cx24110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct cx24110_state *state = fe->demodulator_priv; - - return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&~0x10)|(((tone==SEC_TONE_ON))?0x10:0)); -} - -static void cx24110_release(struct dvb_frontend* fe) -{ - struct cx24110_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops cx24110_ops; - -struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, - struct i2c_adapter* i2c) -{ - struct cx24110_state* state = NULL; - int ret; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct cx24110_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->lastber = 0; - state->lastbler = 0; - state->lastesn0 = 0; - - /* check if the demod is there */ - ret = cx24110_readreg(state, 0x00); - if ((ret != 0x5a) && (ret != 0x69)) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx24110_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops cx24110_ops = { - - .info = { - .name = "Conexant CX24110 DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 1011, /* kHz for QPSK frontends */ - .frequency_tolerance = 29500, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_RECOVER - }, - - .release = cx24110_release, - - .init = cx24110_initfe, - .write = _cx24110_pll_write, - .set_frontend = cx24110_set_frontend, - .get_frontend = cx24110_get_frontend, - .read_status = cx24110_read_status, - .read_ber = cx24110_read_ber, - .read_signal_strength = cx24110_read_signal_strength, - .read_snr = cx24110_read_snr, - .read_ucblocks = cx24110_read_ucblocks, - - .diseqc_send_master_cmd = cx24110_send_diseqc_msg, - .set_tone = cx24110_set_tone, - .set_voltage = cx24110_set_voltage, - .diseqc_send_burst = cx24110_diseqc_send_burst, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Conexant CX24110 DVB-S Demodulator driver"); -MODULE_AUTHOR("Peter Hettkamp"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(cx24110_attach); diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h deleted file mode 100644 index fdcceee91f3..00000000000 --- a/drivers/media/dvb/frontends/cx24110.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - cx24110 - Single Chip Satellite Channel Receiver driver module - - Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on - work - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - - 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 CX24110_H -#define CX24110_H - -#include <linux/dvb/frontend.h> - -struct cx24110_config -{ - /* the demodulator's i2c address */ - u8 demod_address; -}; - -static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val) -{ - u8 buf[] = { - (u8)((val >> 24) & 0xff), - (u8)((val >> 16) & 0xff), - (u8)((val >> 8) & 0xff) - }; - - if (fe->ops.write) - return fe->ops.write(fe, buf, 3); - return 0; -} - -#if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE)) -extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_CX24110 - -#endif // CX24110_H diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c deleted file mode 100644 index e4fd533a427..00000000000 --- a/drivers/media/dvb/frontends/cx24113.c +++ /dev/null @@ -1,616 +0,0 @@ -/* - * Driver for Conexant CX24113/CX24128 Tuner (Satellite) - * - * Copyright (C) 2007-8 Patrick Boettcher <pb@linuxtv.org> - * - * Developed for BBTI / Technisat - * - * 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 <linux/slab.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> - -#include "dvb_frontend.h" -#include "cx24113.h" - -static int debug; - -#define info(args...) do { printk(KERN_INFO "CX24113: " args); } while (0) -#define err(args...) do { printk(KERN_ERR "CX24113: " args); } while (0) - -#define dprintk(args...) \ - do { \ - if (debug) { \ - printk(KERN_DEBUG "CX24113: %s: ", __func__); \ - printk(args); \ - } \ - } while (0) - -struct cx24113_state { - struct i2c_adapter *i2c; - const struct cx24113_config *config; - -#define REV_CX24113 0x23 - u8 rev; - u8 ver; - - u8 icp_mode:1; - -#define ICP_LEVEL1 0 -#define ICP_LEVEL2 1 -#define ICP_LEVEL3 2 -#define ICP_LEVEL4 3 - u8 icp_man:2; - u8 icp_auto_low:2; - u8 icp_auto_mlow:2; - u8 icp_auto_mhi:2; - u8 icp_auto_hi:2; - u8 icp_dig; - -#define LNA_MIN_GAIN 0 -#define LNA_MID_GAIN 1 -#define LNA_MAX_GAIN 2 - u8 lna_gain:2; - - u8 acp_on:1; - - u8 vco_mode:2; - u8 vco_shift:1; -#define VCOBANDSEL_6 0x80 -#define VCOBANDSEL_5 0x01 -#define VCOBANDSEL_4 0x02 -#define VCOBANDSEL_3 0x04 -#define VCOBANDSEL_2 0x08 -#define VCOBANDSEL_1 0x10 - u8 vco_band; - -#define VCODIV4 4 -#define VCODIV2 2 - u8 vcodiv; - - u8 bs_delay:4; - u16 bs_freqcnt:13; - u16 bs_rdiv; - u8 prescaler_mode:1; - - u8 rfvga_bias_ctrl; - - s16 tuner_gain_thres; - u8 gain_level; - - u32 frequency; - - u8 refdiv; - - u8 Fwindow_enabled; -}; - -static int cx24113_writereg(struct cx24113_state *state, int reg, int data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->i2c_addr, - .flags = 0, .buf = buf, .len = 2 }; - int err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - printk(KERN_DEBUG "%s: writereg error(err == %i, reg == 0x%02x," - " data == 0x%02x)\n", __func__, err, reg, data); - return err; - } - - return 0; -} - -static int cx24113_readreg(struct cx24113_state *state, u8 reg) -{ - int ret; - u8 b; - struct i2c_msg msg[] = { - { .addr = state->config->i2c_addr, - .flags = 0, .buf = ®, .len = 1 }, - { .addr = state->config->i2c_addr, - .flags = I2C_M_RD, .buf = &b, .len = 1 } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - printk(KERN_DEBUG "%s: reg=0x%x (error=%d)\n", - __func__, reg, ret); - return ret; - } - - return b; -} - -static void cx24113_set_parameters(struct cx24113_state *state) -{ - u8 r; - - r = cx24113_readreg(state, 0x10) & 0x82; - r |= state->icp_mode; - r |= state->icp_man << 4; - r |= state->icp_dig << 2; - r |= state->prescaler_mode << 5; - cx24113_writereg(state, 0x10, r); - - r = (state->icp_auto_low << 0) | (state->icp_auto_mlow << 2) - | (state->icp_auto_mhi << 4) | (state->icp_auto_hi << 6); - cx24113_writereg(state, 0x11, r); - - if (state->rev == REV_CX24113) { - r = cx24113_readreg(state, 0x20) & 0xec; - r |= state->lna_gain; - r |= state->rfvga_bias_ctrl << 4; - cx24113_writereg(state, 0x20, r); - } - - r = cx24113_readreg(state, 0x12) & 0x03; - r |= state->acp_on << 2; - r |= state->bs_delay << 4; - cx24113_writereg(state, 0x12, r); - - r = cx24113_readreg(state, 0x18) & 0x40; - r |= state->vco_shift; - if (state->vco_band == VCOBANDSEL_6) - r |= (1 << 7); - else - r |= (state->vco_band << 1); - cx24113_writereg(state, 0x18, r); - - r = cx24113_readreg(state, 0x14) & 0x20; - r |= (state->vco_mode << 6) | ((state->bs_freqcnt >> 8) & 0x1f); - cx24113_writereg(state, 0x14, r); - cx24113_writereg(state, 0x15, (state->bs_freqcnt & 0xff)); - - cx24113_writereg(state, 0x16, (state->bs_rdiv >> 4) & 0xff); - r = (cx24113_readreg(state, 0x17) & 0x0f) | - ((state->bs_rdiv & 0x0f) << 4); - cx24113_writereg(state, 0x17, r); -} - -#define VGA_0 0x00 -#define VGA_1 0x04 -#define VGA_2 0x02 -#define VGA_3 0x06 -#define VGA_4 0x01 -#define VGA_5 0x05 -#define VGA_6 0x03 -#define VGA_7 0x07 - -#define RFVGA_0 0x00 -#define RFVGA_1 0x01 -#define RFVGA_2 0x02 -#define RFVGA_3 0x03 - -static int cx24113_set_gain_settings(struct cx24113_state *state, - s16 power_estimation) -{ - u8 ampout = cx24113_readreg(state, 0x1d) & 0xf0, - vga = cx24113_readreg(state, 0x1f) & 0x3f, - rfvga = cx24113_readreg(state, 0x20) & 0xf3; - u8 gain_level = power_estimation >= state->tuner_gain_thres; - - dprintk("power estimation: %d, thres: %d, gain_level: %d/%d\n", - power_estimation, state->tuner_gain_thres, - state->gain_level, gain_level); - - if (gain_level == state->gain_level) - return 0; /* nothing to be done */ - - ampout |= 0xf; - - if (gain_level) { - rfvga |= RFVGA_0 << 2; - vga |= (VGA_7 << 3) | VGA_7; - } else { - rfvga |= RFVGA_2 << 2; - vga |= (VGA_6 << 3) | VGA_2; - } - state->gain_level = gain_level; - - cx24113_writereg(state, 0x1d, ampout); - cx24113_writereg(state, 0x1f, vga); - cx24113_writereg(state, 0x20, rfvga); - - return 1; /* did something */ -} - -static int cx24113_set_Fref(struct cx24113_state *state, u8 high) -{ - u8 xtal = cx24113_readreg(state, 0x02); - if (state->rev == 0x43 && state->vcodiv == VCODIV4) - high = 1; - - xtal &= ~0x2; - if (high) - xtal |= high << 1; - return cx24113_writereg(state, 0x02, xtal); -} - -static int cx24113_enable(struct cx24113_state *state, u8 enable) -{ - u8 r21 = (cx24113_readreg(state, 0x21) & 0xc0) | enable; - if (state->rev == REV_CX24113) - r21 |= (1 << 1); - return cx24113_writereg(state, 0x21, r21); -} - -static int cx24113_set_bandwidth(struct cx24113_state *state, u32 bandwidth_khz) -{ - u8 r; - - if (bandwidth_khz <= 19000) - r = 0x03 << 6; - else if (bandwidth_khz <= 25000) - r = 0x02 << 6; - else - r = 0x01 << 6; - - dprintk("bandwidth to be set: %d\n", bandwidth_khz); - bandwidth_khz *= 10; - bandwidth_khz -= 10000; - bandwidth_khz /= 1000; - bandwidth_khz += 5; - bandwidth_khz /= 10; - - dprintk("bandwidth: %d %d\n", r >> 6, bandwidth_khz); - - r |= bandwidth_khz & 0x3f; - - return cx24113_writereg(state, 0x1e, r); -} - -static int cx24113_set_clk_inversion(struct cx24113_state *state, u8 on) -{ - u8 r = (cx24113_readreg(state, 0x10) & 0x7f) | ((on & 0x1) << 7); - return cx24113_writereg(state, 0x10, r); -} - -static int cx24113_get_status(struct dvb_frontend *fe, u32 *status) -{ - struct cx24113_state *state = fe->tuner_priv; - u8 r = (cx24113_readreg(state, 0x10) & 0x02) >> 1; - if (r) - *status |= TUNER_STATUS_LOCKED; - dprintk("PLL locked: %d\n", r); - return 0; -} - -static u8 cx24113_set_ref_div(struct cx24113_state *state, u8 refdiv) -{ - if (state->rev == 0x43 && state->vcodiv == VCODIV4) - refdiv = 2; - return state->refdiv = refdiv; -} - -static void cx24113_calc_pll_nf(struct cx24113_state *state, u16 *n, s32 *f) -{ - s32 N; - s64 F; - u8 R, r; - u8 vcodiv; - u8 factor; - s32 freq_hz = state->frequency * 1000; - - if (state->config->xtal_khz < 20000) - factor = 1; - else - factor = 2; - - if (state->rev == REV_CX24113) { - if (state->frequency >= 1100000) - vcodiv = VCODIV2; - else - vcodiv = VCODIV4; - } else { - if (state->frequency >= 1165000) - vcodiv = VCODIV2; - else - vcodiv = VCODIV4; - } - state->vcodiv = vcodiv; - - dprintk("calculating N/F for %dHz with vcodiv %d\n", freq_hz, vcodiv); - R = 0; - do { - R = cx24113_set_ref_div(state, R + 1); - - /* calculate tuner PLL settings: */ - N = (freq_hz / 100 * vcodiv) * R; - N /= (state->config->xtal_khz) * factor * 2; - N += 5; /* For round up. */ - N /= 10; - N -= 32; - } while (N < 6 && R < 3); - - if (N < 6) { - err("strange frequency: N < 6\n"); - return; - } - F = freq_hz; - F *= (u64) (R * vcodiv * 262144); - dprintk("1 N: %d, F: %lld, R: %d\n", N, (long long)F, R); - do_div(F, state->config->xtal_khz*1000 * factor * 2); - dprintk("2 N: %d, F: %lld, R: %d\n", N, (long long)F, R); - F -= (N + 32) * 262144; - - dprintk("3 N: %d, F: %lld, R: %d\n", N, (long long)F, R); - - if (state->Fwindow_enabled) { - if (F > (262144 / 2 - 1638)) - F = 262144 / 2 - 1638; - if (F < (-262144 / 2 + 1638)) - F = -262144 / 2 + 1638; - if ((F < 3277 && F > 0) || (F > -3277 && F < 0)) { - F = 0; - r = cx24113_readreg(state, 0x10); - cx24113_writereg(state, 0x10, r | (1 << 6)); - } - } - dprintk("4 N: %d, F: %lld, R: %d\n", N, (long long)F, R); - - *n = (u16) N; - *f = (s32) F; -} - - -static void cx24113_set_nfr(struct cx24113_state *state, u16 n, s32 f, u8 r) -{ - u8 reg; - cx24113_writereg(state, 0x19, (n >> 1) & 0xff); - - reg = ((n & 0x1) << 7) | ((f >> 11) & 0x7f); - cx24113_writereg(state, 0x1a, reg); - - cx24113_writereg(state, 0x1b, (f >> 3) & 0xff); - - reg = cx24113_readreg(state, 0x1c) & 0x1f; - cx24113_writereg(state, 0x1c, reg | ((f & 0x7) << 5)); - - cx24113_set_Fref(state, r - 1); -} - -static int cx24113_set_frequency(struct cx24113_state *state, u32 frequency) -{ - u8 r = 1; /* or 2 */ - u16 n = 6; - s32 f = 0; - - r = cx24113_readreg(state, 0x14); - cx24113_writereg(state, 0x14, r & 0x3f); - - r = cx24113_readreg(state, 0x10); - cx24113_writereg(state, 0x10, r & 0xbf); - - state->frequency = frequency; - - dprintk("tuning to frequency: %d\n", frequency); - - cx24113_calc_pll_nf(state, &n, &f); - cx24113_set_nfr(state, n, f, state->refdiv); - - r = cx24113_readreg(state, 0x18) & 0xbf; - if (state->vcodiv != VCODIV2) - r |= 1 << 6; - cx24113_writereg(state, 0x18, r); - - /* The need for this sleep is not clear. But helps in some cases */ - msleep(5); - - r = cx24113_readreg(state, 0x1c) & 0xef; - cx24113_writereg(state, 0x1c, r | (1 << 4)); - return 0; -} - -static int cx24113_init(struct dvb_frontend *fe) -{ - struct cx24113_state *state = fe->tuner_priv; - int ret; - - state->tuner_gain_thres = -50; - state->gain_level = 255; /* to force a gain-setting initialization */ - state->icp_mode = 0; - - if (state->config->xtal_khz < 11000) { - state->icp_auto_hi = ICP_LEVEL4; - state->icp_auto_mhi = ICP_LEVEL4; - state->icp_auto_mlow = ICP_LEVEL3; - state->icp_auto_low = ICP_LEVEL3; - } else { - state->icp_auto_hi = ICP_LEVEL4; - state->icp_auto_mhi = ICP_LEVEL4; - state->icp_auto_mlow = ICP_LEVEL3; - state->icp_auto_low = ICP_LEVEL2; - } - - state->icp_dig = ICP_LEVEL3; - state->icp_man = ICP_LEVEL1; - state->acp_on = 1; - state->vco_mode = 0; - state->vco_shift = 0; - state->vco_band = VCOBANDSEL_1; - state->bs_delay = 8; - state->bs_freqcnt = 0x0fff; - state->bs_rdiv = 0x0fff; - state->prescaler_mode = 0; - state->lna_gain = LNA_MAX_GAIN; - state->rfvga_bias_ctrl = 1; - state->Fwindow_enabled = 1; - - cx24113_set_Fref(state, 0); - cx24113_enable(state, 0x3d); - cx24113_set_parameters(state); - - cx24113_set_gain_settings(state, -30); - - cx24113_set_bandwidth(state, 18025); - cx24113_set_clk_inversion(state, 1); - - if (state->config->xtal_khz >= 40000) - ret = cx24113_writereg(state, 0x02, - (cx24113_readreg(state, 0x02) & 0xfb) | (1 << 2)); - else - ret = cx24113_writereg(state, 0x02, - (cx24113_readreg(state, 0x02) & 0xfb) | (0 << 2)); - - return ret; -} - -static int cx24113_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx24113_state *state = fe->tuner_priv; - /* for a ROLL-OFF factor of 0.35, 0.2: 600, 0.25: 625 */ - u32 roll_off = 675; - u32 bw; - - bw = ((p->u.qpsk.symbol_rate/100) * roll_off) / 1000; - bw += (10000000/100) + 5; - bw /= 10; - bw += 1000; - cx24113_set_bandwidth(state, bw); - - cx24113_set_frequency(state, p->frequency); - msleep(5); - return cx24113_get_status(fe, &bw); -} - -static s8 cx24113_agc_table[2][10] = { - {-54, -41, -35, -30, -25, -21, -16, -10, -6, -2}, - {-39, -35, -30, -25, -19, -15, -11, -5, 1, 9}, -}; - -void cx24113_agc_callback(struct dvb_frontend *fe) -{ - struct cx24113_state *state = fe->tuner_priv; - s16 s, i; - if (!fe->ops.read_signal_strength) - return; - - do { - /* this only works with the current CX24123 implementation */ - fe->ops.read_signal_strength(fe, (u16 *) &s); - s >>= 8; - dprintk("signal strength: %d\n", s); - for (i = 0; i < sizeof(cx24113_agc_table[0]); i++) - if (cx24113_agc_table[state->gain_level][i] > s) - break; - s = -25 - i*5; - } while (cx24113_set_gain_settings(state, s)); -} -EXPORT_SYMBOL(cx24113_agc_callback); - -static int cx24113_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct cx24113_state *state = fe->tuner_priv; - *frequency = state->frequency; - return 0; -} - -static int cx24113_release(struct dvb_frontend *fe) -{ - struct cx24113_state *state = fe->tuner_priv; - dprintk("\n"); - fe->tuner_priv = NULL; - kfree(state); - return 0; -} - -static const struct dvb_tuner_ops cx24113_tuner_ops = { - .info = { - .name = "Conexant CX24113", - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 125, - }, - - .release = cx24113_release, - - .init = cx24113_init, - .sleep = NULL, - - .set_params = cx24113_set_params, - .get_frequency = cx24113_get_frequency, - .get_bandwidth = NULL, - .get_status = cx24113_get_status, -}; - -struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, - const struct cx24113_config *config, struct i2c_adapter *i2c) -{ - /* allocate memory for the internal state */ - struct cx24113_state *state = - kzalloc(sizeof(struct cx24113_state), GFP_KERNEL); - int rc; - if (state == NULL) { - err("Unable to kzalloc\n"); - goto error; - } - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - info("trying to detect myself\n"); - - /* making a dummy read, because of some expected troubles - * after power on */ - cx24113_readreg(state, 0x00); - - rc = cx24113_readreg(state, 0x00); - if (rc < 0) { - info("CX24113 not found.\n"); - goto error; - } - state->rev = rc; - - switch (rc) { - case 0x43: - info("detected CX24113 variant\n"); - break; - case REV_CX24113: - info("sucessfully detected\n"); - break; - default: - err("unsupported device id: %x\n", state->rev); - goto error; - } - state->ver = cx24113_readreg(state, 0x01); - info("version: %x\n", state->ver); - - /* create dvb_frontend */ - memcpy(&fe->ops.tuner_ops, &cx24113_tuner_ops, - sizeof(struct dvb_tuner_ops)); - fe->tuner_priv = state; - return fe; - -error: - kfree(state); - - return NULL; -} -EXPORT_SYMBOL(cx24113_attach); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); - -MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>"); -MODULE_DESCRIPTION("DVB Frontend module for Conexant CX24113/CX24128hardware"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/media/dvb/frontends/cx24113.h b/drivers/media/dvb/frontends/cx24113.h deleted file mode 100644 index 5de0f7ffd8d..00000000000 --- a/drivers/media/dvb/frontends/cx24113.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Driver for Conexant CX24113/CX24128 Tuner (Satelite) - * - * Copyright (C) 2007-8 Patrick Boettcher <pb@linuxtv.org> - * - * 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 CX24113_H -#define CX24113_H - -struct dvb_frontend; - -struct cx24113_config { - u8 i2c_addr; /* 0x14 or 0x54 */ - - u32 xtal_khz; -}; - -#if defined(CONFIG_DVB_TUNER_CX24113) || \ - (defined(CONFIG_DVB_TUNER_CX24113_MODULE) && defined(MODULE)) -extern struct dvb_frontend *cx24113_attach(struct dvb_frontend *, - const struct cx24113_config *config, struct i2c_adapter *i2c); - -extern void cx24113_agc_callback(struct dvb_frontend *fe); -#else -static inline struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, - const struct cx24113_config *config, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} - -static inline void cx24113_agc_callback(struct dvb_frontend *fe) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -} -#endif - -#endif /* CX24113_H */ diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c deleted file mode 100644 index 9b9f57264ce..00000000000 --- a/drivers/media/dvb/frontends/cx24116.c +++ /dev/null @@ -1,1509 +0,0 @@ -/* - Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver - - Copyright (C) 2006-2008 Steven Toth <stoth@hauppauge.com> - Copyright (C) 2006-2007 Georg Acher - Copyright (C) 2007-2008 Darron Broad - March 2007 - Fixed some bugs. - Added diseqc support. - Added corrected signal strength support. - August 2007 - Sync with legacy version. - Some clean ups. - Copyright (C) 2008 Igor Liplianin - 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 - 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 <linux/slab.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/firmware.h> - -#include "dvb_frontend.h" -#include "cx24116.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); - -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_INFO "cx24116: " args); \ - } while (0) - -#define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw" -#define CX24116_SEARCH_RANGE_KHZ 5000 - -/* known registers */ -#define CX24116_REG_COMMAND (0x00) /* command args 0x00..0x1e */ -#define CX24116_REG_EXECUTE (0x1f) /* execute command */ -#define CX24116_REG_MAILBOX (0x96) /* FW or multipurpose mailbox? */ -#define CX24116_REG_RESET (0x20) /* reset status > 0 */ -#define CX24116_REG_SIGNAL (0x9e) /* signal low */ -#define CX24116_REG_SSTATUS (0x9d) /* signal high / status */ -#define CX24116_REG_QUALITY8 (0xa3) -#define CX24116_REG_QSTATUS (0xbc) -#define CX24116_REG_QUALITY0 (0xd5) -#define CX24116_REG_BER0 (0xc9) -#define CX24116_REG_BER8 (0xc8) -#define CX24116_REG_BER16 (0xc7) -#define CX24116_REG_BER24 (0xc6) -#define CX24116_REG_UCB0 (0xcb) -#define CX24116_REG_UCB8 (0xca) -#define CX24116_REG_CLKDIV (0xf3) -#define CX24116_REG_RATEDIV (0xf9) - -/* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */ -#define CX24116_REG_FECSTATUS (0x9c) - -/* FECSTATUS bits */ -/* mask to determine configured fec (not tuned) or actual fec (tuned) */ -#define CX24116_FEC_FECMASK (0x1f) - -/* Select DVB-S demodulator, else DVB-S2 */ -#define CX24116_FEC_DVBS (0x20) -#define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */ - -/* Pilot mode requested when tuning else always reset when tuned */ -#define CX24116_FEC_PILOT (0x80) - -/* arg buffer size */ -#define CX24116_ARGLEN (0x1e) - -/* rolloff */ -#define CX24116_ROLLOFF_020 (0x00) -#define CX24116_ROLLOFF_025 (0x01) -#define CX24116_ROLLOFF_035 (0x02) - -/* pilot bit */ -#define CX24116_PILOT_OFF (0x00) -#define CX24116_PILOT_ON (0x40) - -/* signal status */ -#define CX24116_HAS_SIGNAL (0x01) -#define CX24116_HAS_CARRIER (0x02) -#define CX24116_HAS_VITERBI (0x04) -#define CX24116_HAS_SYNCLOCK (0x08) -#define CX24116_HAS_UNKNOWN1 (0x10) -#define CX24116_HAS_UNKNOWN2 (0x20) -#define CX24116_STATUS_MASK (0x0f) -#define CX24116_SIGNAL_MASK (0xc0) - -#define CX24116_DISEQC_TONEOFF (0) /* toneburst never sent */ -#define CX24116_DISEQC_TONECACHE (1) /* toneburst cached */ -#define CX24116_DISEQC_MESGCACHE (2) /* message cached */ - -/* arg offset for DiSEqC */ -#define CX24116_DISEQC_BURST (1) -#define CX24116_DISEQC_ARG2_2 (2) /* unknown value=2 */ -#define CX24116_DISEQC_ARG3_0 (3) /* unknown value=0 */ -#define CX24116_DISEQC_ARG4_0 (4) /* unknown value=0 */ -#define CX24116_DISEQC_MSGLEN (5) -#define CX24116_DISEQC_MSGOFS (6) - -/* DiSEqC burst */ -#define CX24116_DISEQC_MINI_A (0) -#define CX24116_DISEQC_MINI_B (1) - -/* DiSEqC tone burst */ -static int toneburst = 1; -module_param(toneburst, int, 0644); -MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\ - "2=MESSAGE CACHE (default:1)"); - -/* SNR measurements */ -static int esno_snr; -module_param(esno_snr, int, 0644); -MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, "\ - "1=ESNO(db * 10) (default:0)"); - -enum cmds { - CMD_SET_VCO = 0x10, - CMD_TUNEREQUEST = 0x11, - CMD_MPEGCONFIG = 0x13, - CMD_TUNERINIT = 0x14, - CMD_BANDWIDTH = 0x15, - CMD_GETAGC = 0x19, - CMD_LNBCONFIG = 0x20, - CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */ - CMD_LNBDCLEVEL = 0x22, - CMD_SET_TONE = 0x23, - CMD_UPDFWVERS = 0x35, - CMD_TUNERSLEEP = 0x36, - CMD_AGCCONTROL = 0x3b, /* Unknown */ -}; - -/* The Demod/Tuner can't easily provide these, we cache them */ -struct cx24116_tuning { - u32 frequency; - u32 symbol_rate; - fe_spectral_inversion_t inversion; - fe_code_rate_t fec; - - fe_delivery_system_t delsys; - fe_modulation_t modulation; - fe_pilot_t pilot; - fe_rolloff_t rolloff; - - /* Demod values */ - u8 fec_val; - u8 fec_mask; - u8 inversion_val; - u8 pilot_val; - u8 rolloff_val; -}; - -/* Basic commands that are sent to the firmware */ -struct cx24116_cmd { - u8 len; - u8 args[CX24116_ARGLEN]; -}; - -struct cx24116_state { - struct i2c_adapter *i2c; - const struct cx24116_config *config; - - struct dvb_frontend frontend; - - struct cx24116_tuning dcur; - struct cx24116_tuning dnxt; - - u8 skip_fw_load; - u8 burst; - struct cx24116_cmd dsec_cmd; -}; - -static int cx24116_writereg(struct cx24116_state *state, int reg, int data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, - .flags = 0, .buf = buf, .len = 2 }; - int err; - - if (debug > 1) - printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n", - __func__, reg, data); - - err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x," - " value == 0x%02x)\n", __func__, err, reg, data); - return -EREMOTEIO; - } - - return 0; -} - -/* Bulk byte writes to a single I2C address, for 32k firmware load */ -static int cx24116_writeregN(struct cx24116_state *state, int reg, - const u8 *data, u16 len) -{ - int ret = -EREMOTEIO; - struct i2c_msg msg; - u8 *buf; - - buf = kmalloc(len + 1, GFP_KERNEL); - if (buf == NULL) { - printk("Unable to kmalloc\n"); - ret = -ENOMEM; - goto error; - } - - *(buf) = reg; - memcpy(buf + 1, data, len); - - msg.addr = state->config->demod_address; - msg.flags = 0; - msg.buf = buf; - msg.len = len + 1; - - if (debug > 1) - printk(KERN_INFO "cx24116: %s: write regN 0x%02x, len = %d\n", - __func__, reg, len); - - ret = i2c_transfer(state->i2c, &msg, 1); - if (ret != 1) { - printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n", - __func__, ret, reg); - ret = -EREMOTEIO; - } - -error: - kfree(buf); - - return ret; -} - -static int cx24116_readreg(struct cx24116_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, - .buf = b0, .len = 1 }, - { .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: reg=0x%x (error=%d)\n", - __func__, reg, ret); - return ret; - } - - if (debug > 1) - printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n", - reg, b1[0]); - - return b1[0]; -} - -static int cx24116_set_inversion(struct cx24116_state *state, - fe_spectral_inversion_t inversion) -{ - dprintk("%s(%d)\n", __func__, inversion); - - switch (inversion) { - case INVERSION_OFF: - state->dnxt.inversion_val = 0x00; - break; - case INVERSION_ON: - state->dnxt.inversion_val = 0x04; - break; - case INVERSION_AUTO: - state->dnxt.inversion_val = 0x0C; - break; - default: - return -EINVAL; - } - - state->dnxt.inversion = inversion; - - return 0; -} - -/* - * modfec (modulation and FEC) - * =========================== - * - * MOD FEC mask/val standard - * ---- -------- ----------- -------- - * QPSK FEC_1_2 0x02 0x02+X DVB-S - * QPSK FEC_2_3 0x04 0x02+X DVB-S - * QPSK FEC_3_4 0x08 0x02+X DVB-S - * QPSK FEC_4_5 0x10 0x02+X DVB-S (?) - * QPSK FEC_5_6 0x20 0x02+X DVB-S - * QPSK FEC_6_7 0x40 0x02+X DVB-S - * QPSK FEC_7_8 0x80 0x02+X DVB-S - * QPSK FEC_8_9 0x01 0x02+X DVB-S (?) (NOT SUPPORTED?) - * QPSK AUTO 0xff 0x02+X DVB-S - * - * For DVB-S high byte probably represents FEC - * and low byte selects the modulator. The high - * byte is search range mask. Bit 5 may turn - * on DVB-S and remaining bits represent some - * kind of calibration (how/what i do not know). - * - * Eg.(2/3) szap "Zone Horror" - * - * mask/val = 0x04, 0x20 - * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK - * - * mask/val = 0x04, 0x30 - * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK - * - * After tuning FECSTATUS contains actual FEC - * in use numbered 1 through to 8 for 1/2 .. 2/3 etc - * - * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only) - * - * NBC-QPSK FEC_1_2 0x00, 0x04 DVB-S2 - * NBC-QPSK FEC_3_5 0x00, 0x05 DVB-S2 - * NBC-QPSK FEC_2_3 0x00, 0x06 DVB-S2 - * NBC-QPSK FEC_3_4 0x00, 0x07 DVB-S2 - * NBC-QPSK FEC_4_5 0x00, 0x08 DVB-S2 - * NBC-QPSK FEC_5_6 0x00, 0x09 DVB-S2 - * NBC-QPSK FEC_8_9 0x00, 0x0a DVB-S2 - * NBC-QPSK FEC_9_10 0x00, 0x0b DVB-S2 - * - * NBC-8PSK FEC_3_5 0x00, 0x0c DVB-S2 - * NBC-8PSK FEC_2_3 0x00, 0x0d DVB-S2 - * NBC-8PSK FEC_3_4 0x00, 0x0e DVB-S2 - * NBC-8PSK FEC_5_6 0x00, 0x0f DVB-S2 - * NBC-8PSK FEC_8_9 0x00, 0x10 DVB-S2 - * NBC-8PSK FEC_9_10 0x00, 0x11 DVB-S2 - * - * For DVB-S2 low bytes selects both modulator - * and FEC. High byte is meaningless here. To - * set pilot, bit 6 (0x40) is set. When inspecting - * FECSTATUS bit 7 (0x80) represents the pilot - * selection whilst not tuned. When tuned, actual FEC - * in use is found in FECSTATUS as per above. Pilot - * value is reset. - */ - -/* A table of modulation, fec and configuration bytes for the demod. - * Not all S2 mmodulation schemes are support and not all rates with - * a scheme are support. Especially, no auto detect when in S2 mode. - */ -static struct cx24116_modfec { - fe_delivery_system_t delivery_system; - fe_modulation_t modulation; - fe_code_rate_t fec; - u8 mask; /* In DVBS mode this is used to autodetect */ - u8 val; /* Passed to the firmware to indicate mode selection */ -} CX24116_MODFEC_MODES[] = { - /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */ - - /*mod fec mask val */ - { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 }, - { SYS_DVBS, QPSK, FEC_1_2, 0x02, 0x2e }, /* 00000010 00101110 */ - { SYS_DVBS, QPSK, FEC_2_3, 0x04, 0x2f }, /* 00000100 00101111 */ - { SYS_DVBS, QPSK, FEC_3_4, 0x08, 0x30 }, /* 00001000 00110000 */ - { SYS_DVBS, QPSK, FEC_4_5, 0xfe, 0x30 }, /* 000?0000 ? */ - { SYS_DVBS, QPSK, FEC_5_6, 0x20, 0x31 }, /* 00100000 00110001 */ - { SYS_DVBS, QPSK, FEC_6_7, 0xfe, 0x30 }, /* 0?000000 ? */ - { SYS_DVBS, QPSK, FEC_7_8, 0x80, 0x32 }, /* 10000000 00110010 */ - { SYS_DVBS, QPSK, FEC_8_9, 0xfe, 0x30 }, /* 0000000? ? */ - { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 }, - /* NBC-QPSK */ - { SYS_DVBS2, QPSK, FEC_1_2, 0x00, 0x04 }, - { SYS_DVBS2, QPSK, FEC_3_5, 0x00, 0x05 }, - { SYS_DVBS2, QPSK, FEC_2_3, 0x00, 0x06 }, - { SYS_DVBS2, QPSK, FEC_3_4, 0x00, 0x07 }, - { SYS_DVBS2, QPSK, FEC_4_5, 0x00, 0x08 }, - { SYS_DVBS2, QPSK, FEC_5_6, 0x00, 0x09 }, - { SYS_DVBS2, QPSK, FEC_8_9, 0x00, 0x0a }, - { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b }, - /* 8PSK */ - { SYS_DVBS2, PSK_8, FEC_3_5, 0x00, 0x0c }, - { SYS_DVBS2, PSK_8, FEC_2_3, 0x00, 0x0d }, - { SYS_DVBS2, PSK_8, FEC_3_4, 0x00, 0x0e }, - { SYS_DVBS2, PSK_8, FEC_5_6, 0x00, 0x0f }, - { SYS_DVBS2, PSK_8, FEC_8_9, 0x00, 0x10 }, - { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 }, - /* - * `val' can be found in the FECSTATUS register when tuning. - * FECSTATUS will give the actual FEC in use if tuning was successful. - */ -}; - -static int cx24116_lookup_fecmod(struct cx24116_state *state, - fe_delivery_system_t d, fe_modulation_t m, fe_code_rate_t f) -{ - int i, ret = -EOPNOTSUPP; - - dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f); - - for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) { - if ((d == CX24116_MODFEC_MODES[i].delivery_system) && - (m == CX24116_MODFEC_MODES[i].modulation) && - (f == CX24116_MODFEC_MODES[i].fec)) { - ret = i; - break; - } - } - - return ret; -} - -static int cx24116_set_fec(struct cx24116_state *state, - fe_delivery_system_t delsys, fe_modulation_t mod, fe_code_rate_t fec) -{ - int ret = 0; - - dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec); - - ret = cx24116_lookup_fecmod(state, delsys, mod, fec); - - if (ret < 0) - return ret; - - state->dnxt.fec = fec; - state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val; - state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask; - dprintk("%s() mask/val = 0x%02x/0x%02x\n", __func__, - state->dnxt.fec_mask, state->dnxt.fec_val); - - return 0; -} - -static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate) -{ - dprintk("%s(%d)\n", __func__, rate); - - /* check if symbol rate is within limits */ - if ((rate > state->frontend.ops.info.symbol_rate_max) || - (rate < state->frontend.ops.info.symbol_rate_min)) { - dprintk("%s() unsupported symbol_rate = %d\n", __func__, rate); - return -EOPNOTSUPP; - } - - state->dnxt.symbol_rate = rate; - dprintk("%s() symbol_rate = %d\n", __func__, rate); - - return 0; -} - -static int cx24116_load_firmware(struct dvb_frontend *fe, - const struct firmware *fw); - -static int cx24116_firmware_ondemand(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - const struct firmware *fw; - int ret = 0; - - dprintk("%s()\n", __func__); - - if (cx24116_readreg(state, 0x20) > 0) { - - if (state->skip_fw_load) - return 0; - - /* Load firmware */ - /* request the firmware, this will block until loaded */ - printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", - __func__, CX24116_DEFAULT_FIRMWARE); - ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, - &state->i2c->dev); - printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", - __func__); - if (ret) { - printk(KERN_ERR "%s: No firmware uploaded " - "(timeout or file not found?)\n", __func__); - return ret; - } - - /* Make sure we don't recurse back through here - * during loading */ - state->skip_fw_load = 1; - - ret = cx24116_load_firmware(fe, fw); - if (ret) - printk(KERN_ERR "%s: Writing firmware to device failed\n", - __func__); - - release_firmware(fw); - - printk(KERN_INFO "%s: Firmware upload %s\n", __func__, - ret == 0 ? "complete" : "failed"); - - /* Ensure firmware is always loaded if required */ - state->skip_fw_load = 0; - } - - return ret; -} - -/* Take a basic firmware command structure, format it - * and forward it for processing - */ -static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd) -{ - struct cx24116_state *state = fe->demodulator_priv; - int i, ret; - - dprintk("%s()\n", __func__); - - /* Load the firmware if required */ - ret = cx24116_firmware_ondemand(fe); - if (ret != 0) { - printk(KERN_ERR "%s(): Unable initialise the firmware\n", - __func__); - return ret; - } - - /* Write the command */ - for (i = 0; i < cmd->len ; i++) { - dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]); - cx24116_writereg(state, i, cmd->args[i]); - } - - /* Start execution and wait for cmd to terminate */ - cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01); - while (cx24116_readreg(state, CX24116_REG_EXECUTE)) { - msleep(10); - if (i++ > 64) { - /* Avoid looping forever if the firmware does - not respond */ - printk(KERN_WARNING "%s() Firmware not responding\n", - __func__); - return -EREMOTEIO; - } - } - return 0; -} - -static int cx24116_load_firmware(struct dvb_frontend *fe, - const struct firmware *fw) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int i, ret; - unsigned char vers[4]; - - dprintk("%s\n", __func__); - dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n", - fw->size, - fw->data[0], - fw->data[1], - fw->data[fw->size-2], - fw->data[fw->size-1]); - - /* Toggle 88x SRST pin to reset demod */ - if (state->config->reset_device) - state->config->reset_device(fe); - - /* Begin the firmware load process */ - /* Prepare the demod, load the firmware, cleanup after load */ - - /* Init PLL */ - cx24116_writereg(state, 0xE5, 0x00); - cx24116_writereg(state, 0xF1, 0x08); - cx24116_writereg(state, 0xF2, 0x13); - - /* Start PLL */ - cx24116_writereg(state, 0xe0, 0x03); - cx24116_writereg(state, 0xe0, 0x00); - - /* Unknown */ - cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46); - cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00); - - /* Unknown */ - cx24116_writereg(state, 0xF0, 0x03); - cx24116_writereg(state, 0xF4, 0x81); - cx24116_writereg(state, 0xF5, 0x00); - cx24116_writereg(state, 0xF6, 0x00); - - /* write the entire firmware as one transaction */ - cx24116_writeregN(state, 0xF7, fw->data, fw->size); - - cx24116_writereg(state, 0xF4, 0x10); - cx24116_writereg(state, 0xF0, 0x00); - cx24116_writereg(state, 0xF8, 0x06); - - /* Firmware CMD 10: VCO config */ - cmd.args[0x00] = CMD_SET_VCO; - cmd.args[0x01] = 0x05; - cmd.args[0x02] = 0xdc; - cmd.args[0x03] = 0xda; - cmd.args[0x04] = 0xae; - cmd.args[0x05] = 0xaa; - cmd.args[0x06] = 0x04; - cmd.args[0x07] = 0x9d; - cmd.args[0x08] = 0xfc; - cmd.args[0x09] = 0x06; - cmd.len = 0x0a; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00); - - /* Firmware CMD 14: Tuner config */ - cmd.args[0x00] = CMD_TUNERINIT; - cmd.args[0x01] = 0x00; - cmd.args[0x02] = 0x00; - cmd.len = 0x03; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - cx24116_writereg(state, 0xe5, 0x00); - - /* Firmware CMD 13: MPEG config */ - cmd.args[0x00] = CMD_MPEGCONFIG; - cmd.args[0x01] = 0x01; - cmd.args[0x02] = 0x75; - cmd.args[0x03] = 0x00; - if (state->config->mpg_clk_pos_pol) - cmd.args[0x04] = state->config->mpg_clk_pos_pol; - else - cmd.args[0x04] = 0x02; - cmd.args[0x05] = 0x00; - cmd.len = 0x06; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - /* Firmware CMD 35: Get firmware version */ - cmd.args[0x00] = CMD_UPDFWVERS; - cmd.len = 0x02; - for (i = 0; i < 4; i++) { - cmd.args[0x01] = i; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX); - } - printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__, - vers[0], vers[1], vers[2], vers[3]); - - return 0; -} - -static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct cx24116_state *state = fe->demodulator_priv; - - int lock = cx24116_readreg(state, CX24116_REG_SSTATUS) & - CX24116_STATUS_MASK; - - dprintk("%s: status = 0x%02x\n", __func__, lock); - - *status = 0; - - if (lock & CX24116_HAS_SIGNAL) - *status |= FE_HAS_SIGNAL; - if (lock & CX24116_HAS_CARRIER) - *status |= FE_HAS_CARRIER; - if (lock & CX24116_HAS_VITERBI) - *status |= FE_HAS_VITERBI; - if (lock & CX24116_HAS_SYNCLOCK) - *status |= FE_HAS_SYNC | FE_HAS_LOCK; - - return 0; -} - -static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct cx24116_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - *ber = (cx24116_readreg(state, CX24116_REG_BER24) << 24) | - (cx24116_readreg(state, CX24116_REG_BER16) << 16) | - (cx24116_readreg(state, CX24116_REG_BER8) << 8) | - cx24116_readreg(state, CX24116_REG_BER0); - - return 0; -} - -/* TODO Determine function and scale appropriately */ -static int cx24116_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int ret; - u16 sig_reading; - - dprintk("%s()\n", __func__); - - /* Firmware CMD 19: Get AGC */ - cmd.args[0x00] = CMD_GETAGC; - cmd.len = 0x01; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - sig_reading = - (cx24116_readreg(state, - CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) | - (cx24116_readreg(state, CX24116_REG_SIGNAL) << 6); - *signal_strength = 0 - sig_reading; - - dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", - __func__, sig_reading, *signal_strength); - - return 0; -} - -/* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */ -static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr) -{ - struct cx24116_state *state = fe->demodulator_priv; - u8 snr_reading; - static const u32 snr_tab[] = { /* 10 x Table (rounded up) */ - 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667, - 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667, - 0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667, - 0x18000 }; - - dprintk("%s()\n", __func__); - - snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0); - - if (snr_reading >= 0xa0 /* 100% */) - *snr = 0xffff; - else - *snr = snr_tab[(snr_reading & 0xf0) >> 4] + - (snr_tab[(snr_reading & 0x0f)] >> 4); - - dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__, - snr_reading, *snr); - - return 0; -} - -/* The reelbox patches show the value in the registers represents - * ESNO, from 0->30db (values 0->300). We provide this value by - * default. - */ -static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr) -{ - struct cx24116_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - *snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 | - cx24116_readreg(state, CX24116_REG_QUALITY0); - - dprintk("%s: raw 0x%04x\n", __func__, *snr); - - return 0; -} - -static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - if (esno_snr == 1) - return cx24116_read_snr_esno(fe, snr); - else - return cx24116_read_snr_pct(fe, snr); -} - -static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct cx24116_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - *ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) | - cx24116_readreg(state, CX24116_REG_UCB0); - - return 0; -} - -/* Overwrite the current tuning params, we are about to tune */ -static void cx24116_clone_params(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur)); -} - -/* Wait for LNB */ -static int cx24116_wait_for_lnb(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - int i; - - dprintk("%s() qstatus = 0x%02x\n", __func__, - cx24116_readreg(state, CX24116_REG_QSTATUS)); - - /* Wait for up to 300 ms */ - for (i = 0; i < 30 ; i++) { - if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20) - return 0; - msleep(10); - } - - dprintk("%s(): LNB not ready\n", __func__); - - 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) -{ - struct cx24116_cmd cmd; - int ret; - - dprintk("%s(%d)\n", __func__, tone); - if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { - printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone); - return -EINVAL; - } - - /* Wait for LNB ready */ - ret = cx24116_wait_for_lnb(fe); - if (ret != 0) - return ret; - - /* Min delay time after DiSEqC send */ - msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ - - /* Now we set the tone */ - cmd.args[0x00] = CMD_SET_TONE; - cmd.args[0x01] = 0x00; - cmd.args[0x02] = 0x00; - - switch (tone) { - case SEC_TONE_ON: - dprintk("%s: setting tone on\n", __func__); - cmd.args[0x03] = 0x01; - break; - case SEC_TONE_OFF: - dprintk("%s: setting tone off\n", __func__); - cmd.args[0x03] = 0x00; - break; - } - cmd.len = 0x04; - - /* Min delay time before DiSEqC send */ - msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ - - return cx24116_cmd_execute(fe, &cmd); -} - -/* Initialise DiSEqC */ -static int cx24116_diseqc_init(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int ret; - - /* Firmware CMD 20: LNB/DiSEqC config */ - cmd.args[0x00] = CMD_LNBCONFIG; - cmd.args[0x01] = 0x00; - cmd.args[0x02] = 0x10; - cmd.args[0x03] = 0x00; - cmd.args[0x04] = 0x8f; - cmd.args[0x05] = 0x28; - cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01; - cmd.args[0x07] = 0x01; - cmd.len = 0x08; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - /* Prepare a DiSEqC command */ - state->dsec_cmd.args[0x00] = CMD_LNBSEND; - - /* DiSEqC burst */ - state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A; - - /* Unknown */ - state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02; - state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00; - /* Continuation flag? */ - state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; - - /* DiSEqC message length */ - state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00; - - /* Command length */ - state->dsec_cmd.len = CX24116_DISEQC_MSGOFS; - - return 0; -} - -/* Send DiSEqC message with derived burst (hack) || previous burst */ -static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *d) -{ - struct cx24116_state *state = fe->demodulator_priv; - int i, ret; - - /* Dump DiSEqC message */ - if (debug) { - printk(KERN_INFO "cx24116: %s(", __func__); - for (i = 0 ; i < d->msg_len ;) { - printk(KERN_INFO "0x%02x", d->msg[i]); - if (++i < d->msg_len) - printk(KERN_INFO ", "); - } - printk(") toneburst=%d\n", toneburst); - } - - /* Validate length */ - if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS)) - return -EINVAL; - - /* DiSEqC message */ - for (i = 0; i < d->msg_len; i++) - state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i]; - - /* DiSEqC message length */ - state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len; - - /* Command length */ - state->dsec_cmd.len = CX24116_DISEQC_MSGOFS + - state->dsec_cmd.args[CX24116_DISEQC_MSGLEN]; - - /* DiSEqC toneburst */ - if (toneburst == CX24116_DISEQC_MESGCACHE) - /* Message is cached */ - return 0; - - else if (toneburst == CX24116_DISEQC_TONEOFF) - /* Message is sent without burst */ - state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0; - - else if (toneburst == CX24116_DISEQC_TONECACHE) { - /* - * Message is sent with derived else cached burst - * - * WRITE PORT GROUP COMMAND 38 - * - * 0/A/A: E0 10 38 F0..F3 - * 1/B/B: E0 10 38 F4..F7 - * 2/C/A: E0 10 38 F8..FB - * 3/D/B: E0 10 38 FC..FF - * - * databyte[3]= 8421:8421 - * ABCD:WXYZ - * CLR :SET - * - * WX= PORT SELECT 0..3 (X=TONEBURST) - * Y = VOLTAGE (0=13V, 1=18V) - * Z = BAND (0=LOW, 1=HIGH(22K)) - */ - if (d->msg_len >= 4 && d->msg[2] == 0x38) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = - ((d->msg[3] & 4) >> 2); - if (debug) - dprintk("%s burst=%d\n", __func__, - state->dsec_cmd.args[CX24116_DISEQC_BURST]); - } - - /* Wait for LNB ready */ - ret = cx24116_wait_for_lnb(fe); - if (ret != 0) - return ret; - - /* Wait for voltage/min repeat delay */ - msleep(100); - - /* Command */ - ret = cx24116_cmd_execute(fe, &state->dsec_cmd); - if (ret != 0) - return ret; - /* - * Wait for send - * - * Eutelsat spec: - * >15ms delay + (XXX determine if FW does this, see set_tone) - * 13.5ms per byte + - * >15ms delay + - * 12.5ms burst + - * >15ms delay (XXX determine if FW does this, see set_tone) - */ - msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + - ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60)); - - return 0; -} - -/* Send DiSEqC burst */ -static int cx24116_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) -{ - struct cx24116_state *state = fe->demodulator_priv; - int ret; - - dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst); - - /* DiSEqC burst */ - if (burst == SEC_MINI_A) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = - CX24116_DISEQC_MINI_A; - else if (burst == SEC_MINI_B) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = - CX24116_DISEQC_MINI_B; - else - return -EINVAL; - - /* DiSEqC toneburst */ - if (toneburst != CX24116_DISEQC_MESGCACHE) - /* Burst is cached */ - return 0; - - /* Burst is to be sent with cached message */ - - /* Wait for LNB ready */ - ret = cx24116_wait_for_lnb(fe); - if (ret != 0) - return ret; - - /* Wait for voltage/min repeat delay */ - msleep(100); - - /* Command */ - ret = cx24116_cmd_execute(fe, &state->dsec_cmd); - if (ret != 0) - return ret; - - /* - * Wait for send - * - * Eutelsat spec: - * >15ms delay + (XXX determine if FW does this, see set_tone) - * 13.5ms per byte + - * >15ms delay + - * 12.5ms burst + - * >15ms delay (XXX determine if FW does this, see set_tone) - */ - msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60); - - return 0; -} - -static void cx24116_release(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - dprintk("%s\n", __func__); - kfree(state); -} - -static struct dvb_frontend_ops cx24116_ops; - -struct dvb_frontend *cx24116_attach(const struct cx24116_config *config, - struct i2c_adapter *i2c) -{ - struct cx24116_state *state = NULL; - int ret; - - dprintk("%s\n", __func__); - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL); - if (state == NULL) - goto error1; - - state->config = config; - state->i2c = i2c; - - /* check if the demod is present */ - ret = (cx24116_readreg(state, 0xFF) << 8) | - cx24116_readreg(state, 0xFE); - if (ret != 0x0501) { - printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n"); - goto error2; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx24116_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error2: kfree(state); -error1: return NULL; -} -EXPORT_SYMBOL(cx24116_attach); - -/* - * Initialise or wake up device - * - * Power config will reset and load initial firmware if required - */ -static int cx24116_initfe(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int ret; - - dprintk("%s()\n", __func__); - - /* Power on */ - cx24116_writereg(state, 0xe0, 0); - cx24116_writereg(state, 0xe1, 0); - cx24116_writereg(state, 0xea, 0); - - /* Firmware CMD 36: Power config */ - cmd.args[0x00] = CMD_TUNERSLEEP; - cmd.args[0x01] = 0; - cmd.len = 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - ret = cx24116_diseqc_init(fe); - if (ret != 0) - return ret; - - /* HVR-4000 needs this */ - return cx24116_set_voltage(fe, SEC_VOLTAGE_13); -} - -/* - * Put device to sleep - */ -static int cx24116_sleep(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int ret; - - dprintk("%s()\n", __func__); - - /* Firmware CMD 36: Power config */ - cmd.args[0x00] = CMD_TUNERSLEEP; - cmd.args[0x01] = 1; - cmd.len = 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - /* Power off (Shutdown clocks) */ - cx24116_writereg(state, 0xea, 0xff); - cx24116_writereg(state, 0xe1, 1); - cx24116_writereg(state, 0xe0, 1); - - return 0; -} - -static int cx24116_set_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int cx24116_get_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -/* dvb-core told us to tune, the tv property cache will be complete, - * it's safe for is to pull values and use them for tuning purposes. - */ -static int cx24116_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct cx24116_cmd cmd; - fe_status_t tunerstat; - int i, status, ret, retune = 1; - - dprintk("%s()\n", __func__); - - switch (c->delivery_system) { - case SYS_DVBS: - dprintk("%s: DVB-S delivery system selected\n", __func__); - - /* Only QPSK is supported for DVB-S */ - if (c->modulation != QPSK) { - dprintk("%s: unsupported modulation selected (%d)\n", - __func__, c->modulation); - return -EOPNOTSUPP; - } - - /* Pilot doesn't exist in DVB-S, turn bit off */ - state->dnxt.pilot_val = CX24116_PILOT_OFF; - - /* DVB-S only supports 0.35 */ - if (c->rolloff != ROLLOFF_35) { - dprintk("%s: unsupported rolloff selected (%d)\n", - __func__, c->rolloff); - return -EOPNOTSUPP; - } - state->dnxt.rolloff_val = CX24116_ROLLOFF_035; - break; - - case SYS_DVBS2: - dprintk("%s: DVB-S2 delivery system selected\n", __func__); - - /* - * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2, - * but not hardware auto detection - */ - if (c->modulation != PSK_8 && c->modulation != QPSK) { - dprintk("%s: unsupported modulation selected (%d)\n", - __func__, c->modulation); - return -EOPNOTSUPP; - } - - switch (c->pilot) { - case PILOT_AUTO: /* Not supported but emulated */ - state->dnxt.pilot_val = (c->modulation == QPSK) - ? CX24116_PILOT_OFF : CX24116_PILOT_ON; - retune++; - break; - case PILOT_OFF: - state->dnxt.pilot_val = CX24116_PILOT_OFF; - break; - case PILOT_ON: - state->dnxt.pilot_val = CX24116_PILOT_ON; - break; - default: - dprintk("%s: unsupported pilot mode selected (%d)\n", - __func__, c->pilot); - return -EOPNOTSUPP; - } - - switch (c->rolloff) { - case ROLLOFF_20: - state->dnxt.rolloff_val = CX24116_ROLLOFF_020; - break; - case ROLLOFF_25: - state->dnxt.rolloff_val = CX24116_ROLLOFF_025; - break; - case ROLLOFF_35: - state->dnxt.rolloff_val = CX24116_ROLLOFF_035; - break; - case ROLLOFF_AUTO: /* Rolloff must be explicit */ - default: - dprintk("%s: unsupported rolloff selected (%d)\n", - __func__, c->rolloff); - return -EOPNOTSUPP; - } - break; - - default: - dprintk("%s: unsupported delivery system selected (%d)\n", - __func__, c->delivery_system); - return -EOPNOTSUPP; - } - state->dnxt.delsys = c->delivery_system; - state->dnxt.modulation = c->modulation; - state->dnxt.frequency = c->frequency; - state->dnxt.pilot = c->pilot; - state->dnxt.rolloff = c->rolloff; - - ret = cx24116_set_inversion(state, c->inversion); - if (ret != 0) - return ret; - - /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */ - ret = cx24116_set_fec(state, c->delivery_system, c->modulation, c->fec_inner); - if (ret != 0) - return ret; - - ret = cx24116_set_symbolrate(state, c->symbol_rate); - if (ret != 0) - return ret; - - /* discard the 'current' tuning parameters and prepare to tune */ - cx24116_clone_params(fe); - - dprintk("%s: delsys = %d\n", __func__, state->dcur.delsys); - dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation); - dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency); - dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__, - state->dcur.pilot, state->dcur.pilot_val); - dprintk("%s: retune = %d\n", __func__, retune); - dprintk("%s: rolloff = %d (val = 0x%02x)\n", __func__, - state->dcur.rolloff, state->dcur.rolloff_val); - dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate); - dprintk("%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__, - state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val); - dprintk("%s: Inversion = %d (val = 0x%02x)\n", __func__, - state->dcur.inversion, state->dcur.inversion_val); - - /* This is also done in advise/acquire on HVR4000 but not on LITE */ - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - - /* Set/Reset B/W */ - cmd.args[0x00] = CMD_BANDWIDTH; - cmd.args[0x01] = 0x01; - cmd.len = 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - /* Prepare a tune request */ - cmd.args[0x00] = CMD_TUNEREQUEST; - - /* Frequency */ - cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16; - cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8; - cmd.args[0x03] = (state->dcur.frequency & 0x0000ff); - - /* Symbol Rate */ - cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8; - cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff); - - /* Automatic Inversion */ - cmd.args[0x06] = state->dcur.inversion_val; - - /* Modulation / FEC / Pilot */ - cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val; - - cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8; - cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff; - cmd.args[0x0a] = 0x00; - cmd.args[0x0b] = 0x00; - cmd.args[0x0c] = state->dcur.rolloff_val; - cmd.args[0x0d] = state->dcur.fec_mask; - - if (state->dcur.symbol_rate > 30000000) { - cmd.args[0x0e] = 0x04; - cmd.args[0x0f] = 0x00; - cmd.args[0x10] = 0x01; - cmd.args[0x11] = 0x77; - cmd.args[0x12] = 0x36; - cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44); - cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01); - } else { - cmd.args[0x0e] = 0x06; - cmd.args[0x0f] = 0x00; - cmd.args[0x10] = 0x00; - cmd.args[0x11] = 0xFA; - cmd.args[0x12] = 0x24; - cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46); - cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00); - } - - cmd.len = 0x13; - - /* We need to support pilot and non-pilot tuning in the - * driver automatically. This is a workaround for because - * the demod does not support autodetect. - */ - do { - /* Reset status register */ - status = cx24116_readreg(state, CX24116_REG_SSTATUS) - & CX24116_SIGNAL_MASK; - cx24116_writereg(state, CX24116_REG_SSTATUS, status); - - /* Tune */ - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - break; - - /* - * Wait for up to 500 ms before retrying - * - * If we are able to tune then generally it occurs within 100ms. - * If it takes longer, try a different toneburst setting. - */ - for (i = 0; i < 50 ; i++) { - cx24116_read_status(fe, &tunerstat); - status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC); - if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) { - dprintk("%s: Tuned\n", __func__); - goto tuned; - } - msleep(10); - } - - dprintk("%s: Not tuned\n", __func__); - - /* Toggle pilot bit when in auto-pilot */ - if (state->dcur.pilot == PILOT_AUTO) - cmd.args[0x07] ^= CX24116_PILOT_ON; - } while (--retune); - -tuned: /* Set/Reset B/W */ - cmd.args[0x00] = CMD_BANDWIDTH; - cmd.args[0x01] = 0x00; - cmd.len = 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - return ret; -} - -static int cx24116_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, - unsigned int mode_flags, unsigned int *delay, fe_status_t *status) -{ - *delay = HZ / 5; - if (params) { - int ret = cx24116_set_frontend(fe, params); - if (ret) - return ret; - } - return cx24116_read_status(fe, status); -} - -static int cx24116_get_algo(struct dvb_frontend *fe) -{ - return DVBFE_ALGO_HW; -} - -static struct dvb_frontend_ops cx24116_ops = { - - .info = { - .name = "Conexant CX24116/CX24118", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 1011, /* kHz for QPSK frontends */ - .frequency_tolerance = 5000, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_2G_MODULATION | - FE_CAN_QPSK | FE_CAN_RECOVER - }, - - .release = cx24116_release, - - .init = cx24116_initfe, - .sleep = cx24116_sleep, - .read_status = cx24116_read_status, - .read_ber = cx24116_read_ber, - .read_signal_strength = cx24116_read_signal_strength, - .read_snr = cx24116_read_snr, - .read_ucblocks = cx24116_read_ucblocks, - .set_tone = cx24116_set_tone, - .set_voltage = cx24116_set_voltage, - .diseqc_send_master_cmd = cx24116_send_diseqc_msg, - .diseqc_send_burst = cx24116_diseqc_send_burst, - .get_frontend_algo = cx24116_get_algo, - .tune = cx24116_tune, - - .set_property = cx24116_set_property, - .get_property = cx24116_get_property, - .set_frontend = cx24116_set_frontend, -}; - -MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/media/dvb/frontends/cx24116.h b/drivers/media/dvb/frontends/cx24116.h deleted file mode 100644 index b1b76b47a14..00000000000 --- a/drivers/media/dvb/frontends/cx24116.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver - - Copyright (C) 2006 Steven Toth <stoth@linuxtv.com> - - 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 CX24116_H -#define CX24116_H - -#include <linux/dvb/frontend.h> - -struct cx24116_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* Need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); - - /* Need to reset device during firmware loading */ - int (*reset_device)(struct dvb_frontend *fe); - - /* Need to set MPEG parameters */ - u8 mpg_clk_pos_pol:0x02; -}; - -#if defined(CONFIG_DVB_CX24116) || \ - (defined(CONFIG_DVB_CX24116_MODULE) && defined(MODULE)) -extern struct dvb_frontend *cx24116_attach( - const struct cx24116_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *cx24116_attach( - const struct cx24116_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif /* CX24116_H */ diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c deleted file mode 100644 index 0592f043ea6..00000000000 --- a/drivers/media/dvb/frontends/cx24123.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* - * Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver - * - * Copyright (C) 2005 Steven Toth <stoth@linuxtv.org> - * - * Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc> - * - * Support for CX24123/CX24113-NIM by Patrick Boettcher <pb@linuxtv.org> - * - * 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 <linux/slab.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> - -#include "dvb_frontend.h" -#include "cx24123.h" - -#define XTAL 10111000 - -static int force_band; -module_param(force_band, int, 0644); -MODULE_PARM_DESC(force_band, "Force a specific band select "\ - "(1-9, default:off)."); - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); - -#define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0) -#define err(args...) do { printk(KERN_ERR "CX24123: " args); } while (0) - -#define dprintk(args...) \ - do { \ - if (debug) { \ - printk(KERN_DEBUG "CX24123: %s: ", __func__); \ - printk(args); \ - } \ - } while (0) - -struct cx24123_state { - struct i2c_adapter *i2c; - const struct cx24123_config *config; - - struct dvb_frontend frontend; - - /* Some PLL specifics for tuning */ - u32 VCAarg; - u32 VGAarg; - u32 bandselectarg; - u32 pllarg; - u32 FILTune; - - struct i2c_adapter tuner_i2c_adapter; - - u8 demod_rev; - - /* The Demod/Tuner can't easily provide these, we cache them */ - u32 currentfreq; - u32 currentsymbolrate; -}; - -/* Various tuner defaults need to be established for a given symbol rate Sps */ -static struct cx24123_AGC_val { - u32 symbolrate_low; - u32 symbolrate_high; - u32 VCAprogdata; - u32 VGAprogdata; - u32 FILTune; -} cx24123_AGC_vals[] = -{ - { - .symbolrate_low = 1000000, - .symbolrate_high = 4999999, - /* the specs recommend other values for VGA offsets, - but tests show they are wrong */ - .VGAprogdata = (1 << 19) | (0x180 << 9) | 0x1e0, - .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x07, - .FILTune = 0x27f /* 0.41 V */ - }, - { - .symbolrate_low = 5000000, - .symbolrate_high = 14999999, - .VGAprogdata = (1 << 19) | (0x180 << 9) | 0x1e0, - .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x1f, - .FILTune = 0x317 /* 0.90 V */ - }, - { - .symbolrate_low = 15000000, - .symbolrate_high = 45000000, - .VGAprogdata = (1 << 19) | (0x100 << 9) | 0x180, - .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x3f, - .FILTune = 0x145 /* 2.70 V */ - }, -}; - -/* - * Various tuner defaults need to be established for a given frequency kHz. - * fixme: The bounds on the bands do not match the doc in real life. - * fixme: Some of them have been moved, other might need adjustment. - */ -static struct cx24123_bandselect_val { - u32 freq_low; - u32 freq_high; - u32 VCOdivider; - u32 progdata; -} cx24123_bandselect_vals[] = -{ - /* band 1 */ - { - .freq_low = 950000, - .freq_high = 1074999, - .VCOdivider = 4, - .progdata = (0 << 19) | (0 << 9) | 0x40, - }, - - /* band 2 */ - { - .freq_low = 1075000, - .freq_high = 1177999, - .VCOdivider = 4, - .progdata = (0 << 19) | (0 << 9) | 0x80, - }, - - /* band 3 */ - { - .freq_low = 1178000, - .freq_high = 1295999, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x01, - }, - - /* band 4 */ - { - .freq_low = 1296000, - .freq_high = 1431999, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x02, - }, - - /* band 5 */ - { - .freq_low = 1432000, - .freq_high = 1575999, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x04, - }, - - /* band 6 */ - { - .freq_low = 1576000, - .freq_high = 1717999, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x08, - }, - - /* band 7 */ - { - .freq_low = 1718000, - .freq_high = 1855999, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x10, - }, - - /* band 8 */ - { - .freq_low = 1856000, - .freq_high = 2035999, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x20, - }, - - /* band 9 */ - { - .freq_low = 2036000, - .freq_high = 2150000, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x40, - }, -}; - -static struct { - u8 reg; - u8 data; -} cx24123_regdata[] = -{ - {0x00, 0x03}, /* Reset system */ - {0x00, 0x00}, /* Clear reset */ - {0x03, 0x07}, /* QPSK, DVB, Auto Acquisition (default) */ - {0x04, 0x10}, /* MPEG */ - {0x05, 0x04}, /* MPEG */ - {0x06, 0x31}, /* MPEG (default) */ - {0x0b, 0x00}, /* Freq search start point (default) */ - {0x0c, 0x00}, /* Demodulator sample gain (default) */ - {0x0d, 0x7f}, /* Force driver to shift until the maximum (+-10 MHz) */ - {0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */ - {0x0f, 0xfe}, /* FEC search mask (all supported codes) */ - {0x10, 0x01}, /* Default search inversion, no repeat (default) */ - {0x16, 0x00}, /* Enable reading of frequency */ - {0x17, 0x01}, /* Enable EsNO Ready Counter */ - {0x1c, 0x80}, /* Enable error counter */ - {0x20, 0x00}, /* Tuner burst clock rate = 500KHz */ - {0x21, 0x15}, /* Tuner burst mode, word length = 0x15 */ - {0x28, 0x00}, /* Enable FILTERV with positive pol., DiSEqC 2.x off */ - {0x29, 0x00}, /* DiSEqC LNB_DC off */ - {0x2a, 0xb0}, /* DiSEqC Parameters (default) */ - {0x2b, 0x73}, /* DiSEqC Tone Frequency (default) */ - {0x2c, 0x00}, /* DiSEqC Message (0x2c - 0x31) */ - {0x2d, 0x00}, - {0x2e, 0x00}, - {0x2f, 0x00}, - {0x30, 0x00}, - {0x31, 0x00}, - {0x32, 0x8c}, /* DiSEqC Parameters (default) */ - {0x33, 0x00}, /* Interrupts off (0x33 - 0x34) */ - {0x34, 0x00}, - {0x35, 0x03}, /* DiSEqC Tone Amplitude (default) */ - {0x36, 0x02}, /* DiSEqC Parameters (default) */ - {0x37, 0x3a}, /* DiSEqC Parameters (default) */ - {0x3a, 0x00}, /* Enable AGC accumulator (for signal strength) */ - {0x44, 0x00}, /* Constellation (default) */ - {0x45, 0x00}, /* Symbol count (default) */ - {0x46, 0x0d}, /* Symbol rate estimator on (default) */ - {0x56, 0xc1}, /* Error Counter = Viterbi BER */ - {0x57, 0xff}, /* Error Counter Window (default) */ - {0x5c, 0x20}, /* Acquisition AFC Expiration window (default is 0x10) */ - {0x67, 0x83}, /* Non-DCII symbol clock */ -}; - -static int cx24123_i2c_writereg(struct cx24123_state *state, - u8 i2c_addr, int reg, int data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { - .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2 - }; - int err; - - /* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, reg, data); */ - - err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - printk("%s: writereg error(err == %i, reg == 0x%02x," - " data == 0x%02x)\n", __func__, err, reg, data); - return err; - } - - return 0; -} - -static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg) -{ - int ret; - u8 b = 0; - struct i2c_msg msg[] = { - { .addr = i2c_addr, .flags = 0, .buf = ®, .len = 1 }, - { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &b, .len = 1 } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - err("%s: reg=0x%x (error=%d)\n", __func__, reg, ret); - return ret; - } - - /* printk(KERN_DEBUG "rd(%02x): %02x %02x\n", i2c_addr, reg, b); */ - - return b; -} - -#define cx24123_readreg(state, reg) \ - cx24123_i2c_readreg(state, state->config->demod_address, reg) -#define cx24123_writereg(state, reg, val) \ - cx24123_i2c_writereg(state, state->config->demod_address, reg, val) - -static int cx24123_set_inversion(struct cx24123_state *state, - fe_spectral_inversion_t inversion) -{ - u8 nom_reg = cx24123_readreg(state, 0x0e); - u8 auto_reg = cx24123_readreg(state, 0x10); - - switch (inversion) { - case INVERSION_OFF: - dprintk("inversion off\n"); - cx24123_writereg(state, 0x0e, nom_reg & ~0x80); - cx24123_writereg(state, 0x10, auto_reg | 0x80); - break; - case INVERSION_ON: - dprintk("inversion on\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x80); - cx24123_writereg(state, 0x10, auto_reg | 0x80); - break; - case INVERSION_AUTO: - dprintk("inversion auto\n"); - cx24123_writereg(state, 0x10, auto_reg & ~0x80); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int cx24123_get_inversion(struct cx24123_state *state, - fe_spectral_inversion_t *inversion) -{ - u8 val; - - val = cx24123_readreg(state, 0x1b) >> 7; - - if (val == 0) { - dprintk("read inversion off\n"); - *inversion = INVERSION_OFF; - } else { - dprintk("read inversion on\n"); - *inversion = INVERSION_ON; - } - - return 0; -} - -static int cx24123_set_fec(struct cx24123_state *state, fe_code_rate_t fec) -{ - u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07; - - if ((fec < FEC_NONE) || (fec > FEC_AUTO)) - fec = FEC_AUTO; - - /* Set the soft decision threshold */ - if (fec == FEC_1_2) - cx24123_writereg(state, 0x43, - cx24123_readreg(state, 0x43) | 0x01); - else - cx24123_writereg(state, 0x43, - cx24123_readreg(state, 0x43) & ~0x01); - - switch (fec) { - case FEC_1_2: - dprintk("set FEC to 1/2\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x01); - cx24123_writereg(state, 0x0f, 0x02); - break; - case FEC_2_3: - dprintk("set FEC to 2/3\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x02); - cx24123_writereg(state, 0x0f, 0x04); - break; - case FEC_3_4: - dprintk("set FEC to 3/4\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x03); - cx24123_writereg(state, 0x0f, 0x08); - break; - case FEC_4_5: - dprintk("set FEC to 4/5\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x04); - cx24123_writereg(state, 0x0f, 0x10); - break; - case FEC_5_6: - dprintk("set FEC to 5/6\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x05); - cx24123_writereg(state, 0x0f, 0x20); - break; - case FEC_6_7: - dprintk("set FEC to 6/7\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x06); - cx24123_writereg(state, 0x0f, 0x40); - break; - case FEC_7_8: - dprintk("set FEC to 7/8\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x07); - cx24123_writereg(state, 0x0f, 0x80); - break; - case FEC_AUTO: - dprintk("set FEC to auto\n"); - cx24123_writereg(state, 0x0f, 0xfe); - break; - default: - return -EOPNOTSUPP; - } - - return 0; -} - -static int cx24123_get_fec(struct cx24123_state *state, fe_code_rate_t *fec) -{ - int ret; - - ret = cx24123_readreg(state, 0x1b); - if (ret < 0) - return ret; - ret = ret & 0x07; - - switch (ret) { - case 1: - *fec = FEC_1_2; - break; - case 2: - *fec = FEC_2_3; - break; - case 3: - *fec = FEC_3_4; - break; - case 4: - *fec = FEC_4_5; - break; - case 5: - *fec = FEC_5_6; - break; - case 6: - *fec = FEC_6_7; - break; - case 7: - *fec = FEC_7_8; - break; - default: - /* this can happen when there's no lock */ - *fec = FEC_NONE; - } - - return 0; -} - -/* Approximation of closest integer of log2(a/b). It actually gives the - lowest integer i such that 2^i >= round(a/b) */ -static u32 cx24123_int_log2(u32 a, u32 b) -{ - u32 exp, nearest = 0; - u32 div = a / b; - if (a % b >= b / 2) - ++div; - if (div < (1 << 31)) { - for (exp = 1; div > exp; nearest++) - exp += exp; - } - return nearest; -} - -static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate) -{ - u32 tmp, sample_rate, ratio, sample_gain; - u8 pll_mult; - - /* check if symbol rate is within limits */ - if ((srate > state->frontend.ops.info.symbol_rate_max) || - (srate < state->frontend.ops.info.symbol_rate_min)) - return -EOPNOTSUPP;; - - /* choose the sampling rate high enough for the required operation, - while optimizing the power consumed by the demodulator */ - if (srate < (XTAL*2)/2) - pll_mult = 2; - else if (srate < (XTAL*3)/2) - pll_mult = 3; - else if (srate < (XTAL*4)/2) - pll_mult = 4; - else if (srate < (XTAL*5)/2) - pll_mult = 5; - else if (srate < (XTAL*6)/2) - pll_mult = 6; - else if (srate < (XTAL*7)/2) - pll_mult = 7; - else if (srate < (XTAL*8)/2) - pll_mult = 8; - else - pll_mult = 9; - - - sample_rate = pll_mult * XTAL; - - /* - SYSSymbolRate[21:0] = (srate << 23) / sample_rate - - We have to use 32 bit unsigned arithmetic without precision loss. - The maximum srate is 45000000 or 0x02AEA540. This number has - only 6 clear bits on top, hence we can shift it left only 6 bits - at a time. Borrowed from cx24110.c - */ - - tmp = srate << 6; - ratio = tmp / sample_rate; - - tmp = (tmp % sample_rate) << 6; - ratio = (ratio << 6) + (tmp / sample_rate); - - tmp = (tmp % sample_rate) << 6; - ratio = (ratio << 6) + (tmp / sample_rate); - - tmp = (tmp % sample_rate) << 5; - ratio = (ratio << 5) + (tmp / sample_rate); - - - cx24123_writereg(state, 0x01, pll_mult * 6); - - cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f); - cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff); - cx24123_writereg(state, 0x0a, ratio & 0xff); - - /* also set the demodulator sample gain */ - sample_gain = cx24123_int_log2(sample_rate, srate); - tmp = cx24123_readreg(state, 0x0c) & ~0xe0; - cx24123_writereg(state, 0x0c, tmp | sample_gain << 5); - - dprintk("srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n", - srate, ratio, sample_rate, sample_gain); - - return 0; -} - -/* - * Based on the required frequency and symbolrate, the tuner AGC has - * to be configured and the correct band selected. - * Calculate those values. - */ -static int cx24123_pll_calculate(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - u32 ndiv = 0, adiv = 0, vco_div = 0; - int i = 0; - int pump = 2; - int band = 0; - int num_bands = ARRAY_SIZE(cx24123_bandselect_vals); - struct cx24123_bandselect_val *bsv = NULL; - struct cx24123_AGC_val *agcv = NULL; - - /* Defaults for low freq, low rate */ - state->VCAarg = cx24123_AGC_vals[0].VCAprogdata; - state->VGAarg = cx24123_AGC_vals[0].VGAprogdata; - state->bandselectarg = cx24123_bandselect_vals[0].progdata; - vco_div = cx24123_bandselect_vals[0].VCOdivider; - - /* For the given symbol rate, determine the VCA, VGA and - * FILTUNE programming bits */ - for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) { - agcv = &cx24123_AGC_vals[i]; - if ((agcv->symbolrate_low <= p->u.qpsk.symbol_rate) && - (agcv->symbolrate_high >= p->u.qpsk.symbol_rate)) { - state->VCAarg = agcv->VCAprogdata; - state->VGAarg = agcv->VGAprogdata; - state->FILTune = agcv->FILTune; - } - } - - /* determine the band to use */ - if (force_band < 1 || force_band > num_bands) { - for (i = 0; i < num_bands; i++) { - bsv = &cx24123_bandselect_vals[i]; - if ((bsv->freq_low <= p->frequency) && - (bsv->freq_high >= p->frequency)) - band = i; - } - } else - band = force_band - 1; - - state->bandselectarg = cx24123_bandselect_vals[band].progdata; - vco_div = cx24123_bandselect_vals[band].VCOdivider; - - /* determine the charge pump current */ - if (p->frequency < (cx24123_bandselect_vals[band].freq_low + - cx24123_bandselect_vals[band].freq_high) / 2) - pump = 0x01; - else - pump = 0x02; - - /* Determine the N/A dividers for the requested lband freq (in kHz). */ - /* Note: the reference divider R=10, frequency is in KHz, - * XTAL is in Hz */ - ndiv = (((p->frequency * vco_div * 10) / - (2 * XTAL / 1000)) / 32) & 0x1ff; - adiv = (((p->frequency * vco_div * 10) / - (2 * XTAL / 1000)) % 32) & 0x1f; - - if (adiv == 0 && ndiv > 0) - ndiv--; - - /* control bits 11, refdiv 11, charge pump polarity 1, - * charge pump current, ndiv, adiv */ - state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | - (pump << 14) | (ndiv << 5) | adiv; - - return 0; -} - -/* - * Tuner data is 21 bits long, must be left-aligned in data. - * Tuner cx24109 is written through a dedicated 3wire interface - * on the demod chip. - */ -static int cx24123_pll_writereg(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p, u32 data) -{ - struct cx24123_state *state = fe->demodulator_priv; - unsigned long timeout; - - dprintk("pll writereg called, data=0x%08x\n", data); - - /* align the 21 bytes into to bit23 boundary */ - data = data << 3; - - /* Reset the demod pll word length to 0x15 bits */ - cx24123_writereg(state, 0x21, 0x15); - - /* write the msb 8 bits, wait for the send to be completed */ - timeout = jiffies + msecs_to_jiffies(40); - cx24123_writereg(state, 0x22, (data >> 16) & 0xff); - while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { - if (time_after(jiffies, timeout)) { - err("%s: demodulator is not responding, "\ - "possibly hung, aborting.\n", __func__); - return -EREMOTEIO; - } - msleep(10); - } - - /* send another 8 bytes, wait for the send to be completed */ - timeout = jiffies + msecs_to_jiffies(40); - cx24123_writereg(state, 0x22, (data >> 8) & 0xff); - while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { - if (time_after(jiffies, timeout)) { - err("%s: demodulator is not responding, "\ - "possibly hung, aborting.\n", __func__); - return -EREMOTEIO; - } - msleep(10); - } - - /* send the lower 5 bits of this byte, padded with 3 LBB, - * wait for the send to be completed */ - timeout = jiffies + msecs_to_jiffies(40); - cx24123_writereg(state, 0x22, (data) & 0xff); - while ((cx24123_readreg(state, 0x20) & 0x80)) { - if (time_after(jiffies, timeout)) { - err("%s: demodulator is not responding," \ - "possibly hung, aborting.\n", __func__); - return -EREMOTEIO; - } - msleep(10); - } - - /* Trigger the demod to configure the tuner */ - cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2); - cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd); - - return 0; -} - -static int cx24123_pll_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - u8 val; - - dprintk("frequency=%i\n", p->frequency); - - if (cx24123_pll_calculate(fe, p) != 0) { - err("%s: cx24123_pll_calcutate failed\n", __func__); - return -EINVAL; - } - - /* Write the new VCO/VGA */ - cx24123_pll_writereg(fe, p, state->VCAarg); - cx24123_pll_writereg(fe, p, state->VGAarg); - - /* Write the new bandselect and pll args */ - cx24123_pll_writereg(fe, p, state->bandselectarg); - cx24123_pll_writereg(fe, p, state->pllarg); - - /* set the FILTUNE voltage */ - val = cx24123_readreg(state, 0x28) & ~0x3; - cx24123_writereg(state, 0x27, state->FILTune >> 2); - cx24123_writereg(state, 0x28, val | (state->FILTune & 0x3)); - - dprintk("pll tune VCA=%d, band=%d, pll=%d\n", state->VCAarg, - state->bandselectarg, state->pllarg); - - return 0; -} - - -/* - * 0x23: - * [7:7] = BTI enabled - * [6:6] = I2C repeater enabled - * [5:5] = I2C repeater start - * [0:0] = BTI start - */ - -/* mode == 1 -> i2c-repeater, 0 -> bti */ -static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start) -{ - u8 r = cx24123_readreg(state, 0x23) & 0x1e; - if (mode) - r |= (1 << 6) | (start << 5); - else - r |= (1 << 7) | (start); - return cx24123_writereg(state, 0x23, r); -} - -static int cx24123_initfe(struct dvb_frontend *fe) -{ - struct cx24123_state *state = fe->demodulator_priv; - int i; - - dprintk("init frontend\n"); - - /* Configure the demod to a good set of defaults */ - for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++) - cx24123_writereg(state, cx24123_regdata[i].reg, - cx24123_regdata[i].data); - - /* Set the LNB polarity */ - if (state->config->lnb_polarity) - cx24123_writereg(state, 0x32, - cx24123_readreg(state, 0x32) | 0x02); - - if (state->config->dont_use_pll) - cx24123_repeater_mode(state, 1, 0); - - return 0; -} - -static int cx24123_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) -{ - struct cx24123_state *state = fe->demodulator_priv; - u8 val; - - val = cx24123_readreg(state, 0x29) & ~0x40; - - switch (voltage) { - case SEC_VOLTAGE_13: - dprintk("setting voltage 13V\n"); - return cx24123_writereg(state, 0x29, val & 0x7f); - case SEC_VOLTAGE_18: - dprintk("setting voltage 18V\n"); - return cx24123_writereg(state, 0x29, val | 0x80); - case SEC_VOLTAGE_OFF: - /* already handled in cx88-dvb */ - return 0; - default: - return -EINVAL; - }; - - return 0; -} - -/* wait for diseqc queue to become ready (or timeout) */ -static void cx24123_wait_for_diseqc(struct cx24123_state *state) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(200); - while (!(cx24123_readreg(state, 0x29) & 0x40)) { - if (time_after(jiffies, timeout)) { - err("%s: diseqc queue not ready, " \ - "command may be lost.\n", __func__); - break; - } - msleep(10); - } -} - -static int cx24123_send_diseqc_msg(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *cmd) -{ - struct cx24123_state *state = fe->demodulator_priv; - int i, val, tone; - - dprintk("\n"); - - /* stop continuous tone if enabled */ - tone = cx24123_readreg(state, 0x29); - if (tone & 0x10) - cx24123_writereg(state, 0x29, tone & ~0x50); - - /* wait for diseqc queue ready */ - cx24123_wait_for_diseqc(state); - - /* select tone mode */ - cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb); - - for (i = 0; i < cmd->msg_len; i++) - cx24123_writereg(state, 0x2C + i, cmd->msg[i]); - - val = cx24123_readreg(state, 0x29); - cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) | - ((cmd->msg_len-3) & 3)); - - /* wait for diseqc message to finish sending */ - cx24123_wait_for_diseqc(state); - - /* restart continuous tone if enabled */ - if (tone & 0x10) - cx24123_writereg(state, 0x29, tone & ~0x40); - - return 0; -} - -static int cx24123_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) -{ - struct cx24123_state *state = fe->demodulator_priv; - int val, tone; - - dprintk("\n"); - - /* stop continuous tone if enabled */ - tone = cx24123_readreg(state, 0x29); - if (tone & 0x10) - cx24123_writereg(state, 0x29, tone & ~0x50); - - /* wait for diseqc queue ready */ - cx24123_wait_for_diseqc(state); - - /* select tone mode */ - cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4); - msleep(30); - val = cx24123_readreg(state, 0x29); - if (burst == SEC_MINI_A) - cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00)); - else if (burst == SEC_MINI_B) - cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x08)); - else - return -EINVAL; - - cx24123_wait_for_diseqc(state); - cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb); - - /* restart continuous tone if enabled */ - if (tone & 0x10) - cx24123_writereg(state, 0x29, tone & ~0x40); - - return 0; -} - -static int cx24123_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct cx24123_state *state = fe->demodulator_priv; - int sync = cx24123_readreg(state, 0x14); - - *status = 0; - if (state->config->dont_use_pll) { - u32 tun_status = 0; - if (fe->ops.tuner_ops.get_status) - fe->ops.tuner_ops.get_status(fe, &tun_status); - if (tun_status & TUNER_STATUS_LOCKED) - *status |= FE_HAS_SIGNAL; - } else { - int lock = cx24123_readreg(state, 0x20); - if (lock & 0x01) - *status |= FE_HAS_SIGNAL; - } - - if (sync & 0x02) - *status |= FE_HAS_CARRIER; /* Phase locked */ - if (sync & 0x04) - *status |= FE_HAS_VITERBI; - - /* Reed-Solomon Status */ - if (sync & 0x08) - *status |= FE_HAS_SYNC; - if (sync & 0x80) - *status |= FE_HAS_LOCK; /*Full Sync */ - - return 0; -} - -/* - * Configured to return the measurement of errors in blocks, - * because no UCBLOCKS value is available, so this value doubles up - * to satisfy both measurements. - */ -static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct cx24123_state *state = fe->demodulator_priv; - - /* The true bit error rate is this value divided by - the window size (set as 256 * 255) */ - *ber = ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) | - (cx24123_readreg(state, 0x1d) << 8 | - cx24123_readreg(state, 0x1e)); - - dprintk("BER = %d\n", *ber); - - return 0; -} - -static int cx24123_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - struct cx24123_state *state = fe->demodulator_priv; - - /* larger = better */ - *signal_strength = cx24123_readreg(state, 0x3b) << 8; - - dprintk("Signal strength = %d\n", *signal_strength); - - return 0; -} - -static int cx24123_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct cx24123_state *state = fe->demodulator_priv; - - /* Inverted raw Es/N0 count, totally bogus but better than the - BER threshold. */ - *snr = 65535 - (((u16)cx24123_readreg(state, 0x18) << 8) | - (u16)cx24123_readreg(state, 0x19)); - - dprintk("read S/N index = %d\n", *snr); - - return 0; -} - -static int cx24123_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - - dprintk("\n"); - - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - - state->currentfreq = p->frequency; - state->currentsymbolrate = p->u.qpsk.symbol_rate; - - cx24123_set_inversion(state, p->inversion); - cx24123_set_fec(state, p->u.qpsk.fec_inner); - cx24123_set_symbolrate(state, p->u.qpsk.symbol_rate); - - if (!state->config->dont_use_pll) - cx24123_pll_tune(fe, p); - else if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, p); - else - err("it seems I don't have a tuner..."); - - /* Enable automatic aquisition and reset cycle */ - cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07)); - cx24123_writereg(state, 0x00, 0x10); - cx24123_writereg(state, 0x00, 0); - - if (state->config->agc_callback) - state->config->agc_callback(fe); - - return 0; -} - -static int cx24123_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - - dprintk("\n"); - - if (cx24123_get_inversion(state, &p->inversion) != 0) { - err("%s: Failed to get inversion status\n", __func__); - return -EREMOTEIO; - } - if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) { - err("%s: Failed to get fec status\n", __func__); - return -EREMOTEIO; - } - p->frequency = state->currentfreq; - p->u.qpsk.symbol_rate = state->currentsymbolrate; - - return 0; -} - -static int cx24123_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct cx24123_state *state = fe->demodulator_priv; - u8 val; - - /* wait for diseqc queue ready */ - cx24123_wait_for_diseqc(state); - - val = cx24123_readreg(state, 0x29) & ~0x40; - - switch (tone) { - case SEC_TONE_ON: - dprintk("setting tone on\n"); - return cx24123_writereg(state, 0x29, val | 0x10); - case SEC_TONE_OFF: - dprintk("setting tone off\n"); - return cx24123_writereg(state, 0x29, val & 0xef); - default: - err("CASE reached default with tone=%d\n", tone); - return -EINVAL; - } - - return 0; -} - -static int cx24123_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, - unsigned int mode_flags, - unsigned int *delay, - fe_status_t *status) -{ - int retval = 0; - - if (params != NULL) - retval = cx24123_set_frontend(fe, params); - - if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) - cx24123_read_status(fe, status); - *delay = HZ/10; - - return retval; -} - -static int cx24123_get_algo(struct dvb_frontend *fe) -{ - return 1; /* FE_ALGO_HW */ -} - -static void cx24123_release(struct dvb_frontend *fe) -{ - struct cx24123_state *state = fe->demodulator_priv; - dprintk("\n"); - i2c_del_adapter(&state->tuner_i2c_adapter); - kfree(state); -} - -static int cx24123_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msg[], int num) -{ - struct cx24123_state *state = i2c_get_adapdata(i2c_adap); - /* this repeater closes after the first stop */ - cx24123_repeater_mode(state, 1, 1); - return i2c_transfer(state->i2c, msg, num); -} - -static u32 cx24123_tuner_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm cx24123_tuner_i2c_algo = { - .master_xfer = cx24123_tuner_i2c_tuner_xfer, - .functionality = cx24123_tuner_i2c_func, -}; - -struct i2c_adapter * - cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe) -{ - struct cx24123_state *state = fe->demodulator_priv; - return &state->tuner_i2c_adapter; -} -EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter); - -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"); - if (state == NULL) { - err("Unable to kzalloc\n"); - goto error; - } - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* check if the demod is there */ - state->demod_rev = cx24123_readreg(state, 0x00); - switch (state->demod_rev) { - case 0xe1: - info("detected CX24123C\n"); - break; - case 0xd1: - info("detected CX24123\n"); - break; - default: - err("wrong demod revision: %x\n", state->demod_rev); - goto error; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx24123_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - /* create tuner i2c adapter */ - if (config->dont_use_pll) - cx24123_repeater_mode(state, 1, 0); - - strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus", - sizeof(state->tuner_i2c_adapter.name)); - state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, - state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo; - state->tuner_i2c_adapter.algo_data = NULL; - i2c_set_adapdata(&state->tuner_i2c_adapter, state); - if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) { - err("tuner i2c bus could not be initialized\n"); - goto error; - } - - return &state->frontend; - -error: - kfree(state); - - return NULL; -} -EXPORT_SYMBOL(cx24123_attach); - -static struct dvb_frontend_ops cx24123_ops = { - - .info = { - .name = "Conexant CX24123/CX24109", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 1011, /* kHz for QPSK frontends */ - .frequency_tolerance = 5000, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_RECOVER - }, - - .release = cx24123_release, - - .init = cx24123_initfe, - .set_frontend = cx24123_set_frontend, - .get_frontend = cx24123_get_frontend, - .read_status = cx24123_read_status, - .read_ber = cx24123_read_ber, - .read_signal_strength = cx24123_read_signal_strength, - .read_snr = cx24123_read_snr, - .diseqc_send_master_cmd = cx24123_send_diseqc_msg, - .diseqc_send_burst = cx24123_diseqc_send_burst, - .set_tone = cx24123_set_tone, - .set_voltage = cx24123_set_voltage, - .tune = cx24123_tune, - .get_frontend_algo = cx24123_get_algo, -}; - -MODULE_DESCRIPTION("DVB Frontend module for Conexant " \ - "CX24123/CX24109/CX24113 hardware"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h deleted file mode 100644 index 51ae866e9fe..00000000000 --- a/drivers/media/dvb/frontends/cx24123.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver - - Copyright (C) 2005 Steven Toth <stoth@linuxtv.org> - - 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 CX24123_H -#define CX24123_H - -#include <linux/dvb/frontend.h> - -struct cx24123_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* Need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); - - /* 0 = LNB voltage normal, 1 = LNB voltage inverted */ - int lnb_polarity; - - /* this device has another tuner */ - u8 dont_use_pll; - void (*agc_callback) (struct dvb_frontend *); -}; - -#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) \ - && defined(MODULE)) -extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, - struct i2c_adapter *i2c); -extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *); -#else -static inline struct dvb_frontend *cx24123_attach( - const struct cx24123_config *config, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -static struct i2c_adapter * - cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif /* CX24123_H */ diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c deleted file mode 100644 index fe895bf7b18..00000000000 --- a/drivers/media/dvb/frontends/dib0070.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner. - * - * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ -#include <linux/kernel.h> -#include <linux/i2c.h> - -#include "dvb_frontend.h" - -#include "dib0070.h" -#include "dibx000_common.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); - -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB0070: "); printk(args); printk("\n"); } } while (0) - -#define DIB0070_P1D 0x00 -#define DIB0070_P1F 0x01 -#define DIB0070_P1G 0x03 -#define DIB0070S_P1A 0x02 - -struct dib0070_state { - struct i2c_adapter *i2c; - struct dvb_frontend *fe; - const struct dib0070_config *cfg; - u16 wbd_ff_offset; - u8 revision; -}; - -static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) -{ - u8 b[2]; - struct i2c_msg msg[2] = { - { .addr = state->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, - { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 }, - }; - if (i2c_transfer(state->i2c, msg, 2) != 2) { - printk(KERN_WARNING "DiB0070 I2C read failed\n"); - return 0; - } - return (b[0] << 8) | b[1]; -} - -static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) -{ - u8 b[3] = { reg, val >> 8, val & 0xff }; - struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 }; - if (i2c_transfer(state->i2c, &msg, 1) != 1) { - printk(KERN_WARNING "DiB0070 I2C write failed\n"); - return -EREMOTEIO; - } - return 0; -} - -#define HARD_RESET(state) do { if (state->cfg->reset) { state->cfg->reset(state->fe,1); msleep(10); state->cfg->reset(state->fe,0); msleep(10); } } while (0) - -static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) -{ - struct dib0070_state *st = fe->tuner_priv; - u16 tmp = 0; - tmp = dib0070_read_reg(st, 0x02) & 0x3fff; - - switch(BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)) { - case 8000: - tmp |= (0 << 14); - break; - case 7000: - tmp |= (1 << 14); - break; - case 6000: - tmp |= (2 << 14); - break; - case 5000: - default: - tmp |= (3 << 14); - break; - } - dib0070_write_reg(st, 0x02, tmp); - return 0; -} - -static void dib0070_captrim(struct dib0070_state *st, u16 LO4) -{ - int8_t captrim, fcaptrim, step_sign, step; - u16 adc, adc_diff = 3000; - - - - dib0070_write_reg(st, 0x0f, 0xed10); - dib0070_write_reg(st, 0x17, 0x0034); - - dib0070_write_reg(st, 0x18, 0x0032); - msleep(2); - - step = captrim = fcaptrim = 64; - - do { - step /= 2; - dib0070_write_reg(st, 0x14, LO4 | captrim); - msleep(1); - adc = dib0070_read_reg(st, 0x19); - - dprintk( "CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", captrim, adc, (u32) adc*(u32)1800/(u32)1024); - - if (adc >= 400) { - adc -= 400; - step_sign = -1; - } else { - adc = 400 - adc; - step_sign = 1; - } - - if (adc < adc_diff) { - dprintk( "CAPTRIM=%hd is closer to target (%hd/%hd)", captrim, adc, adc_diff); - adc_diff = adc; - fcaptrim = captrim; - - - - } - captrim += (step_sign * step); - } while (step >= 1); - - dib0070_write_reg(st, 0x14, LO4 | fcaptrim); - dib0070_write_reg(st, 0x18, 0x07ff); -} - -#define LPF 100 // define for the loop filter 100kHz by default 16-07-06 -#define LO4_SET_VCO_HFDIV(l, v, h) l |= ((v) << 11) | ((h) << 7) -#define LO4_SET_SD(l, s) l |= ((s) << 14) | ((s) << 12) -#define LO4_SET_CTRIM(l, c) l |= (c) << 10 -static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) -{ - struct dib0070_state *st = fe->tuner_priv; - u32 freq = ch->frequency/1000 + (BAND_OF_FREQUENCY(ch->frequency/1000) == BAND_VHF ? st->cfg->freq_offset_khz_vhf : st->cfg->freq_offset_khz_uhf); - - u8 band = BAND_OF_FREQUENCY(freq), c; - - /*******************VCO***********************************/ - u16 lo4 = 0; - - u8 REFDIV, PRESC = 2; - u32 FBDiv, Rest, FREF, VCOF_kHz; - u16 Num, Den; - /*******************FrontEnd******************************/ - u16 value = 0; - - dprintk( "Tuning for Band: %hd (%d kHz)", band, freq); - - - dib0070_write_reg(st, 0x17, 0x30); - - dib0070_set_bandwidth(fe, ch); /* c is used as HF */ - switch (st->revision) { - case DIB0070S_P1A: - switch (band) { - case BAND_LBAND: - LO4_SET_VCO_HFDIV(lo4, 1, 1); - c = 2; - break; - case BAND_SBAND: - LO4_SET_VCO_HFDIV(lo4, 0, 0); - LO4_SET_CTRIM(lo4, 1);; - c = 1; - break; - case BAND_UHF: - default: - if (freq < 570000) { - LO4_SET_VCO_HFDIV(lo4, 1, 3); - PRESC = 6; c = 6; - } else if (freq < 680000) { - LO4_SET_VCO_HFDIV(lo4, 0, 2); - c = 4; - } else { - LO4_SET_VCO_HFDIV(lo4, 1, 2); - c = 4; - } - break; - } break; - - case DIB0070_P1G: - case DIB0070_P1F: - default: - switch (band) { - case BAND_FM: - LO4_SET_VCO_HFDIV(lo4, 0, 7); - c = 24; - break; - case BAND_LBAND: - LO4_SET_VCO_HFDIV(lo4, 1, 0); - c = 2; - break; - case BAND_VHF: - if (freq < 180000) { - LO4_SET_VCO_HFDIV(lo4, 0, 3); - c = 16; - } else if (freq < 190000) { - LO4_SET_VCO_HFDIV(lo4, 1, 3); - c = 16; - } else { - LO4_SET_VCO_HFDIV(lo4, 0, 6); - c = 12; - } - break; - - case BAND_UHF: - default: - if (freq < 570000) { - LO4_SET_VCO_HFDIV(lo4, 1, 5); - c = 6; - } else if (freq < 700000) { - LO4_SET_VCO_HFDIV(lo4, 0, 1); - c = 4; - } else { - LO4_SET_VCO_HFDIV(lo4, 1, 1); - c = 4; - } - break; - } - break; - } - - dprintk( "HFDIV code: %hd", (lo4 >> 7) & 0xf); - dprintk( "VCO = %hd", (lo4 >> 11) & 0x3); - - - VCOF_kHz = (c * freq) * 2; - dprintk( "VCOF in kHz: %d ((%hd*%d) << 1))",VCOF_kHz, c, freq); - - switch (band) { - case BAND_VHF: - REFDIV = (u8) ((st->cfg->clock_khz + 9999) / 10000); - break; - case BAND_FM: - REFDIV = (u8) ((st->cfg->clock_khz) / 1000); - break; - default: - REFDIV = (u8) ( st->cfg->clock_khz / 10000); - break; - } - FREF = st->cfg->clock_khz / REFDIV; - - dprintk( "REFDIV: %hd, FREF: %d", REFDIV, FREF); - - - - switch (st->revision) { - case DIB0070S_P1A: - FBDiv = (VCOF_kHz / PRESC / FREF); - Rest = (VCOF_kHz / PRESC) - FBDiv * FREF; - break; - - case DIB0070_P1G: - case DIB0070_P1F: - default: - FBDiv = (freq / (FREF / 2)); - Rest = 2 * freq - FBDiv * FREF; - break; - } - - - if (Rest < LPF) Rest = 0; - else if (Rest < 2 * LPF) Rest = 2 * LPF; - else if (Rest > (FREF - LPF)) { Rest = 0 ; FBDiv += 1; } - else if (Rest > (FREF - 2 * LPF)) Rest = FREF - 2 * LPF; - Rest = (Rest * 6528) / (FREF / 10); - dprintk( "FBDIV: %d, Rest: %d", FBDiv, Rest); - - Num = 0; - Den = 1; - - if (Rest > 0) { - LO4_SET_SD(lo4, 1); - Den = 255; - Num = (u16)Rest; - } - dprintk( "Num: %hd, Den: %hd, SD: %hd",Num, Den, (lo4 >> 12) & 0x1); - - - - dib0070_write_reg(st, 0x11, (u16)FBDiv); - - - dib0070_write_reg(st, 0x12, (Den << 8) | REFDIV); - - - dib0070_write_reg(st, 0x13, Num); - - - value = 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001; - - switch (band) { - case BAND_UHF: value |= 0x4000 | 0x0800; break; - case BAND_LBAND: value |= 0x2000 | 0x0400; break; - default: value |= 0x8000 | 0x1000; break; - } - dib0070_write_reg(st, 0x20, value); - - dib0070_captrim(st, lo4); - if (st->revision == DIB0070S_P1A) { - if (band == BAND_SBAND) - dib0070_write_reg(st, 0x15, 0x16e2); - else - dib0070_write_reg(st, 0x15, 0x56e5); - } - - - - switch (band) { - case BAND_UHF: value = 0x7c82; break; - case BAND_LBAND: value = 0x7c84; break; - default: value = 0x7c81; break; - } - dib0070_write_reg(st, 0x0f, value); - dib0070_write_reg(st, 0x06, 0x3fff); - - /* Front End */ - /* c == TUNE, value = SWITCH */ - c = 0; - value = 0; - switch (band) { - case BAND_FM: - c = 0; value = 1; - break; - - case BAND_VHF: - if (freq <= 180000) c = 0; - else if (freq <= 188200) c = 1; - else if (freq <= 196400) c = 2; - else c = 3; - value = 1; - break; - - case BAND_LBAND: - if (freq <= 1500000) c = 0; - else if (freq <= 1600000) c = 1; - else c = 3; - break; - - case BAND_SBAND: - c = 7; - dib0070_write_reg(st, 0x1d,0xFFFF); - break; - - case BAND_UHF: - default: - if (st->cfg->flip_chip) { - if (freq <= 550000) c = 0; - else if (freq <= 590000) c = 1; - else if (freq <= 666000) c = 3; - else c = 5; - } else { - if (freq <= 550000) c = 2; - else if (freq <= 650000) c = 3; - else if (freq <= 750000) c = 5; - else if (freq <= 850000) c = 6; - else c = 7; - } - value = 2; - break; - } - - /* default: LNA_MATCH=7, BIAS=3 */ - dib0070_write_reg(st, 0x07, (value << 11) | (7 << 8) | (c << 3) | (3 << 0)); - dib0070_write_reg(st, 0x08, (c << 10) | (3 << 7) | (127)); - dib0070_write_reg(st, 0x0d, 0x0d80); - - - dib0070_write_reg(st, 0x18, 0x07ff); - dib0070_write_reg(st, 0x17, 0x0033); - - return 0; -} - -static int dib0070_wakeup(struct dvb_frontend *fe) -{ - struct dib0070_state *st = fe->tuner_priv; - if (st->cfg->sleep) - st->cfg->sleep(fe, 0); - return 0; -} - -static int dib0070_sleep(struct dvb_frontend *fe) -{ - struct dib0070_state *st = fe->tuner_priv; - if (st->cfg->sleep) - st->cfg->sleep(fe, 1); - return 0; -} - -static u16 dib0070_p1f_defaults[] = - -{ - 7, 0x02, - 0x0008, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0002, - 0x0100, - - 3, 0x0d, - 0x0d80, - 0x0001, - 0x0000, - - 4, 0x11, - 0x0000, - 0x0103, - 0x0000, - 0x0000, - - 3, 0x16, - 0x0004 | 0x0040, - 0x0030, - 0x07ff, - - 6, 0x1b, - 0x4112, - 0xff00, - 0xc07f, - 0x0000, - 0x0180, - 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001, - - 0, -}; - -static void dib0070_wbd_calibration(struct dvb_frontend *fe) -{ - u16 wbd_offs; - struct dib0070_state *state = fe->tuner_priv; - - if (state->cfg->sleep) - state->cfg->sleep(fe, 0); - - dib0070_write_reg(state, 0x0f, 0x6d81); - dib0070_write_reg(state, 0x20, 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001); - msleep(9); - wbd_offs = dib0070_read_reg(state, 0x19); - dib0070_write_reg(state, 0x20, 0); - state->wbd_ff_offset = ((wbd_offs * 8 * 18 / 33 + 1) / 2); - dprintk( "WBDStart = %d (Vargen) - FF = %hd", (u32) wbd_offs * 1800/1024, state->wbd_ff_offset); - - if (state->cfg->sleep) - state->cfg->sleep(fe, 1); - -} - -u16 dib0070_wbd_offset(struct dvb_frontend *fe) -{ - struct dib0070_state *st = fe->tuner_priv; - return st->wbd_ff_offset; -} - -EXPORT_SYMBOL(dib0070_wbd_offset); -static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt) -{ - struct dib0070_state *state = fe->tuner_priv; - u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); - dprintk( "CTRL_LO5: 0x%x", lo5); - return dib0070_write_reg(state, 0x15, lo5); -} - -#define pgm_read_word(w) (*w) -static int dib0070_reset(struct dib0070_state *state) -{ - u16 l, r, *n; - - HARD_RESET(state); - - -#ifndef FORCE_SBAND_TUNER - if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1) - state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff; - else -#endif - state->revision = DIB0070S_P1A; - - /* P1F or not */ - dprintk( "Revision: %x", state->revision); - - if (state->revision == DIB0070_P1D) { - dprintk( "Error: this driver is not to be used meant for P1D or earlier"); - return -EINVAL; - } - - n = (u16 *) dib0070_p1f_defaults; - l = pgm_read_word(n++); - while (l) { - r = pgm_read_word(n++); - do { - dib0070_write_reg(state, (u8)r, pgm_read_word(n++)); - r++; - } while (--l); - l = pgm_read_word(n++); - } - - if (state->cfg->force_crystal_mode != 0) - r = state->cfg->force_crystal_mode; - else if (state->cfg->clock_khz >= 24000) - r = 1; - else - r = 2; - - r |= state->cfg->osc_buffer_state << 3; - - dib0070_write_reg(state, 0x10, r); - dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 4)); - - if (state->cfg->invert_iq) { - r = dib0070_read_reg(state, 0x02) & 0xffdf; - dib0070_write_reg(state, 0x02, r | (1 << 5)); - } - - - if (state->revision == DIB0070S_P1A) - dib0070_set_ctrl_lo5(state->fe, 4, 7, 3, 1); - else - dib0070_set_ctrl_lo5(state->fe, 4, 4, 2, 0); - - dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8); - return 0; -} - - -static int dib0070_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static struct dvb_tuner_ops dib0070_ops = { - .info = { - .name = "DiBcom DiB0070", - .frequency_min = 45000000, - .frequency_max = 860000000, - .frequency_step = 1000, - }, - .release = dib0070_release, - - .init = dib0070_wakeup, - .sleep = dib0070_sleep, - .set_params = dib0070_tune_digital, -// .get_frequency = dib0070_get_frequency, -// .get_bandwidth = dib0070_get_bandwidth -}; - -struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) -{ - struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL); - if (state == NULL) - return NULL; - - state->cfg = cfg; - state->i2c = i2c; - state->fe = fe; - fe->tuner_priv = state; - - if (dib0070_reset(state) != 0) - goto free_mem; - - dib0070_wbd_calibration(fe); - - printk(KERN_INFO "DiB0070: successfully identified\n"); - memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops)); - - fe->tuner_priv = state; - return fe; - -free_mem: - kfree(state); - fe->tuner_priv = NULL; - return NULL; -} -EXPORT_SYMBOL(dib0070_attach); - -MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); -MODULE_DESCRIPTION("Driver for the DiBcom 0070 base-band RF Tuner"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h deleted file mode 100644 index 9670f5d20cf..00000000000 --- a/drivers/media/dvb/frontends/dib0070.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner. - * - * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ -#ifndef DIB0070_H -#define DIB0070_H - -struct dvb_frontend; -struct i2c_adapter; - -#define DEFAULT_DIB0070_I2C_ADDRESS 0x60 - -struct dib0070_config { - u8 i2c_address; - - /* tuner pins controlled externally */ - int (*reset) (struct dvb_frontend *, int); - int (*sleep) (struct dvb_frontend *, int); - - /* offset in kHz */ - int freq_offset_khz_uhf; - int freq_offset_khz_vhf; - - u8 osc_buffer_state; /* 0= normal, 1= tri-state */ - u32 clock_khz; - u8 clock_pad_drive; /* (Drive + 1) * 2mA */ - - u8 invert_iq; /* invert Q - in case I or Q is inverted on the board */ - - u8 force_crystal_mode; /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */ - - u8 flip_chip; -}; - -#if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE)) -extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, - struct dib0070_config *cfg); -extern u16 dib0070_wbd_offset(struct dvb_frontend *); -#else -static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, - struct dib0070_config *cfg) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} - -static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} -#endif - -#endif diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h deleted file mode 100644 index ba917359fa6..00000000000 --- a/drivers/media/dvb/frontends/dib3000.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * public header file of the frontend drivers for mobile DVB-T demodulators - * DiBcom 3000M-B and DiBcom 3000P/M-C (http://www.dibcom.fr/) - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * based on GPL code from DibCom, which has - * - * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - * Acknowledgements - * - * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver - * sources, on which this driver (and the dvb-dibusb) are based. - * - * see Documentation/dvb/README.dibusb for more information - * - */ - -#ifndef DIB3000_H -#define DIB3000_H - -#include <linux/dvb/frontend.h> - -struct dib3000_config -{ - /* the demodulator's i2c address */ - u8 demod_address; -}; - -struct dib_fe_xfer_ops -{ - /* pid and transfer handling is done in the demodulator */ - int (*pid_parse)(struct dvb_frontend *fe, int onoff); - int (*fifo_ctrl)(struct dvb_frontend *fe, int onoff); - int (*pid_ctrl)(struct dvb_frontend *fe, int index, int pid, int onoff); - int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl); -}; - -#if defined(CONFIG_DVB_DIB3000MB) || (defined(CONFIG_DVB_DIB3000MB_MODULE) && defined(MODULE)) -extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, - struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); -#else -static inline struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, - struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_DIB3000MB - -#endif // DIB3000_H diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c deleted file mode 100644 index 136b9d2164d..00000000000 --- a/drivers/media/dvb/frontends/dib3000mb.c +++ /dev/null @@ -1,841 +0,0 @@ -/* - * Frontend driver for mobile DVB-T demodulator DiBcom 3000M-B - * DiBcom (http://www.dibcom.fr/) - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * based on GPL code from DibCom, which has - * - * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - * Acknowledgements - * - * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver - * sources, on which this driver (and the dvb-dibusb) are based. - * - * see Documentation/dvb/README.dibusb for more information - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" - -#include "dib3000.h" -#include "dib3000mb_priv.h" - -/* Version information */ -#define DRIVER_VERSION "0.1" -#define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator" -#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de" - -#ifdef CONFIG_DVB_DIBCOM_DEBUG -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able))."); -#endif -#define deb_info(args...) dprintk(0x01,args) -#define deb_i2c(args...) dprintk(0x02,args) -#define deb_srch(args...) dprintk(0x04,args) -#define deb_info(args...) dprintk(0x01,args) -#define deb_xfer(args...) dprintk(0x02,args) -#define deb_setf(args...) dprintk(0x04,args) -#define deb_getf(args...) dprintk(0x08,args) - -#ifdef CONFIG_DVB_DIBCOM_DEBUG -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able))."); -#endif - -static int dib3000_read_reg(struct dib3000_state *state, u16 reg) -{ - u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff }; - u8 rb[2]; - struct i2c_msg msg[] = { - { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 }, - { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 }, - }; - - if (i2c_transfer(state->i2c, msg, 2) != 2) - deb_i2c("i2c read error\n"); - - deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg, - (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]); - - return (rb[0] << 8) | rb[1]; -} - -static int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val) -{ - u8 b[] = { - (reg >> 8) & 0xff, reg & 0xff, - (val >> 8) & 0xff, val & 0xff, - }; - struct i2c_msg msg[] = { - { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 } - }; - deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val); - - return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0; -} - -static int dib3000_search_status(u16 irq,u16 lock) -{ - if (irq & 0x02) { - if (lock & 0x01) { - deb_srch("auto search succeeded\n"); - return 1; // auto search succeeded - } else { - deb_srch("auto search not successful\n"); - return 0; // auto search failed - } - } else if (irq & 0x01) { - deb_srch("auto search failed\n"); - return 0; // auto search failed - } - return -1; // try again -} - -/* for auto search */ -static u16 dib3000_seq[2][2][2] = /* fft,gua, inv */ - { /* fft */ - { /* gua */ - { 0, 1 }, /* 0 0 { 0,1 } */ - { 3, 9 }, /* 0 1 { 0,1 } */ - }, - { - { 2, 5 }, /* 1 0 { 0,1 } */ - { 6, 11 }, /* 1 1 { 0,1 } */ - } - }; - -static int dib3000mb_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep); - -static int dib3000mb_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep, int tuner) -{ - struct dib3000_state* state = fe->demodulator_priv; - struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; - fe_code_rate_t fe_cr = FEC_NONE; - int search_state, seq; - - if (tuner && fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fep); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - - deb_setf("bandwidth: "); - switch (ofdm->bandwidth) { - case BANDWIDTH_8_MHZ: - deb_setf("8 MHz\n"); - wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]); - wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz); - break; - case BANDWIDTH_7_MHZ: - deb_setf("7 MHz\n"); - wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]); - wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz); - break; - case BANDWIDTH_6_MHZ: - deb_setf("6 MHz\n"); - wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]); - wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz); - break; - case BANDWIDTH_AUTO: - return -EOPNOTSUPP; - default: - err("unkown bandwidth value."); - return -EINVAL; - } - } - wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4); - - deb_setf("transmission mode: "); - switch (ofdm->transmission_mode) { - case TRANSMISSION_MODE_2K: - deb_setf("2k\n"); - wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K); - break; - case TRANSMISSION_MODE_8K: - deb_setf("8k\n"); - wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_8K); - break; - case TRANSMISSION_MODE_AUTO: - deb_setf("auto\n"); - break; - default: - return -EINVAL; - } - - deb_setf("guard: "); - switch (ofdm->guard_interval) { - case GUARD_INTERVAL_1_32: - deb_setf("1_32\n"); - wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32); - break; - case GUARD_INTERVAL_1_16: - deb_setf("1_16\n"); - wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_16); - break; - case GUARD_INTERVAL_1_8: - deb_setf("1_8\n"); - wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_8); - break; - case GUARD_INTERVAL_1_4: - deb_setf("1_4\n"); - wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_4); - break; - case GUARD_INTERVAL_AUTO: - deb_setf("auto\n"); - break; - default: - return -EINVAL; - } - - deb_setf("inversion: "); - switch (fep->inversion) { - case INVERSION_OFF: - deb_setf("off\n"); - wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF); - break; - case INVERSION_AUTO: - deb_setf("auto "); - break; - case INVERSION_ON: - deb_setf("on\n"); - wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_ON); - break; - default: - return -EINVAL; - } - - deb_setf("constellation: "); - switch (ofdm->constellation) { - case QPSK: - deb_setf("qpsk\n"); - wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK); - break; - case QAM_16: - deb_setf("qam16\n"); - wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_16QAM); - break; - case QAM_64: - deb_setf("qam64\n"); - wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_64QAM); - break; - case QAM_AUTO: - break; - default: - return -EINVAL; - } - deb_setf("hierarchy: "); - switch (ofdm->hierarchy_information) { - case HIERARCHY_NONE: - deb_setf("none "); - /* fall through */ - case HIERARCHY_1: - deb_setf("alpha=1\n"); - wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1); - break; - case HIERARCHY_2: - deb_setf("alpha=2\n"); - wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2); - break; - case HIERARCHY_4: - deb_setf("alpha=4\n"); - wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4); - break; - case HIERARCHY_AUTO: - deb_setf("alpha=auto\n"); - break; - default: - return -EINVAL; - } - - deb_setf("hierarchy: "); - if (ofdm->hierarchy_information == HIERARCHY_NONE) { - deb_setf("none\n"); - wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF); - wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP); - fe_cr = ofdm->code_rate_HP; - } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) { - deb_setf("on\n"); - wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON); - wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP); - fe_cr = ofdm->code_rate_LP; - } - deb_setf("fec: "); - switch (fe_cr) { - case FEC_1_2: - deb_setf("1_2\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_1_2); - break; - case FEC_2_3: - deb_setf("2_3\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_2_3); - break; - case FEC_3_4: - deb_setf("3_4\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_3_4); - break; - case FEC_5_6: - deb_setf("5_6\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_5_6); - break; - case FEC_7_8: - deb_setf("7_8\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_7_8); - break; - case FEC_NONE: - deb_setf("none "); - break; - case FEC_AUTO: - deb_setf("auto\n"); - break; - default: - return -EINVAL; - } - - seq = dib3000_seq - [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO] - [ofdm->guard_interval == GUARD_INTERVAL_AUTO] - [fep->inversion == INVERSION_AUTO]; - - deb_setf("seq? %d\n", seq); - - wr(DIB3000MB_REG_SEQ, seq); - - wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE); - - if (ofdm->transmission_mode == TRANSMISSION_MODE_2K) { - if (ofdm->guard_interval == GUARD_INTERVAL_1_8) { - wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_2K_1_8); - } else { - wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT); - } - - wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_2K); - } else { - wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_DEFAULT); - } - - wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_OFF); - wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF); - wr(DIB3000MB_REG_MOBILE_MODE, DIB3000MB_MOBILE_MODE_OFF); - - wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_high); - - wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_ACTIVATE); - - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC + DIB3000MB_RESTART_CTRL); - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); - - /* wait for AGC lock */ - msleep(70); - - wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low); - - /* something has to be auto searched */ - if (ofdm->constellation == QAM_AUTO || - ofdm->hierarchy_information == HIERARCHY_AUTO || - fe_cr == FEC_AUTO || - fep->inversion == INVERSION_AUTO) { - int as_count=0; - - deb_setf("autosearch enabled.\n"); - - wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT); - - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH); - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); - - while ((search_state = - dib3000_search_status( - rd(DIB3000MB_REG_AS_IRQ_PENDING), - rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100) - msleep(1); - - deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count); - - if (search_state == 1) { - struct dvb_frontend_parameters feps; - if (dib3000mb_get_frontend(fe, &feps) == 0) { - deb_setf("reading tuning data from frontend succeeded.\n"); - return dib3000mb_set_frontend(fe, &feps, 0); - } - } - - } else { - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL); - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); - } - - return 0; -} - -static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) -{ - struct dib3000_state* state = fe->demodulator_priv; - - deb_info("dib3000mb is getting up.\n"); - wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP); - - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC); - - wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE); - wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE_RST); - - wr(DIB3000MB_REG_CLOCK, DIB3000MB_CLOCK_DEFAULT); - - wr(DIB3000MB_REG_ELECT_OUT_MODE, DIB3000MB_ELECT_OUT_MODE_ON); - - wr(DIB3000MB_REG_DDS_FREQ_MSB, DIB3000MB_DDS_FREQ_MSB); - wr(DIB3000MB_REG_DDS_FREQ_LSB, DIB3000MB_DDS_FREQ_LSB); - - wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]); - - wr_foreach(dib3000mb_reg_impulse_noise, - dib3000mb_impulse_noise_values[DIB3000MB_IMPNOISE_OFF]); - - wr_foreach(dib3000mb_reg_agc_gain, dib3000mb_default_agc_gain); - - wr(DIB3000MB_REG_PHASE_NOISE, DIB3000MB_PHASE_NOISE_DEFAULT); - - wr_foreach(dib3000mb_reg_phase_noise, dib3000mb_default_noise_phase); - - wr_foreach(dib3000mb_reg_lock_duration, dib3000mb_default_lock_duration); - - wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low); - - wr(DIB3000MB_REG_LOCK0_MASK, DIB3000MB_LOCK0_DEFAULT); - wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4); - wr(DIB3000MB_REG_LOCK2_MASK, DIB3000MB_LOCK2_DEFAULT); - wr(DIB3000MB_REG_SEQ, dib3000_seq[1][1][1]); - - wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz); - - wr(DIB3000MB_REG_UNK_68, DIB3000MB_UNK_68); - wr(DIB3000MB_REG_UNK_69, DIB3000MB_UNK_69); - wr(DIB3000MB_REG_UNK_71, DIB3000MB_UNK_71); - wr(DIB3000MB_REG_UNK_77, DIB3000MB_UNK_77); - wr(DIB3000MB_REG_UNK_78, DIB3000MB_UNK_78); - wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT); - wr(DIB3000MB_REG_UNK_92, DIB3000MB_UNK_92); - wr(DIB3000MB_REG_UNK_96, DIB3000MB_UNK_96); - wr(DIB3000MB_REG_UNK_97, DIB3000MB_UNK_97); - wr(DIB3000MB_REG_UNK_106, DIB3000MB_UNK_106); - wr(DIB3000MB_REG_UNK_107, DIB3000MB_UNK_107); - wr(DIB3000MB_REG_UNK_108, DIB3000MB_UNK_108); - wr(DIB3000MB_REG_UNK_122, DIB3000MB_UNK_122); - wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF); - wr(DIB3000MB_REG_BERLEN, DIB3000MB_BERLEN_DEFAULT); - - wr_foreach(dib3000mb_reg_filter_coeffs, dib3000mb_filter_coeffs); - - wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_ON); - wr(DIB3000MB_REG_MULTI_DEMOD_MSB, DIB3000MB_MULTI_DEMOD_MSB); - wr(DIB3000MB_REG_MULTI_DEMOD_LSB, DIB3000MB_MULTI_DEMOD_LSB); - - wr(DIB3000MB_REG_OUTPUT_MODE, DIB3000MB_OUTPUT_MODE_SLAVE); - - wr(DIB3000MB_REG_FIFO_142, DIB3000MB_FIFO_142); - wr(DIB3000MB_REG_MPEG2_OUT_MODE, DIB3000MB_MPEG2_OUT_MODE_188); - wr(DIB3000MB_REG_PID_PARSE, DIB3000MB_PID_PARSE_ACTIVATE); - wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT); - wr(DIB3000MB_REG_FIFO_146, DIB3000MB_FIFO_146); - wr(DIB3000MB_REG_FIFO_147, DIB3000MB_FIFO_147); - - wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF); - - return 0; -} - -static int dib3000mb_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib3000_state* state = fe->demodulator_priv; - struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; - fe_code_rate_t *cr; - u16 tps_val; - int inv_test1,inv_test2; - u32 dds_val, threshold = 0x800000; - - if (!rd(DIB3000MB_REG_TPS_LOCK)) - return 0; - - dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB); - deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB)); - if (dds_val < threshold) - inv_test1 = 0; - else if (dds_val == threshold) - inv_test1 = 1; - else - inv_test1 = 2; - - dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB); - deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB)); - if (dds_val < threshold) - inv_test2 = 0; - else if (dds_val == threshold) - inv_test2 = 1; - else - inv_test2 = 2; - - fep->inversion = - ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) || - ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ? - INVERSION_ON : INVERSION_OFF; - - deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion); - - switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) { - case DIB3000_CONSTELLATION_QPSK: - deb_getf("QPSK "); - ofdm->constellation = QPSK; - break; - case DIB3000_CONSTELLATION_16QAM: - deb_getf("QAM16 "); - ofdm->constellation = QAM_16; - break; - case DIB3000_CONSTELLATION_64QAM: - deb_getf("QAM64 "); - ofdm->constellation = QAM_64; - break; - default: - err("Unexpected constellation returned by TPS (%d)", tps_val); - break; - } - deb_getf("TPS: %d\n", tps_val); - - if (rd(DIB3000MB_REG_TPS_HRCH)) { - deb_getf("HRCH ON\n"); - cr = &ofdm->code_rate_LP; - ofdm->code_rate_HP = FEC_NONE; - switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) { - case DIB3000_ALPHA_0: - deb_getf("HIERARCHY_NONE "); - ofdm->hierarchy_information = HIERARCHY_NONE; - break; - case DIB3000_ALPHA_1: - deb_getf("HIERARCHY_1 "); - ofdm->hierarchy_information = HIERARCHY_1; - break; - case DIB3000_ALPHA_2: - deb_getf("HIERARCHY_2 "); - ofdm->hierarchy_information = HIERARCHY_2; - break; - case DIB3000_ALPHA_4: - deb_getf("HIERARCHY_4 "); - ofdm->hierarchy_information = HIERARCHY_4; - break; - default: - err("Unexpected ALPHA value returned by TPS (%d)", tps_val); - break; - } - deb_getf("TPS: %d\n", tps_val); - - tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP); - } else { - deb_getf("HRCH OFF\n"); - cr = &ofdm->code_rate_HP; - ofdm->code_rate_LP = FEC_NONE; - ofdm->hierarchy_information = HIERARCHY_NONE; - - tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP); - } - - switch (tps_val) { - case DIB3000_FEC_1_2: - deb_getf("FEC_1_2 "); - *cr = FEC_1_2; - break; - case DIB3000_FEC_2_3: - deb_getf("FEC_2_3 "); - *cr = FEC_2_3; - break; - case DIB3000_FEC_3_4: - deb_getf("FEC_3_4 "); - *cr = FEC_3_4; - break; - case DIB3000_FEC_5_6: - deb_getf("FEC_5_6 "); - *cr = FEC_4_5; - break; - case DIB3000_FEC_7_8: - deb_getf("FEC_7_8 "); - *cr = FEC_7_8; - break; - default: - err("Unexpected FEC returned by TPS (%d)", tps_val); - break; - } - deb_getf("TPS: %d\n",tps_val); - - switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) { - case DIB3000_GUARD_TIME_1_32: - deb_getf("GUARD_INTERVAL_1_32 "); - ofdm->guard_interval = GUARD_INTERVAL_1_32; - break; - case DIB3000_GUARD_TIME_1_16: - deb_getf("GUARD_INTERVAL_1_16 "); - ofdm->guard_interval = GUARD_INTERVAL_1_16; - break; - case DIB3000_GUARD_TIME_1_8: - deb_getf("GUARD_INTERVAL_1_8 "); - ofdm->guard_interval = GUARD_INTERVAL_1_8; - break; - case DIB3000_GUARD_TIME_1_4: - deb_getf("GUARD_INTERVAL_1_4 "); - ofdm->guard_interval = GUARD_INTERVAL_1_4; - break; - default: - err("Unexpected Guard Time returned by TPS (%d)", tps_val); - break; - } - deb_getf("TPS: %d\n", tps_val); - - switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) { - case DIB3000_TRANSMISSION_MODE_2K: - deb_getf("TRANSMISSION_MODE_2K "); - ofdm->transmission_mode = TRANSMISSION_MODE_2K; - break; - case DIB3000_TRANSMISSION_MODE_8K: - deb_getf("TRANSMISSION_MODE_8K "); - ofdm->transmission_mode = TRANSMISSION_MODE_8K; - break; - default: - err("unexpected transmission mode return by TPS (%d)", tps_val); - break; - } - deb_getf("TPS: %d\n", tps_val); - - return 0; -} - -static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat) -{ - struct dib3000_state* state = fe->demodulator_priv; - - *stat = 0; - - if (rd(DIB3000MB_REG_AGC_LOCK)) - *stat |= FE_HAS_SIGNAL; - if (rd(DIB3000MB_REG_CARRIER_LOCK)) - *stat |= FE_HAS_CARRIER; - if (rd(DIB3000MB_REG_VIT_LCK)) - *stat |= FE_HAS_VITERBI; - if (rd(DIB3000MB_REG_TS_SYNC_LOCK)) - *stat |= (FE_HAS_SYNC | FE_HAS_LOCK); - - deb_getf("actual status is %2x\n",*stat); - - deb_getf("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n", - rd(DIB3000MB_REG_TPS_LOCK), - rd(DIB3000MB_REG_TPS_QAM), - rd(DIB3000MB_REG_TPS_HRCH), - rd(DIB3000MB_REG_TPS_VIT_ALPHA), - rd(DIB3000MB_REG_TPS_CODE_RATE_HP), - rd(DIB3000MB_REG_TPS_CODE_RATE_LP), - rd(DIB3000MB_REG_TPS_GUARD_TIME), - rd(DIB3000MB_REG_TPS_FFT), - rd(DIB3000MB_REG_TPS_CELL_ID)); - - //*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - return 0; -} - -static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber) -{ - struct dib3000_state* state = fe->demodulator_priv; - - *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB)); - return 0; -} - -/* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */ -static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength) -{ - struct dib3000_state* state = fe->demodulator_priv; - - *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170; - return 0; -} - -static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - struct dib3000_state* state = fe->demodulator_priv; - short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER); - int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) | - rd(DIB3000MB_REG_NOISE_POWER_LSB); - *snr = (sigpow << 8) / ((icipow > 0) ? icipow : 1); - return 0; -} - -static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) -{ - struct dib3000_state* state = fe->demodulator_priv; - - *unc = rd(DIB3000MB_REG_PACKET_ERROR_RATE); - return 0; -} - -static int dib3000mb_sleep(struct dvb_frontend* fe) -{ - struct dib3000_state* state = fe->demodulator_priv; - deb_info("dib3000mb is going to bed.\n"); - wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN); - return 0; -} - -static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 800; - return 0; -} - -static int dib3000mb_fe_init_nonmobile(struct dvb_frontend* fe) -{ - return dib3000mb_fe_init(fe, 0); -} - -static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) -{ - return dib3000mb_set_frontend(fe, fep, 1); -} - -static void dib3000mb_release(struct dvb_frontend* fe) -{ - struct dib3000_state *state = fe->demodulator_priv; - kfree(state); -} - -/* pid filter and transfer stuff */ -static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff) -{ - struct dib3000_state *state = fe->demodulator_priv; - pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0); - wr(index+DIB3000MB_REG_FIRST_PID,pid); - return 0; -} - -static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff) -{ - struct dib3000_state *state = fe->demodulator_priv; - - deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling"); - if (onoff) { - wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_ACTIVATE); - } else { - wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT); - } - return 0; -} - -static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff) -{ - struct dib3000_state *state = fe->demodulator_priv; - deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling"); - wr(DIB3000MB_REG_PID_PARSE,onoff); - return 0; -} - -static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr) -{ - struct dib3000_state *state = fe->demodulator_priv; - if (onoff) { - wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr)); - } else { - wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr)); - } - return 0; -} - -static struct dvb_frontend_ops dib3000mb_ops; - -struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, - struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops) -{ - struct dib3000_state* state = NULL; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->i2c = i2c; - memcpy(&state->config,config,sizeof(struct dib3000_config)); - - /* check for the correct demod */ - if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) - goto error; - - if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - /* set the xfer operations */ - xfer_ops->pid_parse = dib3000mb_pid_parse; - xfer_ops->fifo_ctrl = dib3000mb_fifo_control; - xfer_ops->pid_ctrl = dib3000mb_pid_control; - xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl; - - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops dib3000mb_ops = { - - .info = { - .name = "DiBcom 3000M-B DVB-T", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 62500, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = dib3000mb_release, - - .init = dib3000mb_fe_init_nonmobile, - .sleep = dib3000mb_sleep, - - .set_frontend = dib3000mb_set_frontend_and_tuner, - .get_frontend = dib3000mb_get_frontend, - .get_tune_settings = dib3000mb_fe_get_tune_settings, - - .read_status = dib3000mb_read_status, - .read_ber = dib3000mb_read_ber, - .read_signal_strength = dib3000mb_read_signal_strength, - .read_snr = dib3000mb_read_snr, - .read_ucblocks = dib3000mb_read_unc_blocks, -}; - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(dib3000mb_attach); diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h deleted file mode 100644 index 1a12747fdc9..00000000000 --- a/drivers/media/dvb/frontends/dib3000mb_priv.h +++ /dev/null @@ -1,560 +0,0 @@ -/* - * dib3000mb_priv.h - * - * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - * for more information see dib3000mb.c . - */ - -#ifndef __DIB3000MB_PRIV_H_INCLUDED__ -#define __DIB3000MB_PRIV_H_INCLUDED__ - -/* info and err, taken from usb.h, if there is anything available like by default. */ -#define err(format, arg...) printk(KERN_ERR "dib3000: " format "\n" , ## arg) -#define info(format, arg...) printk(KERN_INFO "dib3000: " format "\n" , ## arg) -#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg) - -/* handy shortcuts */ -#define rd(reg) dib3000_read_reg(state,reg) - -#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \ - { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; } - -#define wr_foreach(a,v) { int i; \ - if (sizeof(a) != sizeof(v)) \ - err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\ - for (i=0; i < sizeof(a)/sizeof(u16); i++) \ - wr(a[i],v[i]); \ - } - -#define set_or(reg,val) wr(reg,rd(reg) | val) - -#define set_and(reg,val) wr(reg,rd(reg) & val) - -/* debug */ - -#ifdef CONFIG_DVB_DIBCOM_DEBUG -#define dprintk(level,args...) \ - do { if ((debug & level)) { printk(args); } } while (0) -#else -#define dprintk(args...) do { } while (0) -#endif - -/* mask for enabling a specific pid for the pid_filter */ -#define DIB3000_ACTIVATE_PID_FILTERING (0x2000) - -/* common values for tuning */ -#define DIB3000_ALPHA_0 ( 0) -#define DIB3000_ALPHA_1 ( 1) -#define DIB3000_ALPHA_2 ( 2) -#define DIB3000_ALPHA_4 ( 4) - -#define DIB3000_CONSTELLATION_QPSK ( 0) -#define DIB3000_CONSTELLATION_16QAM ( 1) -#define DIB3000_CONSTELLATION_64QAM ( 2) - -#define DIB3000_GUARD_TIME_1_32 ( 0) -#define DIB3000_GUARD_TIME_1_16 ( 1) -#define DIB3000_GUARD_TIME_1_8 ( 2) -#define DIB3000_GUARD_TIME_1_4 ( 3) - -#define DIB3000_TRANSMISSION_MODE_2K ( 0) -#define DIB3000_TRANSMISSION_MODE_8K ( 1) - -#define DIB3000_SELECT_LP ( 0) -#define DIB3000_SELECT_HP ( 1) - -#define DIB3000_FEC_1_2 ( 1) -#define DIB3000_FEC_2_3 ( 2) -#define DIB3000_FEC_3_4 ( 3) -#define DIB3000_FEC_5_6 ( 5) -#define DIB3000_FEC_7_8 ( 7) - -#define DIB3000_HRCH_OFF ( 0) -#define DIB3000_HRCH_ON ( 1) - -#define DIB3000_DDS_INVERSION_OFF ( 0) -#define DIB3000_DDS_INVERSION_ON ( 1) - -#define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8)) -#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7))) - -#define DIB3000_REG_MANUFACTOR_ID ( 1025) -#define DIB3000_I2C_ID_DIBCOM (0x01b3) - -#define DIB3000_REG_DEVICE_ID ( 1026) -#define DIB3000MB_DEVICE_ID (0x3000) -#define DIB3000MC_DEVICE_ID (0x3001) -#define DIB3000P_DEVICE_ID (0x3002) - -/* frontend state */ -struct dib3000_state { - struct i2c_adapter* i2c; - -/* configuration settings */ - struct dib3000_config config; - - struct dvb_frontend frontend; - int timing_offset; - int timing_offset_comp_done; - - fe_bandwidth_t last_tuned_bw; - u32 last_tuned_freq; -}; - -/* register addresses and some of their default values */ - -/* restart subsystems */ -#define DIB3000MB_REG_RESTART ( 0) - -#define DIB3000MB_RESTART_OFF ( 0) -#define DIB3000MB_RESTART_AUTO_SEARCH (1 << 1) -#define DIB3000MB_RESTART_CTRL (1 << 2) -#define DIB3000MB_RESTART_AGC (1 << 3) - -/* FFT size */ -#define DIB3000MB_REG_FFT ( 1) - -/* Guard time */ -#define DIB3000MB_REG_GUARD_TIME ( 2) - -/* QAM */ -#define DIB3000MB_REG_QAM ( 3) - -/* Alpha coefficient high priority Viterbi algorithm */ -#define DIB3000MB_REG_VIT_ALPHA ( 4) - -/* spectrum inversion */ -#define DIB3000MB_REG_DDS_INV ( 5) - -/* DDS frequency value (IF position) ad ? values don't match reg_3000mb.txt */ -#define DIB3000MB_REG_DDS_FREQ_MSB ( 6) -#define DIB3000MB_REG_DDS_FREQ_LSB ( 7) -#define DIB3000MB_DDS_FREQ_MSB ( 178) -#define DIB3000MB_DDS_FREQ_LSB ( 8990) - -/* timing frequency (carrier spacing) */ -static u16 dib3000mb_reg_timing_freq[] = { 8,9 }; -static u16 dib3000mb_timing_freq[][2] = { - { 126 , 48873 }, /* 6 MHz */ - { 147 , 57019 }, /* 7 MHz */ - { 168 , 65164 }, /* 8 MHz */ -}; - -/* impulse noise parameter */ -/* 36 ??? */ - -static u16 dib3000mb_reg_impulse_noise[] = { 10,11,12,15,36 }; - -enum dib3000mb_impulse_noise_type { - DIB3000MB_IMPNOISE_OFF, - DIB3000MB_IMPNOISE_MOBILE, - DIB3000MB_IMPNOISE_FIXED, - DIB3000MB_IMPNOISE_DEFAULT -}; - -static u16 dib3000mb_impulse_noise_values[][5] = { - { 0x0000, 0x0004, 0x0014, 0x01ff, 0x0399 }, /* off */ - { 0x0001, 0x0004, 0x0014, 0x01ff, 0x037b }, /* mobile */ - { 0x0001, 0x0004, 0x0020, 0x01bd, 0x0399 }, /* fixed */ - { 0x0000, 0x0002, 0x000a, 0x01ff, 0x0399 }, /* default */ -}; - -/* - * Dual Automatic-Gain-Control - * - gains RF in tuner (AGC1) - * - gains IF after filtering (AGC2) - */ - -/* also from 16 to 18 */ -static u16 dib3000mb_reg_agc_gain[] = { - 19,20,21,22,23,24,25,26,27,28,29,30,31,32 -}; - -static u16 dib3000mb_default_agc_gain[] = - { 0x0001, 52429, 623, 128, 166, 195, 61, /* RF ??? */ - 0x0001, 53766, 38011, 0, 90, 33, 23 }; /* IF ??? */ - -/* phase noise */ -/* 36 is set when setting the impulse noise */ -static u16 dib3000mb_reg_phase_noise[] = { 33,34,35,37,38 }; - -static u16 dib3000mb_default_noise_phase[] = { 2, 544, 0, 5, 4 }; - -/* lock duration */ -static u16 dib3000mb_reg_lock_duration[] = { 39,40 }; -static u16 dib3000mb_default_lock_duration[] = { 135, 135 }; - -/* AGC loop bandwidth */ -static u16 dib3000mb_reg_agc_bandwidth[] = { 43,44,45,46,47,48,49,50 }; - -static u16 dib3000mb_agc_bandwidth_low[] = - { 2088, 10, 2088, 10, 3448, 5, 3448, 5 }; -static u16 dib3000mb_agc_bandwidth_high[] = - { 2349, 5, 2349, 5, 2586, 2, 2586, 2 }; - -/* - * lock0 definition (coff_lock) - */ -#define DIB3000MB_REG_LOCK0_MASK ( 51) -#define DIB3000MB_LOCK0_DEFAULT ( 4) - -/* - * lock1 definition (cpil_lock) - * for auto search - * which values hide behind the lock masks - */ -#define DIB3000MB_REG_LOCK1_MASK ( 52) -#define DIB3000MB_LOCK1_SEARCH_4 (0x0004) -#define DIB3000MB_LOCK1_SEARCH_2048 (0x0800) -#define DIB3000MB_LOCK1_DEFAULT (0x0001) - -/* - * lock2 definition (fec_lock) */ -#define DIB3000MB_REG_LOCK2_MASK ( 53) -#define DIB3000MB_LOCK2_DEFAULT (0x0080) - -/* - * SEQ ? what was that again ... :) - * changes when, inversion, guard time and fft is - * either automatically detected or not - */ -#define DIB3000MB_REG_SEQ ( 54) - -/* bandwidth */ -static u16 dib3000mb_reg_bandwidth[] = { 55,56,57,58,59,60,61,62,63,64,65,66,67 }; -static u16 dib3000mb_bandwidth_6mhz[] = - { 0, 33, 53312, 112, 46635, 563, 36565, 0, 1000, 0, 1010, 1, 45264 }; - -static u16 dib3000mb_bandwidth_7mhz[] = - { 0, 28, 64421, 96, 39973, 483, 3255, 0, 1000, 0, 1010, 1, 45264 }; - -static u16 dib3000mb_bandwidth_8mhz[] = - { 0, 25, 23600, 84, 34976, 422, 43808, 0, 1000, 0, 1010, 1, 45264 }; - -#define DIB3000MB_REG_UNK_68 ( 68) -#define DIB3000MB_UNK_68 ( 0) - -#define DIB3000MB_REG_UNK_69 ( 69) -#define DIB3000MB_UNK_69 ( 0) - -#define DIB3000MB_REG_UNK_71 ( 71) -#define DIB3000MB_UNK_71 ( 0) - -#define DIB3000MB_REG_UNK_77 ( 77) -#define DIB3000MB_UNK_77 ( 6) - -#define DIB3000MB_REG_UNK_78 ( 78) -#define DIB3000MB_UNK_78 (0x0080) - -/* isi */ -#define DIB3000MB_REG_ISI ( 79) -#define DIB3000MB_ISI_ACTIVATE ( 0) -#define DIB3000MB_ISI_INHIBIT ( 1) - -/* sync impovement */ -#define DIB3000MB_REG_SYNC_IMPROVEMENT ( 84) -#define DIB3000MB_SYNC_IMPROVE_2K_1_8 ( 3) -#define DIB3000MB_SYNC_IMPROVE_DEFAULT ( 0) - -/* phase noise compensation inhibition */ -#define DIB3000MB_REG_PHASE_NOISE ( 87) -#define DIB3000MB_PHASE_NOISE_DEFAULT ( 0) - -#define DIB3000MB_REG_UNK_92 ( 92) -#define DIB3000MB_UNK_92 (0x0080) - -#define DIB3000MB_REG_UNK_96 ( 96) -#define DIB3000MB_UNK_96 (0x0010) - -#define DIB3000MB_REG_UNK_97 ( 97) -#define DIB3000MB_UNK_97 (0x0009) - -/* mobile mode ??? */ -#define DIB3000MB_REG_MOBILE_MODE ( 101) -#define DIB3000MB_MOBILE_MODE_ON ( 1) -#define DIB3000MB_MOBILE_MODE_OFF ( 0) - -#define DIB3000MB_REG_UNK_106 ( 106) -#define DIB3000MB_UNK_106 (0x0080) - -#define DIB3000MB_REG_UNK_107 ( 107) -#define DIB3000MB_UNK_107 (0x0080) - -#define DIB3000MB_REG_UNK_108 ( 108) -#define DIB3000MB_UNK_108 (0x0080) - -/* fft */ -#define DIB3000MB_REG_UNK_121 ( 121) -#define DIB3000MB_UNK_121_2K ( 7) -#define DIB3000MB_UNK_121_DEFAULT ( 5) - -#define DIB3000MB_REG_UNK_122 ( 122) -#define DIB3000MB_UNK_122 ( 2867) - -/* QAM for mobile mode */ -#define DIB3000MB_REG_MOBILE_MODE_QAM ( 126) -#define DIB3000MB_MOBILE_MODE_QAM_64 ( 3) -#define DIB3000MB_MOBILE_MODE_QAM_QPSK_16 ( 1) -#define DIB3000MB_MOBILE_MODE_QAM_OFF ( 0) - -/* - * data diversity when having more than one chip on-board - * see also DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY - */ -#define DIB3000MB_REG_DATA_IN_DIVERSITY ( 127) -#define DIB3000MB_DATA_DIVERSITY_IN_OFF ( 0) -#define DIB3000MB_DATA_DIVERSITY_IN_ON ( 2) - -/* vit hrch */ -#define DIB3000MB_REG_VIT_HRCH ( 128) - -/* vit code rate */ -#define DIB3000MB_REG_VIT_CODE_RATE ( 129) - -/* vit select hp */ -#define DIB3000MB_REG_VIT_HP ( 130) - -/* time frame for Bit-Error-Rate calculation */ -#define DIB3000MB_REG_BERLEN ( 135) -#define DIB3000MB_BERLEN_LONG ( 0) -#define DIB3000MB_BERLEN_DEFAULT ( 1) -#define DIB3000MB_BERLEN_MEDIUM ( 2) -#define DIB3000MB_BERLEN_SHORT ( 3) - -/* 142 - 152 FIFO parameters - * which is what ? - */ - -#define DIB3000MB_REG_FIFO_142 ( 142) -#define DIB3000MB_FIFO_142 ( 0) - -/* MPEG2 TS output mode */ -#define DIB3000MB_REG_MPEG2_OUT_MODE ( 143) -#define DIB3000MB_MPEG2_OUT_MODE_204 ( 0) -#define DIB3000MB_MPEG2_OUT_MODE_188 ( 1) - -#define DIB3000MB_REG_PID_PARSE ( 144) -#define DIB3000MB_PID_PARSE_INHIBIT ( 0) -#define DIB3000MB_PID_PARSE_ACTIVATE ( 1) - -#define DIB3000MB_REG_FIFO ( 145) -#define DIB3000MB_FIFO_INHIBIT ( 1) -#define DIB3000MB_FIFO_ACTIVATE ( 0) - -#define DIB3000MB_REG_FIFO_146 ( 146) -#define DIB3000MB_FIFO_146 ( 3) - -#define DIB3000MB_REG_FIFO_147 ( 147) -#define DIB3000MB_FIFO_147 (0x0100) - -/* - * pidfilter - * it is not a hardware pidfilter but a filter which drops all pids - * except the ones set. Necessary because of the limited USB1.1 bandwidth. - * regs 153-168 - */ - -#define DIB3000MB_REG_FIRST_PID ( 153) -#define DIB3000MB_NUM_PIDS ( 16) - -/* - * output mode - * USB devices have to use 'slave'-mode - * see also DIB3000MB_REG_ELECT_OUT_MODE - */ -#define DIB3000MB_REG_OUTPUT_MODE ( 169) -#define DIB3000MB_OUTPUT_MODE_GATED_CLK ( 0) -#define DIB3000MB_OUTPUT_MODE_CONT_CLK ( 1) -#define DIB3000MB_OUTPUT_MODE_SERIAL ( 2) -#define DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY ( 5) -#define DIB3000MB_OUTPUT_MODE_SLAVE ( 6) - -/* irq event mask */ -#define DIB3000MB_REG_IRQ_EVENT_MASK ( 170) -#define DIB3000MB_IRQ_EVENT_MASK ( 0) - -/* filter coefficients */ -static u16 dib3000mb_reg_filter_coeffs[] = { - 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, - 188, 189, 190, 191, 192, 194 -}; - -static u16 dib3000mb_filter_coeffs[] = { - 226, 160, 29, - 979, 998, 19, - 22, 1019, 1006, - 1022, 12, 6, - 1017, 1017, 3, - 6, 1019, - 1021, 2, 3, - 1, 0, -}; - -/* - * mobile algorithm (when you are moving with your device) - * but not faster than 90 km/h - */ -#define DIB3000MB_REG_MOBILE_ALGO ( 195) -#define DIB3000MB_MOBILE_ALGO_ON ( 0) -#define DIB3000MB_MOBILE_ALGO_OFF ( 1) - -/* multiple demodulators algorithm */ -#define DIB3000MB_REG_MULTI_DEMOD_MSB ( 206) -#define DIB3000MB_REG_MULTI_DEMOD_LSB ( 207) - -/* terminator, no more demods */ -#define DIB3000MB_MULTI_DEMOD_MSB ( 32767) -#define DIB3000MB_MULTI_DEMOD_LSB ( 4095) - -/* bring the device into a known */ -#define DIB3000MB_REG_RESET_DEVICE ( 1024) -#define DIB3000MB_RESET_DEVICE (0x812c) -#define DIB3000MB_RESET_DEVICE_RST ( 0) - -/* hardware clock configuration */ -#define DIB3000MB_REG_CLOCK ( 1027) -#define DIB3000MB_CLOCK_DEFAULT (0x9000) -#define DIB3000MB_CLOCK_DIVERSITY (0x92b0) - -/* power down config */ -#define DIB3000MB_REG_POWER_CONTROL ( 1028) -#define DIB3000MB_POWER_DOWN ( 1) -#define DIB3000MB_POWER_UP ( 0) - -/* electrical output mode */ -#define DIB3000MB_REG_ELECT_OUT_MODE ( 1029) -#define DIB3000MB_ELECT_OUT_MODE_OFF ( 0) -#define DIB3000MB_ELECT_OUT_MODE_ON ( 1) - -/* set the tuner i2c address */ -#define DIB3000MB_REG_TUNER ( 1089) - -/* monitoring registers (read only) */ - -/* agc loop locked (size: 1) */ -#define DIB3000MB_REG_AGC_LOCK ( 324) - -/* agc power (size: 16) */ -#define DIB3000MB_REG_AGC_POWER ( 325) - -/* agc1 value (16) */ -#define DIB3000MB_REG_AGC1_VALUE ( 326) - -/* agc2 value (16) */ -#define DIB3000MB_REG_AGC2_VALUE ( 327) - -/* total RF power (16), can be used for signal strength */ -#define DIB3000MB_REG_RF_POWER ( 328) - -/* dds_frequency with offset (24) */ -#define DIB3000MB_REG_DDS_VALUE_MSB ( 339) -#define DIB3000MB_REG_DDS_VALUE_LSB ( 340) - -/* timing offset signed (24) */ -#define DIB3000MB_REG_TIMING_OFFSET_MSB ( 341) -#define DIB3000MB_REG_TIMING_OFFSET_LSB ( 342) - -/* fft start position (13) */ -#define DIB3000MB_REG_FFT_WINDOW_POS ( 353) - -/* carriers locked (1) */ -#define DIB3000MB_REG_CARRIER_LOCK ( 355) - -/* noise power (24) */ -#define DIB3000MB_REG_NOISE_POWER_MSB ( 372) -#define DIB3000MB_REG_NOISE_POWER_LSB ( 373) - -#define DIB3000MB_REG_MOBILE_NOISE_MSB ( 374) -#define DIB3000MB_REG_MOBILE_NOISE_LSB ( 375) - -/* - * signal power (16), this and the above can be - * used to calculate the signal/noise - ratio - */ -#define DIB3000MB_REG_SIGNAL_POWER ( 380) - -/* mer (24) */ -#define DIB3000MB_REG_MER_MSB ( 381) -#define DIB3000MB_REG_MER_LSB ( 382) - -/* - * Transmission Parameter Signalling (TPS) - * the following registers can be used to get TPS-information. - * The values are according to the DVB-T standard. - */ - -/* TPS locked (1) */ -#define DIB3000MB_REG_TPS_LOCK ( 394) - -/* QAM from TPS (2) (values according to DIB3000MB_REG_QAM) */ -#define DIB3000MB_REG_TPS_QAM ( 398) - -/* hierarchy from TPS (1) */ -#define DIB3000MB_REG_TPS_HRCH ( 399) - -/* alpha from TPS (3) (values according to DIB3000MB_REG_VIT_ALPHA) */ -#define DIB3000MB_REG_TPS_VIT_ALPHA ( 400) - -/* code rate high priority from TPS (3) (values according to DIB3000MB_FEC_*) */ -#define DIB3000MB_REG_TPS_CODE_RATE_HP ( 401) - -/* code rate low priority from TPS (3) if DIB3000MB_REG_TPS_VIT_ALPHA */ -#define DIB3000MB_REG_TPS_CODE_RATE_LP ( 402) - -/* guard time from TPS (2) (values according to DIB3000MB_REG_GUARD_TIME */ -#define DIB3000MB_REG_TPS_GUARD_TIME ( 403) - -/* fft size from TPS (2) (values according to DIB3000MB_REG_FFT) */ -#define DIB3000MB_REG_TPS_FFT ( 404) - -/* cell id from TPS (16) */ -#define DIB3000MB_REG_TPS_CELL_ID ( 406) - -/* TPS (68) */ -#define DIB3000MB_REG_TPS_1 ( 408) -#define DIB3000MB_REG_TPS_2 ( 409) -#define DIB3000MB_REG_TPS_3 ( 410) -#define DIB3000MB_REG_TPS_4 ( 411) -#define DIB3000MB_REG_TPS_5 ( 412) - -/* bit error rate (before RS correction) (21) */ -#define DIB3000MB_REG_BER_MSB ( 414) -#define DIB3000MB_REG_BER_LSB ( 415) - -/* packet error rate (uncorrected TS packets) (16) */ -#define DIB3000MB_REG_PACKET_ERROR_RATE ( 417) - -/* uncorrected packet count (16) */ -#define DIB3000MB_REG_UNC ( 420) - -/* viterbi locked (1) */ -#define DIB3000MB_REG_VIT_LCK ( 421) - -/* viterbi inidcator (16) */ -#define DIB3000MB_REG_VIT_INDICATOR ( 422) - -/* transport stream sync lock (1) */ -#define DIB3000MB_REG_TS_SYNC_LOCK ( 423) - -/* transport stream RS lock (1) */ -#define DIB3000MB_REG_TS_RS_LOCK ( 424) - -/* lock mask 0 value (1) */ -#define DIB3000MB_REG_LOCK0_VALUE ( 425) - -/* lock mask 1 value (1) */ -#define DIB3000MB_REG_LOCK1_VALUE ( 426) - -/* lock mask 2 value (1) */ -#define DIB3000MB_REG_LOCK2_VALUE ( 427) - -/* interrupt pending for auto search */ -#define DIB3000MB_REG_AS_IRQ_PENDING ( 434) - -#endif diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c deleted file mode 100644 index fa851601e7d..00000000000 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ /dev/null @@ -1,924 +0,0 @@ -/* - * Driver for DiBcom DiB3000MC/P-demodulator. - * - * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/) - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * This code is partially based on the previous dib3000mc.c . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ - -#include <linux/kernel.h> -#include <linux/i2c.h> - -#include "dvb_frontend.h" - -#include "dib3000mc.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); - -static int buggy_sfn_workaround; -module_param(buggy_sfn_workaround, int, 0644); -MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)"); - -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0) - -struct dib3000mc_state { - struct dvb_frontend demod; - struct dib3000mc_config *cfg; - - u8 i2c_addr; - struct i2c_adapter *i2c_adap; - - struct dibx000_i2c_master i2c_master; - - u32 timf; - - fe_bandwidth_t current_bandwidth; - - u16 dev_id; - - u8 sfn_workaround_active :1; -}; - -static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg) -{ - u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff }; - u8 rb[2]; - struct i2c_msg msg[2] = { - { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, - { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, - }; - - if (i2c_transfer(state->i2c_adap, msg, 2) != 2) - dprintk("i2c read error on %d\n",reg); - - return (rb[0] << 8) | rb[1]; -} - -static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val) -{ - u8 b[4] = { - (reg >> 8) & 0xff, reg & 0xff, - (val >> 8) & 0xff, val & 0xff, - }; - struct i2c_msg msg = { - .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 - }; - return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; -} - -static int dib3000mc_identify(struct dib3000mc_state *state) -{ - u16 value; - if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) { - dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value); - return -EREMOTEIO; - } - - value = dib3000mc_read_word(state, 1026); - if (value != 0x3001 && value != 0x3002) { - dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value); - return -EREMOTEIO; - } - state->dev_id = value; - - dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id); - - return 0; -} - -static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset) -{ - u32 timf; - - if (state->timf == 0) { - timf = 1384402; // default value for 8MHz - if (update_offset) - msleep(200); // first time we do an update - } else - timf = state->timf; - - timf *= (bw / 1000); - - if (update_offset) { - s16 tim_offs = dib3000mc_read_word(state, 416); - - if (tim_offs & 0x2000) - tim_offs -= 0x4000; - - if (nfft == TRANSMISSION_MODE_2K) - tim_offs *= 4; - - timf += tim_offs; - state->timf = timf / (bw / 1000); - } - - dprintk("timf: %d\n", timf); - - dib3000mc_write_word(state, 23, (u16) (timf >> 16)); - dib3000mc_write_word(state, 24, (u16) (timf ) & 0xffff); - - return 0; -} - -static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state) -{ - u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb; - if (state->cfg->pwm3_inversion) { - reg_51 = (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0); - reg_52 |= (1 << 2); - } else { - reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0); - reg_52 |= (1 << 8); - } - dib3000mc_write_word(state, 51, reg_51); - dib3000mc_write_word(state, 52, reg_52); - - if (state->cfg->use_pwm3) - dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0)); - else - dib3000mc_write_word(state, 245, 0); - - dib3000mc_write_word(state, 1040, 0x3); - return 0; -} - -static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode) -{ - int ret = 0; - u16 fifo_threshold = 1792; - u16 outreg = 0; - u16 outmode = 0; - u16 elecout = 1; - u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */ - - dprintk("-I- Setting output mode for demod %p to %d\n", - &state->demod, mode); - - switch (mode) { - case OUTMODE_HIGH_Z: // disable - elecout = 0; - break; - case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock - outmode = 0; - break; - case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock - outmode = 1; - break; - case OUTMODE_MPEG2_SERIAL: // STBs with serial input - outmode = 2; - break; - case OUTMODE_MPEG2_FIFO: // e.g. USB feeding - elecout = 3; - /*ADDR @ 206 : - P_smo_error_discard [1;6:6] = 0 - P_smo_rs_discard [1;5:5] = 0 - P_smo_pid_parse [1;4:4] = 0 - P_smo_fifo_flush [1;3:3] = 0 - P_smo_mode [2;2:1] = 11 - P_smo_ovf_prot [1;0:0] = 0 - */ - smo_reg |= 3 << 1; - fifo_threshold = 512; - outmode = 5; - break; - case OUTMODE_DIVERSITY: - outmode = 4; - elecout = 1; - break; - default: - dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod); - outmode = 0; - break; - } - - if ((state->cfg->output_mpeg2_in_188_bytes)) - smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1 - - outreg = dib3000mc_read_word(state, 244) & 0x07FF; - outreg |= (outmode << 11); - ret |= dib3000mc_write_word(state, 244, outreg); - ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/ - ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */ - ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */ - return ret; -} - -static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw) -{ - u16 bw_cfg[6] = { 0 }; - u16 imp_bw_cfg[3] = { 0 }; - u16 reg; - -/* settings here are for 27.7MHz */ - switch (bw) { - case 8000: - bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20; - imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7; - break; - - case 7000: - bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7; - imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0; - break; - - case 6000: - bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5; - imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089; - break; - - case 5000: - bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500; - imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072; - break; - - default: return -EINVAL; - } - - for (reg = 6; reg < 12; reg++) - dib3000mc_write_word(state, reg, bw_cfg[reg - 6]); - dib3000mc_write_word(state, 12, 0x0000); - dib3000mc_write_word(state, 13, 0x03e8); - dib3000mc_write_word(state, 14, 0x0000); - dib3000mc_write_word(state, 15, 0x03f2); - dib3000mc_write_word(state, 16, 0x0001); - dib3000mc_write_word(state, 17, 0xb0d0); - // P_sec_len - dib3000mc_write_word(state, 18, 0x0393); - dib3000mc_write_word(state, 19, 0x8700); - - for (reg = 55; reg < 58; reg++) - dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]); - - // Timing configuration - dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0); - - return 0; -} - -static u16 impulse_noise_val[29] = - -{ - 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3, - 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2, - 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd -}; - -static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft) -{ - u16 i; - for (i = 58; i < 87; i++) - dib3000mc_write_word(state, i, impulse_noise_val[i-58]); - - if (nfft == TRANSMISSION_MODE_8K) { - dib3000mc_write_word(state, 58, 0x3b); - dib3000mc_write_word(state, 84, 0x00); - dib3000mc_write_word(state, 85, 0x8200); - } - - dib3000mc_write_word(state, 34, 0x1294); - dib3000mc_write_word(state, 35, 0x1ff8); - if (mode == 1) - dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10)); -} - -static int dib3000mc_init(struct dvb_frontend *demod) -{ - struct dib3000mc_state *state = demod->demodulator_priv; - struct dibx000_agc_config *agc = state->cfg->agc; - - // Restart Configuration - dib3000mc_write_word(state, 1027, 0x8000); - dib3000mc_write_word(state, 1027, 0x0000); - - // power up the demod + mobility configuration - dib3000mc_write_word(state, 140, 0x0000); - dib3000mc_write_word(state, 1031, 0); - - if (state->cfg->mobile_mode) { - dib3000mc_write_word(state, 139, 0x0000); - dib3000mc_write_word(state, 141, 0x0000); - dib3000mc_write_word(state, 175, 0x0002); - dib3000mc_write_word(state, 1032, 0x0000); - } else { - dib3000mc_write_word(state, 139, 0x0001); - dib3000mc_write_word(state, 141, 0x0000); - dib3000mc_write_word(state, 175, 0x0000); - dib3000mc_write_word(state, 1032, 0x012C); - } - dib3000mc_write_word(state, 1033, 0x0000); - - // P_clk_cfg - dib3000mc_write_word(state, 1037, 0x3130); - - // other configurations - - // P_ctrl_sfreq - dib3000mc_write_word(state, 33, (5 << 0)); - dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0)); - - // Phase noise control - // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange - dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0)); - - if (state->cfg->phase_noise_mode == 0) - dib3000mc_write_word(state, 111, 0x00); - else - dib3000mc_write_word(state, 111, 0x02); - - // P_agc_global - dib3000mc_write_word(state, 50, 0x8000); - - // agc setup misc - dib3000mc_setup_pwm_state(state); - - // P_agc_counter_lock - dib3000mc_write_word(state, 53, 0x87); - // P_agc_counter_unlock - dib3000mc_write_word(state, 54, 0x87); - - /* agc */ - dib3000mc_write_word(state, 36, state->cfg->max_time); - dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0)); - dib3000mc_write_word(state, 38, state->cfg->pwm3_value); - dib3000mc_write_word(state, 39, state->cfg->ln_adc_level); - - // set_agc_loop_Bw - dib3000mc_write_word(state, 40, 0x0179); - dib3000mc_write_word(state, 41, 0x03f0); - - dib3000mc_write_word(state, 42, agc->agc1_max); - dib3000mc_write_word(state, 43, agc->agc1_min); - dib3000mc_write_word(state, 44, agc->agc2_max); - dib3000mc_write_word(state, 45, agc->agc2_min); - dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2); - dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2); - dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2); - dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2); - -// Begin: TimeOut registers - // P_pha3_thres - dib3000mc_write_word(state, 110, 3277); - // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80 - dib3000mc_write_word(state, 26, 0x6680); - // lock_mask0 - dib3000mc_write_word(state, 1, 4); - // lock_mask1 - dib3000mc_write_word(state, 2, 4); - // lock_mask2 - dib3000mc_write_word(state, 3, 0x1000); - // P_search_maxtrial=1 - dib3000mc_write_word(state, 5, 1); - - dib3000mc_set_bandwidth(state, 8000); - - // div_lock_mask - dib3000mc_write_word(state, 4, 0x814); - - dib3000mc_write_word(state, 21, (1 << 9) | 0x164); - dib3000mc_write_word(state, 22, 0x463d); - - // Spurious rm cfg - // P_cspu_regul, P_cspu_win_cut - dib3000mc_write_word(state, 120, 0x200f); - // P_adp_selec_monit - dib3000mc_write_word(state, 134, 0); - - // Fec cfg - dib3000mc_write_word(state, 195, 0x10); - - // diversity register: P_dvsy_sync_wait.. - dib3000mc_write_word(state, 180, 0x2FF0); - - // Impulse noise configuration - dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K); - - // output mode set-up - dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z); - - /* close the i2c-gate */ - dib3000mc_write_word(state, 769, (1 << 7) ); - - return 0; -} - -static int dib3000mc_sleep(struct dvb_frontend *demod) -{ - struct dib3000mc_state *state = demod->demodulator_priv; - - dib3000mc_write_word(state, 1031, 0xFFFF); - dib3000mc_write_word(state, 1032, 0xFFFF); - dib3000mc_write_word(state, 1033, 0xFFF0); - - return 0; -} - -static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam) -{ - u16 cfg[4] = { 0 },reg; - switch (qam) { - case QPSK: - cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0; - break; - case QAM_16: - cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0; - break; - case QAM_64: - cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8; - break; - } - for (reg = 129; reg < 133; reg++) - dib3000mc_write_word(state, reg, cfg[reg - 129]); -} - -static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_frontend_parameters *ch, u16 seq) -{ - u16 value; - dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); - dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 0); - -// if (boost) -// dib3000mc_write_word(state, 100, (11 << 6) + 6); -// else - dib3000mc_write_word(state, 100, (16 << 6) + 9); - - dib3000mc_write_word(state, 1027, 0x0800); - dib3000mc_write_word(state, 1027, 0x0000); - - //Default cfg isi offset adp - dib3000mc_write_word(state, 26, 0x6680); - dib3000mc_write_word(state, 29, 0x1273); - dib3000mc_write_word(state, 33, 5); - dib3000mc_set_adp_cfg(state, QAM_16); - dib3000mc_write_word(state, 133, 15564); - - dib3000mc_write_word(state, 12 , 0x0); - dib3000mc_write_word(state, 13 , 0x3e8); - dib3000mc_write_word(state, 14 , 0x0); - dib3000mc_write_word(state, 15 , 0x3f2); - - dib3000mc_write_word(state, 93,0); - dib3000mc_write_word(state, 94,0); - dib3000mc_write_word(state, 95,0); - dib3000mc_write_word(state, 96,0); - dib3000mc_write_word(state, 97,0); - dib3000mc_write_word(state, 98,0); - - dib3000mc_set_impulse_noise(state, 0, ch->u.ofdm.transmission_mode); - - value = 0; - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: value |= (0 << 7); break; - default: - case TRANSMISSION_MODE_8K: value |= (1 << 7); break; - } - switch (ch->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_32: value |= (0 << 5); break; - case GUARD_INTERVAL_1_16: value |= (1 << 5); break; - case GUARD_INTERVAL_1_4: value |= (3 << 5); break; - default: - case GUARD_INTERVAL_1_8: value |= (2 << 5); break; - } - switch (ch->u.ofdm.constellation) { - case QPSK: value |= (0 << 3); break; - case QAM_16: value |= (1 << 3); break; - default: - case QAM_64: value |= (2 << 3); break; - } - switch (HIERARCHY_1) { - case HIERARCHY_2: value |= 2; break; - case HIERARCHY_4: value |= 4; break; - default: - case HIERARCHY_1: value |= 1; break; - } - dib3000mc_write_word(state, 0, value); - dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4)); - - value = 0; - if (ch->u.ofdm.hierarchy_information == 1) - value |= (1 << 4); - if (1 == 1) - value |= 1; - switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) { - case FEC_2_3: value |= (2 << 1); break; - case FEC_3_4: value |= (3 << 1); break; - case FEC_5_6: value |= (5 << 1); break; - case FEC_7_8: value |= (7 << 1); break; - default: - case FEC_1_2: value |= (1 << 1); break; - } - dib3000mc_write_word(state, 181, value); - - // diversity synchro delay add 50% SFN margin - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_8K: value = 256; break; - case TRANSMISSION_MODE_2K: - default: value = 64; break; - } - switch (ch->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_16: value *= 2; break; - case GUARD_INTERVAL_1_8: value *= 4; break; - case GUARD_INTERVAL_1_4: value *= 8; break; - default: - case GUARD_INTERVAL_1_32: value *= 1; break; - } - value <<= 4; - value |= dib3000mc_read_word(state, 180) & 0x000f; - dib3000mc_write_word(state, 180, value); - - // restart demod - value = dib3000mc_read_word(state, 0); - dib3000mc_write_word(state, 0, value | (1 << 9)); - dib3000mc_write_word(state, 0, value); - - msleep(30); - - dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->u.ofdm.transmission_mode); -} - -static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *chan) -{ - struct dib3000mc_state *state = demod->demodulator_priv; - u16 reg; -// u32 val; - struct dvb_frontend_parameters schan; - - schan = *chan; - - /* TODO what is that ? */ - - /* a channel for autosearch */ - schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - schan.u.ofdm.constellation = QAM_64; - schan.u.ofdm.code_rate_HP = FEC_2_3; - schan.u.ofdm.code_rate_LP = FEC_2_3; - schan.u.ofdm.hierarchy_information = 0; - - dib3000mc_set_channel_cfg(state, &schan, 11); - - reg = dib3000mc_read_word(state, 0); - dib3000mc_write_word(state, 0, reg | (1 << 8)); - dib3000mc_read_word(state, 511); - dib3000mc_write_word(state, 0, reg); - - return 0; -} - -static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod) -{ - struct dib3000mc_state *state = demod->demodulator_priv; - u16 irq_pending = dib3000mc_read_word(state, 511); - - if (irq_pending & 0x1) // failed - return 1; - - if (irq_pending & 0x2) // succeeded - return 2; - - return 0; // still pending -} - -static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib3000mc_state *state = demod->demodulator_priv; - - // ** configure demod ** - dib3000mc_set_channel_cfg(state, ch, 0); - - // activates isi - if (state->sfn_workaround_active) { - dprintk("SFN workaround is active\n"); - dib3000mc_write_word(state, 29, 0x1273); - dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift - } else { - dib3000mc_write_word(state, 29, 0x1073); - dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift - } - - dib3000mc_set_adp_cfg(state, (u8)ch->u.ofdm.constellation); - if (ch->u.ofdm.transmission_mode == TRANSMISSION_MODE_8K) { - dib3000mc_write_word(state, 26, 38528); - dib3000mc_write_word(state, 33, 8); - } else { - dib3000mc_write_word(state, 26, 30336); - dib3000mc_write_word(state, 33, 6); - } - - if (dib3000mc_read_word(state, 509) & 0x80) - dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 1); - - return 0; -} - -struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating) -{ - struct dib3000mc_state *st = demod->demodulator_priv; - return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating); -} - -EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master); - -static int dib3000mc_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - u16 tps = dib3000mc_read_word(state,458); - - fep->inversion = INVERSION_AUTO; - - fep->u.ofdm.bandwidth = state->current_bandwidth; - - switch ((tps >> 8) & 0x1) { - case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; - case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break; - } - - switch (tps & 0x3) { - case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break; - case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break; - case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break; - case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break; - } - - switch ((tps >> 13) & 0x3) { - case 0: fep->u.ofdm.constellation = QPSK; break; - case 1: fep->u.ofdm.constellation = QAM_16; break; - case 2: - default: fep->u.ofdm.constellation = QAM_64; break; - } - - /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ - /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */ - - fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; - switch ((tps >> 5) & 0x7) { - case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break; - case 7: - default: fep->u.ofdm.code_rate_HP = FEC_7_8; break; - - } - - switch ((tps >> 2) & 0x7) { - case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break; - case 7: - default: fep->u.ofdm.code_rate_LP = FEC_7_8; break; - } - - return 0; -} - -static int dib3000mc_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - int ret; - - dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z); - - state->current_bandwidth = fep->u.ofdm.bandwidth; - dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth)); - - /* maybe the parameter has been changed */ - state->sfn_workaround_active = buggy_sfn_workaround; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fep); - msleep(100); - } - - if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || - fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || - fep->u.ofdm.constellation == QAM_AUTO || - fep->u.ofdm.code_rate_HP == FEC_AUTO) { - int i = 1000, found; - - dib3000mc_autosearch_start(fe, fep); - do { - msleep(1); - found = dib3000mc_autosearch_is_irq(fe); - } while (found == 0 && i--); - - dprintk("autosearch returns: %d\n",found); - if (found == 0 || found == 1) - return 0; // no channel found - - dib3000mc_get_frontend(fe, fep); - } - - ret = dib3000mc_tune(fe, fep); - - /* make this a config parameter */ - dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO); - return ret; -} - -static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - u16 lock = dib3000mc_read_word(state, 509); - - *stat = 0; - - if (lock & 0x8000) - *stat |= FE_HAS_SIGNAL; - if (lock & 0x3000) - *stat |= FE_HAS_CARRIER; - if (lock & 0x0100) - *stat |= FE_HAS_VITERBI; - if (lock & 0x0010) - *stat |= FE_HAS_SYNC; - if (lock & 0x0008) - *stat |= FE_HAS_LOCK; - - return 0; -} - -static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501); - return 0; -} - -static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - *unc = dib3000mc_read_word(state, 508); - return 0; -} - -static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - u16 val = dib3000mc_read_word(state, 392); - *strength = 65535 - val; - return 0; -} - -static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - *snr = 0x0000; - return 0; -} - -static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void dib3000mc_release(struct dvb_frontend *fe) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - dibx000_exit_i2c_master(&state->i2c_master); - kfree(state); -} - -int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0); - return 0; -} -EXPORT_SYMBOL(dib3000mc_pid_control); - -int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4); - tmp |= (onoff << 4); - return dib3000mc_write_word(state, 206, tmp); -} -EXPORT_SYMBOL(dib3000mc_pid_parse); - -void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - state->cfg = cfg; -} -EXPORT_SYMBOL(dib3000mc_set_config); - -int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[]) -{ - struct dib3000mc_state st = { .i2c_adap = i2c }; - int k; - u8 new_addr; - - static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26}; - - for (k = no_of_demods-1; k >= 0; k--) { - st.cfg = &cfg[k]; - - /* designated i2c address */ - new_addr = DIB3000MC_I2C_ADDRESS[k]; - st.i2c_addr = new_addr; - if (dib3000mc_identify(&st) != 0) { - st.i2c_addr = default_addr; - if (dib3000mc_identify(&st) != 0) { - dprintk("-E- DiB3000P/MC #%d: not identified\n", k); - return -ENODEV; - } - } - - dib3000mc_set_output_mode(&st, OUTMODE_MPEG2_PAR_CONT_CLK); - - // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0) - dib3000mc_write_word(&st, 1024, (new_addr << 3) | 0x1); - st.i2c_addr = new_addr; - } - - for (k = 0; k < no_of_demods; k++) { - st.cfg = &cfg[k]; - st.i2c_addr = DIB3000MC_I2C_ADDRESS[k]; - - dib3000mc_write_word(&st, 1024, st.i2c_addr << 3); - - /* turn off data output */ - dib3000mc_set_output_mode(&st, OUTMODE_HIGH_Z); - } - return 0; -} -EXPORT_SYMBOL(dib3000mc_i2c_enumeration); - -static struct dvb_frontend_ops dib3000mc_ops; - -struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg) -{ - struct dvb_frontend *demod; - struct dib3000mc_state *st; - st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL); - if (st == NULL) - return NULL; - - st->cfg = cfg; - st->i2c_adap = i2c_adap; - st->i2c_addr = i2c_addr; - - demod = &st->demod; - demod->demodulator_priv = st; - memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); - - if (dib3000mc_identify(st) != 0) - goto error; - - dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr); - - dib3000mc_write_word(st, 1037, 0x3130); - - return demod; - -error: - kfree(st); - return NULL; -} -EXPORT_SYMBOL(dib3000mc_attach); - -static struct dvb_frontend_ops dib3000mc_ops = { - .info = { - .name = "DiBcom 3000MC/P", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 62500, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = dib3000mc_release, - - .init = dib3000mc_init, - .sleep = dib3000mc_sleep, - - .set_frontend = dib3000mc_set_frontend, - .get_tune_settings = dib3000mc_fe_get_tune_settings, - .get_frontend = dib3000mc_get_frontend, - - .read_status = dib3000mc_read_status, - .read_ber = dib3000mc_read_ber, - .read_signal_strength = dib3000mc_read_signal_strength, - .read_snr = dib3000mc_read_snr, - .read_ucblocks = dib3000mc_read_unc_blocks, -}; - -MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); -MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h deleted file mode 100644 index d75ffad2d75..00000000000 --- a/drivers/media/dvb/frontends/dib3000mc.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Driver for DiBcom DiB3000MC/P-demodulator. - * - * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/) - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher\@desy.de) - * - * This code is partially based on the previous dib3000mc.c . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ -#ifndef DIB3000MC_H -#define DIB3000MC_H - -#include "dibx000_common.h" - -struct dib3000mc_config { - struct dibx000_agc_config *agc; - - u8 phase_noise_mode; - u8 impulse_noise_mode; - - u8 pwm3_inversion; - u8 use_pwm3; - u16 pwm3_value; - - u16 max_time; - u16 ln_adc_level; - - u8 agc_command1 :1; - u8 agc_command2 :1; - - u8 mobile_mode; - - u8 output_mpeg2_in_188_bytes; -}; - -#define DEFAULT_DIB3000MC_I2C_ADDRESS 16 -#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 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) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} - -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; -} - -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); - -extern void dib3000mc_set_config(struct dvb_frontend *, struct dib3000mc_config *); - -#endif diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c deleted file mode 100644 index 0109720353b..00000000000 --- a/drivers/media/dvb/frontends/dib7000m.c +++ /dev/null @@ -1,1409 +0,0 @@ -/* - * Linux-DVB Driver for DiBcom's DiB7000M and - * first generation DiB7000P-demodulator-family. - * - * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ -#include <linux/kernel.h> -#include <linux/i2c.h> - -#include "dvb_frontend.h" - -#include "dib7000m.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); - -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000M: "); printk(args); printk("\n"); } } while (0) - -struct dib7000m_state { - struct dvb_frontend demod; - struct dib7000m_config cfg; - - u8 i2c_addr; - struct i2c_adapter *i2c_adap; - - struct dibx000_i2c_master i2c_master; - -/* offset is 1 in case of the 7000MC */ - u8 reg_offs; - - u16 wbd_ref; - - u8 current_band; - fe_bandwidth_t current_bandwidth; - struct dibx000_agc_config *current_agc; - u32 timf; - u32 timf_default; - u32 internal_clk; - - u8 div_force_off : 1; - u8 div_state : 1; - u16 div_sync_wait; - - u16 revision; - - u8 agc_state; -}; - -enum dib7000m_power_mode { - DIB7000M_POWER_ALL = 0, - - DIB7000M_POWER_NO, - DIB7000M_POWER_INTERF_ANALOG_AGC, - DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD, - DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD, - DIB7000M_POWER_INTERFACE_ONLY, -}; - -static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg) -{ - u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff }; - u8 rb[2]; - struct i2c_msg msg[2] = { - { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, - { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, - }; - - if (i2c_transfer(state->i2c_adap, msg, 2) != 2) - dprintk("i2c read error on %d",reg); - - return (rb[0] << 8) | rb[1]; -} - -static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val) -{ - u8 b[4] = { - (reg >> 8) & 0xff, reg & 0xff, - (val >> 8) & 0xff, val & 0xff, - }; - struct i2c_msg msg = { - .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 - }; - return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; -} -static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf) -{ - u16 l = 0, r, *n; - n = buf; - l = *n++; - while (l) { - r = *n++; - - if (state->reg_offs && (r >= 112 && r <= 331)) // compensate for 7000MC - r++; - - do { - dib7000m_write_word(state, r, *n++); - r++; - } while (--l); - l = *n++; - } -} - -static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode) -{ - int ret = 0; - u16 outreg, fifo_threshold, smo_mode, - sram = 0x0005; /* by default SRAM output is disabled */ - - outreg = 0; - fifo_threshold = 1792; - smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1); - - dprintk( "setting output mode for demod %p to %d", &state->demod, mode); - - switch (mode) { - case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock - outreg = (1 << 10); /* 0x0400 */ - break; - case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock - outreg = (1 << 10) | (1 << 6); /* 0x0440 */ - break; - case OUTMODE_MPEG2_SERIAL: // STBs with serial input - outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */ - break; - case OUTMODE_DIVERSITY: - if (state->cfg.hostbus_diversity) - outreg = (1 << 10) | (4 << 6); /* 0x0500 */ - else - sram |= 0x0c00; - break; - case OUTMODE_MPEG2_FIFO: // e.g. USB feeding - smo_mode |= (3 << 1); - fifo_threshold = 512; - outreg = (1 << 10) | (5 << 6); - break; - case OUTMODE_HIGH_Z: // disable - outreg = 0; - break; - default: - dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod); - break; - } - - if (state->cfg.output_mpeg2_in_188_bytes) - smo_mode |= (1 << 5) ; - - ret |= dib7000m_write_word(state, 294 + state->reg_offs, smo_mode); - ret |= dib7000m_write_word(state, 295 + state->reg_offs, fifo_threshold); /* synchronous fread */ - ret |= dib7000m_write_word(state, 1795, outreg); - ret |= dib7000m_write_word(state, 1805, sram); - - if (state->revision == 0x4003) { - u16 clk_cfg1 = dib7000m_read_word(state, 909) & 0xfffd; - if (mode == OUTMODE_DIVERSITY) - clk_cfg1 |= (1 << 1); // P_O_CLK_en - dib7000m_write_word(state, 909, clk_cfg1); - } - return ret; -} - -static void dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode) -{ - /* by default everything is going to be powered off */ - u16 reg_903 = 0xffff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906 = 0x3fff; - u8 offset = 0; - - /* now, depending on the requested mode, we power on */ - switch (mode) { - /* power up everything in the demod */ - case DIB7000M_POWER_ALL: - reg_903 = 0x0000; reg_904 = 0x0000; reg_905 = 0x0000; reg_906 = 0x0000; - break; - - /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */ - case DIB7000M_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */ - reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2)); - break; - - case DIB7000M_POWER_INTERF_ANALOG_AGC: - reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10)); - reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2)); - reg_906 &= ~((1 << 0)); - break; - - case DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD: - reg_903 = 0x0000; reg_904 = 0x801f; reg_905 = 0x0000; reg_906 = 0x0000; - break; - - case DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD: - reg_903 = 0x0000; reg_904 = 0x8000; reg_905 = 0x010b; reg_906 = 0x0000; - break; - case DIB7000M_POWER_NO: - break; - } - - /* always power down unused parts */ - if (!state->cfg.mobile_mode) - reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1); - - /* P_sdio_select_clk = 0 on MC and after*/ - if (state->revision != 0x4000) - reg_906 <<= 1; - - if (state->revision == 0x4003) - offset = 1; - - dib7000m_write_word(state, 903 + offset, reg_903); - dib7000m_write_word(state, 904 + offset, reg_904); - dib7000m_write_word(state, 905 + offset, reg_905); - dib7000m_write_word(state, 906 + offset, reg_906); -} - -static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no) -{ - int ret = 0; - u16 reg_913 = dib7000m_read_word(state, 913), - reg_914 = dib7000m_read_word(state, 914); - - switch (no) { - case DIBX000_SLOW_ADC_ON: - reg_914 |= (1 << 1) | (1 << 0); - ret |= dib7000m_write_word(state, 914, reg_914); - reg_914 &= ~(1 << 1); - break; - - case DIBX000_SLOW_ADC_OFF: - reg_914 |= (1 << 1) | (1 << 0); - break; - - case DIBX000_ADC_ON: - if (state->revision == 0x4000) { // workaround for PA/MA - // power-up ADC - dib7000m_write_word(state, 913, 0); - dib7000m_write_word(state, 914, reg_914 & 0x3); - // power-down bandgag - dib7000m_write_word(state, 913, (1 << 15)); - dib7000m_write_word(state, 914, reg_914 & 0x3); - } - - reg_913 &= 0x0fff; - reg_914 &= 0x0003; - break; - - case DIBX000_ADC_OFF: // leave the VBG voltage on - reg_913 |= (1 << 14) | (1 << 13) | (1 << 12); - reg_914 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2); - break; - - case DIBX000_VBG_ENABLE: - reg_913 &= ~(1 << 15); - break; - - case DIBX000_VBG_DISABLE: - reg_913 |= (1 << 15); - break; - - default: - break; - } - -// dprintk( "913: %x, 914: %x", reg_913, reg_914); - ret |= dib7000m_write_word(state, 913, reg_913); - ret |= dib7000m_write_word(state, 914, reg_914); - - return ret; -} - -static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw) -{ - u32 timf; - - // store the current bandwidth for later use - state->current_bandwidth = bw; - - if (state->timf == 0) { - dprintk( "using default timf"); - timf = state->timf_default; - } else { - dprintk( "using updated timf"); - timf = state->timf; - } - - timf = timf * (bw / 50) / 160; - - dib7000m_write_word(state, 23, (u16) ((timf >> 16) & 0xffff)); - dib7000m_write_word(state, 24, (u16) ((timf ) & 0xffff)); - - return 0; -} - -static int dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff) -{ - struct dib7000m_state *state = demod->demodulator_priv; - - if (state->div_force_off) { - dprintk( "diversity combination deactivated - forced by COFDM parameters"); - onoff = 0; - } - state->div_state = (u8)onoff; - - if (onoff) { - dib7000m_write_word(state, 263 + state->reg_offs, 6); - dib7000m_write_word(state, 264 + state->reg_offs, 6); - dib7000m_write_word(state, 266 + state->reg_offs, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0)); - } else { - dib7000m_write_word(state, 263 + state->reg_offs, 1); - dib7000m_write_word(state, 264 + state->reg_offs, 0); - dib7000m_write_word(state, 266 + state->reg_offs, 0); - } - - return 0; -} - -static int dib7000m_sad_calib(struct dib7000m_state *state) -{ - -/* internal */ -// dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth - dib7000m_write_word(state, 929, (0 << 1) | (0 << 0)); - dib7000m_write_word(state, 930, 776); // 0.625*3.3 / 4096 - - /* do the calibration */ - dib7000m_write_word(state, 929, (1 << 0)); - dib7000m_write_word(state, 929, (0 << 0)); - - msleep(1); - - return 0; -} - -static void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw) -{ - dib7000m_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff)); - dib7000m_write_word(state, 19, (u16) ( (bw->internal*1000) & 0xffff)); - dib7000m_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff)); - dib7000m_write_word(state, 22, (u16) ( bw->ifreq & 0xffff)); - - dib7000m_write_word(state, 928, bw->sad_cfg); -} - -static void dib7000m_reset_pll(struct dib7000m_state *state) -{ - const struct dibx000_bandwidth_config *bw = state->cfg.bw; - u16 reg_907,reg_910; - - /* default */ - reg_907 = (bw->pll_bypass << 15) | (bw->modulo << 7) | - (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | - (bw->enable_refdiv << 1) | (0 << 0); - reg_910 = (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset; - - // for this oscillator frequency should be 30 MHz for the Master (default values in the board_parameters give that value) - // this is only working only for 30 MHz crystals - if (!state->cfg.quartz_direct) { - reg_910 |= (1 << 5); // forcing the predivider to 1 - - // if the previous front-end is baseband, its output frequency is 15 MHz (prev freq divided by 2) - if(state->cfg.input_clk_is_div_2) - reg_907 |= (16 << 9); - else // otherwise the previous front-end puts out its input (default 30MHz) - no extra division necessary - reg_907 |= (8 << 9); - } else { - reg_907 |= (bw->pll_ratio & 0x3f) << 9; - reg_910 |= (bw->pll_prediv << 5); - } - - dib7000m_write_word(state, 910, reg_910); // pll cfg - dib7000m_write_word(state, 907, reg_907); // clk cfg0 - dib7000m_write_word(state, 908, 0x0006); // clk_cfg1 - - dib7000m_reset_pll_common(state, bw); -} - -static void dib7000mc_reset_pll(struct dib7000m_state *state) -{ - const struct dibx000_bandwidth_config *bw = state->cfg.bw; - u16 clk_cfg1; - - // clk_cfg0 - dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0)); - - // clk_cfg1 - //dib7000m_write_word(state, 908, (1 << 14) | (3 << 12) |(0 << 11) | - clk_cfg1 = (0 << 14) | (3 << 12) |(0 << 11) | - (bw->IO_CLK_en_core << 10) | (bw->bypclk_div << 5) | (bw->enable_refdiv << 4) | - (1 << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0); - dib7000m_write_word(state, 908, clk_cfg1); - clk_cfg1 = (clk_cfg1 & 0xfff7) | (bw->pll_bypass << 3); - dib7000m_write_word(state, 908, clk_cfg1); - - // smpl_cfg - dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7)); - - dib7000m_reset_pll_common(state, bw); -} - -static int dib7000m_reset_gpio(struct dib7000m_state *st) -{ - /* reset the GPIOs */ - dib7000m_write_word(st, 773, st->cfg.gpio_dir); - dib7000m_write_word(st, 774, st->cfg.gpio_val); - - /* TODO 782 is P_gpio_od */ - - dib7000m_write_word(st, 775, st->cfg.gpio_pwm_pos); - - dib7000m_write_word(st, 780, st->cfg.pwm_freq_div); - return 0; -} - -static u16 dib7000m_defaults_common[] = - -{ - // auto search configuration - 3, 2, - 0x0004, - 0x1000, - 0x0814, - - 12, 6, - 0x001b, - 0x7740, - 0x005b, - 0x8d80, - 0x01c9, - 0xc380, - 0x0000, - 0x0080, - 0x0000, - 0x0090, - 0x0001, - 0xd4c0, - - 1, 26, - 0x6680, // P_corm_thres Lock algorithms configuration - - 1, 170, - 0x0410, // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on - - 8, 173, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - - 1, 182, - 8192, // P_fft_nb_to_cut - - 2, 195, - 0x0ccd, // P_pha3_thres - 0, // P_cti_use_cpe, P_cti_use_prog - - 1, 205, - 0x200f, // P_cspu_regul, P_cspu_win_cut - - 5, 214, - 0x023d, // P_adp_regul_cnt - 0x00a4, // P_adp_noise_cnt - 0x00a4, // P_adp_regul_ext - 0x7ff0, // P_adp_noise_ext - 0x3ccc, // P_adp_fil - - 1, 226, - 0, // P_2d_byp_ti_num - - 1, 255, - 0x800, // P_equal_thres_wgn - - 1, 263, - 0x0001, - - 1, 281, - 0x0010, // P_fec_* - - 1, 294, - 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard - - 0 -}; - -static u16 dib7000m_defaults[] = - -{ - /* set ADC level to -16 */ - 11, 76, - (1 << 13) - 825 - 117, - (1 << 13) - 837 - 117, - (1 << 13) - 811 - 117, - (1 << 13) - 766 - 117, - (1 << 13) - 737 - 117, - (1 << 13) - 693 - 117, - (1 << 13) - 648 - 117, - (1 << 13) - 619 - 117, - (1 << 13) - 575 - 117, - (1 << 13) - 531 - 117, - (1 << 13) - 501 - 117, - - // Tuner IO bank: max drive (14mA) - 1, 912, - 0x2c8a, - - 1, 1817, - 1, - - 0, -}; - -static int dib7000m_demod_reset(struct dib7000m_state *state) -{ - dib7000m_set_power_mode(state, DIB7000M_POWER_ALL); - - /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */ - dib7000m_set_adc_state(state, DIBX000_VBG_ENABLE); - - /* restart all parts */ - dib7000m_write_word(state, 898, 0xffff); - dib7000m_write_word(state, 899, 0xffff); - dib7000m_write_word(state, 900, 0xff0f); - dib7000m_write_word(state, 901, 0xfffc); - - dib7000m_write_word(state, 898, 0); - dib7000m_write_word(state, 899, 0); - dib7000m_write_word(state, 900, 0); - dib7000m_write_word(state, 901, 0); - - if (state->revision == 0x4000) - dib7000m_reset_pll(state); - else - dib7000mc_reset_pll(state); - - if (dib7000m_reset_gpio(state) != 0) - dprintk( "GPIO reset was not successful."); - - if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0) - dprintk( "OUTPUT_MODE could not be reset."); - - /* unforce divstr regardless whether i2c enumeration was done or not */ - dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) ); - - dib7000m_set_bandwidth(state, 8000); - - dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON); - dib7000m_sad_calib(state); - dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF); - - if (state->cfg.dvbt_mode) - dib7000m_write_word(state, 1796, 0x0); // select DVB-T output - - if (state->cfg.mobile_mode) - dib7000m_write_word(state, 261 + state->reg_offs, 2); - else - dib7000m_write_word(state, 224 + state->reg_offs, 1); - - // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ... - if(state->cfg.tuner_is_baseband) - dib7000m_write_word(state, 36, 0x0755); - else - dib7000m_write_word(state, 36, 0x1f55); - - // P_divclksel=3 P_divbitsel=1 - if (state->revision == 0x4000) - dib7000m_write_word(state, 909, (3 << 10) | (1 << 6)); - else - dib7000m_write_word(state, 909, (3 << 4) | 1); - - dib7000m_write_tab(state, dib7000m_defaults_common); - dib7000m_write_tab(state, dib7000m_defaults); - - dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY); - - state->internal_clk = state->cfg.bw->internal; - - return 0; -} - -static void dib7000m_restart_agc(struct dib7000m_state *state) -{ - // P_restart_iqc & P_restart_agc - dib7000m_write_word(state, 898, 0x0c00); - dib7000m_write_word(state, 898, 0x0000); -} - -static int dib7000m_agc_soft_split(struct dib7000m_state *state) -{ - u16 agc,split_offset; - - if(!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0) - return 0; - - // n_agc_global - agc = dib7000m_read_word(state, 390); - - if (agc > state->current_agc->split.min_thres) - split_offset = state->current_agc->split.min; - else if (agc < state->current_agc->split.max_thres) - split_offset = state->current_agc->split.max; - else - split_offset = state->current_agc->split.max * - (agc - state->current_agc->split.min_thres) / - (state->current_agc->split.max_thres - state->current_agc->split.min_thres); - - dprintk( "AGC split_offset: %d",split_offset); - - // P_agc_force_split and P_agc_split_offset - return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset); -} - -static int dib7000m_update_lna(struct dib7000m_state *state) -{ - u16 dyn_gain; - - if (state->cfg.update_lna) { - // read dyn_gain here (because it is demod-dependent and not fe) - dyn_gain = dib7000m_read_word(state, 390); - - if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed - dib7000m_restart_agc(state); - return 1; - } - } - return 0; -} - -static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band) -{ - struct dibx000_agc_config *agc = NULL; - int i; - if (state->current_band == band && state->current_agc != NULL) - return 0; - state->current_band = band; - - for (i = 0; i < state->cfg.agc_config_count; i++) - if (state->cfg.agc[i].band_caps & band) { - agc = &state->cfg.agc[i]; - break; - } - - if (agc == NULL) { - dprintk( "no valid AGC configuration found for band 0x%02x",band); - return -EINVAL; - } - - state->current_agc = agc; - - /* AGC */ - dib7000m_write_word(state, 72 , agc->setup); - dib7000m_write_word(state, 73 , agc->inv_gain); - dib7000m_write_word(state, 74 , agc->time_stabiliz); - dib7000m_write_word(state, 97 , (agc->alpha_level << 12) | agc->thlock); - - // Demod AGC loop configuration - dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp); - dib7000m_write_word(state, 99, (agc->beta_mant << 6) | agc->beta_exp); - - dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d", - state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel); - - /* AGC continued */ - if (state->wbd_ref != 0) - dib7000m_write_word(state, 102, state->wbd_ref); - else // use default - dib7000m_write_word(state, 102, agc->wbd_ref); - - dib7000m_write_word(state, 103, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) ); - dib7000m_write_word(state, 104, agc->agc1_max); - dib7000m_write_word(state, 105, agc->agc1_min); - dib7000m_write_word(state, 106, agc->agc2_max); - dib7000m_write_word(state, 107, agc->agc2_min); - dib7000m_write_word(state, 108, (agc->agc1_pt1 << 8) | agc->agc1_pt2 ); - dib7000m_write_word(state, 109, (agc->agc1_slope1 << 8) | agc->agc1_slope2); - dib7000m_write_word(state, 110, (agc->agc2_pt1 << 8) | agc->agc2_pt2); - dib7000m_write_word(state, 111, (agc->agc2_slope1 << 8) | agc->agc2_slope2); - - if (state->revision > 0x4000) { // settings for the MC - dib7000m_write_word(state, 71, agc->agc1_pt3); -// dprintk( "929: %x %d %d", -// (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel); - dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); - } else { - // wrong default values - u16 b[9] = { 676, 696, 717, 737, 758, 778, 799, 819, 840 }; - for (i = 0; i < 9; i++) - dib7000m_write_word(state, 88 + i, b[i]); - } - return 0; -} - -static void dib7000m_update_timf(struct dib7000m_state *state) -{ - u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437); - state->timf = timf * 160 / (state->current_bandwidth / 50); - dib7000m_write_word(state, 23, (u16) (timf >> 16)); - dib7000m_write_word(state, 24, (u16) (timf & 0xffff)); - dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->timf_default); -} - -static int dib7000m_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib7000m_state *state = demod->demodulator_priv; - u16 cfg_72 = dib7000m_read_word(state, 72); - int ret = -1; - u8 *agc_state = &state->agc_state; - u8 agc_split; - - switch (state->agc_state) { - case 0: - // set power-up level: interf+analog+AGC - dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC); - dib7000m_set_adc_state(state, DIBX000_ADC_ON); - - if (dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0) - return -1; - - ret = 7; /* ADC power up */ - (*agc_state)++; - break; - - case 1: - /* AGC initialization */ - if (state->cfg.agc_control) - state->cfg.agc_control(&state->demod, 1); - - dib7000m_write_word(state, 75, 32768); - if (!state->current_agc->perform_agc_softsplit) { - /* we are using the wbd - so slow AGC startup */ - dib7000m_write_word(state, 103, 1 << 8); /* force 0 split on WBD and restart AGC */ - (*agc_state)++; - ret = 5; - } else { - /* default AGC startup */ - (*agc_state) = 4; - /* wait AGC rough lock time */ - ret = 7; - } - - dib7000m_restart_agc(state); - break; - - case 2: /* fast split search path after 5sec */ - dib7000m_write_word(state, 72, cfg_72 | (1 << 4)); /* freeze AGC loop */ - dib7000m_write_word(state, 103, 2 << 9); /* fast split search 0.25kHz */ - (*agc_state)++; - ret = 14; - break; - - case 3: /* split search ended */ - agc_split = (u8)dib7000m_read_word(state, 392); /* store the split value for the next time */ - dib7000m_write_word(state, 75, dib7000m_read_word(state, 390)); /* set AGC gain start value */ - - dib7000m_write_word(state, 72, cfg_72 & ~(1 << 4)); /* std AGC loop */ - dib7000m_write_word(state, 103, (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */ - - dib7000m_restart_agc(state); - - dprintk( "SPLIT %p: %hd", demod, agc_split); - - (*agc_state)++; - ret = 5; - break; - - case 4: /* LNA startup */ - /* wait AGC accurate lock time */ - ret = 7; - - if (dib7000m_update_lna(state)) - // wait only AGC rough lock time - ret = 5; - else - (*agc_state)++; - break; - - case 5: - dib7000m_agc_soft_split(state); - - if (state->cfg.agc_control) - state->cfg.agc_control(&state->demod, 0); - - (*agc_state)++; - break; - - default: - break; - } - return ret; -} - -static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_frontend_parameters *ch, u8 seq) -{ - u16 value, est[4]; - - dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); - - /* nfft, guard, qam, alpha */ - value = 0; - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: value |= (0 << 7); break; - case /* 4K MODE */ 255: value |= (2 << 7); break; - default: - case TRANSMISSION_MODE_8K: value |= (1 << 7); break; - } - switch (ch->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_32: value |= (0 << 5); break; - case GUARD_INTERVAL_1_16: value |= (1 << 5); break; - case GUARD_INTERVAL_1_4: value |= (3 << 5); break; - default: - case GUARD_INTERVAL_1_8: value |= (2 << 5); break; - } - switch (ch->u.ofdm.constellation) { - case QPSK: value |= (0 << 3); break; - case QAM_16: value |= (1 << 3); break; - default: - case QAM_64: value |= (2 << 3); break; - } - switch (HIERARCHY_1) { - case HIERARCHY_2: value |= 2; break; - case HIERARCHY_4: value |= 4; break; - default: - case HIERARCHY_1: value |= 1; break; - } - dib7000m_write_word(state, 0, value); - dib7000m_write_word(state, 5, (seq << 4)); - - /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */ - value = 0; - if (1 != 0) - value |= (1 << 6); - if (ch->u.ofdm.hierarchy_information == 1) - value |= (1 << 4); - if (1 == 1) - value |= 1; - switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) { - case FEC_2_3: value |= (2 << 1); break; - case FEC_3_4: value |= (3 << 1); break; - case FEC_5_6: value |= (5 << 1); break; - case FEC_7_8: value |= (7 << 1); break; - default: - case FEC_1_2: value |= (1 << 1); break; - } - dib7000m_write_word(state, 267 + state->reg_offs, value); - - /* offset loop parameters */ - - /* P_timf_alpha = 6, P_corm_alpha=6, P_corm_thres=0x80 */ - dib7000m_write_word(state, 26, (6 << 12) | (6 << 8) | 0x80); - - /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=1, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */ - dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (1 << 9) | (3 << 5) | (1 << 4) | (0x3)); - - /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max=3 */ - dib7000m_write_word(state, 32, (0 << 4) | 0x3); - - /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step=5 */ - dib7000m_write_word(state, 33, (0 << 4) | 0x5); - - /* P_dvsy_sync_wait */ - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_8K: value = 256; break; - case /* 4K MODE */ 255: value = 128; break; - case TRANSMISSION_MODE_2K: - default: value = 64; break; - } - switch (ch->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_16: value *= 2; break; - case GUARD_INTERVAL_1_8: value *= 4; break; - case GUARD_INTERVAL_1_4: value *= 8; break; - default: - case GUARD_INTERVAL_1_32: value *= 1; break; - } - state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO - - /* deactive the possibility of diversity reception if extended interleave - not for 7000MC */ - /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */ - if (1 == 1 || state->revision > 0x4000) - state->div_force_off = 0; - else - state->div_force_off = 1; - dib7000m_set_diversity_in(&state->demod, state->div_state); - - /* channel estimation fine configuration */ - switch (ch->u.ofdm.constellation) { - case QAM_64: - est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ - est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */ - est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ - est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */ - break; - case QAM_16: - est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */ - est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */ - est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ - est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */ - break; - default: - est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */ - est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */ - est[2] = 0x0333; /* P_adp_regul_ext 0.1 */ - est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */ - break; - } - for (value = 0; value < 4; value++) - dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]); - - // set power-up level: autosearch - dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD); -} - -static int dib7000m_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib7000m_state *state = demod->demodulator_priv; - struct dvb_frontend_parameters schan; - int ret = 0; - u32 value, factor; - - schan = *ch; - - schan.u.ofdm.constellation = QAM_64; - schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - schan.u.ofdm.code_rate_HP = FEC_2_3; - schan.u.ofdm.code_rate_LP = FEC_3_4; - schan.u.ofdm.hierarchy_information = 0; - - dib7000m_set_channel(state, &schan, 7); - - factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth); - if (factor >= 5000) - factor = 1; - else - factor = 6; - - // always use the setting for 8MHz here lock_time for 7,6 MHz are longer - value = 30 * state->internal_clk * factor; - ret |= dib7000m_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time - ret |= dib7000m_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time - value = 100 * state->internal_clk * factor; - ret |= dib7000m_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time - ret |= dib7000m_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time - value = 500 * state->internal_clk * factor; - ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time - ret |= dib7000m_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time - - // start search - value = dib7000m_read_word(state, 0); - ret |= dib7000m_write_word(state, 0, (u16) (value | (1 << 9))); - - /* clear n_irq_pending */ - if (state->revision == 0x4000) - dib7000m_write_word(state, 1793, 0); - else - dib7000m_read_word(state, 537); - - ret |= dib7000m_write_word(state, 0, (u16) value); - - return ret; -} - -static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg) -{ - u16 irq_pending = dib7000m_read_word(state, reg); - - if (irq_pending & 0x1) { // failed - dprintk( "autosearch failed"); - return 1; - } - - if (irq_pending & 0x2) { // succeeded - dprintk( "autosearch succeeded"); - return 2; - } - return 0; // still pending -} - -static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod) -{ - struct dib7000m_state *state = demod->demodulator_priv; - if (state->revision == 0x4000) - return dib7000m_autosearch_irq(state, 1793); - else - return dib7000m_autosearch_irq(state, 537); -} - -static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib7000m_state *state = demod->demodulator_priv; - int ret = 0; - u16 value; - - // we are already tuned - just resuming from suspend - if (ch != NULL) - dib7000m_set_channel(state, ch, 0); - else - return -EINVAL; - - // restart demod - ret |= dib7000m_write_word(state, 898, 0x4000); - ret |= dib7000m_write_word(state, 898, 0x0000); - msleep(45); - - dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD); - /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */ - ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3)); - - // never achieved a lock before - wait for timfreq to update - if (state->timf == 0) - msleep(200); - - //dump_reg(state); - /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */ - value = (6 << 8) | 0x80; - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: value |= (7 << 12); break; - case /* 4K MODE */ 255: value |= (8 << 12); break; - default: - case TRANSMISSION_MODE_8K: value |= (9 << 12); break; - } - ret |= dib7000m_write_word(state, 26, value); - - /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */ - value = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: value |= 0x6; break; - case /* 4K MODE */ 255: value |= 0x7; break; - default: - case TRANSMISSION_MODE_8K: value |= 0x8; break; - } - ret |= dib7000m_write_word(state, 32, value); - - /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */ - value = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: value |= 0x6; break; - case /* 4K MODE */ 255: value |= 0x7; break; - default: - case TRANSMISSION_MODE_8K: value |= 0x8; break; - } - ret |= dib7000m_write_word(state, 33, value); - - // we achieved a lock - it's time to update the timf freq - if ((dib7000m_read_word(state, 535) >> 6) & 0x1) - dib7000m_update_timf(state); - - dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); - return ret; -} - -static int dib7000m_wakeup(struct dvb_frontend *demod) -{ - struct dib7000m_state *state = demod->demodulator_priv; - - dib7000m_set_power_mode(state, DIB7000M_POWER_ALL); - - if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) - dprintk( "could not start Slow ADC"); - - return 0; -} - -static int dib7000m_sleep(struct dvb_frontend *demod) -{ - struct dib7000m_state *st = demod->demodulator_priv; - dib7000m_set_output_mode(st, OUTMODE_HIGH_Z); - dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY); - return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | - dib7000m_set_adc_state(st, DIBX000_ADC_OFF); -} - -static int dib7000m_identify(struct dib7000m_state *state) -{ - u16 value; - - if ((value = dib7000m_read_word(state, 896)) != 0x01b3) { - dprintk( "wrong Vendor ID (0x%x)",value); - return -EREMOTEIO; - } - - state->revision = dib7000m_read_word(state, 897); - if (state->revision != 0x4000 && - state->revision != 0x4001 && - state->revision != 0x4002 && - state->revision != 0x4003) { - dprintk( "wrong Device ID (0x%x)",value); - return -EREMOTEIO; - } - - /* protect this driver to be used with 7000PC */ - if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) { - dprintk( "this driver does not work with DiB7000PC"); - return -EREMOTEIO; - } - - switch (state->revision) { - case 0x4000: dprintk( "found DiB7000MA/PA/MB/PB"); break; - case 0x4001: state->reg_offs = 1; dprintk( "found DiB7000HC"); break; - case 0x4002: state->reg_offs = 1; dprintk( "found DiB7000MC"); break; - case 0x4003: state->reg_offs = 1; dprintk( "found DiB9000"); break; - } - - return 0; -} - - -static int dib7000m_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib7000m_state *state = fe->demodulator_priv; - u16 tps = dib7000m_read_word(state,480); - - fep->inversion = INVERSION_AUTO; - - fep->u.ofdm.bandwidth = state->current_bandwidth; - - switch ((tps >> 8) & 0x3) { - case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; - case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break; - /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */ - } - - switch (tps & 0x3) { - case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break; - case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break; - case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break; - case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break; - } - - switch ((tps >> 14) & 0x3) { - case 0: fep->u.ofdm.constellation = QPSK; break; - case 1: fep->u.ofdm.constellation = QAM_16; break; - case 2: - default: fep->u.ofdm.constellation = QAM_64; break; - } - - /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ - /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */ - - fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; - switch ((tps >> 5) & 0x7) { - case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break; - case 7: - default: fep->u.ofdm.code_rate_HP = FEC_7_8; break; - - } - - switch ((tps >> 2) & 0x7) { - case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break; - case 7: - default: fep->u.ofdm.code_rate_LP = FEC_7_8; break; - } - - /* native interleaver: (dib7000m_read_word(state, 481) >> 5) & 0x1 */ - - return 0; -} - -static int dib7000m_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib7000m_state *state = fe->demodulator_priv; - int time, ret; - - dib7000m_set_output_mode(state, OUTMODE_HIGH_Z); - - state->current_bandwidth = fep->u.ofdm.bandwidth; - dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth)); - - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, fep); - - /* start up the AGC */ - state->agc_state = 0; - do { - time = dib7000m_agc_startup(fe, fep); - if (time != -1) - msleep(time); - } while (time != -1); - - if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || - fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || - fep->u.ofdm.constellation == QAM_AUTO || - fep->u.ofdm.code_rate_HP == FEC_AUTO) { - int i = 800, found; - - dib7000m_autosearch_start(fe, fep); - do { - msleep(1); - found = dib7000m_autosearch_is_irq(fe); - } while (found == 0 && i--); - - dprintk("autosearch returns: %d",found); - if (found == 0 || found == 1) - return 0; // no channel found - - dib7000m_get_frontend(fe, fep); - } - - ret = dib7000m_tune(fe, fep); - - /* make this a config parameter */ - dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO); - return ret; -} - -static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat) -{ - struct dib7000m_state *state = fe->demodulator_priv; - u16 lock = dib7000m_read_word(state, 535); - - *stat = 0; - - if (lock & 0x8000) - *stat |= FE_HAS_SIGNAL; - if (lock & 0x3000) - *stat |= FE_HAS_CARRIER; - if (lock & 0x0100) - *stat |= FE_HAS_VITERBI; - if (lock & 0x0010) - *stat |= FE_HAS_SYNC; - if (lock & 0x0008) - *stat |= FE_HAS_LOCK; - - return 0; -} - -static int dib7000m_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct dib7000m_state *state = fe->demodulator_priv; - *ber = (dib7000m_read_word(state, 526) << 16) | dib7000m_read_word(state, 527); - return 0; -} - -static int dib7000m_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) -{ - struct dib7000m_state *state = fe->demodulator_priv; - *unc = dib7000m_read_word(state, 534); - return 0; -} - -static int dib7000m_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct dib7000m_state *state = fe->demodulator_priv; - u16 val = dib7000m_read_word(state, 390); - *strength = 65535 - val; - return 0; -} - -static int dib7000m_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - *snr = 0x0000; - return 0; -} - -static int dib7000m_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void dib7000m_release(struct dvb_frontend *demod) -{ - struct dib7000m_state *st = demod->demodulator_priv; - dibx000_exit_i2c_master(&st->i2c_master); - kfree(st); -} - -struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating) -{ - struct dib7000m_state *st = demod->demodulator_priv; - return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating); -} -EXPORT_SYMBOL(dib7000m_get_i2c_master); - -#if 0 -/* used with some prototype boards */ -int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, - u8 default_addr, struct dib7000m_config cfg[]) -{ - struct dib7000m_state st = { .i2c_adap = i2c }; - int k = 0; - u8 new_addr = 0; - - for (k = no_of_demods-1; k >= 0; k--) { - st.cfg = cfg[k]; - - /* designated i2c address */ - new_addr = (0x40 + k) << 1; - st.i2c_addr = new_addr; - if (dib7000m_identify(&st) != 0) { - st.i2c_addr = default_addr; - if (dib7000m_identify(&st) != 0) { - dprintk("DiB7000M #%d: not identified", k); - return -EIO; - } - } - - /* start diversity to pull_down div_str - just for i2c-enumeration */ - dib7000m_set_output_mode(&st, OUTMODE_DIVERSITY); - - dib7000m_write_word(&st, 1796, 0x0); // select DVB-T output - - /* set new i2c address and force divstart */ - dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2); - - dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr); - } - - for (k = 0; k < no_of_demods; k++) { - st.cfg = cfg[k]; - st.i2c_addr = (0x40 + k) << 1; - - // unforce divstr - dib7000m_write_word(&st,1794, st.i2c_addr << 2); - - /* deactivate div - it was just for i2c-enumeration */ - dib7000m_set_output_mode(&st, OUTMODE_HIGH_Z); - } - - return 0; -} -EXPORT_SYMBOL(dib7000m_i2c_enumeration); -#endif - -static struct dvb_frontend_ops dib7000m_ops; -struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg) -{ - struct dvb_frontend *demod; - struct dib7000m_state *st; - st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL); - if (st == NULL) - return NULL; - - memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config)); - st->i2c_adap = i2c_adap; - st->i2c_addr = i2c_addr; - - demod = &st->demod; - demod->demodulator_priv = st; - memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops)); - - st->timf_default = cfg->bw->timf; - - if (dib7000m_identify(st) != 0) - goto error; - - if (st->revision == 0x4000) - dibx000_init_i2c_master(&st->i2c_master, DIB7000, st->i2c_adap, st->i2c_addr); - else - dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c_adap, st->i2c_addr); - - dib7000m_demod_reset(st); - - return demod; - -error: - kfree(st); - return NULL; -} -EXPORT_SYMBOL(dib7000m_attach); - -static struct dvb_frontend_ops dib7000m_ops = { - .info = { - .name = "DiBcom 7000MA/MB/PA/PB/MC", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 62500, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = dib7000m_release, - - .init = dib7000m_wakeup, - .sleep = dib7000m_sleep, - - .set_frontend = dib7000m_set_frontend, - .get_tune_settings = dib7000m_fe_get_tune_settings, - .get_frontend = dib7000m_get_frontend, - - .read_status = dib7000m_read_status, - .read_ber = dib7000m_read_ber, - .read_signal_strength = dib7000m_read_signal_strength, - .read_snr = dib7000m_read_snr, - .read_ucblocks = dib7000m_read_unc_blocks, -}; - -MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); -MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dib7000m.h b/drivers/media/dvb/frontends/dib7000m.h deleted file mode 100644 index 113819ce9f0..00000000000 --- a/drivers/media/dvb/frontends/dib7000m.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef DIB7000M_H -#define DIB7000M_H - -#include "dibx000_common.h" - -struct dib7000m_config { - u8 dvbt_mode; - u8 output_mpeg2_in_188_bytes; - u8 hostbus_diversity; - u8 tuner_is_baseband; - u8 mobile_mode; - int (*update_lna) (struct dvb_frontend *, u16 agc_global); - - u8 agc_config_count; - struct dibx000_agc_config *agc; - - struct dibx000_bandwidth_config *bw; - -#define DIB7000M_GPIO_DEFAULT_DIRECTIONS 0xffff - u16 gpio_dir; -#define DIB7000M_GPIO_DEFAULT_VALUES 0x0000 - u16 gpio_val; -#define DIB7000M_GPIO_PWM_POS0(v) ((v & 0xf) << 12) -#define DIB7000M_GPIO_PWM_POS1(v) ((v & 0xf) << 8 ) -#define DIB7000M_GPIO_PWM_POS2(v) ((v & 0xf) << 4 ) -#define DIB7000M_GPIO_PWM_POS3(v) (v & 0xf) -#define DIB7000M_GPIO_DEFAULT_PWM_POS 0xffff - u16 gpio_pwm_pos; - - u16 pwm_freq_div; - - u8 quartz_direct; - - u8 input_clk_is_div_2; - - int (*agc_control) (struct dvb_frontend *, u8 before); -}; - -#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); -extern INT dib7000m_enable_vbg_voltage(struct dibDemod *demod); -extern void dib7000m_set_hostbus_diversity(struct dibDemod *demod, UCHAR onoff); -extern USHORT dib7000m_get_current_agc_global(struct dibDemod *demod); -*/ - -#endif diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c deleted file mode 100644 index 8217e5b38f4..00000000000 --- a/drivers/media/dvb/frontends/dib7000p.c +++ /dev/null @@ -1,1394 +0,0 @@ -/* - * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC). - * - * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ -#include <linux/kernel.h> -#include <linux/i2c.h> - -#include "dvb_frontend.h" - -#include "dib7000p.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); - -static int buggy_sfn_workaround; -module_param(buggy_sfn_workaround, int, 0644); -MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)"); - -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0) - -struct dib7000p_state { - struct dvb_frontend demod; - struct dib7000p_config cfg; - - u8 i2c_addr; - struct i2c_adapter *i2c_adap; - - struct dibx000_i2c_master i2c_master; - - u16 wbd_ref; - - u8 current_band; - u32 current_bandwidth; - struct dibx000_agc_config *current_agc; - u32 timf; - - u8 div_force_off : 1; - u8 div_state : 1; - u16 div_sync_wait; - - u8 agc_state; - - u16 gpio_dir; - u16 gpio_val; - - u8 sfn_workaround_active :1; -}; - -enum dib7000p_power_mode { - DIB7000P_POWER_ALL = 0, - DIB7000P_POWER_ANALOG_ADC, - DIB7000P_POWER_INTERFACE_ONLY, -}; - -static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) -{ - u8 wb[2] = { reg >> 8, reg & 0xff }; - u8 rb[2]; - struct i2c_msg msg[2] = { - { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, - { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, - }; - - if (i2c_transfer(state->i2c_adap, msg, 2) != 2) - dprintk("i2c read error on %d",reg); - - return (rb[0] << 8) | rb[1]; -} - -static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val) -{ - u8 b[4] = { - (reg >> 8) & 0xff, reg & 0xff, - (val >> 8) & 0xff, val & 0xff, - }; - struct i2c_msg msg = { - .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 - }; - return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; -} -static void dib7000p_write_tab(struct dib7000p_state *state, u16 *buf) -{ - u16 l = 0, r, *n; - n = buf; - l = *n++; - while (l) { - r = *n++; - - do { - dib7000p_write_word(state, r, *n++); - r++; - } while (--l); - l = *n++; - } -} - -static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode) -{ - int ret = 0; - u16 outreg, fifo_threshold, smo_mode; - - outreg = 0; - fifo_threshold = 1792; - smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1); - - dprintk( "setting output mode for demod %p to %d", - &state->demod, mode); - - switch (mode) { - case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock - outreg = (1 << 10); /* 0x0400 */ - break; - case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock - outreg = (1 << 10) | (1 << 6); /* 0x0440 */ - break; - case OUTMODE_MPEG2_SERIAL: // STBs with serial input - outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */ - break; - case OUTMODE_DIVERSITY: - if (state->cfg.hostbus_diversity) - outreg = (1 << 10) | (4 << 6); /* 0x0500 */ - else - outreg = (1 << 11); - break; - case OUTMODE_MPEG2_FIFO: // e.g. USB feeding - smo_mode |= (3 << 1); - fifo_threshold = 512; - outreg = (1 << 10) | (5 << 6); - break; - case OUTMODE_ANALOG_ADC: - outreg = (1 << 10) | (3 << 6); - break; - case OUTMODE_HIGH_Z: // disable - outreg = 0; - break; - default: - dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod); - break; - } - - if (state->cfg.output_mpeg2_in_188_bytes) - smo_mode |= (1 << 5) ; - - ret |= dib7000p_write_word(state, 235, smo_mode); - ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */ - ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */ - - return ret; -} - -static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff) -{ - struct dib7000p_state *state = demod->demodulator_priv; - - if (state->div_force_off) { - dprintk( "diversity combination deactivated - forced by COFDM parameters"); - onoff = 0; - } - state->div_state = (u8)onoff; - - if (onoff) { - dib7000p_write_word(state, 204, 6); - dib7000p_write_word(state, 205, 16); - /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */ - dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0)); - } else { - dib7000p_write_word(state, 204, 1); - dib7000p_write_word(state, 205, 0); - dib7000p_write_word(state, 207, 0); - } - - return 0; -} - -static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode) -{ - /* by default everything is powered off */ - u16 reg_774 = 0xffff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, - reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff); - - /* now, depending on the requested mode, we power on */ - switch (mode) { - /* power up everything in the demod */ - case DIB7000P_POWER_ALL: - reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0; reg_899 = 0x0; reg_1280 &= 0x01ff; - break; - - case DIB7000P_POWER_ANALOG_ADC: - /* dem, cfg, iqc, sad, agc */ - reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9)); - /* nud */ - reg_776 &= ~((1 << 0)); - /* Dout */ - reg_1280 &= ~((1 << 11)); - /* fall through wanted to enable the interfaces */ - - /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */ - case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */ - reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10)); - break; - -/* TODO following stuff is just converted from the dib7000-driver - check when is used what */ - } - - dib7000p_write_word(state, 774, reg_774); - dib7000p_write_word(state, 775, reg_775); - dib7000p_write_word(state, 776, reg_776); - dib7000p_write_word(state, 899, reg_899); - dib7000p_write_word(state, 1280, reg_1280); - - return 0; -} - -static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no) -{ - u16 reg_908 = dib7000p_read_word(state, 908), - reg_909 = dib7000p_read_word(state, 909); - - switch (no) { - case DIBX000_SLOW_ADC_ON: - reg_909 |= (1 << 1) | (1 << 0); - dib7000p_write_word(state, 909, reg_909); - reg_909 &= ~(1 << 1); - break; - - case DIBX000_SLOW_ADC_OFF: - reg_909 |= (1 << 1) | (1 << 0); - break; - - case DIBX000_ADC_ON: - reg_908 &= 0x0fff; - reg_909 &= 0x0003; - break; - - case DIBX000_ADC_OFF: // leave the VBG voltage on - reg_908 |= (1 << 14) | (1 << 13) | (1 << 12); - reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2); - break; - - case DIBX000_VBG_ENABLE: - reg_908 &= ~(1 << 15); - break; - - case DIBX000_VBG_DISABLE: - reg_908 |= (1 << 15); - break; - - default: - break; - } - -// dprintk( "908: %x, 909: %x\n", reg_908, reg_909); - - dib7000p_write_word(state, 908, reg_908); - dib7000p_write_word(state, 909, reg_909); -} - -static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw) -{ - u32 timf; - - // store the current bandwidth for later use - state->current_bandwidth = bw; - - if (state->timf == 0) { - dprintk( "using default timf"); - timf = state->cfg.bw->timf; - } else { - dprintk( "using updated timf"); - timf = state->timf; - } - - timf = timf * (bw / 50) / 160; - - dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff)); - dib7000p_write_word(state, 24, (u16) ((timf ) & 0xffff)); - - return 0; -} - -static int dib7000p_sad_calib(struct dib7000p_state *state) -{ -/* internal */ -// dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth - dib7000p_write_word(state, 73, (0 << 1) | (0 << 0)); - dib7000p_write_word(state, 74, 776); // 0.625*3.3 / 4096 - - /* do the calibration */ - dib7000p_write_word(state, 73, (1 << 0)); - dib7000p_write_word(state, 73, (0 << 0)); - - msleep(1); - - return 0; -} - -int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value) -{ - struct dib7000p_state *state = demod->demodulator_priv; - if (value > 4095) - value = 4095; - state->wbd_ref = value; - return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value); -} - -EXPORT_SYMBOL(dib7000p_set_wbd_ref); -static void dib7000p_reset_pll(struct dib7000p_state *state) -{ - struct dibx000_bandwidth_config *bw = &state->cfg.bw[0]; - u16 clk_cfg0; - - /* force PLL bypass */ - clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) | - (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | - (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0); - - dib7000p_write_word(state, 900, clk_cfg0); - - /* P_pll_cfg */ - dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset); - clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff); - dib7000p_write_word(state, 900, clk_cfg0); - - dib7000p_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff)); - dib7000p_write_word(state, 19, (u16) ( (bw->internal*1000 ) & 0xffff)); - dib7000p_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff)); - dib7000p_write_word(state, 22, (u16) ( (bw->ifreq ) & 0xffff)); - - dib7000p_write_word(state, 72, bw->sad_cfg); -} - -static int dib7000p_reset_gpio(struct dib7000p_state *st) -{ - /* reset the GPIOs */ - dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st->gpio_dir, st->gpio_val,st->cfg.gpio_pwm_pos); - - dib7000p_write_word(st, 1029, st->gpio_dir); - dib7000p_write_word(st, 1030, st->gpio_val); - - /* TODO 1031 is P_gpio_od */ - - dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos); - - dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div); - return 0; -} - -static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val) -{ - st->gpio_dir = dib7000p_read_word(st, 1029); - st->gpio_dir &= ~(1 << num); /* reset the direction bit */ - st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */ - dib7000p_write_word(st, 1029, st->gpio_dir); - - st->gpio_val = dib7000p_read_word(st, 1030); - st->gpio_val &= ~(1 << num); /* reset the direction bit */ - st->gpio_val |= (val & 0x01) << num; /* set the new value */ - dib7000p_write_word(st, 1030, st->gpio_val); - - return 0; -} - -int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val) -{ - struct dib7000p_state *state = demod->demodulator_priv; - return dib7000p_cfg_gpio(state, num, dir, val); -} - -EXPORT_SYMBOL(dib7000p_set_gpio); -static u16 dib7000p_defaults[] = - -{ - // auto search configuration - 3, 2, - 0x0004, - 0x1000, - 0x0814, /* Equal Lock */ - - 12, 6, - 0x001b, - 0x7740, - 0x005b, - 0x8d80, - 0x01c9, - 0xc380, - 0x0000, - 0x0080, - 0x0000, - 0x0090, - 0x0001, - 0xd4c0, - - 1, 26, - 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26 - - /* set ADC level to -16 */ - 11, 79, - (1 << 13) - 825 - 117, - (1 << 13) - 837 - 117, - (1 << 13) - 811 - 117, - (1 << 13) - 766 - 117, - (1 << 13) - 737 - 117, - (1 << 13) - 693 - 117, - (1 << 13) - 648 - 117, - (1 << 13) - 619 - 117, - (1 << 13) - 575 - 117, - (1 << 13) - 531 - 117, - (1 << 13) - 501 - 117, - - 1, 142, - 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16 - - /* disable power smoothing */ - 8, 145, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - - 1, 154, - 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0 - - 1, 168, - 0x0ccd, // P_pha3_thres, default 0x3000 - -// 1, 169, -// 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010 - - 1, 183, - 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005 - - 5, 187, - 0x023d, // P_adp_regul_cnt=573, default: 410 - 0x00a4, // P_adp_noise_cnt= - 0x00a4, // P_adp_regul_ext - 0x7ff0, // P_adp_noise_ext - 0x3ccc, // P_adp_fil - - 1, 198, - 0x800, // P_equal_thres_wgn - - 1, 222, - 0x0010, // P_fec_ber_rs_len=2 - - 1, 235, - 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard - - 2, 901, - 0x0006, // P_clk_cfg1 - (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1 - - 1, 905, - 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive - - 0, -}; - -static int dib7000p_demod_reset(struct dib7000p_state *state) -{ - dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); - - dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE); - - /* restart all parts */ - dib7000p_write_word(state, 770, 0xffff); - dib7000p_write_word(state, 771, 0xffff); - dib7000p_write_word(state, 772, 0x001f); - dib7000p_write_word(state, 898, 0x0003); - /* except i2c, sdio, gpio - control interfaces */ - dib7000p_write_word(state, 1280, 0x01fc - ((1 << 7) | (1 << 6) | (1 << 5)) ); - - dib7000p_write_word(state, 770, 0); - dib7000p_write_word(state, 771, 0); - dib7000p_write_word(state, 772, 0); - dib7000p_write_word(state, 898, 0); - dib7000p_write_word(state, 1280, 0); - - /* default */ - dib7000p_reset_pll(state); - - if (dib7000p_reset_gpio(state) != 0) - dprintk( "GPIO reset was not successful."); - - if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0) - dprintk( "OUTPUT_MODE could not be reset."); - - /* unforce divstr regardless whether i2c enumeration was done or not */ - dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1) ); - - dib7000p_set_bandwidth(state, 8000); - - dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON); - dib7000p_sad_calib(state); - dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF); - - // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ... - if(state->cfg.tuner_is_baseband) - dib7000p_write_word(state, 36,0x0755); - else - dib7000p_write_word(state, 36,0x1f55); - - dib7000p_write_tab(state, dib7000p_defaults); - - dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); - - - return 0; -} - -static void dib7000p_pll_clk_cfg(struct dib7000p_state *state) -{ - u16 tmp = 0; - tmp = dib7000p_read_word(state, 903); - dib7000p_write_word(state, 903, (tmp | 0x1)); //pwr-up pll - tmp = dib7000p_read_word(state, 900); - dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); //use High freq clock -} - -static void dib7000p_restart_agc(struct dib7000p_state *state) -{ - // P_restart_iqc & P_restart_agc - dib7000p_write_word(state, 770, (1 << 11) | (1 << 9)); - dib7000p_write_word(state, 770, 0x0000); -} - -static int dib7000p_update_lna(struct dib7000p_state *state) -{ - u16 dyn_gain; - - // when there is no LNA to program return immediatly - if (state->cfg.update_lna) { - // read dyn_gain here (because it is demod-dependent and not fe) - dyn_gain = dib7000p_read_word(state, 394); - if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed - dib7000p_restart_agc(state); - return 1; - } - } - - return 0; -} - -static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band) -{ - struct dibx000_agc_config *agc = NULL; - int i; - if (state->current_band == band && state->current_agc != NULL) - return 0; - state->current_band = band; - - for (i = 0; i < state->cfg.agc_config_count; i++) - if (state->cfg.agc[i].band_caps & band) { - agc = &state->cfg.agc[i]; - break; - } - - if (agc == NULL) { - dprintk( "no valid AGC configuration found for band 0x%02x",band); - return -EINVAL; - } - - state->current_agc = agc; - - /* AGC */ - dib7000p_write_word(state, 75 , agc->setup ); - dib7000p_write_word(state, 76 , agc->inv_gain ); - dib7000p_write_word(state, 77 , agc->time_stabiliz ); - dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock); - - // Demod AGC loop configuration - dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp); - dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp); - - /* AGC continued */ - dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d", - state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel); - - if (state->wbd_ref != 0) - dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref); - else - dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref); - - dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8)); - - dib7000p_write_word(state, 107, agc->agc1_max); - dib7000p_write_word(state, 108, agc->agc1_min); - dib7000p_write_word(state, 109, agc->agc2_max); - dib7000p_write_word(state, 110, agc->agc2_min); - dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2); - dib7000p_write_word(state, 112, agc->agc1_pt3); - dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2); - dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2); - dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2); - return 0; -} - -static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib7000p_state *state = demod->demodulator_priv; - int ret = -1; - u8 *agc_state = &state->agc_state; - u8 agc_split; - - switch (state->agc_state) { - case 0: - // set power-up level: interf+analog+AGC - dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); - dib7000p_set_adc_state(state, DIBX000_ADC_ON); - dib7000p_pll_clk_cfg(state); - - if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0) - return -1; - - ret = 7; - (*agc_state)++; - break; - - case 1: - // AGC initialization - if (state->cfg.agc_control) - state->cfg.agc_control(&state->demod, 1); - - dib7000p_write_word(state, 78, 32768); - if (!state->current_agc->perform_agc_softsplit) { - /* we are using the wbd - so slow AGC startup */ - /* force 0 split on WBD and restart AGC */ - dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8)); - (*agc_state)++; - ret = 5; - } else { - /* default AGC startup */ - (*agc_state) = 4; - /* wait AGC rough lock time */ - ret = 7; - } - - dib7000p_restart_agc(state); - break; - - case 2: /* fast split search path after 5sec */ - dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */ - dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */ - (*agc_state)++; - ret = 14; - break; - - case 3: /* split search ended */ - agc_split = (u8)dib7000p_read_word(state, 396); /* store the split value for the next time */ - dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */ - - dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */ - dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */ - - dib7000p_restart_agc(state); - - dprintk( "SPLIT %p: %hd", demod, agc_split); - - (*agc_state)++; - ret = 5; - break; - - case 4: /* LNA startup */ - // wait AGC accurate lock time - ret = 7; - - if (dib7000p_update_lna(state)) - // wait only AGC rough lock time - ret = 5; - else // nothing was done, go to the next state - (*agc_state)++; - break; - - case 5: - if (state->cfg.agc_control) - state->cfg.agc_control(&state->demod, 0); - (*agc_state)++; - break; - default: - break; - } - return ret; -} - -static void dib7000p_update_timf(struct dib7000p_state *state) -{ - u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428); - state->timf = timf * 160 / (state->current_bandwidth / 50); - dib7000p_write_word(state, 23, (u16) (timf >> 16)); - dib7000p_write_word(state, 24, (u16) (timf & 0xffff)); - dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->cfg.bw->timf); - -} - -static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq) -{ - u16 value, est[4]; - - dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); - - /* nfft, guard, qam, alpha */ - value = 0; - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: value |= (0 << 7); break; - case /* 4K MODE */ 255: value |= (2 << 7); break; - default: - case TRANSMISSION_MODE_8K: value |= (1 << 7); break; - } - switch (ch->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_32: value |= (0 << 5); break; - case GUARD_INTERVAL_1_16: value |= (1 << 5); break; - case GUARD_INTERVAL_1_4: value |= (3 << 5); break; - default: - case GUARD_INTERVAL_1_8: value |= (2 << 5); break; - } - switch (ch->u.ofdm.constellation) { - case QPSK: value |= (0 << 3); break; - case QAM_16: value |= (1 << 3); break; - default: - case QAM_64: value |= (2 << 3); break; - } - switch (HIERARCHY_1) { - case HIERARCHY_2: value |= 2; break; - case HIERARCHY_4: value |= 4; break; - default: - case HIERARCHY_1: value |= 1; break; - } - dib7000p_write_word(state, 0, value); - dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */ - - /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */ - value = 0; - if (1 != 0) - value |= (1 << 6); - if (ch->u.ofdm.hierarchy_information == 1) - value |= (1 << 4); - if (1 == 1) - value |= 1; - switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) { - case FEC_2_3: value |= (2 << 1); break; - case FEC_3_4: value |= (3 << 1); break; - case FEC_5_6: value |= (5 << 1); break; - case FEC_7_8: value |= (7 << 1); break; - default: - case FEC_1_2: value |= (1 << 1); break; - } - dib7000p_write_word(state, 208, value); - - /* offset loop parameters */ - dib7000p_write_word(state, 26, 0x6680); // timf(6xxx) - dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3) - dib7000p_write_word(state, 29, 0x1273); // isi - dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5) - - /* P_dvsy_sync_wait */ - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_8K: value = 256; break; - case /* 4K MODE */ 255: value = 128; break; - case TRANSMISSION_MODE_2K: - default: value = 64; break; - } - switch (ch->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_16: value *= 2; break; - case GUARD_INTERVAL_1_8: value *= 4; break; - case GUARD_INTERVAL_1_4: value *= 8; break; - default: - case GUARD_INTERVAL_1_32: value *= 1; break; - } - state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO - - /* deactive the possibility of diversity reception if extended interleaver */ - state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K; - dib7000p_set_diversity_in(&state->demod, state->div_state); - - /* channel estimation fine configuration */ - switch (ch->u.ofdm.constellation) { - case QAM_64: - est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ - est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */ - est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ - est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */ - break; - case QAM_16: - est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */ - est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */ - est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ - est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */ - break; - default: - est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */ - est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */ - est[2] = 0x0333; /* P_adp_regul_ext 0.1 */ - est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */ - break; - } - for (value = 0; value < 4; value++) - dib7000p_write_word(state, 187 + value, est[value]); -} - -static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib7000p_state *state = demod->demodulator_priv; - struct dvb_frontend_parameters schan; - u32 value, factor; - - schan = *ch; - schan.u.ofdm.constellation = QAM_64; - schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - schan.u.ofdm.code_rate_HP = FEC_2_3; - schan.u.ofdm.code_rate_LP = FEC_3_4; - schan.u.ofdm.hierarchy_information = 0; - - dib7000p_set_channel(state, &schan, 7); - - factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth); - if (factor >= 5000) - factor = 1; - else - factor = 6; - - // always use the setting for 8MHz here lock_time for 7,6 MHz are longer - value = 30 * state->cfg.bw->internal * factor; - dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time - dib7000p_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time - value = 100 * state->cfg.bw->internal * factor; - dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time - dib7000p_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time - value = 500 * state->cfg.bw->internal * factor; - dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time - dib7000p_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time - - value = dib7000p_read_word(state, 0); - dib7000p_write_word(state, 0, (u16) ((1 << 9) | value)); - dib7000p_read_word(state, 1284); - dib7000p_write_word(state, 0, (u16) value); - - return 0; -} - -static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod) -{ - struct dib7000p_state *state = demod->demodulator_priv; - u16 irq_pending = dib7000p_read_word(state, 1284); - - if (irq_pending & 0x1) // failed - return 1; - - if (irq_pending & 0x2) // succeeded - return 2; - - return 0; // still pending -} - -static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw) -{ - static s16 notch[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392}; - static u8 sine [] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22, - 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51, - 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80, - 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105, - 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126, - 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146, - 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165, - 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212, - 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224, - 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235, - 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243, - 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249, - 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254, - 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255}; - - u32 xtal = state->cfg.bw->xtal_hz / 1000; - int f_rel = ( (rf_khz + xtal/2) / xtal) * xtal - rf_khz; - int k; - int coef_re[8],coef_im[8]; - int bw_khz = bw; - u32 pha; - - dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal); - - - if (f_rel < -bw_khz/2 || f_rel > bw_khz/2) - return; - - bw_khz /= 100; - - dib7000p_write_word(state, 142 ,0x0610); - - for (k = 0; k < 8; k++) { - pha = ((f_rel * (k+1) * 112 * 80/bw_khz) /1000) & 0x3ff; - - if (pha==0) { - coef_re[k] = 256; - coef_im[k] = 0; - } else if(pha < 256) { - coef_re[k] = sine[256-(pha&0xff)]; - coef_im[k] = sine[pha&0xff]; - } else if (pha == 256) { - coef_re[k] = 0; - coef_im[k] = 256; - } else if (pha < 512) { - coef_re[k] = -sine[pha&0xff]; - coef_im[k] = sine[256 - (pha&0xff)]; - } else if (pha == 512) { - coef_re[k] = -256; - coef_im[k] = 0; - } else if (pha < 768) { - coef_re[k] = -sine[256-(pha&0xff)]; - coef_im[k] = -sine[pha&0xff]; - } else if (pha == 768) { - coef_re[k] = 0; - coef_im[k] = -256; - } else { - coef_re[k] = sine[pha&0xff]; - coef_im[k] = -sine[256 - (pha&0xff)]; - } - - coef_re[k] *= notch[k]; - coef_re[k] += (1<<14); - if (coef_re[k] >= (1<<24)) - coef_re[k] = (1<<24) - 1; - coef_re[k] /= (1<<15); - - coef_im[k] *= notch[k]; - coef_im[k] += (1<<14); - if (coef_im[k] >= (1<<24)) - coef_im[k] = (1<<24)-1; - coef_im[k] /= (1<<15); - - dprintk( "PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]); - - dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff)); - dib7000p_write_word(state, 144, coef_im[k] & 0x3ff); - dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff)); - } - dib7000p_write_word(state,143 ,0); -} - -static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib7000p_state *state = demod->demodulator_priv; - u16 tmp = 0; - - if (ch != NULL) - dib7000p_set_channel(state, ch, 0); - else - return -EINVAL; - - // restart demod - dib7000p_write_word(state, 770, 0x4000); - dib7000p_write_word(state, 770, 0x0000); - msleep(45); - - /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */ - tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3); - if (state->sfn_workaround_active) { - dprintk( "SFN workaround is active"); - tmp |= (1 << 9); - dib7000p_write_word(state, 166, 0x4000); // P_pha3_force_pha_shift - } else { - dib7000p_write_word(state, 166, 0x0000); // P_pha3_force_pha_shift - } - dib7000p_write_word(state, 29, tmp); - - // never achieved a lock with that bandwidth so far - wait for osc-freq to update - if (state->timf == 0) - msleep(200); - - /* offset loop parameters */ - - /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */ - tmp = (6 << 8) | 0x80; - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: tmp |= (7 << 12); break; - case /* 4K MODE */ 255: tmp |= (8 << 12); break; - default: - case TRANSMISSION_MODE_8K: tmp |= (9 << 12); break; - } - dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */ - - /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */ - tmp = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: tmp |= 0x6; break; - case /* 4K MODE */ 255: tmp |= 0x7; break; - default: - case TRANSMISSION_MODE_8K: tmp |= 0x8; break; - } - dib7000p_write_word(state, 32, tmp); - - /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */ - tmp = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: tmp |= 0x6; break; - case /* 4K MODE */ 255: tmp |= 0x7; break; - default: - case TRANSMISSION_MODE_8K: tmp |= 0x8; break; - } - dib7000p_write_word(state, 33, tmp); - - tmp = dib7000p_read_word(state,509); - if (!((tmp >> 6) & 0x1)) { - /* restart the fec */ - tmp = dib7000p_read_word(state,771); - dib7000p_write_word(state, 771, tmp | (1 << 1)); - dib7000p_write_word(state, 771, tmp); - msleep(10); - tmp = dib7000p_read_word(state,509); - } - - // we achieved a lock - it's time to update the osc freq - if ((tmp >> 6) & 0x1) - dib7000p_update_timf(state); - - if (state->cfg.spur_protect) - dib7000p_spur_protect(state, ch->frequency/1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); - - dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); - return 0; -} - -static int dib7000p_wakeup(struct dvb_frontend *demod) -{ - struct dib7000p_state *state = demod->demodulator_priv; - dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); - dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON); - return 0; -} - -static int dib7000p_sleep(struct dvb_frontend *demod) -{ - struct dib7000p_state *state = demod->demodulator_priv; - return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); -} - -static int dib7000p_identify(struct dib7000p_state *st) -{ - u16 value; - dprintk( "checking demod on I2C address: %d (%x)", - st->i2c_addr, st->i2c_addr); - - if ((value = dib7000p_read_word(st, 768)) != 0x01b3) { - dprintk( "wrong Vendor ID (read=0x%x)",value); - return -EREMOTEIO; - } - - if ((value = dib7000p_read_word(st, 769)) != 0x4000) { - dprintk( "wrong Device ID (%x)",value); - return -EREMOTEIO; - } - - return 0; -} - - -static int dib7000p_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib7000p_state *state = fe->demodulator_priv; - u16 tps = dib7000p_read_word(state,463); - - fep->inversion = INVERSION_AUTO; - - fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth); - - switch ((tps >> 8) & 0x3) { - case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; - case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break; - /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */ - } - - switch (tps & 0x3) { - case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break; - case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break; - case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break; - case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break; - } - - switch ((tps >> 14) & 0x3) { - case 0: fep->u.ofdm.constellation = QPSK; break; - case 1: fep->u.ofdm.constellation = QAM_16; break; - case 2: - default: fep->u.ofdm.constellation = QAM_64; break; - } - - /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ - /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */ - - fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; - switch ((tps >> 5) & 0x7) { - case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break; - case 7: - default: fep->u.ofdm.code_rate_HP = FEC_7_8; break; - - } - - switch ((tps >> 2) & 0x7) { - case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break; - case 7: - default: fep->u.ofdm.code_rate_LP = FEC_7_8; break; - } - - /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */ - - return 0; -} - -static int dib7000p_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib7000p_state *state = fe->demodulator_priv; - int time, ret; - - dib7000p_set_output_mode(state, OUTMODE_HIGH_Z); - - /* maybe the parameter has been changed */ - state->sfn_workaround_active = buggy_sfn_workaround; - - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, fep); - - /* start up the AGC */ - state->agc_state = 0; - do { - time = dib7000p_agc_startup(fe, fep); - if (time != -1) - msleep(time); - } while (time != -1); - - if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || - fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || - fep->u.ofdm.constellation == QAM_AUTO || - fep->u.ofdm.code_rate_HP == FEC_AUTO) { - int i = 800, found; - - dib7000p_autosearch_start(fe, fep); - do { - msleep(1); - found = dib7000p_autosearch_is_irq(fe); - } while (found == 0 && i--); - - dprintk("autosearch returns: %d",found); - if (found == 0 || found == 1) - return 0; // no channel found - - dib7000p_get_frontend(fe, fep); - } - - ret = dib7000p_tune(fe, fep); - - /* make this a config parameter */ - dib7000p_set_output_mode(state, state->cfg.output_mode); - return ret; -} - -static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat) -{ - struct dib7000p_state *state = fe->demodulator_priv; - u16 lock = dib7000p_read_word(state, 509); - - *stat = 0; - - if (lock & 0x8000) - *stat |= FE_HAS_SIGNAL; - if (lock & 0x3000) - *stat |= FE_HAS_CARRIER; - if (lock & 0x0100) - *stat |= FE_HAS_VITERBI; - if (lock & 0x0010) - *stat |= FE_HAS_SYNC; - if (lock & 0x0008) - *stat |= FE_HAS_LOCK; - - return 0; -} - -static int dib7000p_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct dib7000p_state *state = fe->demodulator_priv; - *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501); - return 0; -} - -static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) -{ - struct dib7000p_state *state = fe->demodulator_priv; - *unc = dib7000p_read_word(state, 506); - return 0; -} - -static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct dib7000p_state *state = fe->demodulator_priv; - u16 val = dib7000p_read_word(state, 394); - *strength = 65535 - val; - return 0; -} - -static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - *snr = 0x0000; - return 0; -} - -static int dib7000p_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void dib7000p_release(struct dvb_frontend *demod) -{ - struct dib7000p_state *st = demod->demodulator_priv; - dibx000_exit_i2c_master(&st->i2c_master); - kfree(st); -} - -int dib7000pc_detection(struct i2c_adapter *i2c_adap) -{ - u8 tx[2], rx[2]; - struct i2c_msg msg[2] = { - { .addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2 }, - { .addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2 }, - }; - - tx[0] = 0x03; - tx[1] = 0x00; - - if (i2c_transfer(i2c_adap, msg, 2) == 2) - if (rx[0] == 0x01 && rx[1] == 0xb3) { - dprintk("-D- DiB7000PC detected"); - return 1; - } - - msg[0].addr = msg[1].addr = 0x40; - - if (i2c_transfer(i2c_adap, msg, 2) == 2) - if (rx[0] == 0x01 && rx[1] == 0xb3) { - dprintk("-D- DiB7000PC detected"); - return 1; - } - - dprintk("-D- DiB7000PC not detected"); - return 0; -} -EXPORT_SYMBOL(dib7000pc_detection); - -struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating) -{ - struct dib7000p_state *st = demod->demodulator_priv; - return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating); -} -EXPORT_SYMBOL(dib7000p_get_i2c_master); - -int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]) -{ - struct dib7000p_state st = { .i2c_adap = i2c }; - int k = 0; - u8 new_addr = 0; - - for (k = no_of_demods-1; k >= 0; k--) { - st.cfg = cfg[k]; - - /* designated i2c address */ - new_addr = (0x40 + k) << 1; - st.i2c_addr = new_addr; - if (dib7000p_identify(&st) != 0) { - st.i2c_addr = default_addr; - if (dib7000p_identify(&st) != 0) { - dprintk("DiB7000P #%d: not identified\n", k); - return -EIO; - } - } - - /* start diversity to pull_down div_str - just for i2c-enumeration */ - dib7000p_set_output_mode(&st, OUTMODE_DIVERSITY); - - /* set new i2c address and force divstart */ - dib7000p_write_word(&st, 1285, (new_addr << 2) | 0x2); - - dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr); - } - - for (k = 0; k < no_of_demods; k++) { - st.cfg = cfg[k]; - st.i2c_addr = (0x40 + k) << 1; - - // unforce divstr - dib7000p_write_word(&st, 1285, st.i2c_addr << 2); - - /* deactivate div - it was just for i2c-enumeration */ - dib7000p_set_output_mode(&st, OUTMODE_HIGH_Z); - } - - return 0; -} -EXPORT_SYMBOL(dib7000p_i2c_enumeration); - -static struct dvb_frontend_ops dib7000p_ops; -struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg) -{ - struct dvb_frontend *demod; - struct dib7000p_state *st; - st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL); - if (st == NULL) - return NULL; - - memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config)); - st->i2c_adap = i2c_adap; - st->i2c_addr = i2c_addr; - st->gpio_val = cfg->gpio_val; - st->gpio_dir = cfg->gpio_dir; - - /* Ensure the output mode remains at the previous default if it's - * not specifically set by the caller. - */ - if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && - (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK)) - st->cfg.output_mode = OUTMODE_MPEG2_FIFO; - - demod = &st->demod; - demod->demodulator_priv = st; - memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops)); - - if (dib7000p_identify(st) != 0) - goto error; - - dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr); - - dib7000p_demod_reset(st); - - return demod; - -error: - kfree(st); - return NULL; -} -EXPORT_SYMBOL(dib7000p_attach); - -static struct dvb_frontend_ops dib7000p_ops = { - .info = { - .name = "DiBcom 7000PC", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 62500, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = dib7000p_release, - - .init = dib7000p_wakeup, - .sleep = dib7000p_sleep, - - .set_frontend = dib7000p_set_frontend, - .get_tune_settings = dib7000p_fe_get_tune_settings, - .get_frontend = dib7000p_get_frontend, - - .read_status = dib7000p_read_status, - .read_ber = dib7000p_read_ber, - .read_signal_strength = dib7000p_read_signal_strength, - .read_snr = dib7000p_read_snr, - .read_ucblocks = dib7000p_read_unc_blocks, -}; - -MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); -MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h deleted file mode 100644 index 02a4c82f0c7..00000000000 --- a/drivers/media/dvb/frontends/dib7000p.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef DIB7000P_H -#define DIB7000P_H - -#include "dibx000_common.h" - -struct dib7000p_config { - u8 output_mpeg2_in_188_bytes; - u8 hostbus_diversity; - u8 tuner_is_baseband; - int (*update_lna) (struct dvb_frontend *, u16 agc_global); - - u8 agc_config_count; - struct dibx000_agc_config *agc; - struct dibx000_bandwidth_config *bw; - -#define DIB7000P_GPIO_DEFAULT_DIRECTIONS 0xffff - u16 gpio_dir; -#define DIB7000P_GPIO_DEFAULT_VALUES 0x0000 - u16 gpio_val; -#define DIB7000P_GPIO_PWM_POS0(v) ((v & 0xf) << 12) -#define DIB7000P_GPIO_PWM_POS1(v) ((v & 0xf) << 8 ) -#define DIB7000P_GPIO_PWM_POS2(v) ((v & 0xf) << 4 ) -#define DIB7000P_GPIO_PWM_POS3(v) (v & 0xf) -#define DIB7000P_GPIO_DEFAULT_PWM_POS 0xffff - u16 gpio_pwm_pos; - - u16 pwm_freq_div; - - u8 quartz_direct; - - u8 spur_protect; - - int (*agc_control) (struct dvb_frontend *, u8 before); - - u8 output_mode; -}; - -#define DEFAULT_DIB7000P_I2C_ADDRESS 18 - -#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); -extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, - enum dibx000_i2c_interface, - int); -extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, - int no_of_demods, u8 default_addr, - 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, - struct dib7000p_config *cfg) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} - -static inline -struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, - 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[]) -{ - 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) -{ - 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) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} - -static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} -#endif - -#endif diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c deleted file mode 100644 index 315e09e95b0..00000000000 --- a/drivers/media/dvb/frontends/dibx000_common.c +++ /dev/null @@ -1,152 +0,0 @@ -#include <linux/i2c.h> - -#include "dibx000_common.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); - -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); } } while (0) - -static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) -{ - u8 b[4] = { - (reg >> 8) & 0xff, reg & 0xff, - (val >> 8) & 0xff, val & 0xff, - }; - struct i2c_msg msg = { - .addr = mst->i2c_addr, .flags = 0, .buf = b, .len = 4 - }; - return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; -} - - -static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf) -{ - if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) { - dprintk("selecting interface: %d\n",intf); - mst->selected_interface = intf; - return dibx000_write_word(mst, mst->base_reg + 4, intf); - } - return 0; -} - -static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 addr, int onoff) -{ - u16 val; - - - if (onoff) - val = addr << 8; // bit 7 = use master or not, if 0, the gate is open - else - val = 1 << 7; - - if (mst->device_rev > DIB7000) - val <<= 1; - - tx[0] = (((mst->base_reg + 1) >> 8) & 0xff); - tx[1] = ( (mst->base_reg + 1) & 0xff); - tx[2] = val >> 8; - tx[3] = val & 0xff; - - return 0; -} - -static u32 dibx000_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) -{ - struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); - struct i2c_msg m[2 + num]; - u8 tx_open[4], tx_close[4]; - - memset(m,0, sizeof(struct i2c_msg) * (2 + num)); - - dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER); - - dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1); - m[0].addr = mst->i2c_addr; - m[0].buf = tx_open; - m[0].len = 4; - - memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); - - dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0); - m[num+1].addr = mst->i2c_addr; - m[num+1].buf = tx_close; - m[num+1].len = 4; - - return i2c_transfer(mst->i2c_adap, m, 2+num) == 2 + num ? num : -EIO; -} - -static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = { - .master_xfer = dibx000_i2c_gated_tuner_xfer, - .functionality = dibx000_i2c_func, -}; - -struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating) -{ - struct i2c_adapter *i2c = NULL; - - switch (intf) { - case DIBX000_I2C_INTERFACE_TUNER: - if (gating) - i2c = &mst->gated_tuner_i2c_adap; - break; - default: - printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n"); - break; - } - - return i2c; -} -EXPORT_SYMBOL(dibx000_get_i2c_adapter); - -static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char *name, struct dibx000_i2c_master *mst) -{ - strncpy(i2c_adap->name, name, sizeof(i2c_adap->name)); - i2c_adap->class = I2C_CLASS_TV_DIGITAL, - i2c_adap->algo = algo; - i2c_adap->algo_data = NULL; - i2c_set_adapdata(i2c_adap, mst); - if (i2c_add_adapter(i2c_adap) < 0) - return -ENODEV; - return 0; -} - -int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr) -{ - u8 tx[4]; - struct i2c_msg m = { .addr = i2c_addr >> 1, .buf = tx, .len = 4 }; - - mst->device_rev = device_rev; - mst->i2c_adap = i2c_adap; - mst->i2c_addr = i2c_addr >> 1; - - if (device_rev == DIB7000P) - mst->base_reg = 1024; - else - mst->base_reg = 768; - - if (i2c_adapter_init(&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo, "DiBX000 tuner I2C bus", mst) != 0) - printk(KERN_ERR "DiBX000: could not initialize the tuner i2c_adapter\n"); - - /* initialize the i2c-master by closing the gate */ - dibx000_i2c_gate_ctrl(mst, tx, 0, 0); - - return i2c_transfer(i2c_adap, &m, 1) == 1; -} -EXPORT_SYMBOL(dibx000_init_i2c_master); - -void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst) -{ - i2c_del_adapter(&mst->gated_tuner_i2c_adap); -} -EXPORT_SYMBOL(dibx000_exit_i2c_master); - -MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); -MODULE_DESCRIPTION("Common function the DiBcom demodulator family"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h deleted file mode 100644 index 84e4d536292..00000000000 --- a/drivers/media/dvb/frontends/dibx000_common.h +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef DIBX000_COMMON_H -#define DIBX000_COMMON_H - -enum dibx000_i2c_interface { - DIBX000_I2C_INTERFACE_TUNER = 0, - DIBX000_I2C_INTERFACE_GPIO_1_2 = 1, - DIBX000_I2C_INTERFACE_GPIO_3_4 = 2 -}; - -struct dibx000_i2c_master { -#define DIB3000MC 1 -#define DIB7000 2 -#define DIB7000P 11 -#define DIB7000MC 12 - u16 device_rev; - - enum dibx000_i2c_interface selected_interface; - -// struct i2c_adapter tuner_i2c_adap; - struct i2c_adapter gated_tuner_i2c_adap; - - struct i2c_adapter *i2c_adap; - u8 i2c_addr; - - u16 base_reg; -}; - -extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr); -extern struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating); -extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst); - -#define BAND_LBAND 0x01 -#define BAND_UHF 0x02 -#define BAND_VHF 0x04 -#define BAND_SBAND 0x08 -#define BAND_FM 0x10 - -#define BAND_OF_FREQUENCY(freq_kHz) ( (freq_kHz) <= 115000 ? BAND_FM : \ - (freq_kHz) <= 250000 ? BAND_VHF : \ - (freq_kHz) <= 863000 ? BAND_UHF : \ - (freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND ) - -struct dibx000_agc_config { - /* defines the capabilities of this AGC-setting - using the BAND_-defines*/ - u8 band_caps; - - u16 setup; - - u16 inv_gain; - u16 time_stabiliz; - - u8 alpha_level; - u16 thlock; - - u8 wbd_inv; - u16 wbd_ref; - u8 wbd_sel; - u8 wbd_alpha; - - u16 agc1_max; - u16 agc1_min; - u16 agc2_max; - u16 agc2_min; - - u8 agc1_pt1; - u8 agc1_pt2; - u8 agc1_pt3; - - u8 agc1_slope1; - u8 agc1_slope2; - - u8 agc2_pt1; - u8 agc2_pt2; - - u8 agc2_slope1; - u8 agc2_slope2; - - u8 alpha_mant; - u8 alpha_exp; - - u8 beta_mant; - u8 beta_exp; - - u8 perform_agc_softsplit; - - struct { - u16 min; - u16 max; - u16 min_thres; - u16 max_thres; - } split; -}; - -struct dibx000_bandwidth_config { - u32 internal; - u32 sampling; - - u8 pll_prediv; - u8 pll_ratio; - u8 pll_range; - u8 pll_reset; - u8 pll_bypass; - - u8 enable_refdiv; - u8 bypclk_div; - u8 IO_CLK_en_core; - u8 ADClkSrc; - u8 modulo; - - u16 sad_cfg; - - u32 ifreq; - u32 timf; - - u32 xtal_hz; -}; - -enum dibx000_adc_states { - DIBX000_SLOW_ADC_ON = 0, - DIBX000_SLOW_ADC_OFF, - DIBX000_ADC_ON, - DIBX000_ADC_OFF, - DIBX000_VBG_ENABLE, - DIBX000_VBG_DISABLE, -}; - -#define BANDWIDTH_TO_KHZ(v) ( (v) == BANDWIDTH_8_MHZ ? 8000 : \ - (v) == BANDWIDTH_7_MHZ ? 7000 : \ - (v) == BANDWIDTH_6_MHZ ? 6000 : 8000 ) - -#define BANDWIDTH_TO_INDEX(v) ( \ - (v) == 8000 ? BANDWIDTH_8_MHZ : \ - (v) == 7000 ? BANDWIDTH_7_MHZ : \ - (v) == 6000 ? BANDWIDTH_6_MHZ : BANDWIDTH_8_MHZ ) - -/* Chip output mode. */ -#define OUTMODE_HIGH_Z 0 -#define OUTMODE_MPEG2_PAR_GATED_CLK 1 -#define OUTMODE_MPEG2_PAR_CONT_CLK 2 -#define OUTMODE_MPEG2_SERIAL 7 -#define OUTMODE_DIVERSITY 4 -#define OUTMODE_MPEG2_FIFO 5 -#define OUTMODE_ANALOG_ADC 6 - -#endif diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c deleted file mode 100644 index 172f1f928f0..00000000000 --- a/drivers/media/dvb/frontends/drx397xD.c +++ /dev/null @@ -1,1510 +0,0 @@ -/* - * Driver for Micronas drx397xD demodulator - * - * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@gmail.com> - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -#define DEBUG /* uncomment if you want debugging output */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/firmware.h> -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "drx397xD.h" - -static const char mod_name[] = "drx397xD"; - -#define MAX_CLOCK_DRIFT 200 /* maximal 200 PPM allowed */ - -#define F_SET_0D0h 1 -#define F_SET_0D4h 2 - -enum fw_ix { -#define _FW_ENTRY(a, b, c) b -#include "drx397xD_fw.h" -}; - -/* chip specifics */ -struct drx397xD_state { - struct i2c_adapter *i2c; - struct dvb_frontend frontend; - struct drx397xD_config config; - enum fw_ix chip_rev; - int flags; - u32 bandwidth_parm; /* internal bandwidth conversions */ - u32 f_osc; /* w90: actual osc frequency [Hz] */ -}; - -/* Firmware */ -static const char *blob_name[] = { -#define _BLOB_ENTRY(a, b) a -#include "drx397xD_fw.h" -}; - -enum blob_ix { -#define _BLOB_ENTRY(a, b) b -#include "drx397xD_fw.h" -}; - -static struct { - const char *name; - const struct firmware *file; - rwlock_t lock; - int refcnt; - const u8 *data[ARRAY_SIZE(blob_name)]; -} fw[] = { -#define _FW_ENTRY(a, b, c) { \ - .name = a, \ - .file = NULL, \ - .lock = __RW_LOCK_UNLOCKED(fw[c].lock), \ - .refcnt = 0, \ - .data = { } } -#include "drx397xD_fw.h" -}; - -/* use only with writer lock aquired */ -static void _drx_release_fw(struct drx397xD_state *s, enum fw_ix ix) -{ - memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); - if (fw[ix].file) - release_firmware(fw[ix].file); -} - -static void drx_release_fw(struct drx397xD_state *s) -{ - enum fw_ix ix = s->chip_rev; - - pr_debug("%s\n", __func__); - - write_lock(&fw[ix].lock); - if (fw[ix].refcnt) { - fw[ix].refcnt--; - if (fw[ix].refcnt == 0) - _drx_release_fw(s, ix); - } - write_unlock(&fw[ix].lock); -} - -static int drx_load_fw(struct drx397xD_state *s, enum fw_ix ix) -{ - const u8 *data; - size_t size, len; - int i = 0, j, rc = -EINVAL; - - pr_debug("%s\n", __func__); - - if (ix < 0 || ix >= ARRAY_SIZE(fw)) - return -EINVAL; - s->chip_rev = ix; - - write_lock(&fw[ix].lock); - if (fw[ix].file) { - rc = 0; - goto exit_ok; - } - memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); - - if (request_firmware(&fw[ix].file, fw[ix].name, &s->i2c->dev) != 0) { - printk(KERN_ERR "%s: Firmware \"%s\" not available\n", - mod_name, fw[ix].name); - rc = -ENOENT; - goto exit_err; - } - - if (!fw[ix].file->data || fw[ix].file->size < 10) - goto exit_corrupt; - - data = fw[ix].file->data; - size = fw[ix].file->size; - - if (data[i++] != 2) /* check firmware version */ - goto exit_corrupt; - - do { - switch (data[i++]) { - case 0x00: /* bytecode */ - if (i >= size) - break; - i += data[i]; - case 0x01: /* reset */ - case 0x02: /* sleep */ - i++; - break; - case 0xfe: /* name */ - len = strnlen(&data[i], size - i); - if (i + len + 1 >= size) - goto exit_corrupt; - if (data[i + len + 1] != 0) - goto exit_corrupt; - for (j = 0; j < ARRAY_SIZE(blob_name); j++) { - if (strcmp(blob_name[j], &data[i]) == 0) { - fw[ix].data[j] = &data[i + len + 1]; - pr_debug("Loading %s\n", blob_name[j]); - } - } - i += len + 1; - break; - case 0xff: /* file terminator */ - if (i == size) { - rc = 0; - goto exit_ok; - } - default: - goto exit_corrupt; - } - } while (i < size); - -exit_corrupt: - printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name); -exit_err: - _drx_release_fw(s, ix); - fw[ix].refcnt--; -exit_ok: - fw[ix].refcnt++; - write_unlock(&fw[ix].lock); - - return rc; -} - -/* i2c bus IO */ -static int write_fw(struct drx397xD_state *s, enum blob_ix ix) -{ - const u8 *data; - int len, rc = 0, i = 0; - struct i2c_msg msg = { - .addr = s->config.demod_address, - .flags = 0 - }; - - if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) { - pr_debug("%s drx_fw_ix_t out of range\n", __func__); - return -EINVAL; - } - pr_debug("%s %s\n", __func__, blob_name[ix]); - - read_lock(&fw[s->chip_rev].lock); - data = fw[s->chip_rev].data[ix]; - if (!data) { - rc = -EINVAL; - goto exit_rc; - } - - for (;;) { - switch (data[i++]) { - case 0: /* bytecode */ - len = data[i++]; - msg.len = len; - msg.buf = (__u8 *) &data[i]; - if (i2c_transfer(s->i2c, &msg, 1) != 1) { - rc = -EIO; - goto exit_rc; - } - i += len; - break; - case 1: /* reset */ - case 2: /* sleep */ - i++; - break; - default: - goto exit_rc; - } - } -exit_rc: - read_unlock(&fw[s->chip_rev].lock); - - return 0; -} - -/* Function is not endian safe, use the RD16 wrapper below */ -static int _read16(struct drx397xD_state *s, __le32 i2c_adr) -{ - int rc; - u8 a[4]; - __le16 v; - struct i2c_msg msg[2] = { - { - .addr = s->config.demod_address, - .flags = 0, - .buf = a, - .len = sizeof(a) - }, { - .addr = s->config.demod_address, - .flags = I2C_M_RD, - .buf = (u8 *)&v, - .len = sizeof(v) - } - }; - - *(__le32 *) a = i2c_adr; - - rc = i2c_transfer(s->i2c, msg, 2); - if (rc != 2) - return -EIO; - - return le16_to_cpu(v); -} - -/* Function is not endian safe, use the WR16.. wrappers below */ -static int _write16(struct drx397xD_state *s, __le32 i2c_adr, __le16 val) -{ - u8 a[6]; - int rc; - struct i2c_msg msg = { - .addr = s->config.demod_address, - .flags = 0, - .buf = a, - .len = sizeof(a) - }; - - *(__le32 *)a = i2c_adr; - *(__le16 *)&a[4] = val; - - rc = i2c_transfer(s->i2c, &msg, 1); - if (rc != 1) - return -EIO; - - return 0; -} - -#define WR16(ss, adr, val) \ - _write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val)) -#define WR16_E0(ss, adr, val) \ - _write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val)) -#define RD16(ss, adr) \ - _read16(ss, I2C_ADR_C0(adr)) - -#define EXIT_RC(cmd) \ - if ((rc = (cmd)) < 0) \ - goto exit_rc - -/* Tuner callback */ -static int PLL_Set(struct drx397xD_state *s, - struct dvb_frontend_parameters *fep, int *df_tuner) -{ - struct dvb_frontend *fe = &s->frontend; - u32 f_tuner, f = fep->frequency; - int rc; - - pr_debug("%s\n", __func__); - - if ((f > s->frontend.ops.tuner_ops.info.frequency_max) || - (f < s->frontend.ops.tuner_ops.info.frequency_min)) - return -EINVAL; - - *df_tuner = 0; - if (!s->frontend.ops.tuner_ops.set_params || - !s->frontend.ops.tuner_ops.get_frequency) - return -ENOSYS; - - rc = s->frontend.ops.tuner_ops.set_params(fe, fep); - if (rc < 0) - return rc; - - rc = s->frontend.ops.tuner_ops.get_frequency(fe, &f_tuner); - if (rc < 0) - return rc; - - *df_tuner = f_tuner - f; - pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __func__, f, - f_tuner); - - return 0; -} - -/* Demodulator helper functions */ -static int SC_WaitForReady(struct drx397xD_state *s) -{ - int cnt = 1000; - int rc; - - pr_debug("%s\n", __func__); - - while (cnt--) { - rc = RD16(s, 0x820043); - if (rc == 0) - return 0; - } - - return -1; -} - -static int SC_SendCommand(struct drx397xD_state *s, int cmd) -{ - int rc; - - pr_debug("%s\n", __func__); - - WR16(s, 0x820043, cmd); - SC_WaitForReady(s); - rc = RD16(s, 0x820042); - if ((rc & 0xffff) == 0xffff) - return -1; - - return 0; -} - -static int HI_Command(struct drx397xD_state *s, u16 cmd) -{ - int rc, cnt = 1000; - - pr_debug("%s\n", __func__); - - rc = WR16(s, 0x420032, cmd); - if (rc < 0) - return rc; - - do { - rc = RD16(s, 0x420032); - if (rc == 0) { - rc = RD16(s, 0x420031); - return rc; - } - if (rc < 0) - return rc; - } while (--cnt); - - return rc; -} - -static int HI_CfgCommand(struct drx397xD_state *s) -{ - - pr_debug("%s\n", __func__); - - WR16(s, 0x420033, 0x3973); - WR16(s, 0x420034, s->config.w50); /* code 4, log 4 */ - WR16(s, 0x420035, s->config.w52); /* code 15, log 9 */ - WR16(s, 0x420036, s->config.demod_address << 1); - WR16(s, 0x420037, s->config.w56); /* code (set_i2c ?? initX 1 ), log 1 */ - /* WR16(s, 0x420033, 0x3973); */ - if ((s->config.w56 & 8) == 0) - return HI_Command(s, 3); - - return WR16(s, 0x420032, 0x3); -} - -static const u8 fastIncrDecLUT_15273[] = { - 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, - 0x15, 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x1c, 0x1d, 0x1f -}; - -static const u8 slowIncrDecLUT_15272[] = { - 3, 4, 4, 5, 6 -}; - -static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc) -{ - u16 w06 = agc->w06; - u16 w08 = agc->w08; - u16 w0A = agc->w0A; - u16 w0C = agc->w0C; - int quot, rem, i, rc = -EINVAL; - - pr_debug("%s\n", __func__); - - if (agc->w04 > 0x3ff) - goto exit_rc; - - if (agc->d00 == 1) { - EXIT_RC(RD16(s, 0x0c20010)); - rc &= ~0x10; - EXIT_RC(WR16(s, 0x0c20010, rc)); - return WR16(s, 0x0c20030, agc->w04 & 0x7ff); - } - - if (agc->d00 != 0) - goto exit_rc; - if (w0A < w08) - goto exit_rc; - if (w0A > 0x3ff) - goto exit_rc; - if (w0C > 0x3ff) - goto exit_rc; - if (w06 > 0x3ff) - goto exit_rc; - - EXIT_RC(RD16(s, 0x0c20010)); - rc |= 0x10; - EXIT_RC(WR16(s, 0x0c20010, rc)); - - EXIT_RC(WR16(s, 0x0c20025, (w06 >> 1) & 0x1ff)); - EXIT_RC(WR16(s, 0x0c20031, (w0A - w08) >> 1)); - EXIT_RC(WR16(s, 0x0c20032, ((w0A + w08) >> 1) - 0x1ff)); - - quot = w0C / 113; - rem = w0C % 113; - if (quot <= 8) { - quot = 8 - quot; - } else { - quot = 0; - rem += 113; - } - - EXIT_RC(WR16(s, 0x0c20024, quot)); - - i = fastIncrDecLUT_15273[rem / 8]; - EXIT_RC(WR16(s, 0x0c2002d, i)); - EXIT_RC(WR16(s, 0x0c2002e, i)); - - i = slowIncrDecLUT_15272[rem / 28]; - EXIT_RC(WR16(s, 0x0c2002b, i)); - rc = WR16(s, 0x0c2002c, i); -exit_rc: - return rc; -} - -static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc) -{ - u16 w04 = agc->w04; - u16 w06 = agc->w06; - int rc = -1; - - pr_debug("%s %d 0x%x 0x%x\n", __func__, agc->d00, w04, w06); - - if (w04 > 0x3ff) - goto exit_rc; - - switch (agc->d00) { - case 1: - if (w04 == 0x3ff) - w04 = 0x400; - - EXIT_RC(WR16(s, 0x0c20036, w04)); - s->config.w9C &= ~2; - EXIT_RC(WR16(s, 0x0c20015, s->config.w9C)); - EXIT_RC(RD16(s, 0x0c20010)); - rc &= 0xbfdf; - EXIT_RC(WR16(s, 0x0c20010, rc)); - EXIT_RC(RD16(s, 0x0c20013)); - rc &= ~2; - break; - case 0: - /* loc_8000659 */ - s->config.w9C &= ~2; - EXIT_RC(WR16(s, 0x0c20015, s->config.w9C)); - EXIT_RC(RD16(s, 0x0c20010)); - rc &= 0xbfdf; - rc |= 0x4000; - EXIT_RC(WR16(s, 0x0c20010, rc)); - EXIT_RC(WR16(s, 0x0c20051, (w06 >> 4) & 0x3f)); - EXIT_RC(RD16(s, 0x0c20013)); - rc &= ~2; - break; - default: - s->config.w9C |= 2; - EXIT_RC(WR16(s, 0x0c20015, s->config.w9C)); - EXIT_RC(RD16(s, 0x0c20010)); - rc &= 0xbfdf; - EXIT_RC(WR16(s, 0x0c20010, rc)); - - EXIT_RC(WR16(s, 0x0c20036, 0)); - - EXIT_RC(RD16(s, 0x0c20013)); - rc |= 2; - } - rc = WR16(s, 0x0c20013, rc); - -exit_rc: - return rc; -} - -static int GetLockStatus(struct drx397xD_state *s, int *lockstat) -{ - int rc; - - *lockstat = 0; - - rc = RD16(s, 0x082004b); - if (rc < 0) - return rc; - - if (s->config.d60 != 2) - return 0; - - if ((rc & 7) == 7) - *lockstat |= 1; - if ((rc & 3) == 3) - *lockstat |= 2; - if (rc & 1) - *lockstat |= 4; - return 0; -} - -static int CorrectSysClockDeviation(struct drx397xD_state *s) -{ - int rc = -EINVAL; - int lockstat; - u32 clk, clk_limit; - - pr_debug("%s\n", __func__); - - if (s->config.d5C == 0) { - EXIT_RC(WR16(s, 0x08200e8, 0x010)); - EXIT_RC(WR16(s, 0x08200e9, 0x113)); - s->config.d5C = 1; - return rc; - } - if (s->config.d5C != 1) - goto exit_rc; - - rc = RD16(s, 0x0820048); - - rc = GetLockStatus(s, &lockstat); - if (rc < 0) - goto exit_rc; - if ((lockstat & 1) == 0) - goto exit_rc; - - EXIT_RC(WR16(s, 0x0420033, 0x200)); - EXIT_RC(WR16(s, 0x0420034, 0xc5)); - EXIT_RC(WR16(s, 0x0420035, 0x10)); - EXIT_RC(WR16(s, 0x0420036, 0x1)); - EXIT_RC(WR16(s, 0x0420037, 0xa)); - EXIT_RC(HI_Command(s, 6)); - EXIT_RC(RD16(s, 0x0420040)); - clk = rc; - EXIT_RC(RD16(s, 0x0420041)); - clk |= rc << 16; - - if (clk <= 0x26ffff) - goto exit_rc; - if (clk > 0x610000) - goto exit_rc; - - if (!s->bandwidth_parm) - return -EINVAL; - - /* round & convert to Hz */ - clk = ((u64) (clk + 0x800000) * s->bandwidth_parm + (1 << 20)) >> 21; - clk_limit = s->config.f_osc * MAX_CLOCK_DRIFT / 1000; - - if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) { - s->f_osc = clk; - pr_debug("%s: osc %d %d [Hz]\n", __func__, - s->config.f_osc * 1000, clk - s->config.f_osc * 1000); - } - rc = WR16(s, 0x08200e8, 0); - -exit_rc: - return rc; -} - -static int ConfigureMPEGOutput(struct drx397xD_state *s, int type) -{ - int rc, si, bp; - - pr_debug("%s\n", __func__); - - si = s->config.wA0; - if (s->config.w98 == 0) { - si |= 1; - bp = 0; - } else { - si &= ~1; - bp = 0x200; - } - if (s->config.w9A == 0) - si |= 0x80; - else - si &= ~0x80; - - EXIT_RC(WR16(s, 0x2150045, 0)); - EXIT_RC(WR16(s, 0x2150010, si)); - EXIT_RC(WR16(s, 0x2150011, bp)); - rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0)); - -exit_rc: - return rc; -} - -static int drx_tune(struct drx397xD_state *s, - struct dvb_frontend_parameters *fep) -{ - u16 v22 = 0; - u16 v1C = 0; - u16 v1A = 0; - u16 v18 = 0; - u32 edi = 0, ebx = 0, ebp = 0, edx = 0; - u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0; - - int rc, df_tuner = 0; - int a, b, c, d; - pr_debug("%s %d\n", __func__, s->config.d60); - - if (s->config.d60 != 2) - goto set_tuner; - rc = CorrectSysClockDeviation(s); - if (rc < 0) - goto set_tuner; - - s->config.d60 = 1; - rc = ConfigureMPEGOutput(s, 0); - if (rc < 0) - goto set_tuner; -set_tuner: - - rc = PLL_Set(s, fep, &df_tuner); - if (rc < 0) { - printk(KERN_ERR "Error in pll_set\n"); - goto exit_rc; - } - msleep(200); - - a = rc = RD16(s, 0x2150016); - if (rc < 0) - goto exit_rc; - b = rc = RD16(s, 0x2150010); - if (rc < 0) - goto exit_rc; - c = rc = RD16(s, 0x2150034); - if (rc < 0) - goto exit_rc; - d = rc = RD16(s, 0x2150035); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2150014, c); - rc = WR16(s, 0x2150015, d); - rc = WR16(s, 0x2150010, 0); - rc = WR16(s, 0x2150000, 2); - rc = WR16(s, 0x2150036, 0x0fff); - rc = WR16(s, 0x2150016, a); - - rc = WR16(s, 0x2150010, 2); - rc = WR16(s, 0x2150007, 0); - rc = WR16(s, 0x2150000, 1); - rc = WR16(s, 0x2110000, 0); - rc = WR16(s, 0x0800000, 0); - rc = WR16(s, 0x2800000, 0); - rc = WR16(s, 0x2110010, 0x664); - - rc = write_fw(s, DRXD_ResetECRAM); - rc = WR16(s, 0x2110000, 1); - - rc = write_fw(s, DRXD_InitSC); - if (rc < 0) - goto exit_rc; - - rc = SetCfgIfAgc(s, &s->config.ifagc); - if (rc < 0) - goto exit_rc; - - rc = SetCfgRfAgc(s, &s->config.rfagc); - if (rc < 0) - goto exit_rc; - - if (fep->u.ofdm.transmission_mode != TRANSMISSION_MODE_2K) - v22 = 1; - switch (fep->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_8K: - edi = 1; - if (s->chip_rev == DRXD_FW_B1) - break; - - rc = WR16(s, 0x2010010, 0); - if (rc < 0) - break; - v1C = 0x63; - v1A = 0x53; - v18 = 0x43; - break; - default: - edi = 0; - if (s->chip_rev == DRXD_FW_B1) - break; - - rc = WR16(s, 0x2010010, 1); - if (rc < 0) - break; - - v1C = 0x61; - v1A = 0x47; - v18 = 0x41; - } - - switch (fep->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_4: - edi |= 0x0c; - break; - case GUARD_INTERVAL_1_8: - edi |= 0x08; - break; - case GUARD_INTERVAL_1_16: - edi |= 0x04; - break; - case GUARD_INTERVAL_1_32: - break; - default: - v22 |= 2; - } - - ebx = 0; - ebp = 0; - v20 = 0; - v1E = 0; - v16 = 0; - v14 = 0; - v12 = 0; - v10 = 0; - v0E = 0; - - switch (fep->u.ofdm.hierarchy_information) { - case HIERARCHY_1: - edi |= 0x40; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x1c10047, 1); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010012, 1); - if (rc < 0) - goto exit_rc; - ebx = 0x19f; - ebp = 0x1fb; - v20 = 0x0c0; - v1E = 0x195; - v16 = 0x1d6; - v14 = 0x1ef; - v12 = 4; - v10 = 5; - v0E = 5; - break; - case HIERARCHY_2: - edi |= 0x80; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x1c10047, 2); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010012, 2); - if (rc < 0) - goto exit_rc; - ebx = 0x08f; - ebp = 0x12f; - v20 = 0x0c0; - v1E = 0x11e; - v16 = 0x1d6; - v14 = 0x15e; - v12 = 4; - v10 = 5; - v0E = 5; - break; - case HIERARCHY_4: - edi |= 0xc0; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x1c10047, 3); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010012, 3); - if (rc < 0) - goto exit_rc; - ebx = 0x14d; - ebp = 0x197; - v20 = 0x0c0; - v1E = 0x1ce; - v16 = 0x1d6; - v14 = 0x11a; - v12 = 4; - v10 = 6; - v0E = 5; - break; - default: - v22 |= 8; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x1c10047, 0); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010012, 0); - if (rc < 0) - goto exit_rc; - /* QPSK QAM16 QAM64 */ - ebx = 0x19f; /* 62 */ - ebp = 0x1fb; /* 15 */ - v20 = 0x16a; /* 62 */ - v1E = 0x195; /* 62 */ - v16 = 0x1bb; /* 15 */ - v14 = 0x1ef; /* 15 */ - v12 = 5; /* 16 */ - v10 = 5; /* 16 */ - v0E = 5; /* 16 */ - } - - switch (fep->u.ofdm.constellation) { - default: - v22 |= 4; - case QPSK: - if (s->chip_rev == DRXD_FW_B1) - break; - - rc = WR16(s, 0x1c10046, 0); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010011, 0); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001a, 0x10); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001b, 0); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001c, 0); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10062, v20); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c1002a, v1C); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10015, v16); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10016, v12); - if (rc < 0) - goto exit_rc; - break; - case QAM_16: - edi |= 0x10; - if (s->chip_rev == DRXD_FW_B1) - break; - - rc = WR16(s, 0x1c10046, 1); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010011, 1); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001a, 0x10); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001b, 4); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001c, 0); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10062, v1E); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c1002a, v1A); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10015, v14); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10016, v10); - if (rc < 0) - goto exit_rc; - break; - case QAM_64: - edi |= 0x20; - rc = WR16(s, 0x1c10046, 2); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010011, 2); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001a, 0x20); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001b, 8); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001c, 2); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10062, ebx); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c1002a, v18); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10015, ebp); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10016, v0E); - if (rc < 0) - goto exit_rc; - break; - } - - if (s->config.s20d24 == 1) { - rc = WR16(s, 0x2010013, 0); - } else { - rc = WR16(s, 0x2010013, 1); - edi |= 0x1000; - } - - switch (fep->u.ofdm.code_rate_HP) { - default: - v22 |= 0x10; - case FEC_1_2: - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x2090011, 0); - break; - case FEC_2_3: - edi |= 0x200; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x2090011, 1); - break; - case FEC_3_4: - edi |= 0x400; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x2090011, 2); - break; - case FEC_5_6: /* 5 */ - edi |= 0x600; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x2090011, 3); - break; - case FEC_7_8: /* 7 */ - edi |= 0x800; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x2090011, 4); - break; - }; - if (rc < 0) - goto exit_rc; - - switch (fep->u.ofdm.bandwidth) { - default: - rc = -EINVAL; - goto exit_rc; - case BANDWIDTH_8_MHZ: /* 0 */ - case BANDWIDTH_AUTO: - rc = WR16(s, 0x0c2003f, 0x32); - s->bandwidth_parm = ebx = 0x8b8249; - edx = 0; - break; - case BANDWIDTH_7_MHZ: - rc = WR16(s, 0x0c2003f, 0x3b); - s->bandwidth_parm = ebx = 0x7a1200; - edx = 0x4807; - break; - case BANDWIDTH_6_MHZ: - rc = WR16(s, 0x0c2003f, 0x47); - s->bandwidth_parm = ebx = 0x68a1b6; - edx = 0x0f07; - break; - }; - - if (rc < 0) - goto exit_rc; - - rc = WR16(s, 0x08200ec, edx); - if (rc < 0) - goto exit_rc; - - rc = RD16(s, 0x0820050); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x0820050, rc); - - { - /* Configure bandwidth specific factor */ - ebx = div64_u64(((u64) (s->f_osc) << 21) + (ebx >> 1), - (u64)ebx) - 0x800000; - EXIT_RC(WR16(s, 0x0c50010, ebx & 0xffff)); - EXIT_RC(WR16(s, 0x0c50011, ebx >> 16)); - - /* drx397xD oscillator calibration */ - ebx = div64_u64(((u64) (s->config.f_if + df_tuner) << 28) + - (s->f_osc >> 1), (u64)s->f_osc); - } - ebx &= 0xfffffff; - if (fep->inversion == INVERSION_ON) - ebx = 0x10000000 - ebx; - - EXIT_RC(WR16(s, 0x0c30010, ebx & 0xffff)); - EXIT_RC(WR16(s, 0x0c30011, ebx >> 16)); - - EXIT_RC(WR16(s, 0x0800000, 1)); - EXIT_RC(RD16(s, 0x0800000)); - - - EXIT_RC(SC_WaitForReady(s)); - EXIT_RC(WR16(s, 0x0820042, 0)); - EXIT_RC(WR16(s, 0x0820041, v22)); - EXIT_RC(WR16(s, 0x0820040, edi)); - EXIT_RC(SC_SendCommand(s, 3)); - - rc = RD16(s, 0x0800000); - - SC_WaitForReady(s); - WR16(s, 0x0820042, 0); - WR16(s, 0x0820041, 1); - WR16(s, 0x0820040, 1); - SC_SendCommand(s, 1); - - - rc = WR16(s, 0x2150000, 2); - rc = WR16(s, 0x2150016, a); - rc = WR16(s, 0x2150010, 4); - rc = WR16(s, 0x2150036, 0); - rc = WR16(s, 0x2150000, 1); - s->config.d60 = 2; - -exit_rc: - return rc; -} - -/******************************************************************************* - * DVB interface - ******************************************************************************/ - -static int drx397x_init(struct dvb_frontend *fe) -{ - struct drx397xD_state *s = fe->demodulator_priv; - int rc; - - pr_debug("%s\n", __func__); - - s->config.rfagc.d00 = 2; /* 0x7c */ - s->config.rfagc.w04 = 0; - s->config.rfagc.w06 = 0x3ff; - - s->config.ifagc.d00 = 0; /* 0x68 */ - s->config.ifagc.w04 = 0; - s->config.ifagc.w06 = 140; - s->config.ifagc.w08 = 0; - s->config.ifagc.w0A = 0x3ff; - s->config.ifagc.w0C = 0x388; - - /* for signal strenght calculations */ - s->config.ss76 = 820; - s->config.ss78 = 2200; - s->config.ss7A = 150; - - /* HI_CfgCommand */ - s->config.w50 = 4; - s->config.w52 = 9; - - s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */ - s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */ - s->config.w92 = 12000; - - s->config.w9C = 0x000e; - s->config.w9E = 0x0000; - - /* ConfigureMPEGOutput params */ - s->config.wA0 = 4; - s->config.w98 = 1; - s->config.w9A = 1; - - /* get chip revision */ - rc = RD16(s, 0x2410019); - if (rc < 0) - return -ENODEV; - - if (rc == 0) { - printk(KERN_INFO "%s: chip revision A2\n", mod_name); - rc = drx_load_fw(s, DRXD_FW_A2); - } else { - - rc = (rc >> 12) - 3; - switch (rc) { - case 1: - s->flags |= F_SET_0D4h; - case 0: - case 4: - s->flags |= F_SET_0D0h; - break; - case 2: - case 5: - break; - case 3: - s->flags |= F_SET_0D4h; - break; - default: - return -ENODEV; - }; - printk(KERN_INFO "%s: chip revision B1.%d\n", mod_name, rc); - rc = drx_load_fw(s, DRXD_FW_B1); - } - if (rc < 0) - goto error; - - rc = WR16(s, 0x0420033, 0x3973); - if (rc < 0) - goto error; - - rc = HI_Command(s, 2); - - msleep(1); - - if (s->chip_rev == DRXD_FW_A2) { - rc = WR16(s, 0x043012d, 0x47F); - if (rc < 0) - goto error; - } - rc = WR16_E0(s, 0x0400000, 0); - if (rc < 0) - goto error; - - if (s->config.w92 > 20000 || s->config.w92 % 4000) { - printk(KERN_ERR "%s: invalid osc frequency\n", mod_name); - rc = -1; - goto error; - } - - rc = WR16(s, 0x2410010, 1); - if (rc < 0) - goto error; - rc = WR16(s, 0x2410011, 0x15); - if (rc < 0) - goto error; - rc = WR16(s, 0x2410012, s->config.w92 / 4000); - if (rc < 0) - goto error; -#ifdef ORIG_FW - rc = WR16(s, 0x2410015, 2); - if (rc < 0) - goto error; -#endif - rc = WR16(s, 0x2410017, 0x3973); - if (rc < 0) - goto error; - - s->f_osc = s->config.f_osc * 1000; /* initial estimator */ - - s->config.w56 = 1; - - rc = HI_CfgCommand(s); - if (rc < 0) - goto error; - - rc = write_fw(s, DRXD_InitAtomicRead); - if (rc < 0) - goto error; - - if (s->chip_rev == DRXD_FW_A2) { - rc = WR16(s, 0x2150013, 0); - if (rc < 0) - goto error; - } - - rc = WR16_E0(s, 0x0400002, 0); - if (rc < 0) - goto error; - rc = WR16(s, 0x0400002, 0); - if (rc < 0) - goto error; - - if (s->chip_rev == DRXD_FW_A2) { - rc = write_fw(s, DRXD_ResetCEFR); - if (rc < 0) - goto error; - } - rc = write_fw(s, DRXD_microcode); - if (rc < 0) - goto error; - - s->config.w9C = 0x0e; - if (s->flags & F_SET_0D0h) { - s->config.w9C = 0; - rc = RD16(s, 0x0c20010); - if (rc < 0) - goto write_DRXD_InitFE_1; - - rc &= ~0x1000; - rc = WR16(s, 0x0c20010, rc); - if (rc < 0) - goto write_DRXD_InitFE_1; - - rc = RD16(s, 0x0c20011); - if (rc < 0) - goto write_DRXD_InitFE_1; - - rc &= ~0x8; - rc = WR16(s, 0x0c20011, rc); - if (rc < 0) - goto write_DRXD_InitFE_1; - - rc = WR16(s, 0x0c20012, 1); - } - -write_DRXD_InitFE_1: - - rc = write_fw(s, DRXD_InitFE_1); - if (rc < 0) - goto error; - - rc = 1; - if (s->chip_rev == DRXD_FW_B1) { - if (s->flags & F_SET_0D0h) - rc = 0; - } else { - if (s->flags & F_SET_0D0h) - rc = 4; - } - - rc = WR16(s, 0x0C20012, rc); - if (rc < 0) - goto error; - - rc = WR16(s, 0x0C20013, s->config.w9E); - if (rc < 0) - goto error; - rc = WR16(s, 0x0C20015, s->config.w9C); - if (rc < 0) - goto error; - - rc = write_fw(s, DRXD_InitFE_2); - if (rc < 0) - goto error; - rc = write_fw(s, DRXD_InitFT); - if (rc < 0) - goto error; - rc = write_fw(s, DRXD_InitCP); - if (rc < 0) - goto error; - rc = write_fw(s, DRXD_InitCE); - if (rc < 0) - goto error; - rc = write_fw(s, DRXD_InitEQ); - if (rc < 0) - goto error; - rc = write_fw(s, DRXD_InitEC); - if (rc < 0) - goto error; - rc = write_fw(s, DRXD_InitSC); - if (rc < 0) - goto error; - - rc = SetCfgIfAgc(s, &s->config.ifagc); - if (rc < 0) - goto error; - - rc = SetCfgRfAgc(s, &s->config.rfagc); - if (rc < 0) - goto error; - - rc = ConfigureMPEGOutput(s, 1); - rc = WR16(s, 0x08201fe, 0x0017); - rc = WR16(s, 0x08201ff, 0x0101); - - s->config.d5C = 0; - s->config.d60 = 1; - s->config.d48 = 1; - -error: - return rc; -} - -static int drx397x_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - return 0; -} - -static int drx397x_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct drx397xD_state *s = fe->demodulator_priv; - - s->config.s20d24 = 1; - - return drx_tune(s, params); -} - -static int drx397x_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings - *fe_tune_settings) -{ - fe_tune_settings->min_delay_ms = 10000; - fe_tune_settings->step_size = 0; - fe_tune_settings->max_drift = 0; - - return 0; -} - -static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct drx397xD_state *s = fe->demodulator_priv; - int lockstat; - - GetLockStatus(s, &lockstat); - - *status = 0; - if (lockstat & 2) { - CorrectSysClockDeviation(s); - ConfigureMPEGOutput(s, 1); - *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; - } - if (lockstat & 4) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - - return 0; -} - -static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber) -{ - *ber = 0; - - return 0; -} - -static int drx397x_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - *snr = 0; - - return 0; -} - -static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct drx397xD_state *s = fe->demodulator_priv; - int rc; - - if (s->config.ifagc.d00 == 2) { - *strength = 0xffff; - return 0; - } - rc = RD16(s, 0x0c20035); - if (rc < 0) { - *strength = 0; - return 0; - } - rc &= 0x3ff; - /* Signal strength is calculated using the following formula: - * - * a = 2200 * 150 / (2200 + 150); - * a = a * 3300 / (a + 820); - * b = 2200 * 3300 / (2200 + 820); - * c = (((b-a) * rc) >> 10 + a) << 4; - * strength = ~c & 0xffff; - * - * The following does the same but with less rounding errors: - */ - *strength = ~(7720 + (rc * 30744 >> 10)); - - return 0; -} - -static int drx397x_read_ucblocks(struct dvb_frontend *fe, - unsigned int *ucblocks) -{ - *ucblocks = 0; - - return 0; -} - -static int drx397x_sleep(struct dvb_frontend *fe) -{ - return 0; -} - -static void drx397x_release(struct dvb_frontend *fe) -{ - struct drx397xD_state *s = fe->demodulator_priv; - printk(KERN_INFO "%s: release demodulator\n", mod_name); - if (s) { - drx_release_fw(s); - kfree(s); - } - -} - -static struct dvb_frontend_ops drx397x_ops = { - - .info = { - .name = "Micronas DRX397xD DVB-T Frontend", - .type = FE_OFDM, - .frequency_min = 47125000, - .frequency_max = 855250000, - .frequency_stepsize = 166667, - .frequency_tolerance = 0, - .caps = /* 0x0C01B2EAE */ - FE_CAN_FEC_1_2 | /* = 0x2, */ - FE_CAN_FEC_2_3 | /* = 0x4, */ - FE_CAN_FEC_3_4 | /* = 0x8, */ - FE_CAN_FEC_5_6 | /* = 0x20, */ - FE_CAN_FEC_7_8 | /* = 0x80, */ - FE_CAN_FEC_AUTO | /* = 0x200, */ - FE_CAN_QPSK | /* = 0x400, */ - FE_CAN_QAM_16 | /* = 0x800, */ - FE_CAN_QAM_64 | /* = 0x2000, */ - FE_CAN_QAM_AUTO | /* = 0x10000, */ - FE_CAN_TRANSMISSION_MODE_AUTO | /* = 0x20000, */ - FE_CAN_GUARD_INTERVAL_AUTO | /* = 0x80000, */ - FE_CAN_HIERARCHY_AUTO | /* = 0x100000, */ - FE_CAN_RECOVER | /* = 0x40000000, */ - FE_CAN_MUTE_TS /* = 0x80000000 */ - }, - - .release = drx397x_release, - .init = drx397x_init, - .sleep = drx397x_sleep, - - .set_frontend = drx397x_set_frontend, - .get_tune_settings = drx397x_get_tune_settings, - .get_frontend = drx397x_get_frontend, - - .read_status = drx397x_read_status, - .read_snr = drx397x_read_snr, - .read_signal_strength = drx397x_read_signal_strength, - .read_ber = drx397x_read_ber, - .read_ucblocks = drx397x_read_ucblocks, -}; - -struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config, - struct i2c_adapter *i2c) -{ - struct drx397xD_state *state; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL); - if (!state) - goto error; - - /* setup the state */ - state->i2c = i2c; - memcpy(&state->config, config, sizeof(struct drx397xD_config)); - - /* check if the demod is there */ - if (RD16(state, 0x2410019) < 0) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &drx397x_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - return &state->frontend; -error: - kfree(state); - - return NULL; -} -EXPORT_SYMBOL(drx397xD_attach); - -MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend"); -MODULE_AUTHOR("Henk Vergonet"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/media/dvb/frontends/drx397xD.h b/drivers/media/dvb/frontends/drx397xD.h deleted file mode 100644 index ba05d17290c..00000000000 --- a/drivers/media/dvb/frontends/drx397xD.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Driver for Micronas DVB-T drx397xD demodulator - * - * Copyright (C) 2007 Henk vergonet <Henk.Vergonet@gmail.com> - * - * 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 _DRX397XD_H_INCLUDED -#define _DRX397XD_H_INCLUDED - -#include <linux/dvb/frontend.h> - -#define DRX_F_STEPSIZE 166667 -#define DRX_F_OFFSET 36000000 - -#define I2C_ADR_C0(x) \ -( cpu_to_le32( \ - (u32)( \ - (((u32)(x) & (u32)0x000000ffUL) ) | \ - (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ - (((u32)(x) & (u32)0x0fff0000UL) >> 8) | \ - ( (u32)0x00c00000UL) \ - )) \ -) - -#define I2C_ADR_E0(x) \ -( cpu_to_le32( \ - (u32)( \ - (((u32)(x) & (u32)0x000000ffUL) ) | \ - (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ - (((u32)(x) & (u32)0x0fff0000UL) >> 8) | \ - ( (u32)0x00e00000UL) \ - )) \ -) - -struct drx397xD_CfgRfAgc /* 0x7c */ -{ - int d00; /* 2 */ - u16 w04; - u16 w06; -}; - -struct drx397xD_CfgIfAgc /* 0x68 */ -{ - int d00; /* 0 */ - u16 w04; /* 0 */ - u16 w06; - u16 w08; - u16 w0A; - u16 w0C; -}; - -struct drx397xD_s20 { - int d04; - u32 d18; - u32 d1C; - u32 d20; - u32 d14; - u32 d24; - u32 d0C; - u32 d08; -}; - -struct drx397xD_config -{ - /* demodulator's I2C address */ - u8 demod_address; /* 0x0f */ - - struct drx397xD_CfgIfAgc ifagc; /* 0x68 */ - struct drx397xD_CfgRfAgc rfagc; /* 0x7c */ - u32 s20d24; - - /* HI_CfgCommand parameters */ - u16 w50, w52, /* w54, */ w56; - - int d5C; - int d60; - int d48; - int d28; - - u32 f_if; /* d14: intermediate frequency [Hz] */ - /* 36000000 on Cinergy 2400i DT */ - /* 42800000 on Pinnacle Hybrid PRO 330e */ - - u16 f_osc; /* s66: 48000 oscillator frequency [kHz] */ - - u16 w92; /* 20000 */ - - u16 wA0; - u16 w98; - u16 w9A; - - u16 w9C; /* 0xe0 */ - u16 w9E; /* 0x00 */ - - /* used for signal strength calculations in - drx397x_read_signal_strength - */ - u16 ss78; // 2200 - u16 ss7A; // 150 - u16 ss76; // 820 -}; - -#if defined(CONFIG_DVB_DRX397XD) || (defined(CONFIG_DVB_DRX397XD_MODULE) && defined(MODULE)) -extern struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_DRX397XD */ - -#endif /* _DRX397XD_H_INCLUDED */ diff --git a/drivers/media/dvb/frontends/drx397xD_fw.h b/drivers/media/dvb/frontends/drx397xD_fw.h deleted file mode 100644 index c8b44c1e807..00000000000 --- a/drivers/media/dvb/frontends/drx397xD_fw.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Firmware definitions for Micronas drx397xD - * - * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@gmail.com> - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -#ifdef _FW_ENTRY - _FW_ENTRY("drx397xD.A2.fw", DRXD_FW_A2 = 0, DRXD_FW_A2 ), - _FW_ENTRY("drx397xD.B1.fw", DRXD_FW_B1, DRXD_FW_B1 ), -#undef _FW_ENTRY -#endif /* _FW_ENTRY */ - -#ifdef _BLOB_ENTRY - _BLOB_ENTRY("InitAtomicRead", DRXD_InitAtomicRead = 0 ), - _BLOB_ENTRY("InitCE", DRXD_InitCE ), - _BLOB_ENTRY("InitCP", DRXD_InitCP ), - _BLOB_ENTRY("InitEC", DRXD_InitEC ), - _BLOB_ENTRY("InitEQ", DRXD_InitEQ ), - _BLOB_ENTRY("InitFE_1", DRXD_InitFE_1 ), - _BLOB_ENTRY("InitFE_2", DRXD_InitFE_2 ), - _BLOB_ENTRY("InitFT", DRXD_InitFT ), - _BLOB_ENTRY("InitSC", DRXD_InitSC ), - _BLOB_ENTRY("ResetCEFR", DRXD_ResetCEFR ), - _BLOB_ENTRY("ResetECRAM", DRXD_ResetECRAM ), - _BLOB_ENTRY("microcode", DRXD_microcode ), -#undef _BLOB_ENTRY -#endif /* _BLOB_ENTRY */ diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c deleted file mode 100644 index 9f6349964cd..00000000000 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ /dev/null @@ -1,662 +0,0 @@ -/* - * descriptions + helper functions for simple dvb plls. - * - * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] - * - * 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 <linux/module.h> -#include <linux/dvb/frontend.h> -#include <asm/types.h> - -#include "dvb-pll.h" - -struct dvb_pll_priv { - /* pll number */ - int nr; - - /* i2c details */ - int pll_i2c_address; - struct i2c_adapter *i2c; - - /* the PLL descriptor */ - struct dvb_pll_desc *pll_desc; - - /* cached frequency/bandwidth */ - u32 frequency; - u32 bandwidth; -}; - -#define DVB_PLL_MAX 64 - -static unsigned int dvb_pll_devcount; - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "enable verbose debug messages"); - -static unsigned int id[DVB_PLL_MAX] = - { [ 0 ... (DVB_PLL_MAX-1) ] = DVB_PLL_UNDEFINED }; -module_param_array(id, int, NULL, 0644); -MODULE_PARM_DESC(id, "force pll id to use (DEBUG ONLY)"); - -/* ----------------------------------------------------------- */ - -struct dvb_pll_desc { - char *name; - u32 min; - u32 max; - u32 iffreq; - void (*set)(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params); - u8 *initdata; - u8 *sleepdata; - int count; - struct { - u32 limit; - u32 stepsize; - u8 config; - u8 cb; - } entries[12]; -}; - -/* ----------------------------------------------------------- */ -/* descriptions */ - -static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { - .name = "Thomson dtt7579", - .min = 177000000, - .max = 858000000, - .iffreq= 36166667, - .sleepdata = (u8[]){ 2, 0xb4, 0x03 }, - .count = 4, - .entries = { - { 443250000, 166667, 0xb4, 0x02 }, - { 542000000, 166667, 0xb4, 0x08 }, - { 771000000, 166667, 0xbc, 0x08 }, - { 999999999, 166667, 0xf4, 0x08 }, - }, -}; - -static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - if (BANDWIDTH_7_MHZ == params->u.ofdm.bandwidth) - buf[3] |= 0x10; -} - -static struct dvb_pll_desc dvb_pll_thomson_dtt759x = { - .name = "Thomson dtt759x", - .min = 177000000, - .max = 896000000, - .set = thomson_dtt759x_bw, - .iffreq= 36166667, - .sleepdata = (u8[]){ 2, 0x84, 0x03 }, - .count = 5, - .entries = { - { 264000000, 166667, 0xb4, 0x02 }, - { 470000000, 166667, 0xbc, 0x02 }, - { 735000000, 166667, 0xbc, 0x08 }, - { 835000000, 166667, 0xf4, 0x08 }, - { 999999999, 166667, 0xfc, 0x08 }, - }, -}; - -static struct dvb_pll_desc dvb_pll_lg_z201 = { - .name = "LG z201", - .min = 174000000, - .max = 862000000, - .iffreq= 36166667, - .sleepdata = (u8[]){ 2, 0xbc, 0x03 }, - .count = 5, - .entries = { - { 157500000, 166667, 0xbc, 0x01 }, - { 443250000, 166667, 0xbc, 0x02 }, - { 542000000, 166667, 0xbc, 0x04 }, - { 830000000, 166667, 0xf4, 0x04 }, - { 999999999, 166667, 0xfc, 0x04 }, - }, -}; - -static struct dvb_pll_desc dvb_pll_unknown_1 = { - .name = "unknown 1", /* used by dntv live dvb-t */ - .min = 174000000, - .max = 862000000, - .iffreq= 36166667, - .count = 9, - .entries = { - { 150000000, 166667, 0xb4, 0x01 }, - { 173000000, 166667, 0xbc, 0x01 }, - { 250000000, 166667, 0xb4, 0x02 }, - { 400000000, 166667, 0xbc, 0x02 }, - { 420000000, 166667, 0xf4, 0x02 }, - { 470000000, 166667, 0xfc, 0x02 }, - { 600000000, 166667, 0xbc, 0x08 }, - { 730000000, 166667, 0xf4, 0x08 }, - { 999999999, 166667, 0xfc, 0x08 }, - }, -}; - -/* Infineon TUA6010XS - * used in Thomson Cable Tuner - */ -static struct dvb_pll_desc dvb_pll_tua6010xs = { - .name = "Infineon TUA6010XS", - .min = 44250000, - .max = 858000000, - .iffreq= 36125000, - .count = 3, - .entries = { - { 115750000, 62500, 0x8e, 0x03 }, - { 403250000, 62500, 0x8e, 0x06 }, - { 999999999, 62500, 0x8e, 0x85 }, - }, -}; - -/* Panasonic env57h1xd5 (some Philips PLL ?) */ -static struct dvb_pll_desc dvb_pll_env57h1xd5 = { - .name = "Panasonic ENV57H1XD5", - .min = 44250000, - .max = 858000000, - .iffreq= 36125000, - .count = 4, - .entries = { - { 153000000, 166667, 0xc2, 0x41 }, - { 470000000, 166667, 0xc2, 0x42 }, - { 526000000, 166667, 0xc2, 0x84 }, - { 999999999, 166667, 0xc2, 0xa4 }, - }, -}; - -/* Philips TDA6650/TDA6651 - * used in Panasonic ENV77H11D5 - */ -static void tda665x_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) - buf[3] |= 0x08; -} - -static struct dvb_pll_desc dvb_pll_tda665x = { - .name = "Philips TDA6650/TDA6651", - .min = 44250000, - .max = 858000000, - .set = tda665x_bw, - .iffreq= 36166667, - .initdata = (u8[]){ 4, 0x0b, 0xf5, 0x85, 0xab }, - .count = 12, - .entries = { - { 93834000, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ }, - { 123834000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, - { 161000000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, - { 163834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, - { 253834000, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ }, - { 383834000, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ }, - { 443834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, - { 444000000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, - { 583834000, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ }, - { 793834000, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ }, - { 444834000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, - { 861000000, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ }, - } -}; - -/* Infineon TUA6034 - * used in LG TDTP E102P - */ -static void tua6034_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - if (BANDWIDTH_7_MHZ != params->u.ofdm.bandwidth) - buf[3] |= 0x08; -} - -static struct dvb_pll_desc dvb_pll_tua6034 = { - .name = "Infineon TUA6034", - .min = 44250000, - .max = 858000000, - .iffreq= 36166667, - .count = 3, - .set = tua6034_bw, - .entries = { - { 174500000, 62500, 0xce, 0x01 }, - { 230000000, 62500, 0xce, 0x02 }, - { 999999999, 62500, 0xce, 0x04 }, - }, -}; - -/* ALPS TDED4 - * used in Nebula-Cards and USB boxes - */ -static void tded4_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) - buf[3] |= 0x04; -} - -static struct dvb_pll_desc dvb_pll_tded4 = { - .name = "ALPS TDED4", - .min = 47000000, - .max = 863000000, - .iffreq= 36166667, - .set = tded4_bw, - .count = 4, - .entries = { - { 153000000, 166667, 0x85, 0x01 }, - { 470000000, 166667, 0x85, 0x02 }, - { 823000000, 166667, 0x85, 0x08 }, - { 999999999, 166667, 0x85, 0x88 }, - } -}; - -/* ALPS TDHU2 - * used in AverTVHD MCE A180 - */ -static struct dvb_pll_desc dvb_pll_tdhu2 = { - .name = "ALPS TDHU2", - .min = 54000000, - .max = 864000000, - .iffreq= 44000000, - .count = 4, - .entries = { - { 162000000, 62500, 0x85, 0x01 }, - { 426000000, 62500, 0x85, 0x02 }, - { 782000000, 62500, 0x85, 0x08 }, - { 999999999, 62500, 0x85, 0x88 }, - } -}; - -/* Samsung TBMV30111IN / TBMV30712IN1 - * used in Air2PC ATSC - 2nd generation (nxt2002) - */ -static struct dvb_pll_desc dvb_pll_samsung_tbmv = { - .name = "Samsung TBMV30111IN / TBMV30712IN1", - .min = 54000000, - .max = 860000000, - .iffreq= 44000000, - .count = 6, - .entries = { - { 172000000, 166667, 0xb4, 0x01 }, - { 214000000, 166667, 0xb4, 0x02 }, - { 467000000, 166667, 0xbc, 0x02 }, - { 721000000, 166667, 0xbc, 0x08 }, - { 841000000, 166667, 0xf4, 0x08 }, - { 999999999, 166667, 0xfc, 0x02 }, - } -}; - -/* - * Philips SD1878 Tuner. - */ -static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = { - .name = "Philips SD1878", - .min = 950000, - .max = 2150000, - .iffreq= 249, /* zero-IF, offset 249 is to round up */ - .count = 4, - .entries = { - { 1250000, 500, 0xc4, 0x00}, - { 1450000, 500, 0xc4, 0x40}, - { 2050000, 500, 0xc4, 0x80}, - { 2150000, 500, 0xc4, 0xc0}, - }, -}; - -static void opera1_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) - buf[2] |= 0x08; -} - -static struct dvb_pll_desc dvb_pll_opera1 = { - .name = "Opera Tuner", - .min = 900000, - .max = 2250000, - .iffreq= 0, - .set = opera1_bw, - .count = 8, - .entries = { - { 1064000, 500, 0xe5, 0xc6 }, - { 1169000, 500, 0xe5, 0xe6 }, - { 1299000, 500, 0xe5, 0x24 }, - { 1444000, 500, 0xe5, 0x44 }, - { 1606000, 500, 0xe5, 0x64 }, - { 1777000, 500, 0xe5, 0x84 }, - { 1941000, 500, 0xe5, 0xa4 }, - { 2250000, 500, 0xe5, 0xc4 }, - } -}; - -static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - struct i2c_msg msg = { - .addr = priv->pll_i2c_address, - .flags = 0, - .buf = buf, - .len = 4 - }; - int result; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - result = i2c_transfer(priv->i2c, &msg, 1); - if (result != 1) - printk(KERN_ERR "%s: i2c_transfer failed:%d", - __func__, result); - - buf[2] = 0x9e; - buf[3] = 0x90; - - return; -} - -/* unknown pll used in Samsung DTOS403IH102A DVB-C tuner */ -static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = { - .name = "Samsung DTOS403IH102A", - .min = 44250000, - .max = 858000000, - .iffreq = 36125000, - .count = 8, - .set = samsung_dtos403ih102a_set, - .entries = { - { 135000000, 62500, 0xbe, 0x01 }, - { 177000000, 62500, 0xf6, 0x01 }, - { 370000000, 62500, 0xbe, 0x02 }, - { 450000000, 62500, 0xf6, 0x02 }, - { 466000000, 62500, 0xfe, 0x02 }, - { 538000000, 62500, 0xbe, 0x08 }, - { 826000000, 62500, 0xf6, 0x08 }, - { 999999999, 62500, 0xfe, 0x08 }, - } -}; - -/* ----------------------------------------------------------- */ - -static struct dvb_pll_desc *pll_list[] = { - [DVB_PLL_UNDEFINED] = NULL, - [DVB_PLL_THOMSON_DTT7579] = &dvb_pll_thomson_dtt7579, - [DVB_PLL_THOMSON_DTT759X] = &dvb_pll_thomson_dtt759x, - [DVB_PLL_LG_Z201] = &dvb_pll_lg_z201, - [DVB_PLL_UNKNOWN_1] = &dvb_pll_unknown_1, - [DVB_PLL_TUA6010XS] = &dvb_pll_tua6010xs, - [DVB_PLL_ENV57H1XD5] = &dvb_pll_env57h1xd5, - [DVB_PLL_TUA6034] = &dvb_pll_tua6034, - [DVB_PLL_TDA665X] = &dvb_pll_tda665x, - [DVB_PLL_TDED4] = &dvb_pll_tded4, - [DVB_PLL_TDHU2] = &dvb_pll_tdhu2, - [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv, - [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261, - [DVB_PLL_OPERA1] = &dvb_pll_opera1, - [DVB_PLL_SAMSUNG_DTOS403IH102A] = &dvb_pll_samsung_dtos403ih102a, -}; - -/* ----------------------------------------------------------- */ -/* code */ - -static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - struct dvb_pll_desc *desc = priv->pll_desc; - u32 div; - int i; - - if (params->frequency != 0 && (params->frequency < desc->min || - params->frequency > desc->max)) - return -EINVAL; - - for (i = 0; i < desc->count; i++) { - if (params->frequency > desc->entries[i].limit) - continue; - break; - } - - if (debug) - printk("pll: %s: freq=%d | i=%d/%d\n", desc->name, - params->frequency, i, desc->count); - if (i == desc->count) - return -EINVAL; - - div = (params->frequency + desc->iffreq + - desc->entries[i].stepsize/2) / desc->entries[i].stepsize; - buf[0] = div >> 8; - buf[1] = div & 0xff; - buf[2] = desc->entries[i].config; - buf[3] = desc->entries[i].cb; - - if (desc->set) - desc->set(fe, buf, params); - - if (debug) - printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", - desc->name, div, buf[0], buf[1], buf[2], buf[3]); - - // calculate the frequency we set it to - return (div * desc->entries[i].stepsize) - desc->iffreq; -} - -static int dvb_pll_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static int dvb_pll_sleep(struct dvb_frontend *fe) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - - if (priv->i2c == NULL) - return -EINVAL; - - if (priv->pll_desc->sleepdata) { - struct i2c_msg msg = { .flags = 0, - .addr = priv->pll_i2c_address, - .buf = priv->pll_desc->sleepdata + 1, - .len = priv->pll_desc->sleepdata[0] }; - - int result; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { - return result; - } - return 0; - } - /* Shouldn't be called when initdata is NULL, maybe BUG()? */ - return -EINVAL; -} - -static int dvb_pll_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - u8 buf[4]; - struct i2c_msg msg = - { .addr = priv->pll_i2c_address, .flags = 0, - .buf = buf, .len = sizeof(buf) }; - int result; - u32 frequency = 0; - - if (priv->i2c == NULL) - return -EINVAL; - - if ((result = dvb_pll_configure(fe, buf, params)) < 0) - return result; - else - frequency = result; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { - return result; - } - - priv->frequency = frequency; - priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; - - return 0; -} - -static int dvb_pll_calc_regs(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, - u8 *buf, int buf_len) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - int result; - u32 frequency = 0; - - if (buf_len < 5) - return -EINVAL; - - if ((result = dvb_pll_configure(fe, buf+1, params)) < 0) - return result; - else - frequency = result; - - buf[0] = priv->pll_i2c_address; - - priv->frequency = frequency; - priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; - - return 5; -} - -static int dvb_pll_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - *frequency = priv->frequency; - return 0; -} - -static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - *bandwidth = priv->bandwidth; - return 0; -} - -static int dvb_pll_init(struct dvb_frontend *fe) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - - if (priv->i2c == NULL) - return -EINVAL; - - if (priv->pll_desc->initdata) { - struct i2c_msg msg = { .flags = 0, - .addr = priv->pll_i2c_address, - .buf = priv->pll_desc->initdata + 1, - .len = priv->pll_desc->initdata[0] }; - - int result; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { - return result; - } - return 0; - } - /* Shouldn't be called when initdata is NULL, maybe BUG()? */ - return -EINVAL; -} - -static struct dvb_tuner_ops dvb_pll_tuner_ops = { - .release = dvb_pll_release, - .sleep = dvb_pll_sleep, - .init = dvb_pll_init, - .set_params = dvb_pll_set_params, - .calc_regs = dvb_pll_calc_regs, - .get_frequency = dvb_pll_get_frequency, - .get_bandwidth = dvb_pll_get_bandwidth, -}; - -struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, - struct i2c_adapter *i2c, - unsigned int pll_desc_id) -{ - u8 b1 [] = { 0 }; - struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, - .buf = b1, .len = 1 }; - struct dvb_pll_priv *priv = NULL; - int ret; - struct dvb_pll_desc *desc; - - if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) && - (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list))) - pll_desc_id = id[dvb_pll_devcount]; - - BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list)); - - desc = pll_list[pll_desc_id]; - - if (i2c != NULL) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - ret = i2c_transfer (i2c, &msg, 1); - if (ret != 1) - return NULL; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL); - if (priv == NULL) - return NULL; - - priv->pll_i2c_address = pll_addr; - priv->i2c = i2c; - priv->pll_desc = desc; - priv->nr = dvb_pll_devcount++; - - memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, - sizeof(struct dvb_tuner_ops)); - - strncpy(fe->ops.tuner_ops.info.name, desc->name, - sizeof(fe->ops.tuner_ops.info.name)); - fe->ops.tuner_ops.info.frequency_min = desc->min; - fe->ops.tuner_ops.info.frequency_max = desc->max; - if (!desc->initdata) - fe->ops.tuner_ops.init = NULL; - if (!desc->sleepdata) - fe->ops.tuner_ops.sleep = NULL; - - fe->tuner_priv = priv; - - if ((debug) || (id[priv->nr] == pll_desc_id)) { - printk("dvb-pll[%d]", priv->nr); - if (i2c != NULL) - printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr); - printk(": id# %d (%s) attached, %s\n", pll_desc_id, desc->name, - id[priv->nr] == pll_desc_id ? - "insmod option" : "autodetected"); - } - - return fe; -} -EXPORT_SYMBOL(dvb_pll_attach); - -MODULE_DESCRIPTION("dvb pll library"); -MODULE_AUTHOR("Gerd Knorr"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h deleted file mode 100644 index 05239f579cc..00000000000 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * descriptions + helper functions for simple dvb plls. - */ - -#ifndef __DVB_PLL_H__ -#define __DVB_PLL_H__ - -#include <linux/i2c.h> -#include "dvb_frontend.h" - -#define DVB_PLL_UNDEFINED 0 -#define DVB_PLL_THOMSON_DTT7579 1 -#define DVB_PLL_THOMSON_DTT759X 2 -#define DVB_PLL_LG_Z201 3 -#define DVB_PLL_UNKNOWN_1 4 -#define DVB_PLL_TUA6010XS 5 -#define DVB_PLL_ENV57H1XD5 6 -#define DVB_PLL_TUA6034 7 -#define DVB_PLL_TDA665X 8 -#define DVB_PLL_TDED4 9 -#define DVB_PLL_TDHU2 10 -#define DVB_PLL_SAMSUNG_TBMV 11 -#define DVB_PLL_PHILIPS_SD1878_TDA8261 12 -#define DVB_PLL_OPERA1 13 -#define DVB_PLL_SAMSUNG_DTOS403IH102A 14 - -/** - * Attach a dvb-pll to the supplied frontend structure. - * - * @param fe Frontend to attach to. - * @param pll_addr i2c address of the PLL (if used). - * @param i2c i2c adapter to use (set to NULL if not used). - * @param pll_desc_id dvb_pll_desc to use. - * @return Frontend pointer on success, NULL on failure - */ -#if defined(CONFIG_DVB_PLL) || (defined(CONFIG_DVB_PLL_MODULE) && defined(MODULE)) -extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, - int pll_addr, - struct i2c_adapter *i2c, - unsigned int pll_desc_id); -#else -static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, - int pll_addr, - struct i2c_adapter *i2c, - unsigned int pll_desc_id) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c deleted file mode 100644 index db8a937cc63..00000000000 --- a/drivers/media/dvb/frontends/dvb_dummy_fe.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Driver for Dummy Frontend - * - * Written by Emard <emard@softhome.net> - * - * 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 <linux/module.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "dvb_dummy_fe.h" - - -struct dvb_dummy_fe_state { - struct dvb_frontend frontend; -}; - - -static int dvb_dummy_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - *status = FE_HAS_SIGNAL - | FE_HAS_CARRIER - | FE_HAS_VITERBI - | FE_HAS_SYNC - | FE_HAS_LOCK; - - return 0; -} - -static int dvb_dummy_fe_read_ber(struct dvb_frontend* fe, u32* ber) -{ - *ber = 0; - return 0; -} - -static int dvb_dummy_fe_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - *strength = 0; - return 0; -} - -static int dvb_dummy_fe_read_snr(struct dvb_frontend* fe, u16* snr) -{ - *snr = 0; - return 0; -} - -static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - *ucblocks = 0; - return 0; -} - -static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - return 0; -} - -static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - return 0; -} - -static int dvb_dummy_fe_sleep(struct dvb_frontend* fe) -{ - return 0; -} - -static int dvb_dummy_fe_init(struct dvb_frontend* fe) -{ - return 0; -} - -static int dvb_dummy_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - return 0; -} - -static int dvb_dummy_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - return 0; -} - -static void dvb_dummy_fe_release(struct dvb_frontend* fe) -{ - struct dvb_dummy_fe_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops; - -struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void) -{ - struct dvb_dummy_fe_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops; - -struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void) -{ - struct dvb_dummy_fe_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops dvb_dummy_fe_qam_ops; - -struct dvb_frontend *dvb_dummy_fe_qam_attach(void) -{ - struct dvb_dummy_fe_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = { - - .info = { - .name = "Dummy DVB-T", - .type = FE_OFDM, - .frequency_min = 0, - .frequency_max = 863250000, - .frequency_stepsize = 62500, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | - FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = dvb_dummy_fe_release, - - .init = dvb_dummy_fe_init, - .sleep = dvb_dummy_fe_sleep, - - .set_frontend = dvb_dummy_fe_set_frontend, - .get_frontend = dvb_dummy_fe_get_frontend, - - .read_status = dvb_dummy_fe_read_status, - .read_ber = dvb_dummy_fe_read_ber, - .read_signal_strength = dvb_dummy_fe_read_signal_strength, - .read_snr = dvb_dummy_fe_read_snr, - .read_ucblocks = dvb_dummy_fe_read_ucblocks, -}; - -static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = { - - .info = { - .name = "Dummy DVB-C", - .type = FE_QAM, - .frequency_stepsize = 62500, - .frequency_min = 51000000, - .frequency_max = 858000000, - .symbol_rate_min = (57840000/2)/64, /* SACLK/64 == (XIN/2)/64 */ - .symbol_rate_max = (57840000/2)/4, /* SACLK/4 */ - .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | - FE_CAN_QAM_128 | FE_CAN_QAM_256 | - FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO - }, - - .release = dvb_dummy_fe_release, - - .init = dvb_dummy_fe_init, - .sleep = dvb_dummy_fe_sleep, - - .set_frontend = dvb_dummy_fe_set_frontend, - .get_frontend = dvb_dummy_fe_get_frontend, - - .read_status = dvb_dummy_fe_read_status, - .read_ber = dvb_dummy_fe_read_ber, - .read_signal_strength = dvb_dummy_fe_read_signal_strength, - .read_snr = dvb_dummy_fe_read_snr, - .read_ucblocks = dvb_dummy_fe_read_ucblocks, -}; - -static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = { - - .info = { - .name = "Dummy DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 250, /* kHz for QPSK frontends */ - .frequency_tolerance = 29500, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK - }, - - .release = dvb_dummy_fe_release, - - .init = dvb_dummy_fe_init, - .sleep = dvb_dummy_fe_sleep, - - .set_frontend = dvb_dummy_fe_set_frontend, - .get_frontend = dvb_dummy_fe_get_frontend, - - .read_status = dvb_dummy_fe_read_status, - .read_ber = dvb_dummy_fe_read_ber, - .read_signal_strength = dvb_dummy_fe_read_signal_strength, - .read_snr = dvb_dummy_fe_read_snr, - .read_ucblocks = dvb_dummy_fe_read_ucblocks, - - .set_voltage = dvb_dummy_fe_set_voltage, - .set_tone = dvb_dummy_fe_set_tone, -}; - -MODULE_DESCRIPTION("DVB DUMMY Frontend"); -MODULE_AUTHOR("Emard"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(dvb_dummy_fe_ofdm_attach); -EXPORT_SYMBOL(dvb_dummy_fe_qam_attach); -EXPORT_SYMBOL(dvb_dummy_fe_qpsk_attach); diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.h b/drivers/media/dvb/frontends/dvb_dummy_fe.h deleted file mode 100644 index 1fcb987d638..00000000000 --- a/drivers/media/dvb/frontends/dvb_dummy_fe.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Driver for Dummy Frontend - * - * Written by Emard <emard@softhome.net> - * - * 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_DUMMY_FE_H -#define DVB_DUMMY_FE_H - -#include <linux/dvb/frontend.h> -#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 diff --git a/drivers/media/dvb/frontends/eds1547.h b/drivers/media/dvb/frontends/eds1547.h deleted file mode 100644 index fa79b7c83dd..00000000000 --- a/drivers/media/dvb/frontends/eds1547.h +++ /dev/null @@ -1,133 +0,0 @@ -/* eds1547.h Earda EDS-1547 tuner support -* -* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation, version 2. -* -* see Documentation/dvb/README.dvb-usb for more information -*/ - -#ifndef EDS1547 -#define EDS1547 - -static u8 stv0288_earda_inittab[] = { - 0x01, 0x57, - 0x02, 0x20, - 0x03, 0x8e, - 0x04, 0x8e, - 0x05, 0x12, - 0x06, 0x00, - 0x07, 0x00, - 0x09, 0x00, - 0x0a, 0x04, - 0x0b, 0x00, - 0x0c, 0x00, - 0x0d, 0x00, - 0x0e, 0xd4, - 0x0f, 0x30, - 0x11, 0x44, - 0x12, 0x03, - 0x13, 0x48, - 0x14, 0x84, - 0x15, 0x45, - 0x16, 0xb7, - 0x17, 0x9c, - 0x18, 0x00, - 0x19, 0xa6, - 0x1a, 0x88, - 0x1b, 0x8f, - 0x1c, 0xf0, - 0x20, 0x0b, - 0x21, 0x54, - 0x22, 0x00, - 0x23, 0x00, - 0x2b, 0xff, - 0x2c, 0xf7, - 0x30, 0x00, - 0x31, 0x1e, - 0x32, 0x14, - 0x33, 0x0f, - 0x34, 0x09, - 0x35, 0x0c, - 0x36, 0x05, - 0x37, 0x2f, - 0x38, 0x16, - 0x39, 0xbd, - 0x3a, 0x00, - 0x3b, 0x13, - 0x3c, 0x11, - 0x3d, 0x30, - 0x40, 0x63, - 0x41, 0x04, - 0x42, 0x60, - 0x43, 0x00, - 0x44, 0x00, - 0x45, 0x00, - 0x46, 0x00, - 0x47, 0x00, - 0x4a, 0x00, - 0x50, 0x10, - 0x51, 0x36, - 0x52, 0x09, - 0x53, 0x94, - 0x54, 0x62, - 0x55, 0x29, - 0x56, 0x64, - 0x57, 0x2b, - 0x58, 0x54, - 0x59, 0x86, - 0x5a, 0x00, - 0x5b, 0x9b, - 0x5c, 0x08, - 0x5d, 0x7f, - 0x5e, 0x00, - 0x5f, 0xff, - 0x70, 0x00, - 0x71, 0x00, - 0x72, 0x00, - 0x74, 0x00, - 0x75, 0x00, - 0x76, 0x00, - 0x81, 0x00, - 0x82, 0x3f, - 0x83, 0x3f, - 0x84, 0x00, - 0x85, 0x00, - 0x88, 0x00, - 0x89, 0x00, - 0x8a, 0x00, - 0x8b, 0x00, - 0x8c, 0x00, - 0x90, 0x00, - 0x91, 0x00, - 0x92, 0x00, - 0x93, 0x00, - 0x94, 0x1c, - 0x97, 0x00, - 0xa0, 0x48, - 0xa1, 0x00, - 0xb0, 0xb8, - 0xb1, 0x3a, - 0xb2, 0x10, - 0xb3, 0x82, - 0xb4, 0x80, - 0xb5, 0x82, - 0xb6, 0x82, - 0xb7, 0x82, - 0xb8, 0x20, - 0xb9, 0x00, - 0xf0, 0x00, - 0xf1, 0x00, - 0xf2, 0xc0, - 0xff,0xff, -}; - -static struct stv0288_config earda_config = { - .demod_address = 0x68, - .min_delay_ms = 100, - .inittab = stv0288_earda_inittab, -}; - -#endif diff --git a/drivers/media/dvb/frontends/isl6405.c b/drivers/media/dvb/frontends/isl6405.c deleted file mode 100644 index 33d33f4d886..00000000000 --- a/drivers/media/dvb/frontends/isl6405.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * isl6405.c - driver for dual lnb supply and control ic ISL6405 - * - * Copyright (C) 2008 Hartmut Hackmann - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "isl6405.h" - -struct isl6405 { - u8 config; - u8 override_or; - u8 override_and; - struct i2c_adapter *i2c; - u8 i2c_addr; -}; - -static int isl6405_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct isl6405 *isl6405 = (struct isl6405 *) fe->sec_priv; - struct i2c_msg msg = { .addr = isl6405->i2c_addr, .flags = 0, - .buf = &isl6405->config, - .len = sizeof(isl6405->config) }; - - if (isl6405->override_or & 0x80) { - isl6405->config &= ~(ISL6405_VSEL2 | ISL6405_EN2); - switch (voltage) { - case SEC_VOLTAGE_OFF: - break; - case SEC_VOLTAGE_13: - isl6405->config |= ISL6405_EN2; - break; - case SEC_VOLTAGE_18: - isl6405->config |= (ISL6405_EN2 | ISL6405_VSEL2); - break; - default: - return -EINVAL; - } - } else { - isl6405->config &= ~(ISL6405_VSEL1 | ISL6405_EN1); - switch (voltage) { - case SEC_VOLTAGE_OFF: - break; - case SEC_VOLTAGE_13: - isl6405->config |= ISL6405_EN1; - break; - case SEC_VOLTAGE_18: - isl6405->config |= (ISL6405_EN1 | ISL6405_VSEL1); - break; - default: - return -EINVAL; - }; - } - isl6405->config |= isl6405->override_or; - isl6405->config &= isl6405->override_and; - - return (i2c_transfer(isl6405->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static int isl6405_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) -{ - struct isl6405 *isl6405 = (struct isl6405 *) fe->sec_priv; - struct i2c_msg msg = { .addr = isl6405->i2c_addr, .flags = 0, - .buf = &isl6405->config, - .len = sizeof(isl6405->config) }; - - if (isl6405->override_or & 0x80) { - if (arg) - isl6405->config |= ISL6405_LLC2; - else - isl6405->config &= ~ISL6405_LLC2; - } else { - if (arg) - isl6405->config |= ISL6405_LLC1; - else - isl6405->config &= ~ISL6405_LLC1; - } - isl6405->config |= isl6405->override_or; - isl6405->config &= isl6405->override_and; - - return (i2c_transfer(isl6405->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static void isl6405_release(struct dvb_frontend *fe) -{ - /* power off */ - isl6405_set_voltage(fe, SEC_VOLTAGE_OFF); - - /* free */ - kfree(fe->sec_priv); - fe->sec_priv = NULL; -} - -struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, - u8 i2c_addr, u8 override_set, u8 override_clear) -{ - struct isl6405 *isl6405 = kmalloc(sizeof(struct isl6405), GFP_KERNEL); - if (!isl6405) - return NULL; - - /* default configuration */ - if (override_set & 0x80) - isl6405->config = ISL6405_ISEL2; - else - isl6405->config = ISL6405_ISEL1; - isl6405->i2c = i2c; - isl6405->i2c_addr = i2c_addr; - fe->sec_priv = isl6405; - - /* bits which should be forced to '1' */ - isl6405->override_or = override_set; - - /* bits which should be forced to '0' */ - isl6405->override_and = ~override_clear; - - /* detect if it is present or not */ - if (isl6405_set_voltage(fe, SEC_VOLTAGE_OFF)) { - kfree(isl6405); - fe->sec_priv = NULL; - return NULL; - } - - /* install release callback */ - fe->ops.release_sec = isl6405_release; - - /* override frontend ops */ - fe->ops.set_voltage = isl6405_set_voltage; - fe->ops.enable_high_lnb_voltage = isl6405_enable_high_lnb_voltage; - - return fe; -} -EXPORT_SYMBOL(isl6405_attach); - -MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6405"); -MODULE_AUTHOR("Hartmut Hackmann & Oliver Endriss"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/isl6405.h b/drivers/media/dvb/frontends/isl6405.h deleted file mode 100644 index 1c793d37576..00000000000 --- a/drivers/media/dvb/frontends/isl6405.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * isl6405.h - driver for dual lnb supply and control ic ISL6405 - * - * Copyright (C) 2008 Hartmut Hackmann - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef _ISL6405_H -#define _ISL6405_H - -#include <linux/dvb/frontend.h> - -/* system register bits */ - -/* this bit selects register (control) 1 or 2 - note that the bit maps are different */ - -#define ISL6405_SR 0x80 - -/* SR = 0 */ -#define ISL6405_OLF1 0x01 -#define ISL6405_EN1 0x02 -#define ISL6405_VSEL1 0x04 -#define ISL6405_LLC1 0x08 -#define ISL6405_ENT1 0x10 -#define ISL6405_ISEL1 0x20 -#define ISL6405_DCL 0x40 - -/* SR = 1 */ -#define ISL6405_OLF2 0x01 -#define ISL6405_OTF 0x02 -#define ISL6405_EN2 0x04 -#define ISL6405_VSEL2 0x08 -#define ISL6405_LLC2 0x10 -#define ISL6405_ENT2 0x20 -#define ISL6405_ISEL2 0x40 - -#if defined(CONFIG_DVB_ISL6405) || (defined(CONFIG_DVB_ISL6405_MODULE) && defined(MODULE)) -/* override_set and override_clear control which system register bits (above) - * to always set & clear - */ -extern struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, - u8 i2c_addr, u8 override_set, u8 override_clear); -#else -static inline struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, u8 i2c_addr, - u8 override_set, u8 override_clear) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_ISL6405 */ - -#endif diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c deleted file mode 100644 index 684c8ec166c..00000000000 --- a/drivers/media/dvb/frontends/isl6421.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * isl6421.h - driver for lnb supply and control ic ISL6421 - * - * Copyright (C) 2006 Andrew de Quincey - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "isl6421.h" - -struct isl6421 { - u8 config; - u8 override_or; - u8 override_and; - struct i2c_adapter *i2c; - u8 i2c_addr; -}; - -static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv; - struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, - .buf = &isl6421->config, - .len = sizeof(isl6421->config) }; - - isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1); - - switch(voltage) { - case SEC_VOLTAGE_OFF: - break; - case SEC_VOLTAGE_13: - isl6421->config |= ISL6421_EN1; - break; - case SEC_VOLTAGE_18: - isl6421->config |= (ISL6421_EN1 | ISL6421_VSEL1); - break; - default: - return -EINVAL; - }; - - isl6421->config |= isl6421->override_or; - isl6421->config &= isl6421->override_and; - - return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) -{ - struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv; - struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, - .buf = &isl6421->config, - .len = sizeof(isl6421->config) }; - - if (arg) - isl6421->config |= ISL6421_LLC1; - else - isl6421->config &= ~ISL6421_LLC1; - - isl6421->config |= isl6421->override_or; - isl6421->config &= isl6421->override_and; - - return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static void isl6421_release(struct dvb_frontend *fe) -{ - /* power off */ - isl6421_set_voltage(fe, SEC_VOLTAGE_OFF); - - /* free */ - kfree(fe->sec_priv); - fe->sec_priv = NULL; -} - -struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, - u8 override_set, u8 override_clear) -{ - struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL); - if (!isl6421) - return NULL; - - /* default configuration */ - isl6421->config = ISL6421_ISEL1; - isl6421->i2c = i2c; - isl6421->i2c_addr = i2c_addr; - fe->sec_priv = isl6421; - - /* bits which should be forced to '1' */ - isl6421->override_or = override_set; - - /* bits which should be forced to '0' */ - isl6421->override_and = ~override_clear; - - /* detect if it is present or not */ - if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) { - kfree(isl6421); - fe->sec_priv = NULL; - return NULL; - } - - /* install release callback */ - fe->ops.release_sec = isl6421_release; - - /* override frontend ops */ - fe->ops.set_voltage = isl6421_set_voltage; - fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage; - - return fe; -} -EXPORT_SYMBOL(isl6421_attach); - -MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421"); -MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb/frontends/isl6421.h deleted file mode 100644 index 47e4518a042..00000000000 --- a/drivers/media/dvb/frontends/isl6421.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * isl6421.h - driver for lnb supply and control ic ISL6421 - * - * Copyright (C) 2006 Andrew de Quincey - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef _ISL6421_H -#define _ISL6421_H - -#include <linux/dvb/frontend.h> - -/* system register bits */ -#define ISL6421_OLF1 0x01 -#define ISL6421_EN1 0x02 -#define ISL6421_VSEL1 0x04 -#define ISL6421_LLC1 0x08 -#define ISL6421_ENT1 0x10 -#define ISL6421_ISEL1 0x20 -#define ISL6421_DCL 0x40 - -#if defined(CONFIG_DVB_ISL6421) || (defined(CONFIG_DVB_ISL6421_MODULE) && defined(MODULE)) -/* override_set and override_clear control which system register bits (above) to always set & clear */ -extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, - u8 override_set, u8 override_clear); -#else -static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, - u8 override_set, u8 override_clear) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_ISL6421 - -#endif diff --git a/drivers/media/dvb/frontends/itd1000.c b/drivers/media/dvb/frontends/itd1000.c deleted file mode 100644 index 600dad6b41e..00000000000 --- a/drivers/media/dvb/frontends/itd1000.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite" - * - * Copyright (c) 2007-8 Patrick Boettcher <pb@linuxtv.org> - * - * 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 <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/delay.h> -#include <linux/dvb/frontend.h> -#include <linux/i2c.h> - -#include "dvb_frontend.h" - -#include "itd1000.h" -#include "itd1000_priv.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); - -#define deb(args...) do { \ - if (debug) { \ - printk(KERN_DEBUG "ITD1000: " args);\ - printk("\n"); \ - } \ -} while (0) - -#define warn(args...) do { \ - printk(KERN_WARNING "ITD1000: " args); \ - printk("\n"); \ -} while (0) - -#define info(args...) do { \ - printk(KERN_INFO "ITD1000: " args); \ - printk("\n"); \ -} while (0) - -/* don't write more than one byte with flexcop behind */ -static int itd1000_write_regs(struct itd1000_state *state, u8 reg, u8 v[], u8 len) -{ - u8 buf[1+len]; - struct i2c_msg msg = { - .addr = state->cfg->i2c_address, .flags = 0, .buf = buf, .len = len+1 - }; - buf[0] = reg; - memcpy(&buf[1], v, len); - - /* deb("wr %02x: %02x", reg, v[0]); */ - - if (i2c_transfer(state->i2c, &msg, 1) != 1) { - printk(KERN_WARNING "itd1000 I2C write failed\n"); - return -EREMOTEIO; - } - return 0; -} - -static int itd1000_read_reg(struct itd1000_state *state, u8 reg) -{ - u8 val; - struct i2c_msg msg[2] = { - { .addr = state->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, - { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = &val, .len = 1 }, - }; - - /* ugly flexcop workaround */ - itd1000_write_regs(state, (reg - 1) & 0xff, &state->shadow[(reg - 1) & 0xff], 1); - - if (i2c_transfer(state->i2c, msg, 2) != 2) { - warn("itd1000 I2C read failed"); - return -EREMOTEIO; - } - return val; -} - -static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v) -{ - int ret = itd1000_write_regs(state, r, &v, 1); - state->shadow[r] = v; - return ret; -} - - -static struct { - u32 symbol_rate; - u8 pgaext : 4; /* PLLFH */ - u8 bbgvmin : 4; /* BBGVMIN */ -} itd1000_lpf_pga[] = { - { 0, 0x8, 0x3 }, - { 5200000, 0x8, 0x3 }, - { 12200000, 0x4, 0x3 }, - { 15400000, 0x2, 0x3 }, - { 19800000, 0x2, 0x3 }, - { 21500000, 0x2, 0x3 }, - { 24500000, 0x2, 0x3 }, - { 28400000, 0x2, 0x3 }, - { 33400000, 0x2, 0x3 }, - { 34400000, 0x1, 0x4 }, - { 34400000, 0x1, 0x4 }, - { 38400000, 0x1, 0x4 }, - { 38400000, 0x1, 0x4 }, - { 40400000, 0x1, 0x4 }, - { 45400000, 0x1, 0x4 }, -}; - -static void itd1000_set_lpf_bw(struct itd1000_state *state, u32 symbol_rate) -{ - u8 i; - u8 con1 = itd1000_read_reg(state, CON1) & 0xfd; - u8 pllfh = itd1000_read_reg(state, PLLFH) & 0x0f; - u8 bbgvmin = itd1000_read_reg(state, BBGVMIN) & 0xf0; - u8 bw = itd1000_read_reg(state, BW) & 0xf0; - - deb("symbol_rate = %d", symbol_rate); - - /* not sure what is that ? - starting to download the table */ - itd1000_write_reg(state, CON1, con1 | (1 << 1)); - - for (i = 0; i < ARRAY_SIZE(itd1000_lpf_pga); i++) - if (symbol_rate < itd1000_lpf_pga[i].symbol_rate) { - deb("symrate: index: %d pgaext: %x, bbgvmin: %x", i, itd1000_lpf_pga[i].pgaext, itd1000_lpf_pga[i].bbgvmin); - itd1000_write_reg(state, PLLFH, pllfh | (itd1000_lpf_pga[i].pgaext << 4)); - itd1000_write_reg(state, BBGVMIN, bbgvmin | (itd1000_lpf_pga[i].bbgvmin)); - itd1000_write_reg(state, BW, bw | (i & 0x0f)); - break; - } - - itd1000_write_reg(state, CON1, con1 | (0 << 1)); -} - -static struct { - u8 vcorg; - u32 fmax_rg; -} itd1000_vcorg[] = { - { 1, 920000 }, - { 2, 971000 }, - { 3, 1031000 }, - { 4, 1091000 }, - { 5, 1171000 }, - { 6, 1281000 }, - { 7, 1381000 }, - { 8, 500000 }, /* this is intentional. */ - { 9, 1451000 }, - { 10, 1531000 }, - { 11, 1631000 }, - { 12, 1741000 }, - { 13, 1891000 }, - { 14, 2071000 }, - { 15, 2250000 }, -}; - -static void itd1000_set_vco(struct itd1000_state *state, u32 freq_khz) -{ - u8 i; - u8 gvbb_i2c = itd1000_read_reg(state, GVBB_I2C) & 0xbf; - u8 vco_chp1_i2c = itd1000_read_reg(state, VCO_CHP1_I2C) & 0x0f; - u8 adcout; - - /* reserved bit again (reset ?) */ - itd1000_write_reg(state, GVBB_I2C, gvbb_i2c | (1 << 6)); - - for (i = 0; i < ARRAY_SIZE(itd1000_vcorg); i++) { - if (freq_khz < itd1000_vcorg[i].fmax_rg) { - itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | (itd1000_vcorg[i].vcorg << 4)); - msleep(1); - - adcout = itd1000_read_reg(state, PLLLOCK) & 0x0f; - - deb("VCO: %dkHz: %d -> ADCOUT: %d %02x", freq_khz, itd1000_vcorg[i].vcorg, adcout, vco_chp1_i2c); - - if (adcout > 13) { - if (!(itd1000_vcorg[i].vcorg == 7 || itd1000_vcorg[i].vcorg == 15)) - itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg + 1) << 4)); - } else if (adcout < 2) { - if (!(itd1000_vcorg[i].vcorg == 1 || itd1000_vcorg[i].vcorg == 9)) - itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg - 1) << 4)); - } - break; - } - } -} - -static const struct { - u32 freq; - u8 values[10]; /* RFTR, RFST1 - RFST9 */ -} itd1000_fre_values[] = { - { 1075000, { 0x59, 0x1d, 0x1c, 0x17, 0x16, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, - { 1250000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, - { 1450000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, - { 1650000, { 0x69, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, - { 1750000, { 0x69, 0x1e, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, - { 1850000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } }, - { 1900000, { 0x69, 0x1d, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } }, - { 1950000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0d, 0x0b, 0x0a } }, - { 2050000, { 0x69, 0x1e, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0b, 0x0a } }, - { 2150000, { 0x69, 0x1d, 0x1c, 0x17, 0x15, 0x14, 0x13, 0x0f, 0x0e, 0x0b } } -}; - - -#define FREF 16 - -static void itd1000_set_lo(struct itd1000_state *state, u32 freq_khz) -{ - int i, j; - u32 plln, pllf; - u64 tmp; - - plln = (freq_khz * 1000) / 2 / FREF; - - /* Compute the factional part times 1000 */ - tmp = plln % 1000000; - plln /= 1000000; - - tmp *= 1048576; - do_div(tmp, 1000000); - pllf = (u32) tmp; - - state->frequency = ((plln * 1000) + (pllf * 1000)/1048576) * 2*FREF; - deb("frequency: %dkHz (wanted) %dkHz (set), PLLF = %d, PLLN = %d", freq_khz, state->frequency, pllf, plln); - - itd1000_write_reg(state, PLLNH, 0x80); /* PLLNH */; - itd1000_write_reg(state, PLLNL, plln & 0xff); - itd1000_write_reg(state, PLLFH, (itd1000_read_reg(state, PLLFH) & 0xf0) | ((pllf >> 16) & 0x0f)); - itd1000_write_reg(state, PLLFM, (pllf >> 8) & 0xff); - itd1000_write_reg(state, PLLFL, (pllf >> 0) & 0xff); - - for (i = 0; i < ARRAY_SIZE(itd1000_fre_values); i++) { - if (freq_khz <= itd1000_fre_values[i].freq) { - deb("fre_values: %d", i); - itd1000_write_reg(state, RFTR, itd1000_fre_values[i].values[0]); - for (j = 0; j < 9; j++) - itd1000_write_reg(state, RFST1+j, itd1000_fre_values[i].values[j+1]); - break; - } - } - - itd1000_set_vco(state, freq_khz); -} - -static int itd1000_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct itd1000_state *state = fe->tuner_priv; - u8 pllcon1; - - itd1000_set_lo(state, p->frequency); - itd1000_set_lpf_bw(state, p->u.qpsk.symbol_rate); - - pllcon1 = itd1000_read_reg(state, PLLCON1) & 0x7f; - itd1000_write_reg(state, PLLCON1, pllcon1 | (1 << 7)); - itd1000_write_reg(state, PLLCON1, pllcon1); - - return 0; -} - -static int itd1000_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct itd1000_state *state = fe->tuner_priv; - *frequency = state->frequency; - return 0; -} - -static int itd1000_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -{ - return 0; -} - -static u8 itd1000_init_tab[][2] = { - { PLLCON1, 0x65 }, /* Register does not change */ - { PLLNH, 0x80 }, /* Bits [7:6] do not change */ - { RESERVED_0X6D, 0x3b }, - { VCO_CHP2_I2C, 0x12 }, - { 0x72, 0xf9 }, /* No such regsister defined */ - { RESERVED_0X73, 0xff }, - { RESERVED_0X74, 0xb2 }, - { RESERVED_0X75, 0xc7 }, - { EXTGVBBRF, 0xf0 }, - { DIVAGCCK, 0x80 }, - { BBTR, 0xa0 }, - { RESERVED_0X7E, 0x4f }, - { 0x82, 0x88 }, /* No such regsister defined */ - { 0x83, 0x80 }, /* No such regsister defined */ - { 0x84, 0x80 }, /* No such regsister defined */ - { RESERVED_0X85, 0x74 }, - { RESERVED_0X86, 0xff }, - { RESERVED_0X88, 0x02 }, - { RESERVED_0X89, 0x16 }, - { RFST0, 0x1f }, - { RESERVED_0X94, 0x66 }, - { RESERVED_0X95, 0x66 }, - { RESERVED_0X96, 0x77 }, - { RESERVED_0X97, 0x99 }, - { RESERVED_0X98, 0xff }, - { RESERVED_0X99, 0xfc }, - { RESERVED_0X9A, 0xba }, - { RESERVED_0X9B, 0xaa }, -}; - -static u8 itd1000_reinit_tab[][2] = { - { VCO_CHP1_I2C, 0x8a }, - { BW, 0x87 }, - { GVBB_I2C, 0x03 }, - { BBGVMIN, 0x03 }, - { CON1, 0x2e }, -}; - - -static int itd1000_init(struct dvb_frontend *fe) -{ - struct itd1000_state *state = fe->tuner_priv; - int i; - - for (i = 0; i < ARRAY_SIZE(itd1000_init_tab); i++) - itd1000_write_reg(state, itd1000_init_tab[i][0], itd1000_init_tab[i][1]); - - for (i = 0; i < ARRAY_SIZE(itd1000_reinit_tab); i++) - itd1000_write_reg(state, itd1000_reinit_tab[i][0], itd1000_reinit_tab[i][1]); - - return 0; -} - -static int itd1000_sleep(struct dvb_frontend *fe) -{ - return 0; -} - -static int itd1000_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static const struct dvb_tuner_ops itd1000_tuner_ops = { - .info = { - .name = "Integrant ITD1000", - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 125, /* kHz for QPSK frontends */ - }, - - .release = itd1000_release, - - .init = itd1000_init, - .sleep = itd1000_sleep, - - .set_params = itd1000_set_parameters, - .get_frequency = itd1000_get_frequency, - .get_bandwidth = itd1000_get_bandwidth -}; - - -struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg) -{ - struct itd1000_state *state = NULL; - u8 i = 0; - - state = kzalloc(sizeof(struct itd1000_state), GFP_KERNEL); - if (state == NULL) - return NULL; - - state->cfg = cfg; - state->i2c = i2c; - - i = itd1000_read_reg(state, 0); - if (i != 0) { - kfree(state); - return NULL; - } - info("successfully identified (ID: %d)", i); - - memset(state->shadow, 0xff, sizeof(state->shadow)); - for (i = 0x65; i < 0x9c; i++) - state->shadow[i] = itd1000_read_reg(state, i); - - memcpy(&fe->ops.tuner_ops, &itd1000_tuner_ops, sizeof(struct dvb_tuner_ops)); - - fe->tuner_priv = state; - - return fe; -} -EXPORT_SYMBOL(itd1000_attach); - -MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>"); -MODULE_DESCRIPTION("Integrant ITD1000 driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/itd1000.h b/drivers/media/dvb/frontends/itd1000.h deleted file mode 100644 index 5e18df071b8..00000000000 --- a/drivers/media/dvb/frontends/itd1000.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite" - * - * Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org> - * - * 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 ITD1000_H -#define ITD1000_H - -struct dvb_frontend; -struct i2c_adapter; - -struct itd1000_config { - u8 i2c_address; -}; - -#if defined(CONFIG_DVB_TUNER_ITD1000) || (defined(CONFIG_DVB_TUNER_ITD1000_MODULE) && defined(MODULE)) -extern struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg); -#else -static inline struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif diff --git a/drivers/media/dvb/frontends/itd1000_priv.h b/drivers/media/dvb/frontends/itd1000_priv.h deleted file mode 100644 index 08ca851223c..00000000000 --- a/drivers/media/dvb/frontends/itd1000_priv.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite" - * - * Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org> - * - * 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 ITD1000_PRIV_H -#define ITD1000_PRIV_H - -struct itd1000_state { - struct itd1000_config *cfg; - struct i2c_adapter *i2c; - - u32 frequency; /* contains the value resulting from the LO-setting */ - - /* ugly workaround for flexcop's incapable i2c-controller - * FIXME, if possible - */ - u8 shadow[256]; -}; - -enum itd1000_register { - VCO_CHP1 = 0x65, - VCO_CHP2, - PLLCON1, - PLLNH, - PLLNL, - PLLFH, - PLLFM, - PLLFL, - RESERVED_0X6D, - PLLLOCK, - VCO_CHP2_I2C, - VCO_CHP1_I2C, - BW, - RESERVED_0X73 = 0x73, - RESERVED_0X74, - RESERVED_0X75, - GVBB, - GVRF, - GVBB_I2C, - EXTGVBBRF, - DIVAGCCK, - BBTR, - RFTR, - BBGVMIN, - RESERVED_0X7E, - RESERVED_0X85 = 0x85, - RESERVED_0X86, - CON1, - RESERVED_0X88, - RESERVED_0X89, - RFST0, - RFST1, - RFST2, - RFST3, - RFST4, - RFST5, - RFST6, - RFST7, - RFST8, - RFST9, - RESERVED_0X94, - RESERVED_0X95, - RESERVED_0X96, - RESERVED_0X97, - RESERVED_0X98, - RESERVED_0X99, - RESERVED_0X9A, - RESERVED_0X9B, -}; - -#endif diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c deleted file mode 100644 index e1e70e9e0cb..00000000000 --- a/drivers/media/dvb/frontends/l64781.c +++ /dev/null @@ -1,602 +0,0 @@ -/* - driver for LSI L64781 COFDM demodulator - - Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH - Marko Kohtala <marko.kohtala@luukku.com> - - 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 <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include "dvb_frontend.h" -#include "l64781.h" - - -struct l64781_state { - struct i2c_adapter* i2c; - const struct l64781_config* config; - struct dvb_frontend frontend; - - /* private demodulator data */ - unsigned int first:1; -}; - -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "l64781: " args); \ - } while (0) - -static int debug; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - - -static int l64781_writereg (struct l64781_state* state, u8 reg, u8 data) -{ - int ret; - u8 buf [] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - - if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) - dprintk ("%s: write_reg error (reg == %02x) = %02x!\n", - __func__, reg, ret); - - return (ret != 1) ? -1 : 0; -} - -static int l64781_readreg (struct l64781_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) return ret; - - return b1[0]; -} - -static void apply_tps (struct l64781_state* state) -{ - l64781_writereg (state, 0x2a, 0x00); - l64781_writereg (state, 0x2a, 0x01); - - /* This here is a little bit questionable because it enables - the automatic update of TPS registers. I think we'd need to - handle the IRQ from FE to update some other registers as - well, or at least implement some magic to tuning to correct - to the TPS received from transmission. */ - l64781_writereg (state, 0x2a, 0x02); -} - - -static void reset_afc (struct l64781_state* state) -{ - /* Set AFC stall for the AFC_INIT_FRQ setting, TIM_STALL for - timing offset */ - l64781_writereg (state, 0x07, 0x9e); /* stall AFC */ - l64781_writereg (state, 0x08, 0); /* AFC INIT FREQ */ - l64781_writereg (state, 0x09, 0); - l64781_writereg (state, 0x0a, 0); - l64781_writereg (state, 0x07, 0x8e); - l64781_writereg (state, 0x0e, 0); /* AGC gain to zero in beginning */ - l64781_writereg (state, 0x11, 0x80); /* stall TIM */ - l64781_writereg (state, 0x10, 0); /* TIM_OFFSET_LSB */ - l64781_writereg (state, 0x12, 0); - l64781_writereg (state, 0x13, 0); - l64781_writereg (state, 0x11, 0x00); -} - -static int reset_and_configure (struct l64781_state* state) -{ - u8 buf [] = { 0x06 }; - struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 }; - // NOTE: this is correct in writing to address 0x00 - - return (i2c_transfer(state->i2c, &msg, 1) == 1) ? 0 : -ENODEV; -} - -static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_parameters *param) -{ - struct l64781_state* state = fe->demodulator_priv; - /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */ - static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 }; - /* QPSK, QAM_16, QAM_64 */ - static const u8 qam_tab [] = { 2, 4, 0, 6 }; - static const u8 bw_tab [] = { 8, 7, 6 }; /* 8Mhz, 7MHz, 6MHz */ - static const u8 guard_tab [] = { 1, 2, 4, 8 }; - /* The Grundig 29504-401.04 Tuner comes with 18.432MHz crystal. */ - static const u32 ppm = 8000; - struct dvb_ofdm_parameters *p = ¶m->u.ofdm; - u32 ddfs_offset_fixed; -/* u32 ddfs_offset_variable = 0x6000-((1000000UL+ppm)/ */ -/* bw_tab[p->bandWidth]<<10)/15625; */ - u32 init_freq; - u32 spi_bias; - u8 val0x04; - u8 val0x05; - u8 val0x06; - int bw = p->bandwidth - BANDWIDTH_8_MHZ; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - if (param->inversion != INVERSION_ON && - param->inversion != INVERSION_OFF) - return -EINVAL; - - if (bw < 0 || bw > 2) - return -EINVAL; - - if (p->code_rate_HP != FEC_1_2 && p->code_rate_HP != FEC_2_3 && - p->code_rate_HP != FEC_3_4 && p->code_rate_HP != FEC_5_6 && - p->code_rate_HP != FEC_7_8) - return -EINVAL; - - if (p->hierarchy_information != HIERARCHY_NONE && - (p->code_rate_LP != FEC_1_2 && p->code_rate_LP != FEC_2_3 && - p->code_rate_LP != FEC_3_4 && p->code_rate_LP != FEC_5_6 && - p->code_rate_LP != FEC_7_8)) - return -EINVAL; - - if (p->constellation != QPSK && p->constellation != QAM_16 && - p->constellation != QAM_64) - return -EINVAL; - - if (p->transmission_mode != TRANSMISSION_MODE_2K && - p->transmission_mode != TRANSMISSION_MODE_8K) - return -EINVAL; - - if (p->guard_interval < GUARD_INTERVAL_1_32 || - p->guard_interval > GUARD_INTERVAL_1_4) - return -EINVAL; - - if (p->hierarchy_information < HIERARCHY_NONE || - p->hierarchy_information > HIERARCHY_4) - return -EINVAL; - - ddfs_offset_fixed = 0x4000-(ppm<<16)/bw_tab[p->bandwidth]/1000000; - - /* This works up to 20000 ppm, it overflows if too large ppm! */ - init_freq = (((8UL<<25) + (8UL<<19) / 25*ppm / (15625/25)) / - bw_tab[p->bandwidth] & 0xFFFFFF); - - /* SPI bias calculation is slightly modified to fit in 32bit */ - /* will work for high ppm only... */ - spi_bias = 378 * (1 << 10); - spi_bias *= 16; - spi_bias *= bw_tab[p->bandwidth]; - spi_bias *= qam_tab[p->constellation]; - spi_bias /= p->code_rate_HP + 1; - spi_bias /= (guard_tab[p->guard_interval] + 32); - spi_bias *= 1000ULL; - spi_bias /= 1000ULL + ppm/1000; - spi_bias *= p->code_rate_HP; - - val0x04 = (p->transmission_mode << 2) | p->guard_interval; - val0x05 = fec_tab[p->code_rate_HP]; - - if (p->hierarchy_information != HIERARCHY_NONE) - val0x05 |= (p->code_rate_LP - FEC_1_2) << 3; - - val0x06 = (p->hierarchy_information << 2) | p->constellation; - - l64781_writereg (state, 0x04, val0x04); - l64781_writereg (state, 0x05, val0x05); - l64781_writereg (state, 0x06, val0x06); - - reset_afc (state); - - /* Technical manual section 2.6.1, TIM_IIR_GAIN optimal values */ - l64781_writereg (state, 0x15, - p->transmission_mode == TRANSMISSION_MODE_2K ? 1 : 3); - l64781_writereg (state, 0x16, init_freq & 0xff); - l64781_writereg (state, 0x17, (init_freq >> 8) & 0xff); - l64781_writereg (state, 0x18, (init_freq >> 16) & 0xff); - - l64781_writereg (state, 0x1b, spi_bias & 0xff); - l64781_writereg (state, 0x1c, (spi_bias >> 8) & 0xff); - l64781_writereg (state, 0x1d, ((spi_bias >> 16) & 0x7f) | - (param->inversion == INVERSION_ON ? 0x80 : 0x00)); - - l64781_writereg (state, 0x22, ddfs_offset_fixed & 0xff); - l64781_writereg (state, 0x23, (ddfs_offset_fixed >> 8) & 0x3f); - - l64781_readreg (state, 0x00); /* clear interrupt registers... */ - l64781_readreg (state, 0x01); /* dto. */ - - apply_tps (state); - - return 0; -} - -static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* param) -{ - struct l64781_state* state = fe->demodulator_priv; - int tmp; - - - tmp = l64781_readreg(state, 0x04); - switch(tmp & 3) { - case 0: - param->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - param->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - param->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - param->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; - break; - } - switch((tmp >> 2) & 3) { - case 0: - param->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; - break; - case 1: - param->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - break; - default: - printk("Unexpected value for transmission_mode\n"); - } - - - - tmp = l64781_readreg(state, 0x05); - switch(tmp & 7) { - case 0: - param->u.ofdm.code_rate_HP = FEC_1_2; - break; - case 1: - param->u.ofdm.code_rate_HP = FEC_2_3; - break; - case 2: - param->u.ofdm.code_rate_HP = FEC_3_4; - break; - case 3: - param->u.ofdm.code_rate_HP = FEC_5_6; - break; - case 4: - param->u.ofdm.code_rate_HP = FEC_7_8; - break; - default: - printk("Unexpected value for code_rate_HP\n"); - } - switch((tmp >> 3) & 7) { - case 0: - param->u.ofdm.code_rate_LP = FEC_1_2; - break; - case 1: - param->u.ofdm.code_rate_LP = FEC_2_3; - break; - case 2: - param->u.ofdm.code_rate_LP = FEC_3_4; - break; - case 3: - param->u.ofdm.code_rate_LP = FEC_5_6; - break; - case 4: - param->u.ofdm.code_rate_LP = FEC_7_8; - break; - default: - printk("Unexpected value for code_rate_LP\n"); - } - - - tmp = l64781_readreg(state, 0x06); - switch(tmp & 3) { - case 0: - param->u.ofdm.constellation = QPSK; - break; - case 1: - param->u.ofdm.constellation = QAM_16; - break; - case 2: - param->u.ofdm.constellation = QAM_64; - break; - default: - printk("Unexpected value for constellation\n"); - } - switch((tmp >> 2) & 7) { - case 0: - param->u.ofdm.hierarchy_information = HIERARCHY_NONE; - break; - case 1: - param->u.ofdm.hierarchy_information = HIERARCHY_1; - break; - case 2: - param->u.ofdm.hierarchy_information = HIERARCHY_2; - break; - case 3: - param->u.ofdm.hierarchy_information = HIERARCHY_4; - break; - default: - printk("Unexpected value for hierarchy\n"); - } - - - tmp = l64781_readreg (state, 0x1d); - param->inversion = (tmp & 0x80) ? INVERSION_ON : INVERSION_OFF; - - tmp = (int) (l64781_readreg (state, 0x08) | - (l64781_readreg (state, 0x09) << 8) | - (l64781_readreg (state, 0x0a) << 16)); - param->frequency += tmp; - - return 0; -} - -static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct l64781_state* state = fe->demodulator_priv; - int sync = l64781_readreg (state, 0x32); - int gain = l64781_readreg (state, 0x0e); - - l64781_readreg (state, 0x00); /* clear interrupt registers... */ - l64781_readreg (state, 0x01); /* dto. */ - - *status = 0; - - if (gain > 5) - *status |= FE_HAS_SIGNAL; - - if (sync & 0x02) /* VCXO locked, this criteria should be ok */ - *status |= FE_HAS_CARRIER; - - if (sync & 0x20) - *status |= FE_HAS_VITERBI; - - if (sync & 0x40) - *status |= FE_HAS_SYNC; - - if (sync == 0x7f) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int l64781_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct l64781_state* state = fe->demodulator_priv; - - /* XXX FIXME: set up counting period (reg 0x26...0x28) - */ - *ber = l64781_readreg (state, 0x39) - | (l64781_readreg (state, 0x3a) << 8); - - return 0; -} - -static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) -{ - struct l64781_state* state = fe->demodulator_priv; - - u8 gain = l64781_readreg (state, 0x0e); - *signal_strength = (gain << 8) | gain; - - return 0; -} - -static int l64781_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct l64781_state* state = fe->demodulator_priv; - - u8 avg_quality = 0xff - l64781_readreg (state, 0x33); - *snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/ - - return 0; -} - -static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct l64781_state* state = fe->demodulator_priv; - - *ucblocks = l64781_readreg (state, 0x37) - | (l64781_readreg (state, 0x38) << 8); - - return 0; -} - -static int l64781_sleep(struct dvb_frontend* fe) -{ - struct l64781_state* state = fe->demodulator_priv; - - /* Power down */ - return l64781_writereg (state, 0x3e, 0x5a); -} - -static int l64781_init(struct dvb_frontend* fe) -{ - struct l64781_state* state = fe->demodulator_priv; - - reset_and_configure (state); - - /* Power up */ - l64781_writereg (state, 0x3e, 0xa5); - - /* Reset hard */ - l64781_writereg (state, 0x2a, 0x04); - l64781_writereg (state, 0x2a, 0x00); - - /* Set tuner specific things */ - /* AFC_POL, set also in reset_afc */ - l64781_writereg (state, 0x07, 0x8e); - - /* Use internal ADC */ - l64781_writereg (state, 0x0b, 0x81); - - /* AGC loop gain, and polarity is positive */ - l64781_writereg (state, 0x0c, 0x84); - - /* Internal ADC outputs two's complement */ - l64781_writereg (state, 0x0d, 0x8c); - - /* With ppm=8000, it seems the DTR_SENSITIVITY will result in - value of 2 with all possible bandwidths and guard - intervals, which is the initial value anyway. */ - /*l64781_writereg (state, 0x19, 0x92);*/ - - /* Everything is two's complement, soft bit and CSI_OUT too */ - l64781_writereg (state, 0x1e, 0x09); - - /* delay a bit after first init attempt */ - if (state->first) { - state->first = 0; - msleep(200); - } - - return 0; -} - -static int l64781_get_tune_settings(struct dvb_frontend* fe, - struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 4000; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static void l64781_release(struct dvb_frontend* fe) -{ - struct l64781_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops l64781_ops; - -struct dvb_frontend* l64781_attach(const struct l64781_config* config, - struct i2c_adapter* i2c) -{ - struct l64781_state* state = NULL; - int reg0x3e = -1; - u8 b0 [] = { 0x1a }; - u8 b1 [] = { 0x00 }; - struct i2c_msg msg [] = { { .addr = config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct l64781_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->first = 1; - - /** - * the L64781 won't show up before we send the reset_and_configure() - * broadcast. If nothing responds there is no L64781 on the bus... - */ - if (reset_and_configure(state) < 0) { - dprintk("No response to reset and configure broadcast...\n"); - goto error; - } - - /* The chip always responds to reads */ - if (i2c_transfer(state->i2c, msg, 2) != 2) { - dprintk("No response to read on I2C bus\n"); - goto error; - } - - /* Save current register contents for bailout */ - reg0x3e = l64781_readreg(state, 0x3e); - - /* Reading the POWER_DOWN register always returns 0 */ - if (reg0x3e != 0) { - dprintk("Device doesn't look like L64781\n"); - goto error; - } - - /* Turn the chip off */ - l64781_writereg (state, 0x3e, 0x5a); - - /* Responds to all reads with 0 */ - if (l64781_readreg(state, 0x1a) != 0) { - dprintk("Read 1 returned unexpcted value\n"); - goto error; - } - - /* Turn the chip on */ - l64781_writereg (state, 0x3e, 0xa5); - - /* Responds with register default value */ - if (l64781_readreg(state, 0x1a) != 0xa1) { - dprintk("Read 2 returned unexpcted value\n"); - goto error; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &l64781_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - if (reg0x3e >= 0) - l64781_writereg (state, 0x3e, reg0x3e); /* restore reg 0x3e */ - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops l64781_ops = { - - .info = { - .name = "LSI L64781 DVB-T", - .type = FE_OFDM, - /* .frequency_min = ???,*/ - /* .frequency_max = ???,*/ - .frequency_stepsize = 166666, - /* .frequency_tolerance = ???,*/ - /* .symbol_rate_tolerance = ???,*/ - .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_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_MUTE_TS - }, - - .release = l64781_release, - - .init = l64781_init, - .sleep = l64781_sleep, - - .set_frontend = apply_frontend_param, - .get_frontend = get_frontend, - .get_tune_settings = l64781_get_tune_settings, - - .read_status = l64781_read_status, - .read_ber = l64781_read_ber, - .read_signal_strength = l64781_read_signal_strength, - .read_snr = l64781_read_snr, - .read_ucblocks = l64781_read_ucblocks, -}; - -MODULE_DESCRIPTION("LSI L64781 DVB-T Demodulator driver"); -MODULE_AUTHOR("Holger Waechtler, Marko Kohtala"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(l64781_attach); diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h deleted file mode 100644 index 1305a9e7fb0..00000000000 --- a/drivers/media/dvb/frontends/l64781.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - driver for LSI L64781 COFDM demodulator - - Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH - Marko Kohtala <marko.kohtala@luukku.com> - - 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 L64781_H -#define L64781_H - -#include <linux/dvb/frontend.h> - -struct l64781_config -{ - /* the demodulator's i2c address */ - u8 demod_address; -}; - -#if defined(CONFIG_DVB_L64781) || (defined(CONFIG_DVB_L64781_MODULE) && defined(MODULE)) -extern struct dvb_frontend* l64781_attach(const struct l64781_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* l64781_attach(const struct l64781_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_L64781 - -#endif // L64781_H diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c deleted file mode 100644 index eb72a9866c9..00000000000 --- a/drivers/media/dvb/frontends/lgdt3304.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Driver for LG ATSC lgdt3304 driver - * - * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de> - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "lgdt3304.h" - -static unsigned int debug = 0; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"lgdt3304 debugging (default off)"); - -#define dprintk(fmt, args...) if (debug) do {\ - printk("lgdt3304 debug: " fmt, ##args); } while (0) - -struct lgdt3304_state -{ - struct dvb_frontend frontend; - fe_modulation_t current_modulation; - __u32 snr; - __u32 current_frequency; - __u8 addr; - struct i2c_adapter *i2c; -}; - -static int i2c_write_demod_bytes (struct dvb_frontend *fe, __u8 *buf, int len) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - struct i2c_msg i2cmsgs = { - .addr = state->addr, - .flags = 0, - .len = 3, - .buf = buf - }; - int i; - int err; - - for (i=0; i<len-1; i+=3){ - if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) { - printk("%s i2c_transfer error %d\n", __func__, err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - i2cmsgs.buf += 3; - } - return 0; -} - -static int lgdt3304_i2c_read_reg(struct dvb_frontend *fe, unsigned int reg) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - struct i2c_msg i2cmsgs[2]; - int ret; - __u8 buf; - - __u8 regbuf[2] = { reg>>8, reg&0xff }; - - i2cmsgs[0].addr = state->addr; - i2cmsgs[0].flags = 0; - i2cmsgs[0].len = 2; - i2cmsgs[0].buf = regbuf; - - i2cmsgs[1].addr = state->addr; - i2cmsgs[1].flags = I2C_M_RD; - i2cmsgs[1].len = 1; - i2cmsgs[1].buf = &buf; - - if((ret = i2c_transfer(state->i2c, i2cmsgs, 2))<0) { - printk("%s i2c_transfer error %d\n", __func__, ret); - return ret; - } - - return buf; -} - -static int lgdt3304_i2c_write_reg(struct dvb_frontend *fe, int reg, int val) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - char buffer[3] = { reg>>8, reg&0xff, val }; - int ret; - - struct i2c_msg i2cmsgs = { - .addr = state->addr, - .flags = 0, - .len = 3, - .buf=buffer - }; - ret = i2c_transfer(state->i2c, &i2cmsgs, 1); - if (ret != 1) { - printk("%s i2c_transfer error %d\n", __func__, ret); - return ret; - } - - return 0; -} - - -static int lgdt3304_soft_Reset(struct dvb_frontend *fe) -{ - lgdt3304_i2c_write_reg(fe, 0x0002, 0x9a); - lgdt3304_i2c_write_reg(fe, 0x0002, 0x9b); - mdelay(200); - return 0; -} - -static int lgdt3304_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { - int err = 0; - - static __u8 lgdt3304_vsb8_data[] = { - /* 16bit , 8bit */ - /* regs , val */ - 0x00, 0x00, 0x02, - 0x00, 0x00, 0x13, - 0x00, 0x0d, 0x02, - 0x00, 0x0e, 0x02, - 0x00, 0x12, 0x32, - 0x00, 0x13, 0xc4, - 0x01, 0x12, 0x17, - 0x01, 0x13, 0x15, - 0x01, 0x14, 0x18, - 0x01, 0x15, 0xff, - 0x01, 0x16, 0x2c, - 0x02, 0x14, 0x67, - 0x02, 0x24, 0x8d, - 0x04, 0x27, 0x12, - 0x04, 0x28, 0x4f, - 0x03, 0x08, 0x80, - 0x03, 0x09, 0x00, - 0x03, 0x0d, 0x00, - 0x03, 0x0e, 0x1c, - 0x03, 0x14, 0xe1, - 0x05, 0x0e, 0x5b, - }; - - /* not yet tested .. */ - static __u8 lgdt3304_qam64_data[] = { - /* 16bit , 8bit */ - /* regs , val */ - 0x00, 0x00, 0x18, - 0x00, 0x0d, 0x02, - //0x00, 0x0e, 0x02, - 0x00, 0x12, 0x2a, - 0x00, 0x13, 0x00, - 0x03, 0x14, 0xe3, - 0x03, 0x0e, 0x1c, - 0x03, 0x08, 0x66, - 0x03, 0x09, 0x66, - 0x03, 0x0a, 0x08, - 0x03, 0x0b, 0x9b, - 0x05, 0x0e, 0x5b, - }; - - - /* tested with KWorld a340 */ - static __u8 lgdt3304_qam256_data[] = { - /* 16bit , 8bit */ - /* regs , val */ - 0x00, 0x00, 0x01, //0x19, - 0x00, 0x12, 0x2a, - 0x00, 0x13, 0x80, - 0x00, 0x0d, 0x02, - 0x03, 0x14, 0xe3, - - 0x03, 0x0e, 0x1c, - 0x03, 0x08, 0x66, - 0x03, 0x09, 0x66, - 0x03, 0x0a, 0x08, - 0x03, 0x0b, 0x9b, - - 0x03, 0x0d, 0x14, - //0x05, 0x0e, 0x5b, - 0x01, 0x06, 0x4a, - 0x01, 0x07, 0x3d, - 0x01, 0x08, 0x70, - 0x01, 0x09, 0xa3, - - 0x05, 0x04, 0xfd, - - 0x00, 0x0d, 0x82, - - 0x05, 0x0e, 0x5b, - - 0x05, 0x0e, 0x5b, - - 0x00, 0x02, 0x9a, - - 0x00, 0x02, 0x9b, - - 0x00, 0x00, 0x01, - 0x00, 0x12, 0x2a, - 0x00, 0x13, 0x80, - 0x00, 0x0d, 0x02, - 0x03, 0x14, 0xe3, - - 0x03, 0x0e, 0x1c, - 0x03, 0x08, 0x66, - 0x03, 0x09, 0x66, - 0x03, 0x0a, 0x08, - 0x03, 0x0b, 0x9b, - - 0x03, 0x0d, 0x14, - 0x01, 0x06, 0x4a, - 0x01, 0x07, 0x3d, - 0x01, 0x08, 0x70, - 0x01, 0x09, 0xa3, - - 0x05, 0x04, 0xfd, - - 0x00, 0x0d, 0x82, - - 0x05, 0x0e, 0x5b, - }; - - struct lgdt3304_state *state = fe->demodulator_priv; - if (state->current_modulation != param->u.vsb.modulation) { - switch(param->u.vsb.modulation) { - case VSB_8: - err = i2c_write_demod_bytes(fe, lgdt3304_vsb8_data, - sizeof(lgdt3304_vsb8_data)); - break; - case QAM_64: - err = i2c_write_demod_bytes(fe, lgdt3304_qam64_data, - sizeof(lgdt3304_qam64_data)); - break; - case QAM_256: - err = i2c_write_demod_bytes(fe, lgdt3304_qam256_data, - sizeof(lgdt3304_qam256_data)); - break; - default: - break; - } - - if (err) { - printk("%s error setting modulation\n", __func__); - } else { - state->current_modulation = param->u.vsb.modulation; - } - } - state->current_frequency = param->frequency; - - lgdt3304_soft_Reset(fe); - - - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, param); - - return 0; -} - -static int lgdt3304_init(struct dvb_frontend *fe) { - return 0; -} - -static int lgdt3304_sleep(struct dvb_frontend *fe) { - return 0; -} - - -static int lgdt3304_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - int r011d; - int qam_lck; - - *status = 0; - dprintk("lgdt read status\n"); - - r011d = lgdt3304_i2c_read_reg(fe, 0x011d); - - dprintk("%02x\n", r011d); - - switch(state->current_modulation) { - case VSB_8: - if (r011d & 0x80) { - dprintk("VSB Locked\n"); - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_LOCK; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_SIGNAL; - } - break; - case QAM_64: - case QAM_256: - qam_lck = r011d & 0x7; - switch(qam_lck) { - case 0x0: dprintk("Unlock\n"); - break; - case 0x4: dprintk("1st Lock in acquisition state\n"); - break; - case 0x6: dprintk("2nd Lock in acquisition state\n"); - break; - case 0x7: dprintk("Final Lock in good reception state\n"); - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_LOCK; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_SIGNAL; - break; - } - break; - default: - printk("%s unhandled modulation\n", __func__); - } - - - return 0; -} - -static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber) -{ - dprintk("read ber\n"); - return 0; -} - -static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr) -{ - dprintk("read snr\n"); - return 0; -} - -static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks) -{ - dprintk("read ucblocks\n"); - return 0; -} - -static void lgdt3304_release(struct dvb_frontend *fe) -{ - struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops demod_lgdt3304={ - .info = { - .name = "LG 3304", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, - .symbol_rate_min = 5056941, - .symbol_rate_max = 10762000, - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - .init = lgdt3304_init, - .sleep = lgdt3304_sleep, - .set_frontend = lgdt3304_set_parameters, - .read_snr = lgdt3304_read_snr, - .read_ber = lgdt3304_read_ber, - .read_status = lgdt3304_read_status, - .read_ucblocks = lgdt3304_read_ucblocks, - .release = lgdt3304_release, -}; - -struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, - struct i2c_adapter *i2c) -{ - - struct lgdt3304_state *state; - state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL); - state->addr = config->i2c_address; - state->i2c = i2c; - - memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -EXPORT_SYMBOL_GPL(lgdt3304_attach); -MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>"); -MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/lgdt3304.h b/drivers/media/dvb/frontends/lgdt3304.h deleted file mode 100644 index fc409fe59ac..00000000000 --- a/drivers/media/dvb/frontends/lgdt3304.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Driver for DVB-T lgdt3304 demodulator - * - * Copyright (C) 2008 Markus Rechberger <mrechberger@gmail.com> - * - * 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 LGDT3304_H -#define LGDT3304_H - -#include <linux/dvb/frontend.h> - -struct lgdt3304_config -{ - /* demodulator's I2C address */ - u8 i2c_address; -}; - -#if defined(CONFIG_DVB_LGDT3304) || (defined(CONFIG_DVB_LGDT3304_MODULE) && defined(MODULE)) -extern struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_LGDT */ - -#endif /* LGDT3304_H */ diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c deleted file mode 100644 index d92d0557a80..00000000000 --- a/drivers/media/dvb/frontends/lgdt3305.c +++ /dev/null @@ -1,1087 +0,0 @@ -/* - * Support for LGDT3305 - VSB/QAM - * - * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org> - * - * 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 <linux/dvb/frontend.h> -#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"); - 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 <mkrufky@linuxtv.org>"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("0.1"); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/lgdt3305.h b/drivers/media/dvb/frontends/lgdt3305.h deleted file mode 100644 index 4fa6e52d1fe..00000000000 --- a/drivers/media/dvb/frontends/lgdt3305.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Support for LGDT3305 - VSB/QAM - * - * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org> - * - * 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 <linux/i2c.h> -#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_ */ diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c deleted file mode 100644 index 056387b41a8..00000000000 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ /dev/null @@ -1,820 +0,0 @@ -/* - * Support for LGDT3302 and LGDT3303 - VSB/QAM - * - * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> - * - * 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. - * - */ - -/* - * NOTES ABOUT THIS DRIVER - * - * This Linux driver supports: - * DViCO FusionHDTV 3 Gold-Q - * DViCO FusionHDTV 3 Gold-T - * DViCO FusionHDTV 5 Gold - * DViCO FusionHDTV 5 Lite - * DViCO FusionHDTV 5 USB Gold - * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) - * pcHDTV HD5500 - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <asm/byteorder.h> - -#include "dvb_frontend.h" -#include "dvb_math.h" -#include "lgdt330x_priv.h" -#include "lgdt330x.h" - -/* Use Equalizer Mean Squared Error instead of Phaser Tracker MSE */ -/* #define USE_EQMSE */ - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"Turn on/off lgdt330x frontend debugging (default:off)."); -#define dprintk(args...) \ -do { \ -if (debug) printk(KERN_DEBUG "lgdt330x: " args); \ -} while (0) - -struct lgdt330x_state -{ - struct i2c_adapter* i2c; - - /* Configuration settings */ - const struct lgdt330x_config* config; - - struct dvb_frontend frontend; - - /* Demodulator private data */ - fe_modulation_t current_modulation; - u32 snr; /* Result of last SNR calculation */ - - /* Tuner private data */ - u32 current_frequency; -}; - -static int i2c_write_demod_bytes (struct lgdt330x_state* state, - u8 *buf, /* data bytes to send */ - int len /* number of bytes to send */ ) -{ - struct i2c_msg msg = - { .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = 2 }; - int i; - int err; - - for (i=0; i<len-1; i+=2){ - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __func__, msg.buf[0], msg.buf[1], err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - msg.buf += 2; - } - return 0; -} - -/* - * This routine writes the register (reg) to the demod bus - * then reads the data returned for (len) bytes. - */ - -static u8 i2c_read_demod_bytes (struct lgdt330x_state* state, - enum I2C_REG reg, u8* buf, int len) -{ - u8 wr [] = { reg }; - struct i2c_msg msg [] = { - { .addr = state->config->demod_address, - .flags = 0, .buf = wr, .len = 1 }, - { .addr = state->config->demod_address, - .flags = I2C_M_RD, .buf = buf, .len = len }, - }; - int ret; - ret = i2c_transfer(state->i2c, msg, 2); - if (ret != 2) { - printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __func__, state->config->demod_address, reg, ret); - } else { - ret = 0; - } - return ret; -} - -/* Software reset */ -static int lgdt3302_SwReset(struct lgdt330x_state* state) -{ - u8 ret; - u8 reset[] = { - IRQ_MASK, - 0x00 /* bit 6 is active low software reset - * bits 5-0 are 1 to mask interrupts */ - }; - - ret = i2c_write_demod_bytes(state, - reset, sizeof(reset)); - if (ret == 0) { - - /* force reset high (inactive) and unmask interrupts */ - reset[1] = 0x7f; - ret = i2c_write_demod_bytes(state, - reset, sizeof(reset)); - } - return ret; -} - -static int lgdt3303_SwReset(struct lgdt330x_state* state) -{ - u8 ret; - u8 reset[] = { - 0x02, - 0x00 /* bit 0 is active low software reset */ - }; - - ret = i2c_write_demod_bytes(state, - reset, sizeof(reset)); - if (ret == 0) { - - /* force reset high (inactive) */ - reset[1] = 0x01; - ret = i2c_write_demod_bytes(state, - reset, sizeof(reset)); - } - return ret; -} - -static int lgdt330x_SwReset(struct lgdt330x_state* state) -{ - switch (state->config->demod_chip) { - case LGDT3302: - return lgdt3302_SwReset(state); - case LGDT3303: - return lgdt3303_SwReset(state); - default: - return -ENODEV; - } -} - -static int lgdt330x_init(struct dvb_frontend* fe) -{ - /* Hardware reset is done using gpio[0] of cx23880x chip. - * I'd like to do it here, but don't know how to find chip address. - * cx88-cards.c arranges for the reset bit to be inactive (high). - * Maybe there needs to be a callable function in cx88-core or - * the caller of this function needs to do it. */ - - /* - * Array of byte pairs <address, value> - * to initialize each different chip - */ - static u8 lgdt3302_init_data[] = { - /* Use 50MHz parameter values from spec sheet since xtal is 50 */ - /* Change the value of NCOCTFV[25:0] of carrier - recovery center frequency register */ - VSB_CARRIER_FREQ0, 0x00, - VSB_CARRIER_FREQ1, 0x87, - VSB_CARRIER_FREQ2, 0x8e, - VSB_CARRIER_FREQ3, 0x01, - /* Change the TPCLK pin polarity - data is valid on falling clock */ - DEMUX_CONTROL, 0xfb, - /* Change the value of IFBW[11:0] of - AGC IF/RF loop filter bandwidth register */ - AGC_RF_BANDWIDTH0, 0x40, - AGC_RF_BANDWIDTH1, 0x93, - AGC_RF_BANDWIDTH2, 0x00, - /* Change the value of bit 6, 'nINAGCBY' and - 'NSSEL[1:0] of ACG function control register 2 */ - AGC_FUNC_CTRL2, 0xc6, - /* Change the value of bit 6 'RFFIX' - of AGC function control register 3 */ - AGC_FUNC_CTRL3, 0x40, - /* Set the value of 'INLVTHD' register 0x2a/0x2c - to 0x7fe */ - AGC_DELAY0, 0x07, - AGC_DELAY2, 0xfe, - /* Change the value of IAGCBW[15:8] - of inner AGC loop filter bandwidth */ - AGC_LOOP_BANDWIDTH0, 0x08, - AGC_LOOP_BANDWIDTH1, 0x9a - }; - - static u8 lgdt3303_init_data[] = { - 0x4c, 0x14 - }; - - static u8 flip_1_lgdt3303_init_data[] = { - 0x4c, 0x14, - 0x87, 0xf3 - }; - - static u8 flip_2_lgdt3303_init_data[] = { - 0x4c, 0x14, - 0x87, 0xda - }; - - struct lgdt330x_state* state = fe->demodulator_priv; - char *chip_name; - int err; - - switch (state->config->demod_chip) { - case LGDT3302: - chip_name = "LGDT3302"; - err = i2c_write_demod_bytes(state, lgdt3302_init_data, - sizeof(lgdt3302_init_data)); - break; - case LGDT3303: - chip_name = "LGDT3303"; - switch (state->config->clock_polarity_flip) { - case 2: - err = i2c_write_demod_bytes(state, - flip_2_lgdt3303_init_data, - sizeof(flip_2_lgdt3303_init_data)); - break; - case 1: - err = i2c_write_demod_bytes(state, - flip_1_lgdt3303_init_data, - sizeof(flip_1_lgdt3303_init_data)); - break; - case 0: - default: - err = i2c_write_demod_bytes(state, lgdt3303_init_data, - sizeof(lgdt3303_init_data)); - } - break; - default: - chip_name = "undefined"; - printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n"); - err = -ENODEV; - } - dprintk("%s entered as %s\n", __func__, chip_name); - if (err < 0) - return err; - return lgdt330x_SwReset(state); -} - -static int lgdt330x_read_ber(struct dvb_frontend* fe, u32* ber) -{ - *ber = 0; /* Not supplied by the demod chips */ - return 0; -} - -static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct lgdt330x_state* state = fe->demodulator_priv; - int err; - u8 buf[2]; - - switch (state->config->demod_chip) { - case LGDT3302: - err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1, - buf, sizeof(buf)); - break; - case LGDT3303: - err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1, - buf, sizeof(buf)); - break; - default: - printk(KERN_WARNING - "Only LGDT3302 and LGDT3303 are supported chips.\n"); - err = -ENODEV; - } - - *ucblocks = (buf[0] << 8) | buf[1]; - return 0; -} - -static int lgdt330x_set_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) -{ - /* - * Array of byte pairs <address, value> - * to initialize 8VSB for lgdt3303 chip 50 MHz IF - */ - static u8 lgdt3303_8vsb_44_data[] = { - 0x04, 0x00, - 0x0d, 0x40, - 0x0e, 0x87, - 0x0f, 0x8e, - 0x10, 0x01, - 0x47, 0x8b }; - - /* - * Array of byte pairs <address, value> - * to initialize QAM for lgdt3303 chip - */ - static u8 lgdt3303_qam_data[] = { - 0x04, 0x00, - 0x0d, 0x00, - 0x0e, 0x00, - 0x0f, 0x00, - 0x10, 0x00, - 0x51, 0x63, - 0x47, 0x66, - 0x48, 0x66, - 0x4d, 0x1a, - 0x49, 0x08, - 0x4a, 0x9b }; - - struct lgdt330x_state* state = fe->demodulator_priv; - - static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 }; - - int err; - /* Change only if we are actually changing the modulation */ - if (state->current_modulation != param->u.vsb.modulation) { - switch(param->u.vsb.modulation) { - case VSB_8: - dprintk("%s: VSB_8 MODE\n", __func__); - - /* Select VSB mode */ - top_ctrl_cfg[1] = 0x03; - - /* Select ANT connector if supported by card */ - if (state->config->pll_rf_set) - state->config->pll_rf_set(fe, 1); - - if (state->config->demod_chip == LGDT3303) { - err = i2c_write_demod_bytes(state, lgdt3303_8vsb_44_data, - sizeof(lgdt3303_8vsb_44_data)); - } - break; - - case QAM_64: - dprintk("%s: QAM_64 MODE\n", __func__); - - /* Select QAM_64 mode */ - top_ctrl_cfg[1] = 0x00; - - /* Select CABLE connector if supported by card */ - if (state->config->pll_rf_set) - state->config->pll_rf_set(fe, 0); - - if (state->config->demod_chip == LGDT3303) { - err = i2c_write_demod_bytes(state, lgdt3303_qam_data, - sizeof(lgdt3303_qam_data)); - } - break; - - case QAM_256: - dprintk("%s: QAM_256 MODE\n", __func__); - - /* Select QAM_256 mode */ - top_ctrl_cfg[1] = 0x01; - - /* Select CABLE connector if supported by card */ - if (state->config->pll_rf_set) - state->config->pll_rf_set(fe, 0); - - if (state->config->demod_chip == LGDT3303) { - err = i2c_write_demod_bytes(state, lgdt3303_qam_data, - sizeof(lgdt3303_qam_data)); - } - break; - default: - printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __func__, param->u.vsb.modulation); - return -1; - } - /* - * select serial or parallel MPEG harware interface - * Serial: 0x04 for LGDT3302 or 0x40 for LGDT3303 - * Parallel: 0x00 - */ - top_ctrl_cfg[1] |= state->config->serial_mpeg; - - /* Select the requested mode */ - i2c_write_demod_bytes(state, top_ctrl_cfg, - sizeof(top_ctrl_cfg)); - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - state->current_modulation = param->u.vsb.modulation; - } - - /* Tune to the specified frequency */ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* Keep track of the new frequency */ - /* FIXME this is the wrong way to do this... */ - /* The tuner is shared with the video4linux analog API */ - state->current_frequency = param->frequency; - - lgdt330x_SwReset(state); - return 0; -} - -static int lgdt330x_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters* param) -{ - struct lgdt330x_state *state = fe->demodulator_priv; - param->frequency = state->current_frequency; - return 0; -} - -static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct lgdt330x_state* state = fe->demodulator_priv; - u8 buf[3]; - - *status = 0; /* Reset status result */ - - /* AGC status register */ - i2c_read_demod_bytes(state, AGC_STATUS, buf, 1); - dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]); - if ((buf[0] & 0x0c) == 0x8){ - /* Test signal does not exist flag */ - /* as well as the AGC lock flag. */ - *status |= FE_HAS_SIGNAL; - } - - /* - * You must set the Mask bits to 1 in the IRQ_MASK in order - * to see that status bit in the IRQ_STATUS register. - * This is done in SwReset(); - */ - /* signal status */ - i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf)); - dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __func__, buf[0], buf[1], buf[2]); - - - /* sync status */ - if ((buf[2] & 0x03) == 0x01) { - *status |= FE_HAS_SYNC; - } - - /* FEC error status */ - if ((buf[2] & 0x0c) == 0x08) { - *status |= FE_HAS_LOCK; - *status |= FE_HAS_VITERBI; - } - - /* Carrier Recovery Lock Status Register */ - i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1); - dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]); - switch (state->current_modulation) { - case QAM_256: - case QAM_64: - /* Need to undestand why there are 3 lock levels here */ - if ((buf[0] & 0x07) == 0x07) - *status |= FE_HAS_CARRIER; - break; - case VSB_8: - if ((buf[0] & 0x80) == 0x80) - *status |= FE_HAS_CARRIER; - break; - default: - printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__); - } - - return 0; -} - -static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct lgdt330x_state* state = fe->demodulator_priv; - int err; - u8 buf[3]; - - *status = 0; /* Reset status result */ - - /* lgdt3303 AGC status register */ - err = i2c_read_demod_bytes(state, 0x58, buf, 1); - if (err < 0) - return err; - - dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]); - if ((buf[0] & 0x21) == 0x01){ - /* Test input signal does not exist flag */ - /* as well as the AGC lock flag. */ - *status |= FE_HAS_SIGNAL; - } - - /* Carrier Recovery Lock Status Register */ - i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1); - dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]); - switch (state->current_modulation) { - case QAM_256: - case QAM_64: - /* Need to undestand why there are 3 lock levels here */ - if ((buf[0] & 0x07) == 0x07) - *status |= FE_HAS_CARRIER; - else - break; - i2c_read_demod_bytes(state, 0x8a, buf, 1); - if ((buf[0] & 0x04) == 0x04) - *status |= FE_HAS_SYNC; - if ((buf[0] & 0x01) == 0x01) - *status |= FE_HAS_LOCK; - if ((buf[0] & 0x08) == 0x08) - *status |= FE_HAS_VITERBI; - break; - case VSB_8: - if ((buf[0] & 0x80) == 0x80) - *status |= FE_HAS_CARRIER; - else - break; - i2c_read_demod_bytes(state, 0x38, buf, 1); - if ((buf[0] & 0x02) == 0x00) - *status |= FE_HAS_SYNC; - if ((buf[0] & 0x01) == 0x01) { - *status |= FE_HAS_LOCK; - *status |= FE_HAS_VITERBI; - } - break; - default: - printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__); - } - return 0; -} - -/* Calculate SNR estimation (scaled by 2^24) - - 8-VSB SNR equations from LGDT3302 and LGDT3303 datasheets, QAM - equations from LGDT3303 datasheet. VSB is the same between the '02 - and '03, so maybe QAM is too? Perhaps someone with a newer datasheet - that has QAM information could verify? - - For 8-VSB: (two ways, take your pick) - LGDT3302: - SNR_EQ = 10 * log10(25 * 24^2 / EQ_MSE) - LGDT3303: - SNR_EQ = 10 * log10(25 * 32^2 / EQ_MSE) - LGDT3302 & LGDT3303: - SNR_PT = 10 * log10(25 * 32^2 / PT_MSE) (we use this one) - For 64-QAM: - SNR = 10 * log10( 688128 / MSEQAM) - For 256-QAM: - SNR = 10 * log10( 696320 / MSEQAM) - - We re-write the snr equation as: - SNR * 2^24 = 10*(c - intlog10(MSE)) - Where for 256-QAM, c = log10(696320) * 2^24, and so on. */ - -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 lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; - u8 buf[5]; /* read data buffer */ - u32 noise; /* noise value */ - u32 c; /* per-modulation SNR calculation constant */ - - switch(state->current_modulation) { - case VSB_8: - i2c_read_demod_bytes(state, LGDT3302_EQPH_ERR0, buf, 5); -#ifdef USE_EQMSE - /* Use Equalizer Mean-Square Error Register */ - /* SNR for ranges from -15.61 to +41.58 */ - noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2]; - c = 69765745; /* log10(25*24^2)*2^24 */ -#else - /* Use Phase Tracker Mean-Square Error Register */ - /* SNR for ranges from -13.11 to +44.08 */ - noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4]; - c = 73957994; /* log10(25*32^2)*2^24 */ -#endif - break; - case QAM_64: - case QAM_256: - i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2); - noise = ((buf[0] & 3) << 8) | buf[1]; - c = state->current_modulation == QAM_64 ? 97939837 : 98026066; - /* log10(688128)*2^24 and log10(696320)*2^24 */ - break; - default: - printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n", - __func__); - return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */ - } - - state->snr = calculate_snr(noise, c); - *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */ - - dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise, - state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16); - - return 0; -} - -static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; - u8 buf[5]; /* read data buffer */ - u32 noise; /* noise value */ - u32 c; /* per-modulation SNR calculation constant */ - - switch(state->current_modulation) { - case VSB_8: - i2c_read_demod_bytes(state, LGDT3303_EQPH_ERR0, buf, 5); -#ifdef USE_EQMSE - /* Use Equalizer Mean-Square Error Register */ - /* SNR for ranges from -16.12 to +44.08 */ - noise = ((buf[0] & 0x78) << 13) | (buf[1] << 8) | buf[2]; - c = 73957994; /* log10(25*32^2)*2^24 */ -#else - /* Use Phase Tracker Mean-Square Error Register */ - /* SNR for ranges from -13.11 to +44.08 */ - noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4]; - c = 73957994; /* log10(25*32^2)*2^24 */ -#endif - break; - case QAM_64: - case QAM_256: - i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2); - noise = (buf[0] << 8) | buf[1]; - c = state->current_modulation == QAM_64 ? 97939837 : 98026066; - /* log10(688128)*2^24 and log10(696320)*2^24 */ - break; - default: - printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n", - __func__); - return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */ - } - - state->snr = calculate_snr(noise, c); - *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */ - - dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise, - state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16); - - return 0; -} - -static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - /* 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 lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; - u16 snr; - int ret; - - ret = fe->ops.read_snr(fe, &snr); - if (ret != 0) - return ret; - /* 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; - - return 0; -} - -static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings) -{ - /* I have no idea about this - it may not be needed */ - fe_tune_settings->min_delay_ms = 500; - fe_tune_settings->step_size = 0; - fe_tune_settings->max_drift = 0; - return 0; -} - -static void lgdt330x_release(struct dvb_frontend* fe) -{ - struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops lgdt3302_ops; -static struct dvb_frontend_ops lgdt3303_ops; - -struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, - struct i2c_adapter* i2c) -{ - struct lgdt330x_state* state = NULL; - u8 buf[1]; - - /* Allocate memory for the internal state */ - state = kzalloc(sizeof(struct lgdt330x_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* Setup the state */ - state->config = config; - state->i2c = i2c; - - /* Create dvb_frontend */ - switch (config->demod_chip) { - case LGDT3302: - memcpy(&state->frontend.ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops)); - break; - case LGDT3303: - memcpy(&state->frontend.ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops)); - break; - default: - goto error; - } - state->frontend.demodulator_priv = state; - - /* Verify communication with demod chip */ - if (i2c_read_demod_bytes(state, 2, buf, 1)) - goto error; - - state->current_frequency = -1; - state->current_modulation = -1; - - return &state->frontend; - -error: - kfree(state); - dprintk("%s: ERROR\n",__func__); - return NULL; -} - -static struct dvb_frontend_ops lgdt3302_ops = { - .info = { - .name= "LG Electronics LGDT3302 VSB/QAM Frontend", - .type = FE_ATSC, - .frequency_min= 54000000, - .frequency_max= 858000000, - .frequency_stepsize= 62500, - .symbol_rate_min = 5056941, /* QAM 64 */ - .symbol_rate_max = 10762000, /* VSB 8 */ - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - .init = lgdt330x_init, - .set_frontend = lgdt330x_set_parameters, - .get_frontend = lgdt330x_get_frontend, - .get_tune_settings = lgdt330x_get_tune_settings, - .read_status = lgdt3302_read_status, - .read_ber = lgdt330x_read_ber, - .read_signal_strength = lgdt330x_read_signal_strength, - .read_snr = lgdt3302_read_snr, - .read_ucblocks = lgdt330x_read_ucblocks, - .release = lgdt330x_release, -}; - -static struct dvb_frontend_ops lgdt3303_ops = { - .info = { - .name= "LG Electronics LGDT3303 VSB/QAM Frontend", - .type = FE_ATSC, - .frequency_min= 54000000, - .frequency_max= 858000000, - .frequency_stepsize= 62500, - .symbol_rate_min = 5056941, /* QAM 64 */ - .symbol_rate_max = 10762000, /* VSB 8 */ - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - .init = lgdt330x_init, - .set_frontend = lgdt330x_set_parameters, - .get_frontend = lgdt330x_get_frontend, - .get_tune_settings = lgdt330x_get_tune_settings, - .read_status = lgdt3303_read_status, - .read_ber = lgdt330x_read_ber, - .read_signal_strength = lgdt330x_read_signal_strength, - .read_snr = lgdt3303_read_snr, - .read_ucblocks = lgdt330x_read_ucblocks, - .release = lgdt330x_release, -}; - -MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver"); -MODULE_AUTHOR("Wilson Michaels"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(lgdt330x_attach); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h deleted file mode 100644 index 9012504f0f2..00000000000 --- a/drivers/media/dvb/frontends/lgdt330x.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Support for LGDT3302 and LGDT3303 - VSB/QAM - * - * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> - * - * 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 LGDT330X_H -#define LGDT330X_H - -#include <linux/dvb/frontend.h> - -typedef enum lg_chip_t { - UNDEFINED, - LGDT3302, - LGDT3303 -}lg_chip_type; - -struct lgdt330x_config -{ - /* The demodulator's i2c address */ - u8 demod_address; - - /* LG demodulator chip LGDT3302 or LGDT3303 */ - lg_chip_type demod_chip; - - /* MPEG hardware interface - 0:parallel 1:serial */ - int serial_mpeg; - - /* PLL interface */ - int (*pll_rf_set) (struct dvb_frontend* fe, int index); - - /* Need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); - - /* Flip the polarity of the mpeg data transfer clock using alternate init data - * This option applies ONLY to LGDT3303 - 0:disabled (default) 1:enabled */ - int clock_polarity_flip; -}; - -#if defined(CONFIG_DVB_LGDT330X) || (defined(CONFIG_DVB_LGDT330X_MODULE) && defined(MODULE)) -extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_LGDT330X - -#endif /* LGDT330X_H */ - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/lgdt330x_priv.h b/drivers/media/dvb/frontends/lgdt330x_priv.h deleted file mode 100644 index 38c76695abf..00000000000 --- a/drivers/media/dvb/frontends/lgdt330x_priv.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Support for LGDT3302 and LGDT3303 - VSB/QAM - * - * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> - * - * 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 _LGDT330X_PRIV_ -#define _LGDT330X_PRIV_ - -/* i2c control register addresses */ -enum I2C_REG { - TOP_CONTROL= 0x00, - IRQ_MASK= 0x01, - IRQ_STATUS= 0x02, - VSB_CARRIER_FREQ0= 0x16, - VSB_CARRIER_FREQ1= 0x17, - VSB_CARRIER_FREQ2= 0x18, - VSB_CARRIER_FREQ3= 0x19, - CARRIER_MSEQAM1= 0x1a, - CARRIER_MSEQAM2= 0x1b, - CARRIER_LOCK= 0x1c, - TIMING_RECOVERY= 0x1d, - AGC_DELAY0= 0x2a, - AGC_DELAY1= 0x2b, - AGC_DELAY2= 0x2c, - AGC_RF_BANDWIDTH0= 0x2d, - AGC_RF_BANDWIDTH1= 0x2e, - AGC_RF_BANDWIDTH2= 0x2f, - AGC_LOOP_BANDWIDTH0= 0x30, - AGC_LOOP_BANDWIDTH1= 0x31, - AGC_FUNC_CTRL1= 0x32, - AGC_FUNC_CTRL2= 0x33, - AGC_FUNC_CTRL3= 0x34, - AGC_RFIF_ACC0= 0x39, - AGC_RFIF_ACC1= 0x3a, - AGC_RFIF_ACC2= 0x3b, - AGC_STATUS= 0x3f, - SYNC_STATUS_VSB= 0x43, - DEMUX_CONTROL= 0x66, - LGDT3302_EQPH_ERR0= 0x47, - LGDT3302_EQ_ERR1= 0x48, - LGDT3302_EQ_ERR2= 0x49, - LGDT3302_PH_ERR1= 0x4a, - LGDT3302_PH_ERR2= 0x4b, - LGDT3302_PACKET_ERR_COUNTER1= 0x6a, - LGDT3302_PACKET_ERR_COUNTER2= 0x6b, - LGDT3303_EQPH_ERR0= 0x6e, - LGDT3303_EQ_ERR1= 0x6f, - LGDT3303_EQ_ERR2= 0x70, - LGDT3303_PH_ERR1= 0x71, - LGDT3303_PH_ERR2= 0x72, - LGDT3303_PACKET_ERR_COUNTER1= 0x8b, - LGDT3303_PACKET_ERR_COUNTER2= 0x8c, -}; - -#endif /* _LGDT330X_PRIV_ */ - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/lgs8gl5.c b/drivers/media/dvb/frontends/lgs8gl5.c deleted file mode 100644 index 855852fddf2..00000000000 --- a/drivers/media/dvb/frontends/lgs8gl5.c +++ /dev/null @@ -1,454 +0,0 @@ -/* - Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver - - Copyright (C) 2008 Sirius International (Hong Kong) Limited - Timothy Lee <timothy.lee@siriushk.com> - - 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 <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include "dvb_frontend.h" -#include "lgs8gl5.h" - - -#define REG_RESET 0x02 -#define REG_RESET_OFF 0x01 -#define REG_03 0x03 -#define REG_04 0x04 -#define REG_07 0x07 -#define REG_09 0x09 -#define REG_0A 0x0a -#define REG_0B 0x0b -#define REG_0C 0x0c -#define REG_37 0x37 -#define REG_STRENGTH 0x4b -#define REG_STRENGTH_MASK 0x7f -#define REG_STRENGTH_CARRIER 0x80 -#define REG_INVERSION 0x7c -#define REG_INVERSION_ON 0x80 -#define REG_7D 0x7d -#define REG_7E 0x7e -#define REG_A2 0xa2 -#define REG_STATUS 0xa4 -#define REG_STATUS_SYNC 0x04 -#define REG_STATUS_LOCK 0x01 - - -struct lgs8gl5_state { - struct i2c_adapter *i2c; - const struct lgs8gl5_config *config; - struct dvb_frontend frontend; -}; - - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "lgs8gl5: " args); \ - } while (0) - - -/* Writes into demod's register */ -static int -lgs8gl5_write_reg(struct lgs8gl5_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = {reg, data}; - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = 2 - }; - - ret = i2c_transfer(state->i2c, &msg, 1); - if (ret != 1) - dprintk("%s: error (reg=0x%02x, val=0x%02x, ret=%i)\n", - __func__, reg, data, ret); - return (ret != 1) ? -1 : 0; -} - - -/* Reads from demod's register */ -static int -lgs8gl5_read_reg(struct lgs8gl5_state *state, u8 reg) -{ - int ret; - u8 b0[] = {reg}; - u8 b1[] = {0}; - struct i2c_msg msg[2] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = b0, - .len = 1 - }, - { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = b1, - .len = 1 - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - if (ret != 2) - return -EIO; - - return b1[0]; -} - - -static int -lgs8gl5_update_reg(struct lgs8gl5_state *state, u8 reg, u8 data) -{ - lgs8gl5_read_reg(state, reg); - lgs8gl5_write_reg(state, reg, data); - return 0; -} - - -/* Writes into alternate device's register */ -/* TODO: Find out what that device is for! */ -static int -lgs8gl5_update_alt_reg(struct lgs8gl5_state *state, u8 reg, u8 data) -{ - int ret; - u8 b0[] = {reg}; - u8 b1[] = {0}; - u8 b2[] = {reg, data}; - struct i2c_msg msg[3] = { - { - .addr = state->config->demod_address + 2, - .flags = 0, - .buf = b0, - .len = 1 - }, - { - .addr = state->config->demod_address + 2, - .flags = I2C_M_RD, - .buf = b1, - .len = 1 - }, - { - .addr = state->config->demod_address + 2, - .flags = 0, - .buf = b2, - .len = 2 - }, - }; - - ret = i2c_transfer(state->i2c, msg, 3); - return (ret != 3) ? -1 : 0; -} - - -static void -lgs8gl5_soft_reset(struct lgs8gl5_state *state) -{ - u8 val; - - dprintk("%s\n", __func__); - - val = lgs8gl5_read_reg(state, REG_RESET); - lgs8gl5_write_reg(state, REG_RESET, val & ~REG_RESET_OFF); - lgs8gl5_write_reg(state, REG_RESET, val | REG_RESET_OFF); - msleep(5); -} - - -/* Starts demodulation */ -static void -lgs8gl5_start_demod(struct lgs8gl5_state *state) -{ - u8 val; - int n; - - dprintk("%s\n", __func__); - - lgs8gl5_update_alt_reg(state, 0xc2, 0x28); - lgs8gl5_soft_reset(state); - lgs8gl5_update_reg(state, REG_07, 0x10); - lgs8gl5_update_reg(state, REG_07, 0x10); - lgs8gl5_write_reg(state, REG_09, 0x0e); - lgs8gl5_write_reg(state, REG_0A, 0xe5); - lgs8gl5_write_reg(state, REG_0B, 0x35); - lgs8gl5_write_reg(state, REG_0C, 0x30); - - lgs8gl5_update_reg(state, REG_03, 0x00); - lgs8gl5_update_reg(state, REG_7E, 0x01); - lgs8gl5_update_alt_reg(state, 0xc5, 0x00); - lgs8gl5_update_reg(state, REG_04, 0x02); - lgs8gl5_update_reg(state, REG_37, 0x01); - lgs8gl5_soft_reset(state); - - /* Wait for carrier */ - for (n = 0; n < 10; n++) { - val = lgs8gl5_read_reg(state, REG_STRENGTH); - dprintk("Wait for carrier[%d] 0x%02X\n", n, val); - if (val & REG_STRENGTH_CARRIER) - break; - msleep(4); - } - if (!(val & REG_STRENGTH_CARRIER)) - return; - - /* Wait for lock */ - for (n = 0; n < 20; n++) { - val = lgs8gl5_read_reg(state, REG_STATUS); - dprintk("Wait for lock[%d] 0x%02X\n", n, val); - if (val & REG_STATUS_LOCK) - break; - msleep(12); - } - if (!(val & REG_STATUS_LOCK)) - return; - - lgs8gl5_write_reg(state, REG_7D, lgs8gl5_read_reg(state, REG_A2)); - lgs8gl5_soft_reset(state); -} - - -static int -lgs8gl5_init(struct dvb_frontend *fe) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - lgs8gl5_update_alt_reg(state, 0xc2, 0x28); - lgs8gl5_soft_reset(state); - lgs8gl5_update_reg(state, REG_07, 0x10); - lgs8gl5_update_reg(state, REG_07, 0x10); - lgs8gl5_write_reg(state, REG_09, 0x0e); - lgs8gl5_write_reg(state, REG_0A, 0xe5); - lgs8gl5_write_reg(state, REG_0B, 0x35); - lgs8gl5_write_reg(state, REG_0C, 0x30); - - return 0; -} - - -static int -lgs8gl5_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - u8 level = lgs8gl5_read_reg(state, REG_STRENGTH); - u8 flags = lgs8gl5_read_reg(state, REG_STATUS); - - *status = 0; - - if ((level & REG_STRENGTH_MASK) > 0) - *status |= FE_HAS_SIGNAL; - if (level & REG_STRENGTH_CARRIER) - *status |= FE_HAS_CARRIER; - if (flags & REG_STATUS_SYNC) - *status |= FE_HAS_SYNC; - if (flags & REG_STATUS_LOCK) - *status |= FE_HAS_LOCK; - - return 0; -} - - -static int -lgs8gl5_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - *ber = 0; - - return 0; -} - - -static int -lgs8gl5_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - u8 level = lgs8gl5_read_reg(state, REG_STRENGTH); - *signal_strength = (level & REG_STRENGTH_MASK) << 8; - - return 0; -} - - -static int -lgs8gl5_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - u8 level = lgs8gl5_read_reg(state, REG_STRENGTH); - *snr = (level & REG_STRENGTH_MASK) << 8; - - return 0; -} - - -static int -lgs8gl5_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - *ucblocks = 0; - - return 0; -} - - -static int -lgs8gl5_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ) - return -EINVAL; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* lgs8gl5_set_inversion(state, p->inversion); */ - - lgs8gl5_start_demod(state); - - return 0; -} - - -static int -lgs8gl5_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - u8 inv = lgs8gl5_read_reg(state, REG_INVERSION); - struct dvb_ofdm_parameters *o = &p->u.ofdm; - - p->inversion = (inv & REG_INVERSION_ON) ? INVERSION_ON : INVERSION_OFF; - - o->code_rate_HP = FEC_1_2; - o->code_rate_LP = FEC_7_8; - o->guard_interval = GUARD_INTERVAL_1_32; - o->transmission_mode = TRANSMISSION_MODE_2K; - o->constellation = QAM_64; - o->hierarchy_information = HIERARCHY_NONE; - o->bandwidth = BANDWIDTH_8_MHZ; - - return 0; -} - - -static int -lgs8gl5_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *fesettings) -{ - fesettings->min_delay_ms = 240; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - - -static void -lgs8gl5_release(struct dvb_frontend *fe) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - kfree(state); -} - - -static struct dvb_frontend_ops lgs8gl5_ops; - - -struct dvb_frontend* -lgs8gl5_attach(const struct lgs8gl5_config *config, struct i2c_adapter *i2c) -{ - struct lgs8gl5_state *state = NULL; - - dprintk("%s\n", __func__); - - /* Allocate memory for the internal state */ - state = kmalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* Setup the state */ - state->config = config; - state->i2c = i2c; - - /* Check if the demod is there */ - if (lgs8gl5_read_reg(state, REG_RESET) < 0) - goto error; - - /* Create dvb_frontend */ - memcpy(&state->frontend.ops, &lgs8gl5_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(lgs8gl5_attach); - - -static struct dvb_frontend_ops lgs8gl5_ops = { - .info = { - .name = "Legend Silicon LGS-8GL5 DMB-TH", - .type = FE_OFDM, - .frequency_min = 474000000, - .frequency_max = 858000000, - .frequency_stepsize = 10000, - .frequency_tolerance = 0, - .caps = FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 | - FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_BANDWIDTH_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | - FE_CAN_RECOVER - }, - - .release = lgs8gl5_release, - - .init = lgs8gl5_init, - - .set_frontend = lgs8gl5_set_frontend, - .get_frontend = lgs8gl5_get_frontend, - .get_tune_settings = lgs8gl5_get_tune_settings, - - .read_status = lgs8gl5_read_status, - .read_ber = lgs8gl5_read_ber, - .read_signal_strength = lgs8gl5_read_signal_strength, - .read_snr = lgs8gl5_read_snr, - .read_ucblocks = lgs8gl5_read_ucblocks, -}; - - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Legend Silicon LGS-8GL5 DMB-TH Demodulator driver"); -MODULE_AUTHOR("Timothy Lee"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/lgs8gl5.h b/drivers/media/dvb/frontends/lgs8gl5.h deleted file mode 100644 index d14176787a7..00000000000 --- a/drivers/media/dvb/frontends/lgs8gl5.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver - - Copyright (C) 2008 Sirius International (Hong Kong) Limited - Timothy Lee <timothy.lee@siriushk.com> - - 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 LGS8GL5_H -#define LGS8GL5_H - -#include <linux/dvb/frontend.h> - -struct lgs8gl5_config { - /* the demodulator's i2c address */ - u8 demod_address; -}; - -#if defined(CONFIG_DVB_LGS8GL5) || \ - (defined(CONFIG_DVB_LGS8GL5_MODULE) && defined(MODULE)) -extern struct dvb_frontend *lgs8gl5_attach( - const struct lgs8gl5_config *config, struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *lgs8gl5_attach( - const struct lgs8gl5_config *config, struct i2c_adapter *i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_LGS8GL5 */ - -#endif /* LGS8GL5_H */ diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c deleted file mode 100644 index f9785dfe735..00000000000 --- a/drivers/media/dvb/frontends/lgs8gxx.c +++ /dev/null @@ -1,816 +0,0 @@ -/* - * Support for Legend Silicon DMB-TH demodulator - * LGS8913, LGS8GL5 - * experimental support LGS8G42, LGS8G52 - * - * Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com> - * Copyright (C) 2008 Sirius International (Hong Kong) Limited - * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5) - * - * 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 <asm/div64.h> - -#include "dvb_frontend.h" - -#include "lgs8gxx.h" -#include "lgs8gxx_priv.h" - -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "lgs8gxx: " args); \ - } while (0) - -static int debug; -static int fake_signal_str; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -module_param(fake_signal_str, int, 0644); -MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913." -"Signal strength calculation is slow.(default:off)."); - -/* LGS8GXX internal helper functions */ - -static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 }; - - msg.addr = priv->config->demod_address; - if (reg >= 0xC0) - msg.addr += 0x02; - - if (debug >= 2) - printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n", - __func__, reg, data); - - ret = i2c_transfer(priv->i2c, &msg, 1); - - if (ret != 1) - dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n", - __func__, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data) -{ - int ret; - u8 dev_addr; - - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { .flags = 0, .buf = b0, .len = 1 }, - { .flags = I2C_M_RD, .buf = b1, .len = 1 }, - }; - - dev_addr = priv->config->demod_address; - if (reg >= 0xC0) - dev_addr += 0x02; - msg[1].addr = msg[0].addr = dev_addr; - - ret = i2c_transfer(priv->i2c, msg, 2); - if (ret != 2) { - dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n", - __func__, reg, ret); - return -1; - } - - *p_data = b1[0]; - if (debug >= 2) - printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n", - __func__, reg, b1[0]); - return 0; -} - -static int lgs8gxx_soft_reset(struct lgs8gxx_state *priv) -{ - lgs8gxx_write_reg(priv, 0x02, 0x00); - msleep(1); - lgs8gxx_write_reg(priv, 0x02, 0x01); - msleep(100); - - return 0; -} - -static int lgs8gxx_set_ad_mode(struct lgs8gxx_state *priv) -{ - const struct lgs8gxx_config *config = priv->config; - u8 if_conf; - - if_conf = 0x10; /* AGC output on; */ - - if_conf |= - ((config->ext_adc) ? 0x80 : 0x00) | - ((config->if_neg_center) ? 0x04 : 0x00) | - ((config->if_freq == 0) ? 0x08 : 0x00) | /* Baseband */ - ((config->ext_adc && config->adc_signed) ? 0x02 : 0x00) | - ((config->ext_adc && config->if_neg_edge) ? 0x01 : 0x00); - - if (config->ext_adc && - (config->prod == LGS8GXX_PROD_LGS8G52)) { - lgs8gxx_write_reg(priv, 0xBA, 0x40); - } - - lgs8gxx_write_reg(priv, 0x07, if_conf); - - return 0; -} - -static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/) -{ - u64 val; - u32 v32; - u32 if_clk; - - if_clk = priv->config->if_clk_freq; - - val = freq; - if (freq != 0) { - val *= (u64)1 << 32; - if (if_clk != 0) - do_div(val, if_clk); - v32 = val & 0xFFFFFFFF; - dprintk("Set IF Freq to %dkHz\n", freq); - } else { - v32 = 0; - dprintk("Set IF Freq to baseband\n"); - } - dprintk("AFC_INIT_FREQ = 0x%08X\n", v32); - - lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32)); - lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 8)); - lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 16)); - lgs8gxx_write_reg(priv, 0x0C, 0xFF & (v32 >> 24)); - - return 0; -} - -static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv) -{ - u8 t; - - if (priv->config->prod == LGS8GXX_PROD_LGS8913) - lgs8gxx_write_reg(priv, 0xC6, 0x01); - - lgs8gxx_read_reg(priv, 0x7E, &t); - lgs8gxx_write_reg(priv, 0x7E, t | 0x01); - - /* clear FEC self reset */ - lgs8gxx_read_reg(priv, 0xC5, &t); - lgs8gxx_write_reg(priv, 0xC5, t & 0xE0); - - if (priv->config->prod == LGS8GXX_PROD_LGS8913) { - /* FEC auto detect */ - lgs8gxx_write_reg(priv, 0xC1, 0x03); - - lgs8gxx_read_reg(priv, 0x7C, &t); - t = (t & 0x8C) | 0x03; - lgs8gxx_write_reg(priv, 0x7C, t); - } - - - if (priv->config->prod == LGS8GXX_PROD_LGS8913) { - /* BER test mode */ - lgs8gxx_read_reg(priv, 0xC3, &t); - t = (t & 0xEF) | 0x10; - lgs8gxx_write_reg(priv, 0xC3, t); - } - - if (priv->config->prod == LGS8GXX_PROD_LGS8G52) - lgs8gxx_write_reg(priv, 0xD9, 0x40); - - return 0; -} - -static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv) -{ - int ret = 0; - u8 t; - - /* turn off auto-detect; manual settings */ - lgs8gxx_write_reg(priv, 0x7E, 0); - if (priv->config->prod == LGS8GXX_PROD_LGS8913) - lgs8gxx_write_reg(priv, 0xC1, 0); - - ret = lgs8gxx_read_reg(priv, 0xC5, &t); - t = (t & 0xE0) | 0x06; - lgs8gxx_write_reg(priv, 0xC5, t); - - lgs8gxx_soft_reset(priv); - - return 0; -} - -static int lgs8gxx_is_locked(struct lgs8gxx_state *priv, u8 *locked) -{ - int ret = 0; - u8 t; - - ret = lgs8gxx_read_reg(priv, 0x4B, &t); - if (ret != 0) - return ret; - - *locked = ((t & 0xC0) == 0xC0) ? 1 : 0; - return 0; -} - -static int lgs8gxx_is_autodetect_finished(struct lgs8gxx_state *priv, - u8 *finished) -{ - int ret = 0; - u8 t; - - ret = lgs8gxx_read_reg(priv, 0xA4, &t); - if (ret != 0) - return ret; - - *finished = ((t & 0x3) == 0x1) ? 1 : 0; - - return 0; -} - -static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 *locked) -{ - int err; - u8 ad_fini = 0; - - if (gi == GI_945) - dprintk("try GI 945\n"); - else if (gi == GI_595) - dprintk("try GI 595\n"); - else if (gi == GI_420) - dprintk("try GI 420\n"); - lgs8gxx_write_reg(priv, 0x04, gi); - lgs8gxx_soft_reset(priv); - msleep(50); - err = lgs8gxx_is_autodetect_finished(priv, &ad_fini); - if (err != 0) - return err; - if (ad_fini) { - err = lgs8gxx_is_locked(priv, locked); - if (err != 0) - return err; - } - - return 0; -} - -static int lgs8gxx_auto_detect(struct lgs8gxx_state *priv, - u8 *detected_param, u8 *gi) -{ - int i, j; - int err = 0; - u8 locked = 0, tmp_gi; - - dprintk("%s\n", __func__); - - lgs8gxx_set_mode_auto(priv); - /* Guard Interval */ - lgs8gxx_write_reg(priv, 0x03, 00); - - for (i = 0; i < 2; i++) { - for (j = 0; j < 2; j++) { - tmp_gi = GI_945; - err = lgs8gxx_autolock_gi(priv, GI_945, &locked); - if (err) - goto out; - if (locked) - goto locked; - } - for (j = 0; j < 2; j++) { - tmp_gi = GI_420; - err = lgs8gxx_autolock_gi(priv, GI_420, &locked); - if (err) - goto out; - if (locked) - goto locked; - } - tmp_gi = GI_595; - err = lgs8gxx_autolock_gi(priv, GI_595, &locked); - if (err) - goto out; - if (locked) - goto locked; - } - -locked: - if ((err == 0) && (locked == 1)) { - u8 t; - - lgs8gxx_read_reg(priv, 0xA2, &t); - *detected_param = t; - - if (tmp_gi == GI_945) - dprintk("GI 945 locked\n"); - else if (tmp_gi == GI_595) - dprintk("GI 595 locked\n"); - else if (tmp_gi == GI_420) - dprintk("GI 420 locked\n"); - *gi = tmp_gi; - } - if (!locked) - err = -1; - -out: - return err; -} - -static void lgs8gxx_auto_lock(struct lgs8gxx_state *priv) -{ - s8 err; - u8 gi = 0x2; - u8 detected_param = 0; - - err = lgs8gxx_auto_detect(priv, &detected_param, &gi); - - if (err != 0) { - dprintk("lgs8gxx_auto_detect failed\n"); - } - - /* Apply detected parameters */ - if (priv->config->prod == LGS8GXX_PROD_LGS8913) { - u8 inter_leave_len = detected_param & TIM_MASK ; - inter_leave_len = (inter_leave_len == TIM_LONG) ? 0x60 : 0x40; - detected_param &= CF_MASK | SC_MASK | LGS_FEC_MASK; - detected_param |= inter_leave_len; - } - lgs8gxx_write_reg(priv, 0x7D, detected_param); - if (priv->config->prod == LGS8GXX_PROD_LGS8913) - lgs8gxx_write_reg(priv, 0xC0, detected_param); - /* lgs8gxx_soft_reset(priv); */ - - /* Enter manual mode */ - lgs8gxx_set_mode_manual(priv); - - switch (gi) { - case GI_945: - priv->curr_gi = 945; break; - case GI_595: - priv->curr_gi = 595; break; - case GI_420: - priv->curr_gi = 420; break; - default: - priv->curr_gi = 945; break; - } -} - -static int lgs8gxx_set_mpeg_mode(struct lgs8gxx_state *priv, - u8 serial, u8 clk_pol, u8 clk_gated) -{ - int ret = 0; - u8 t; - - ret = lgs8gxx_read_reg(priv, 0xC2, &t); - if (ret != 0) - return ret; - - t &= 0xF8; - t |= serial ? TS_SERIAL : TS_PARALLEL; - t |= clk_pol ? TS_CLK_INVERTED : TS_CLK_NORMAL; - t |= clk_gated ? TS_CLK_GATED : TS_CLK_FREERUN; - - ret = lgs8gxx_write_reg(priv, 0xC2, t); - if (ret != 0) - return ret; - - return 0; -} - - -/* LGS8913 demod frontend functions */ - -static int lgs8913_init(struct lgs8gxx_state *priv) -{ - u8 t; - - /* LGS8913 specific */ - lgs8gxx_write_reg(priv, 0xc1, 0x3); - - lgs8gxx_read_reg(priv, 0x7c, &t); - lgs8gxx_write_reg(priv, 0x7c, (t&0x8c) | 0x3); - - /* LGS8913 specific */ - lgs8gxx_read_reg(priv, 0xc3, &t); - lgs8gxx_write_reg(priv, 0xc3, t&0x10); - - - return 0; -} - -static int lgs8gxx_init(struct dvb_frontend *fe) -{ - struct lgs8gxx_state *priv = - (struct lgs8gxx_state *)fe->demodulator_priv; - const struct lgs8gxx_config *config = priv->config; - u8 data = 0; - s8 err; - dprintk("%s\n", __func__); - - lgs8gxx_read_reg(priv, 0, &data); - dprintk("reg 0 = 0x%02X\n", data); - - /* Setup MPEG output format */ - err = lgs8gxx_set_mpeg_mode(priv, config->serial_ts, - config->ts_clk_pol, - config->ts_clk_gated); - if (err != 0) - return -EIO; - - if (config->prod == LGS8GXX_PROD_LGS8913) - lgs8913_init(priv); - lgs8gxx_set_if_freq(priv, priv->config->if_freq); - if (config->prod != LGS8GXX_PROD_LGS8913) - lgs8gxx_set_ad_mode(priv); - - return 0; -} - -static void lgs8gxx_release(struct dvb_frontend *fe) -{ - struct lgs8gxx_state *state = fe->demodulator_priv; - dprintk("%s\n", __func__); - - kfree(state); -} - - -static int lgs8gxx_write(struct dvb_frontend *fe, u8 *buf, int len) -{ - struct lgs8gxx_state *priv = fe->demodulator_priv; - - if (len != 2) - return -EINVAL; - - return lgs8gxx_write_reg(priv, buf[0], buf[1]); -} - -static int lgs8gxx_set_fe(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fe_params) -{ - struct lgs8gxx_state *priv = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - /* set frequency */ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fe_params); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* start auto lock */ - lgs8gxx_auto_lock(priv); - - msleep(10); - - return 0; -} - -static int lgs8gxx_get_fe(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fe_params) -{ - struct lgs8gxx_state *priv = fe->demodulator_priv; - u8 t; - - dprintk("%s\n", __func__); - - /* TODO: get real readings from device */ - /* inversion status */ - fe_params->inversion = INVERSION_OFF; - - /* bandwidth */ - fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; - - - lgs8gxx_read_reg(priv, 0x7D, &t); - fe_params->u.ofdm.code_rate_HP = FEC_AUTO; - fe_params->u.ofdm.code_rate_LP = FEC_AUTO; - - /* constellation */ - switch (t & SC_MASK) { - case SC_QAM64: - fe_params->u.ofdm.constellation = QAM_64; - break; - case SC_QAM32: - fe_params->u.ofdm.constellation = QAM_32; - break; - case SC_QAM16: - fe_params->u.ofdm.constellation = QAM_16; - break; - case SC_QAM4: - case SC_QAM4NR: - fe_params->u.ofdm.constellation = QPSK; - break; - default: - fe_params->u.ofdm.constellation = QAM_64; - } - - /* transmission mode */ - fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; - - /* guard interval */ - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; - - /* hierarchy */ - fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE; - - return 0; -} - -static -int lgs8gxx_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *fesettings) -{ - /* FIXME: copy from tda1004x.c */ - fesettings->min_delay_ms = 800; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static int lgs8gxx_read_status(struct dvb_frontend *fe, fe_status_t *fe_status) -{ - struct lgs8gxx_state *priv = fe->demodulator_priv; - s8 ret; - u8 t; - - dprintk("%s\n", __func__); - - ret = lgs8gxx_read_reg(priv, 0x4B, &t); - if (ret != 0) - return -EIO; - - dprintk("Reg 0x4B: 0x%02X\n", t); - - *fe_status = 0; - if (priv->config->prod == LGS8GXX_PROD_LGS8913) { - if ((t & 0x40) == 0x40) - *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; - if ((t & 0x80) == 0x80) - *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | - FE_HAS_LOCK; - } else { - if ((t & 0x80) == 0x80) - *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - } - - /* success */ - dprintk("%s: fe_status=0x%x\n", __func__, *fe_status); - return 0; -} - -static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal) -{ - u16 v; - u8 agc_lvl[2], cat; - - dprintk("%s()\n", __func__); - lgs8gxx_read_reg(priv, 0x3F, &agc_lvl[0]); - lgs8gxx_read_reg(priv, 0x3E, &agc_lvl[1]); - - v = agc_lvl[0]; - v <<= 8; - v |= agc_lvl[1]; - - dprintk("agc_lvl: 0x%04X\n", v); - - if (v < 0x100) - cat = 0; - else if (v < 0x190) - cat = 5; - else if (v < 0x2A8) - cat = 4; - else if (v < 0x381) - cat = 3; - else if (v < 0x400) - cat = 2; - else if (v == 0x400) - cat = 1; - else - cat = 0; - - *signal = cat; - - return 0; -} - -static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal) -{ - u8 t; s8 ret; - s16 max_strength = 0; - u8 str; - u16 i, gi = priv->curr_gi; - - dprintk("%s\n", __func__); - - ret = lgs8gxx_read_reg(priv, 0x4B, &t); - if (ret != 0) - return -EIO; - - if (fake_signal_str) { - if ((t & 0xC0) == 0xC0) { - dprintk("Fake signal strength as 50\n"); - *signal = 0x32; - } else - *signal = 0; - return 0; - } - - dprintk("gi = %d\n", gi); - for (i = 0; i < gi; i++) { - - if ((i & 0xFF) == 0) - lgs8gxx_write_reg(priv, 0x84, 0x03 & (i >> 8)); - lgs8gxx_write_reg(priv, 0x83, i & 0xFF); - - lgs8gxx_read_reg(priv, 0x94, &str); - if (max_strength < str) - max_strength = str; - } - - *signal = max_strength; - dprintk("%s: signal=0x%02X\n", __func__, *signal); - - lgs8gxx_read_reg(priv, 0x95, &t); - dprintk("%s: AVG Noise=0x%02X\n", __func__, t); - - return 0; -} - -static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal) -{ - struct lgs8gxx_state *priv = fe->demodulator_priv; - - if (priv->config->prod == LGS8GXX_PROD_LGS8913) - return lgs8913_read_signal_strength(priv, signal); - else - return lgs8gxx_read_signal_agc(priv, signal); -} - -static int lgs8gxx_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct lgs8gxx_state *priv = fe->demodulator_priv; - u8 t; - *snr = 0; - - lgs8gxx_read_reg(priv, 0x95, &t); - dprintk("AVG Noise=0x%02X\n", t); - *snr = 256 - t; - *snr <<= 8; - dprintk("snr=0x%x\n", *snr); - - return 0; -} - -static int lgs8gxx_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - *ucblocks = 0; - dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks); - return 0; -} - -static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct lgs8gxx_state *priv = fe->demodulator_priv; - u8 r0, r1, r2, r3; - u32 total_cnt, err_cnt; - - dprintk("%s\n", __func__); - - lgs8gxx_write_reg(priv, 0xc6, 0x01); - lgs8gxx_write_reg(priv, 0xc6, 0x41); - lgs8gxx_write_reg(priv, 0xc6, 0x01); - - msleep(200); - - lgs8gxx_write_reg(priv, 0xc6, 0x81); - lgs8gxx_read_reg(priv, 0xd0, &r0); - lgs8gxx_read_reg(priv, 0xd1, &r1); - lgs8gxx_read_reg(priv, 0xd2, &r2); - lgs8gxx_read_reg(priv, 0xd3, &r3); - total_cnt = (r3 << 24) | (r2 << 16) | (r1 << 8) | (r0); - lgs8gxx_read_reg(priv, 0xd4, &r0); - lgs8gxx_read_reg(priv, 0xd5, &r1); - lgs8gxx_read_reg(priv, 0xd6, &r2); - lgs8gxx_read_reg(priv, 0xd7, &r3); - err_cnt = (r3 << 24) | (r2 << 16) | (r1 << 8) | (r0); - dprintk("error=%d total=%d\n", err_cnt, total_cnt); - - if (total_cnt == 0) - *ber = 0; - else - *ber = err_cnt * 100 / total_cnt; - - dprintk("%s: ber=0x%x\n", __func__, *ber); - return 0; -} - -static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct lgs8gxx_state *priv = fe->demodulator_priv; - - if (priv->config->tuner_address == 0) - return 0; - if (enable) { - u8 v = 0x80 | priv->config->tuner_address; - return lgs8gxx_write_reg(priv, 0x01, v); - } - return lgs8gxx_write_reg(priv, 0x01, 0); -} - -static struct dvb_frontend_ops lgs8gxx_ops = { - .info = { - .name = "Legend Silicon LGS8913/LGS8GXX DMB-TH", - .type = FE_OFDM, - .frequency_min = 474000000, - .frequency_max = 858000000, - .frequency_stepsize = 10000, - .caps = - FE_CAN_FEC_AUTO | - FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO - }, - - .release = lgs8gxx_release, - - .init = lgs8gxx_init, - .write = lgs8gxx_write, - .i2c_gate_ctrl = lgs8gxx_i2c_gate_ctrl, - - .set_frontend = lgs8gxx_set_fe, - .get_frontend = lgs8gxx_get_fe, - .get_tune_settings = lgs8gxx_get_tune_settings, - - .read_status = lgs8gxx_read_status, - .read_ber = lgs8gxx_read_ber, - .read_signal_strength = lgs8gxx_read_signal_strength, - .read_snr = lgs8gxx_read_snr, - .read_ucblocks = lgs8gxx_read_ucblocks, -}; - -struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config, - struct i2c_adapter *i2c) -{ - struct lgs8gxx_state *priv = NULL; - u8 data = 0; - - dprintk("%s()\n", __func__); - - if (config == NULL || i2c == NULL) - return NULL; - - priv = kzalloc(sizeof(struct lgs8gxx_state), GFP_KERNEL); - if (priv == NULL) - goto error_out; - - priv->config = config; - priv->i2c = i2c; - - /* check if the demod is there */ - if (lgs8gxx_read_reg(priv, 0, &data) != 0) { - dprintk("%s lgs8gxx not found at i2c addr 0x%02X\n", - __func__, priv->config->demod_address); - goto error_out; - } - - lgs8gxx_read_reg(priv, 1, &data); - - memcpy(&priv->frontend.ops, &lgs8gxx_ops, - sizeof(struct dvb_frontend_ops)); - priv->frontend.demodulator_priv = priv; - - return &priv->frontend; - -error_out: - dprintk("%s() error_out\n", __func__); - kfree(priv); - return NULL; - -} -EXPORT_SYMBOL(lgs8gxx_attach); - -MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver"); -MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/lgs8gxx.h b/drivers/media/dvb/frontends/lgs8gxx.h deleted file mode 100644 index 321d366a830..00000000000 --- a/drivers/media/dvb/frontends/lgs8gxx.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Support for Legend Silicon DMB-TH demodulator - * LGS8913, LGS8GL5 - * experimental support LGS8G42, LGS8G52 - * - * Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com> - * Copyright (C) 2008 Sirius International (Hong Kong) Limited - * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5) - * - * 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 __LGS8GXX_H__ -#define __LGS8GXX_H__ - -#include <linux/dvb/frontend.h> -#include <linux/i2c.h> - -#define LGS8GXX_PROD_LGS8913 0 -#define LGS8GXX_PROD_LGS8GL5 1 -#define LGS8GXX_PROD_LGS8G42 3 -#define LGS8GXX_PROD_LGS8G52 4 -#define LGS8GXX_PROD_LGS8G54 5 - -struct lgs8gxx_config { - - /* product type */ - u8 prod; - - /* the demodulator's i2c address */ - u8 demod_address; - - /* parallel or serial transport stream */ - u8 serial_ts; - - /* transport stream polarity*/ - u8 ts_clk_pol; - - /* transport stream clock gated by ts_valid */ - u8 ts_clk_gated; - - /* A/D Clock frequency */ - u32 if_clk_freq; /* in kHz */ - - /* IF frequency */ - u32 if_freq; /* in kHz */ - - /*Use External ADC*/ - u8 ext_adc; - - /*External ADC output two's complement*/ - u8 adc_signed; - - /*Sample IF data at falling edge of IF_CLK*/ - u8 if_neg_edge; - - /*IF use Negative center frequency*/ - u8 if_neg_center; - - /* slave address and configuration of the tuner */ - u8 tuner_address; -}; - -#if defined(CONFIG_DVB_LGS8GXX) || \ - (defined(CONFIG_DVB_LGS8GXX_MODULE) && defined(MODULE)) -extern struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config, - struct i2c_adapter *i2c); -#else -static inline -struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config, - struct i2c_adapter *i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_LGS8GXX */ - -#endif /* __LGS8GXX_H__ */ diff --git a/drivers/media/dvb/frontends/lgs8gxx_priv.h b/drivers/media/dvb/frontends/lgs8gxx_priv.h deleted file mode 100644 index 9776d30686d..00000000000 --- a/drivers/media/dvb/frontends/lgs8gxx_priv.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Support for Legend Silicon DMB-TH demodulator - * LGS8913, LGS8GL5 - * experimental support LGS8G42, LGS8G52 - * - * Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com> - * Copyright (C) 2008 Sirius International (Hong Kong) Limited - * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5) - * - * 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 LGS8913_PRIV_H -#define LGS8913_PRIV_H - -struct lgs8gxx_state { - struct i2c_adapter *i2c; - /* configuration settings */ - const struct lgs8gxx_config *config; - struct dvb_frontend frontend; - u16 curr_gi; /* current guard interval */ -}; - -#define SC_MASK 0x1C /* Sub-Carrier Modulation Mask */ -#define SC_QAM64 0x10 /* 64QAM modulation */ -#define SC_QAM32 0x0C /* 32QAM modulation */ -#define SC_QAM16 0x08 /* 16QAM modulation */ -#define SC_QAM4NR 0x04 /* 4QAM modulation */ -#define SC_QAM4 0x00 /* 4QAM modulation */ - -#define LGS_FEC_MASK 0x03 /* FEC Rate Mask */ -#define LGS_FEC_0_4 0x00 /* FEC Rate 0.4 */ -#define LGS_FEC_0_6 0x01 /* FEC Rate 0.6 */ -#define LGS_FEC_0_8 0x02 /* FEC Rate 0.8 */ - -#define TIM_MASK 0x20 /* Time Interleave Length Mask */ -#define TIM_LONG 0x00 /* Time Interleave Length = 720 */ -#define TIM_MIDDLE 0x20 /* Time Interleave Length = 240 */ - -#define CF_MASK 0x80 /* Control Frame Mask */ -#define CF_EN 0x80 /* Control Frame On */ - -#define GI_MASK 0x03 /* Guard Interval Mask */ -#define GI_420 0x00 /* 1/9 Guard Interval */ -#define GI_595 0x01 /* */ -#define GI_945 0x02 /* 1/4 Guard Interval */ - - -#define TS_PARALLEL 0x00 /* Parallel TS Output a.k.a. SPI */ -#define TS_SERIAL 0x01 /* Serial TS Output a.k.a. SSI */ -#define TS_CLK_NORMAL 0x00 /* MPEG Clock Normal */ -#define TS_CLK_INVERTED 0x02 /* MPEG Clock Inverted */ -#define TS_CLK_GATED 0x00 /* MPEG clock gated */ -#define TS_CLK_FREERUN 0x04 /* MPEG clock free running*/ - - -#endif diff --git a/drivers/media/dvb/frontends/lnbh24.h b/drivers/media/dvb/frontends/lnbh24.h deleted file mode 100644 index c059b165318..00000000000 --- a/drivers/media/dvb/frontends/lnbh24.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * lnbh24.h - driver for lnb supply and control ic lnbh24 - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> - * - * 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 <linux/dvb/frontend.h> - -#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 deleted file mode 100644 index 1dcc56f32bf..00000000000 --- a/drivers/media/dvb/frontends/lnbp21.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * lnbp21.c - driver for lnb supply and control ic lnbp21 - * - * Copyright (C) 2006 Oliver Endriss - * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#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) -{ - struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv; - struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0, - .buf = &lnbp21->config, - .len = sizeof(lnbp21->config) }; - - lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN); - - switch(voltage) { - case SEC_VOLTAGE_OFF: - break; - case SEC_VOLTAGE_13: - lnbp21->config |= LNBP21_EN; - break; - case SEC_VOLTAGE_18: - lnbp21->config |= (LNBP21_EN | LNBP21_VSEL); - break; - default: - return -EINVAL; - }; - - lnbp21->config |= lnbp21->override_or; - lnbp21->config &= lnbp21->override_and; - - return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -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 = lnbp21->i2c_addr, .flags = 0, - .buf = &lnbp21->config, - .len = sizeof(lnbp21->config) }; - - if (arg) - lnbp21->config |= LNBP21_LLC; - else - lnbp21->config &= ~LNBP21_LLC; - - lnbp21->config |= lnbp21->override_or; - lnbp21->config &= lnbp21->override_and; - - return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static void lnbp21_release(struct dvb_frontend *fe) -{ - /* LNBP power off */ - lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); - - /* free data */ - kfree(fe->sec_priv); - fe->sec_priv = NULL; -} - -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 = config; - lnbp21->i2c = i2c; - lnbp21->i2c_addr = i2c_addr; - fe->sec_priv = lnbp21; - - /* bits which should be forced to '1' */ - lnbp21->override_or = override_set; - - /* bits which should be forced to '0' */ - lnbp21->override_and = ~override_clear; - - /* detect if it is present or not */ - if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) { - kfree(lnbp21); - return NULL; - } - - /* install release callback */ - fe->ops.release_sec = lnbp21_release; - - /* 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 *lnbh24_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, 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 deleted file mode 100644 index fcdf1c650dd..00000000000 --- a/drivers/media/dvb/frontends/lnbp21.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * lnbp21.h - driver for lnb supply and control ic lnbp21 - * - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef _LNBP21_H -#define _LNBP21_H - -/* system register bits */ -/* [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 <linux/dvb/frontend.h> - -#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) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c deleted file mode 100644 index 5ac9b15920f..00000000000 --- a/drivers/media/dvb/frontends/mt312.c +++ /dev/null @@ -1,839 +0,0 @@ -/* - Driver for Zarlink VP310/MT312/ZL10313 Satellite Channel Decoder - - Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org> - Copyright (C) 2008 Matthias Schwarzott <zzam@gentoo.org> - - 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. - - References: - http://products.zarlink.com/product_profiles/MT312.htm - http://products.zarlink.com/product_profiles/SL1935.htm -*/ - -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "mt312_priv.h" -#include "mt312.h" - - -struct mt312_state { - struct i2c_adapter *i2c; - /* configuration settings */ - const struct mt312_config *config; - struct dvb_frontend frontend; - - u8 id; - unsigned long xtal; - u8 freq_mult; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "mt312: " args); \ - } while (0) - -#define MT312_PLL_CLK 10000000UL /* 10 MHz */ -#define MT312_PLL_CLK_10_111 10111000UL /* 10.111 MHz */ - -static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg, - u8 *buf, const size_t count) -{ - int ret; - struct i2c_msg msg[2]; - u8 regbuf[1] = { reg }; - - msg[0].addr = state->config->demod_address; - msg[0].flags = 0; - msg[0].buf = regbuf; - msg[0].len = 1; - msg[1].addr = state->config->demod_address; - msg[1].flags = I2C_M_RD; - msg[1].buf = buf; - msg[1].len = count; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - printk(KERN_ERR "%s: ret == %d\n", __func__, ret); - return -EREMOTEIO; - } - - if (debug) { - int i; - dprintk("R(%d):", reg & 0x7f); - for (i = 0; i < count; i++) - printk(" %02x", buf[i]); - printk("\n"); - } - - return 0; -} - -static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg, - const u8 *src, const size_t count) -{ - int ret; - u8 buf[count + 1]; - struct i2c_msg msg; - - if (debug) { - int i; - dprintk("W(%d):", reg & 0x7f); - for (i = 0; i < count; i++) - printk(" %02x", src[i]); - printk("\n"); - } - - buf[0] = reg; - memcpy(&buf[1], src, count); - - msg.addr = state->config->demod_address; - msg.flags = 0; - msg.buf = buf; - msg.len = count + 1; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) { - dprintk("%s: ret == %d\n", __func__, ret); - return -EREMOTEIO; - } - - return 0; -} - -static inline int mt312_readreg(struct mt312_state *state, - const enum mt312_reg_addr reg, u8 *val) -{ - return mt312_read(state, reg, val, 1); -} - -static inline int mt312_writereg(struct mt312_state *state, - const enum mt312_reg_addr reg, const u8 val) -{ - return mt312_write(state, reg, &val, 1); -} - -static inline u32 mt312_div(u32 a, u32 b) -{ - return (a + (b / 2)) / b; -} - -static int mt312_reset(struct mt312_state *state, const u8 full) -{ - return mt312_writereg(state, RESET, full ? 0x80 : 0x40); -} - -static int mt312_get_inversion(struct mt312_state *state, - fe_spectral_inversion_t *i) -{ - int ret; - u8 vit_mode; - - ret = mt312_readreg(state, VIT_MODE, &vit_mode); - if (ret < 0) - return ret; - - if (vit_mode & 0x80) /* auto inversion was used */ - *i = (vit_mode & 0x40) ? INVERSION_ON : INVERSION_OFF; - - return 0; -} - -static int mt312_get_symbol_rate(struct mt312_state *state, u32 *sr) -{ - int ret; - u8 sym_rate_h; - u8 dec_ratio; - u16 sym_rat_op; - u16 monitor; - u8 buf[2]; - - ret = mt312_readreg(state, SYM_RATE_H, &sym_rate_h); - if (ret < 0) - return ret; - - if (sym_rate_h & 0x80) { - /* symbol rate search was used */ - ret = mt312_writereg(state, MON_CTRL, 0x03); - if (ret < 0) - return ret; - - ret = mt312_read(state, MONITOR_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - monitor = (buf[0] << 8) | buf[1]; - - dprintk("sr(auto) = %u\n", - mt312_div(monitor * 15625, 4)); - } else { - ret = mt312_writereg(state, MON_CTRL, 0x05); - if (ret < 0) - return ret; - - ret = mt312_read(state, MONITOR_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - dec_ratio = ((buf[0] >> 5) & 0x07) * 32; - - ret = mt312_read(state, SYM_RAT_OP_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - sym_rat_op = (buf[0] << 8) | buf[1]; - - dprintk("sym_rat_op=%d dec_ratio=%d\n", - sym_rat_op, dec_ratio); - dprintk("*sr(manual) = %lu\n", - (((state->xtal * 8192) / (sym_rat_op + 8192)) * - 2) - dec_ratio); - } - - return 0; -} - -static int mt312_get_code_rate(struct mt312_state *state, fe_code_rate_t *cr) -{ - const fe_code_rate_t fec_tab[8] = - { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8, - FEC_AUTO, FEC_AUTO }; - - int ret; - u8 fec_status; - - ret = mt312_readreg(state, FEC_STATUS, &fec_status); - if (ret < 0) - return ret; - - *cr = fec_tab[(fec_status >> 4) & 0x07]; - - return 0; -} - -static int mt312_initfe(struct dvb_frontend *fe) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 buf[2]; - - /* wake up */ - ret = mt312_writereg(state, CONFIG, - (state->freq_mult == 6 ? 0x88 : 0x8c)); - if (ret < 0) - return ret; - - /* wait at least 150 usec */ - udelay(150); - - /* full reset */ - ret = mt312_reset(state, 1); - if (ret < 0) - return ret; - -/* Per datasheet, write correct values. 09/28/03 ACCJr. - * If we don't do this, we won't get FE_HAS_VITERBI in the VP310. */ - { - u8 buf_def[8] = { 0x14, 0x12, 0x03, 0x02, - 0x01, 0x00, 0x00, 0x00 }; - - ret = mt312_write(state, VIT_SETUP, buf_def, sizeof(buf_def)); - if (ret < 0) - return ret; - } - - switch (state->id) { - case ID_ZL10313: - /* enable ADC */ - ret = mt312_writereg(state, GPP_CTRL, 0x80); - if (ret < 0) - return ret; - - /* configure ZL10313 for optimal ADC performance */ - buf[0] = 0x80; - buf[1] = 0xB0; - ret = mt312_write(state, HW_CTRL, buf, 2); - if (ret < 0) - return ret; - - /* enable MPEG output and ADCs */ - ret = mt312_writereg(state, HW_CTRL, 0x00); - if (ret < 0) - return ret; - - ret = mt312_writereg(state, MPEG_CTRL, 0x00); - if (ret < 0) - return ret; - - break; - } - - /* SYS_CLK */ - buf[0] = mt312_div(state->xtal * state->freq_mult * 2, 1000000); - - /* DISEQC_RATIO */ - buf[1] = mt312_div(state->xtal, 22000 * 4); - - ret = mt312_write(state, SYS_CLK, buf, sizeof(buf)); - if (ret < 0) - return ret; - - ret = mt312_writereg(state, SNR_THS_HIGH, 0x32); - if (ret < 0) - return ret; - - /* different MOCLK polarity */ - switch (state->id) { - case ID_ZL10313: - buf[0] = 0x33; - break; - default: - buf[0] = 0x53; - break; - } - - ret = mt312_writereg(state, OP_CTRL, buf[0]); - if (ret < 0) - return ret; - - /* TS_SW_LIM */ - buf[0] = 0x8c; - buf[1] = 0x98; - - ret = mt312_write(state, TS_SW_LIM_L, buf, sizeof(buf)); - if (ret < 0) - return ret; - - ret = mt312_writereg(state, CS_SW_LIM, 0x69); - if (ret < 0) - return ret; - - return 0; -} - -static int mt312_send_master_cmd(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *c) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 diseqc_mode; - - if ((c->msg_len == 0) || (c->msg_len > sizeof(c->msg))) - return -EINVAL; - - ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode); - if (ret < 0) - return ret; - - ret = mt312_write(state, (0x80 | DISEQC_INSTR), c->msg, c->msg_len); - if (ret < 0) - return ret; - - ret = mt312_writereg(state, DISEQC_MODE, - (diseqc_mode & 0x40) | ((c->msg_len - 1) << 3) - | 0x04); - if (ret < 0) - return ret; - - /* is there a better way to wait for message to be transmitted */ - msleep(100); - - /* set DISEQC_MODE[2:0] to zero if a return message is expected */ - if (c->msg[0] & 0x02) { - ret = mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40)); - if (ret < 0) - return ret; - } - - return 0; -} - -static int mt312_send_burst(struct dvb_frontend *fe, const fe_sec_mini_cmd_t c) -{ - struct mt312_state *state = fe->demodulator_priv; - const u8 mini_tab[2] = { 0x02, 0x03 }; - - int ret; - u8 diseqc_mode; - - if (c > SEC_MINI_B) - return -EINVAL; - - ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode); - if (ret < 0) - return ret; - - ret = mt312_writereg(state, DISEQC_MODE, - (diseqc_mode & 0x40) | mini_tab[c]); - if (ret < 0) - return ret; - - return 0; -} - -static int mt312_set_tone(struct dvb_frontend *fe, const fe_sec_tone_mode_t t) -{ - struct mt312_state *state = fe->demodulator_priv; - const u8 tone_tab[2] = { 0x01, 0x00 }; - - int ret; - u8 diseqc_mode; - - if (t > SEC_TONE_OFF) - return -EINVAL; - - ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode); - if (ret < 0) - return ret; - - ret = mt312_writereg(state, DISEQC_MODE, - (diseqc_mode & 0x40) | tone_tab[t]); - if (ret < 0) - return ret; - - return 0; -} - -static int mt312_set_voltage(struct dvb_frontend *fe, const fe_sec_voltage_t v) -{ - struct mt312_state *state = fe->demodulator_priv; - const u8 volt_tab[3] = { 0x00, 0x40, 0x00 }; - u8 val; - - if (v > SEC_VOLTAGE_OFF) - return -EINVAL; - - val = volt_tab[v]; - if (state->config->voltage_inverted) - val ^= 0x40; - - return mt312_writereg(state, DISEQC_MODE, val); -} - -static int mt312_read_status(struct dvb_frontend *fe, fe_status_t *s) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 status[3]; - - *s = 0; - - ret = mt312_read(state, QPSK_STAT_H, status, sizeof(status)); - if (ret < 0) - return ret; - - dprintk("QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x," - " FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]); - - if (status[0] & 0xc0) - *s |= FE_HAS_SIGNAL; /* signal noise ratio */ - if (status[0] & 0x04) - *s |= FE_HAS_CARRIER; /* qpsk carrier lock */ - if (status[2] & 0x02) - *s |= FE_HAS_VITERBI; /* viterbi lock */ - if (status[2] & 0x04) - *s |= FE_HAS_SYNC; /* byte align lock */ - if (status[0] & 0x01) - *s |= FE_HAS_LOCK; /* qpsk lock */ - - return 0; -} - -static int mt312_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 buf[3]; - - ret = mt312_read(state, RS_BERCNT_H, buf, 3); - if (ret < 0) - return ret; - - *ber = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) * 64; - - return 0; -} - -static int mt312_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 buf[3]; - u16 agc; - s16 err_db; - - ret = mt312_read(state, AGC_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - agc = (buf[0] << 6) | (buf[1] >> 2); - err_db = (s16) (((buf[1] & 0x03) << 14) | buf[2] << 6) >> 6; - - *signal_strength = agc; - - dprintk("agc=%08x err_db=%hd\n", agc, err_db); - - return 0; -} - -static int mt312_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 buf[2]; - - ret = mt312_read(state, M_SNR_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - *snr = 0xFFFF - ((((buf[0] & 0x7f) << 8) | buf[1]) << 1); - - return 0; -} - -static int mt312_read_ucblocks(struct dvb_frontend *fe, u32 *ubc) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 buf[2]; - - ret = mt312_read(state, RS_UBC_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - *ubc = (buf[0] << 8) | buf[1]; - - return 0; -} - -static int mt312_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 buf[5], config_val; - u16 sr; - - const u8 fec_tab[10] = - { 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f }; - const u8 inv_tab[3] = { 0x00, 0x40, 0x80 }; - - dprintk("%s: Freq %d\n", __func__, p->frequency); - - if ((p->frequency < fe->ops.info.frequency_min) - || (p->frequency > fe->ops.info.frequency_max)) - return -EINVAL; - - if ((p->inversion < INVERSION_OFF) - || (p->inversion > INVERSION_ON)) - return -EINVAL; - - if ((p->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) - || (p->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) - return -EINVAL; - - if ((p->u.qpsk.fec_inner < FEC_NONE) - || (p->u.qpsk.fec_inner > FEC_AUTO)) - return -EINVAL; - - if ((p->u.qpsk.fec_inner == FEC_4_5) - || (p->u.qpsk.fec_inner == FEC_8_9)) - return -EINVAL; - - switch (state->id) { - case ID_VP310: - /* For now we will do this only for the VP310. - * It should be better for the mt312 as well, - * but tuning will be slower. ACCJr 09/29/03 - */ - ret = mt312_readreg(state, CONFIG, &config_val); - if (ret < 0) - return ret; - if (p->u.qpsk.symbol_rate >= 30000000) { - /* Note that 30MS/s should use 90MHz */ - if (state->freq_mult == 6) { - /* We are running 60MHz */ - state->freq_mult = 9; - ret = mt312_initfe(fe); - if (ret < 0) - return ret; - } - } else { - if (state->freq_mult == 9) { - /* We are running 90MHz */ - state->freq_mult = 6; - ret = mt312_initfe(fe); - if (ret < 0) - return ret; - } - } - break; - - case ID_MT312: - case ID_ZL10313: - break; - - default: - return -EINVAL; - } - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* sr = (u16)(sr * 256.0 / 1000000.0) */ - sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625); - - /* SYM_RATE */ - buf[0] = (sr >> 8) & 0x3f; - buf[1] = (sr >> 0) & 0xff; - - /* VIT_MODE */ - buf[2] = inv_tab[p->inversion] | fec_tab[p->u.qpsk.fec_inner]; - - /* QPSK_CTRL */ - buf[3] = 0x40; /* swap I and Q before QPSK demodulation */ - - if (p->u.qpsk.symbol_rate < 10000000) - buf[3] |= 0x04; /* use afc mode */ - - /* GO */ - buf[4] = 0x01; - - ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - mt312_reset(state, 0); - - return 0; -} - -static int mt312_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - - ret = mt312_get_inversion(state, &p->inversion); - if (ret < 0) - return ret; - - ret = mt312_get_symbol_rate(state, &p->u.qpsk.symbol_rate); - if (ret < 0) - return ret; - - ret = mt312_get_code_rate(state, &p->u.qpsk.fec_inner); - if (ret < 0) - return ret; - - return 0; -} - -static int mt312_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct mt312_state *state = fe->demodulator_priv; - - u8 val = 0x00; - int ret; - - switch (state->id) { - case ID_ZL10313: - ret = mt312_readreg(state, GPP_CTRL, &val); - if (ret < 0) - goto error; - - /* preserve this bit to not accidently shutdown ADC */ - val &= 0x80; - break; - } - - if (enable) - val |= 0x40; - else - val &= ~0x40; - - ret = mt312_writereg(state, GPP_CTRL, val); - -error: - return ret; -} - -static int mt312_sleep(struct dvb_frontend *fe) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 config; - - /* reset all registers to defaults */ - ret = mt312_reset(state, 1); - if (ret < 0) - return ret; - - if (state->id == ID_ZL10313) { - /* reset ADC */ - ret = mt312_writereg(state, GPP_CTRL, 0x00); - if (ret < 0) - return ret; - - /* full shutdown of ADCs, mpeg bus tristated */ - ret = mt312_writereg(state, HW_CTRL, 0x0d); - if (ret < 0) - return ret; - } - - ret = mt312_readreg(state, CONFIG, &config); - if (ret < 0) - return ret; - - /* enter standby */ - ret = mt312_writereg(state, CONFIG, config & 0x7f); - if (ret < 0) - return ret; - - return 0; -} - -static int mt312_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *fesettings) -{ - fesettings->min_delay_ms = 50; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static void mt312_release(struct dvb_frontend *fe) -{ - struct mt312_state *state = fe->demodulator_priv; - kfree(state); -} - -#define MT312_SYS_CLK 90000000UL /* 90 MHz */ -static struct dvb_frontend_ops mt312_ops = { - - .info = { - .name = "Zarlink ???? DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128, /* FIXME: adjust freq to real used xtal */ - .symbol_rate_min = MT312_SYS_CLK / 128, /* FIXME as above */ - .symbol_rate_max = MT312_SYS_CLK / 2, - .caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_MUTE_TS | - FE_CAN_RECOVER - }, - - .release = mt312_release, - - .init = mt312_initfe, - .sleep = mt312_sleep, - .i2c_gate_ctrl = mt312_i2c_gate_ctrl, - - .set_frontend = mt312_set_frontend, - .get_frontend = mt312_get_frontend, - .get_tune_settings = mt312_get_tune_settings, - - .read_status = mt312_read_status, - .read_ber = mt312_read_ber, - .read_signal_strength = mt312_read_signal_strength, - .read_snr = mt312_read_snr, - .read_ucblocks = mt312_read_ucblocks, - - .diseqc_send_master_cmd = mt312_send_master_cmd, - .diseqc_send_burst = mt312_send_burst, - .set_tone = mt312_set_tone, - .set_voltage = mt312_set_voltage, -}; - -struct dvb_frontend *mt312_attach(const struct mt312_config *config, - struct i2c_adapter *i2c) -{ - struct mt312_state *state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* check if the demod is there */ - if (mt312_readreg(state, ID, &state->id) < 0) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &mt312_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - switch (state->id) { - case ID_VP310: - strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S"); - state->xtal = MT312_PLL_CLK; - state->freq_mult = 9; - break; - case ID_MT312: - strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S"); - state->xtal = MT312_PLL_CLK; - state->freq_mult = 6; - break; - case ID_ZL10313: - strcpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S"); - state->xtal = MT312_PLL_CLK_10_111; - state->freq_mult = 9; - break; - default: - printk(KERN_WARNING "Only Zarlink VP310/MT312/ZL10313" - " are supported chips.\n"); - goto error; - } - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(mt312_attach); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver"); -MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>"); -MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h deleted file mode 100644 index 29e3bb5496b..00000000000 --- a/drivers/media/dvb/frontends/mt312.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Driver for Zarlink MT312 Satellite Channel Decoder - - Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org> - - 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. - - References: - http://products.zarlink.com/product_profiles/MT312.htm - http://products.zarlink.com/product_profiles/SL1935.htm -*/ - -#ifndef MT312_H -#define MT312_H - -#include <linux/dvb/frontend.h> - -struct mt312_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* inverted voltage setting */ - unsigned int voltage_inverted:1; -}; - -#if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE)) -struct dvb_frontend *mt312_attach(const struct mt312_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *mt312_attach( - const struct mt312_config *config, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_MT312 */ - -#endif /* MT312_H */ diff --git a/drivers/media/dvb/frontends/mt312_priv.h b/drivers/media/dvb/frontends/mt312_priv.h deleted file mode 100644 index a3959f94d63..00000000000 --- a/drivers/media/dvb/frontends/mt312_priv.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - Driver for Zarlink MT312 QPSK Frontend - - Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org> - - 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_FRONTENDS_MT312_PRIV -#define _DVB_FRONTENDS_MT312_PRIV - -enum mt312_reg_addr { - QPSK_INT_H = 0, - QPSK_INT_M = 1, - QPSK_INT_L = 2, - FEC_INT = 3, - QPSK_STAT_H = 4, - QPSK_STAT_L = 5, - FEC_STATUS = 6, - LNB_FREQ_H = 7, - LNB_FREQ_L = 8, - M_SNR_H = 9, - M_SNR_L = 10, - VIT_ERRCNT_H = 11, - VIT_ERRCNT_M = 12, - VIT_ERRCNT_L = 13, - RS_BERCNT_H = 14, - RS_BERCNT_M = 15, - RS_BERCNT_L = 16, - RS_UBC_H = 17, - RS_UBC_L = 18, - SIG_LEVEL = 19, - GPP_CTRL = 20, - RESET = 21, - DISEQC_MODE = 22, - SYM_RATE_H = 23, - SYM_RATE_L = 24, - VIT_MODE = 25, - QPSK_CTRL = 26, - GO = 27, - IE_QPSK_H = 28, - IE_QPSK_M = 29, - IE_QPSK_L = 30, - IE_FEC = 31, - QPSK_STAT_EN = 32, - FEC_STAT_EN = 33, - SYS_CLK = 34, - DISEQC_RATIO = 35, - DISEQC_INSTR = 36, - FR_LIM = 37, - FR_OFF = 38, - AGC_CTRL = 39, - AGC_INIT = 40, - AGC_REF = 41, - AGC_MAX = 42, - AGC_MIN = 43, - AGC_LK_TH = 44, - TS_AGC_LK_TH = 45, - AGC_PWR_SET = 46, - QPSK_MISC = 47, - SNR_THS_LOW = 48, - SNR_THS_HIGH = 49, - TS_SW_RATE = 50, - TS_SW_LIM_L = 51, - TS_SW_LIM_H = 52, - CS_SW_RATE_1 = 53, - CS_SW_RATE_2 = 54, - CS_SW_RATE_3 = 55, - CS_SW_RATE_4 = 56, - CS_SW_LIM = 57, - TS_LPK = 58, - TS_LPK_M = 59, - TS_LPK_L = 60, - CS_KPROP_H = 61, - CS_KPROP_L = 62, - CS_KINT_H = 63, - CS_KINT_L = 64, - QPSK_SCALE = 65, - TLD_OUTCLK_TH = 66, - TLD_INCLK_TH = 67, - FLD_TH = 68, - PLD_OUTLK3 = 69, - PLD_OUTLK2 = 70, - PLD_OUTLK1 = 71, - PLD_OUTLK0 = 72, - PLD_INLK3 = 73, - PLD_INLK2 = 74, - PLD_INLK1 = 75, - PLD_INLK0 = 76, - PLD_ACC_TIME = 77, - SWEEP_PAR = 78, - STARTUP_TIME = 79, - LOSSLOCK_TH = 80, - FEC_LOCK_TM = 81, - LOSSLOCK_TM = 82, - VIT_ERRPER_H = 83, - VIT_ERRPER_M = 84, - VIT_ERRPER_L = 85, - HW_CTRL = 84, /* ZL10313 only */ - MPEG_CTRL = 85, /* ZL10313 only */ - VIT_SETUP = 86, - VIT_REF0 = 87, - VIT_REF1 = 88, - VIT_REF2 = 89, - VIT_REF3 = 90, - VIT_REF4 = 91, - VIT_REF5 = 92, - VIT_REF6 = 93, - VIT_MAXERR = 94, - BA_SETUPT = 95, - OP_CTRL = 96, - FEC_SETUP = 97, - PROG_SYNC = 98, - AFC_SEAR_TH = 99, - CSACC_DIF_TH = 100, - QPSK_LK_CT = 101, - QPSK_ST_CT = 102, - MON_CTRL = 103, - QPSK_RESET = 104, - QPSK_TST_CT = 105, - QPSK_TST_ST = 106, - TEST_R = 107, - AGC_H = 108, - AGC_M = 109, - AGC_L = 110, - FREQ_ERR1_H = 111, - FREQ_ERR1_M = 112, - FREQ_ERR1_L = 113, - FREQ_ERR2_H = 114, - FREQ_ERR2_L = 115, - SYM_RAT_OP_H = 116, - SYM_RAT_OP_L = 117, - DESEQC2_INT = 118, - DISEQC2_STAT = 119, - DISEQC2_FIFO = 120, - DISEQC2_CTRL1 = 121, - DISEQC2_CTRL2 = 122, - MONITOR_H = 123, - MONITOR_L = 124, - TEST_MODE = 125, - ID = 126, - CONFIG = 127 -}; - -enum mt312_model_id { - ID_VP310 = 1, - ID_MT312 = 3, - ID_ZL10313 = 5, -}; - -#endif /* DVB_FRONTENDS_MT312_PRIV */ diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c deleted file mode 100644 index beba5aa0db5..00000000000 --- a/drivers/media/dvb/frontends/mt352.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Driver for Zarlink DVB-T MT352 demodulator - * - * Written by Holger Waechtler <holger@qanu.de> - * and Daniel Mack <daniel@qanu.de> - * - * AVerMedia AVerTV DVB-T 771 support by - * Wolfram Joost <dbox2@frokaschwei.de> - * - * Support for Samsung TDTC9251DH01C(M) tuner - * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it> - * Amauri Celani <acelani@essegi.net> - * - * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by - * Christopher Pascoe <c.pascoe@itee.uq.edu.au> - * - * 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 <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "mt352_priv.h" -#include "mt352.h" - -struct mt352_state { - struct i2c_adapter* i2c; - struct dvb_frontend frontend; - - /* configuration settings */ - struct mt352_config config; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "mt352: " args); \ - } while (0) - -static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val) -{ - struct mt352_state* state = fe->demodulator_priv; - u8 buf[2] = { reg, val }; - struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0, - .buf = buf, .len = 2 }; - int err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - printk("mt352_write() to reg %x failed (err = %d)!\n", reg, err); - return err; - } - return 0; -} - -static int _mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen) -{ - int err,i; - for (i=0; i < ilen-1; i++) - if ((err = mt352_single_write(fe,ibuf[0]+i,ibuf[i+1]))) - return err; - - return 0; -} - -static int mt352_read_register(struct mt352_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config.demod_address, - .flags = 0, - .buf = b0, .len = 1 }, - { .addr = state->config.demod_address, - .flags = I2C_M_RD, - .buf = b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - printk("%s: readreg error (reg=%d, ret==%i)\n", - __func__, reg, ret); - return ret; - } - - return b1[0]; -} - -static int mt352_sleep(struct dvb_frontend* fe) -{ - static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 }; - - _mt352_write(fe, mt352_softdown, sizeof(mt352_softdown)); - return 0; -} - -static void mt352_calc_nominal_rate(struct mt352_state* state, - enum fe_bandwidth bandwidth, - unsigned char *buf) -{ - u32 adc_clock = 20480; /* 20.340 MHz */ - u32 bw,value; - - switch (bandwidth) { - case BANDWIDTH_6_MHZ: - bw = 6; - break; - case BANDWIDTH_7_MHZ: - bw = 7; - break; - case BANDWIDTH_8_MHZ: - default: - bw = 8; - break; - } - if (state->config.adc_clock) - adc_clock = state->config.adc_clock; - - value = 64 * bw * (1<<16) / (7 * 8); - value = value * 1000 / adc_clock; - dprintk("%s: bw %d, adc_clock %d => 0x%x\n", - __func__, bw, adc_clock, value); - buf[0] = msb(value); - buf[1] = lsb(value); -} - -static void mt352_calc_input_freq(struct mt352_state* state, - unsigned char *buf) -{ - int adc_clock = 20480; /* 20.480000 MHz */ - int if2 = 36167; /* 36.166667 MHz */ - int ife,value; - - if (state->config.adc_clock) - adc_clock = state->config.adc_clock; - if (state->config.if2) - if2 = state->config.if2; - - if (adc_clock >= if2 * 2) - ife = if2; - else { - ife = adc_clock - (if2 % adc_clock); - if (ife > adc_clock / 2) - ife = adc_clock - ife; - } - value = -16374 * ife / adc_clock; - dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n", - __func__, if2, ife, adc_clock, value, value & 0x3fff); - buf[0] = msb(value); - buf[1] = lsb(value); -} - -static int mt352_set_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) -{ - struct mt352_state* state = fe->demodulator_priv; - unsigned char buf[13]; - static unsigned char tuner_go[] = { 0x5d, 0x01 }; - static unsigned char fsm_go[] = { 0x5e, 0x01 }; - unsigned int tps = 0; - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; - - switch (op->code_rate_HP) { - case FEC_2_3: - tps |= (1 << 7); - break; - case FEC_3_4: - tps |= (2 << 7); - break; - case FEC_5_6: - tps |= (3 << 7); - break; - case FEC_7_8: - tps |= (4 << 7); - break; - case FEC_1_2: - case FEC_AUTO: - break; - default: - return -EINVAL; - } - - switch (op->code_rate_LP) { - case FEC_2_3: - tps |= (1 << 4); - break; - case FEC_3_4: - tps |= (2 << 4); - break; - case FEC_5_6: - tps |= (3 << 4); - break; - case FEC_7_8: - tps |= (4 << 4); - break; - case FEC_1_2: - case FEC_AUTO: - break; - case FEC_NONE: - if (op->hierarchy_information == HIERARCHY_AUTO || - op->hierarchy_information == HIERARCHY_NONE) - break; - default: - return -EINVAL; - } - - switch (op->constellation) { - case QPSK: - break; - case QAM_AUTO: - case QAM_16: - tps |= (1 << 13); - break; - case QAM_64: - tps |= (2 << 13); - break; - default: - return -EINVAL; - } - - switch (op->transmission_mode) { - case TRANSMISSION_MODE_2K: - case TRANSMISSION_MODE_AUTO: - break; - case TRANSMISSION_MODE_8K: - tps |= (1 << 0); - break; - default: - return -EINVAL; - } - - switch (op->guard_interval) { - case GUARD_INTERVAL_1_32: - case GUARD_INTERVAL_AUTO: - break; - case GUARD_INTERVAL_1_16: - tps |= (1 << 2); - break; - case GUARD_INTERVAL_1_8: - tps |= (2 << 2); - break; - case GUARD_INTERVAL_1_4: - tps |= (3 << 2); - break; - default: - return -EINVAL; - } - - switch (op->hierarchy_information) { - case HIERARCHY_AUTO: - case HIERARCHY_NONE: - break; - case HIERARCHY_1: - tps |= (1 << 10); - break; - case HIERARCHY_2: - tps |= (2 << 10); - break; - case HIERARCHY_4: - tps |= (3 << 10); - break; - default: - return -EINVAL; - } - - - buf[0] = TPS_GIVEN_1; /* TPS_GIVEN_1 and following registers */ - - buf[1] = msb(tps); /* TPS_GIVEN_(1|0) */ - buf[2] = lsb(tps); - - buf[3] = 0x50; // old -// buf[3] = 0xf4; // pinnacle - - mt352_calc_nominal_rate(state, op->bandwidth, buf+4); - mt352_calc_input_freq(state, buf+6); - - if (state->config.no_tuner) { - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - _mt352_write(fe, buf, 8); - _mt352_write(fe, fsm_go, 2); - } else { - if (fe->ops.tuner_ops.calc_regs) { - fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5); - buf[8] <<= 1; - _mt352_write(fe, buf, sizeof(buf)); - _mt352_write(fe, tuner_go, 2); - } - } - - return 0; -} - -static int mt352_get_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) -{ - struct mt352_state* state = fe->demodulator_priv; - u16 tps; - u16 div; - u8 trl; - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; - static const u8 tps_fec_to_api[8] = - { - FEC_1_2, - FEC_2_3, - FEC_3_4, - FEC_5_6, - FEC_7_8, - FEC_AUTO, - FEC_AUTO, - FEC_AUTO - }; - - if ( (mt352_read_register(state,0x00) & 0xC0) != 0xC0 ) - return -EINVAL; - - /* Use TPS_RECEIVED-registers, not the TPS_CURRENT-registers because - * the mt352 sometimes works with the wrong parameters - */ - tps = (mt352_read_register(state, TPS_RECEIVED_1) << 8) | mt352_read_register(state, TPS_RECEIVED_0); - div = (mt352_read_register(state, CHAN_START_1) << 8) | mt352_read_register(state, CHAN_START_0); - trl = mt352_read_register(state, TRL_NOMINAL_RATE_1); - - op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7]; - op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7]; - - switch ( (tps >> 13) & 3) - { - case 0: - op->constellation = QPSK; - break; - case 1: - op->constellation = QAM_16; - break; - case 2: - op->constellation = QAM_64; - break; - default: - op->constellation = QAM_AUTO; - break; - } - - op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : TRANSMISSION_MODE_2K; - - switch ( (tps >> 2) & 3) - { - case 0: - op->guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - op->guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - op->guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - op->guard_interval = GUARD_INTERVAL_1_4; - break; - default: - op->guard_interval = GUARD_INTERVAL_AUTO; - break; - } - - switch ( (tps >> 10) & 7) - { - case 0: - op->hierarchy_information = HIERARCHY_NONE; - break; - case 1: - op->hierarchy_information = HIERARCHY_1; - break; - case 2: - op->hierarchy_information = HIERARCHY_2; - break; - case 3: - op->hierarchy_information = HIERARCHY_4; - break; - default: - op->hierarchy_information = HIERARCHY_AUTO; - break; - } - - param->frequency = ( 500 * (div - IF_FREQUENCYx6) ) / 3 * 1000; - - if (trl == 0x72) - op->bandwidth = BANDWIDTH_8_MHZ; - else if (trl == 0x64) - op->bandwidth = BANDWIDTH_7_MHZ; - else - op->bandwidth = BANDWIDTH_6_MHZ; - - - if (mt352_read_register(state, STATUS_2) & 0x02) - param->inversion = INVERSION_OFF; - else - param->inversion = INVERSION_ON; - - return 0; -} - -static int mt352_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct mt352_state* state = fe->demodulator_priv; - int s0, s1, s3; - - /* FIXME: - * - * The MT352 design manual from Zarlink states (page 46-47): - * - * Notes about the TUNER_GO register: - * - * If the Read_Tuner_Byte (bit-1) is activated, then the tuner status - * byte is copied from the tuner to the STATUS_3 register and - * completion of the read operation is indicated by bit-5 of the - * INTERRUPT_3 register. - */ - - if ((s0 = mt352_read_register(state, STATUS_0)) < 0) - return -EREMOTEIO; - if ((s1 = mt352_read_register(state, STATUS_1)) < 0) - return -EREMOTEIO; - if ((s3 = mt352_read_register(state, STATUS_3)) < 0) - return -EREMOTEIO; - - *status = 0; - if (s0 & (1 << 4)) - *status |= FE_HAS_CARRIER; - if (s0 & (1 << 1)) - *status |= FE_HAS_VITERBI; - if (s0 & (1 << 5)) - *status |= FE_HAS_LOCK; - if (s1 & (1 << 1)) - *status |= FE_HAS_SYNC; - if (s3 & (1 << 6)) - *status |= FE_HAS_SIGNAL; - - if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) != - (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) - *status &= ~FE_HAS_LOCK; - - return 0; -} - -static int mt352_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct mt352_state* state = fe->demodulator_priv; - - *ber = (mt352_read_register (state, RS_ERR_CNT_2) << 16) | - (mt352_read_register (state, RS_ERR_CNT_1) << 8) | - (mt352_read_register (state, RS_ERR_CNT_0)); - - return 0; -} - -static int mt352_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct mt352_state* state = fe->demodulator_priv; - - /* align the 12 bit AGC gain with the most significant bits */ - u16 signal = ((mt352_read_register(state, AGC_GAIN_1) & 0x0f) << 12) | - (mt352_read_register(state, AGC_GAIN_0) << 4); - - /* inverse of gain is signal strength */ - *strength = ~signal; - return 0; -} - -static int mt352_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct mt352_state* state = fe->demodulator_priv; - - u8 _snr = mt352_read_register (state, SNR); - *snr = (_snr << 8) | _snr; - - return 0; -} - -static int mt352_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct mt352_state* state = fe->demodulator_priv; - - *ucblocks = (mt352_read_register (state, RS_UBC_1) << 8) | - (mt352_read_register (state, RS_UBC_0)); - - return 0; -} - -static int mt352_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings) -{ - fe_tune_settings->min_delay_ms = 800; - fe_tune_settings->step_size = 0; - fe_tune_settings->max_drift = 0; - - return 0; -} - -static int mt352_init(struct dvb_frontend* fe) -{ - struct mt352_state* state = fe->demodulator_priv; - - static u8 mt352_reset_attach [] = { RESET, 0xC0 }; - - dprintk("%s: hello\n",__func__); - - if ((mt352_read_register(state, CLOCK_CTL) & 0x10) == 0 || - (mt352_read_register(state, CONFIG) & 0x20) == 0) { - - /* Do a "hard" reset */ - _mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach)); - return state->config.demod_init(fe); - } - - return 0; -} - -static void mt352_release(struct dvb_frontend* fe) -{ - struct mt352_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops mt352_ops; - -struct dvb_frontend* mt352_attach(const struct mt352_config* config, - struct i2c_adapter* i2c) -{ - struct mt352_state* state = NULL; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct mt352_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->i2c = i2c; - memcpy(&state->config,config,sizeof(struct mt352_config)); - - /* check if the demod is there */ - if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &mt352_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops mt352_ops = { - - .info = { - .name = "Zarlink MT352 DVB-T", - .type = FE_OFDM, - .frequency_min = 174000000, - .frequency_max = 862000000, - .frequency_stepsize = 166667, - .frequency_tolerance = 0, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | - FE_CAN_MUTE_TS - }, - - .release = mt352_release, - - .init = mt352_init, - .sleep = mt352_sleep, - .write = _mt352_write, - - .set_frontend = mt352_set_parameters, - .get_frontend = mt352_get_parameters, - .get_tune_settings = mt352_get_tune_settings, - - .read_status = mt352_read_status, - .read_ber = mt352_read_ber, - .read_signal_strength = mt352_read_signal_strength, - .read_snr = mt352_read_snr, - .read_ucblocks = mt352_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Zarlink MT352 DVB-T Demodulator driver"); -MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(mt352_attach); diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h deleted file mode 100644 index 595092f9f0c..00000000000 --- a/drivers/media/dvb/frontends/mt352.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Driver for Zarlink DVB-T MT352 demodulator - * - * Written by Holger Waechtler <holger@qanu.de> - * and Daniel Mack <daniel@qanu.de> - * - * AVerMedia AVerTV DVB-T 771 support by - * Wolfram Joost <dbox2@frokaschwei.de> - * - * Support for Samsung TDTC9251DH01C(M) tuner - * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it> - * Amauri Celani <acelani@essegi.net> - * - * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by - * Christopher Pascoe <c.pascoe@itee.uq.edu.au> - * - * 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 MT352_H -#define MT352_H - -#include <linux/dvb/frontend.h> - -struct mt352_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* frequencies in kHz */ - int adc_clock; // default: 20480 - int if2; // default: 36166 - - /* set if no pll is connected to the secondary i2c bus */ - int no_tuner; - - /* Initialise the demodulator and PLL. Cannot be NULL */ - int (*demod_init)(struct dvb_frontend* fe); -}; - -#if defined(CONFIG_DVB_MT352) || (defined(CONFIG_DVB_MT352_MODULE) && defined(MODULE)) -extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* mt352_attach(const struct mt352_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_MT352 - -static inline int mt352_write(struct dvb_frontend *fe, u8 *buf, int len) { - int r = 0; - if (fe->ops.write) - r = fe->ops.write(fe, buf, len); - return r; -} - -#endif // MT352_H diff --git a/drivers/media/dvb/frontends/mt352_priv.h b/drivers/media/dvb/frontends/mt352_priv.h deleted file mode 100644 index 44ad0d4c8f1..00000000000 --- a/drivers/media/dvb/frontends/mt352_priv.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Driver for Zarlink DVB-T MT352 demodulator - * - * Written by Holger Waechtler <holger@qanu.de> - * and Daniel Mack <daniel@qanu.de> - * - * AVerMedia AVerTV DVB-T 771 support by - * Wolfram Joost <dbox2@frokaschwei.de> - * - * Support for Samsung TDTC9251DH01C(M) tuner - * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it> - * Amauri Celani <acelani@essegi.net> - * - * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by - * Christopher Pascoe <c.pascoe@itee.uq.edu.au> - * - * 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 _MT352_PRIV_ -#define _MT352_PRIV_ - -#define ID_MT352 0x13 - -#define msb(x) (((x) >> 8) & 0xff) -#define lsb(x) ((x) & 0xff) - -enum mt352_reg_addr { - STATUS_0 = 0x00, - STATUS_1 = 0x01, - STATUS_2 = 0x02, - STATUS_3 = 0x03, - STATUS_4 = 0x04, - INTERRUPT_0 = 0x05, - INTERRUPT_1 = 0x06, - INTERRUPT_2 = 0x07, - INTERRUPT_3 = 0x08, - SNR = 0x09, - VIT_ERR_CNT_2 = 0x0A, - VIT_ERR_CNT_1 = 0x0B, - VIT_ERR_CNT_0 = 0x0C, - RS_ERR_CNT_2 = 0x0D, - RS_ERR_CNT_1 = 0x0E, - RS_ERR_CNT_0 = 0x0F, - RS_UBC_1 = 0x10, - RS_UBC_0 = 0x11, - AGC_GAIN_3 = 0x12, - AGC_GAIN_2 = 0x13, - AGC_GAIN_1 = 0x14, - AGC_GAIN_0 = 0x15, - FREQ_OFFSET_2 = 0x17, - FREQ_OFFSET_1 = 0x18, - FREQ_OFFSET_0 = 0x19, - TIMING_OFFSET_1 = 0x1A, - TIMING_OFFSET_0 = 0x1B, - CHAN_FREQ_1 = 0x1C, - CHAN_FREQ_0 = 0x1D, - TPS_RECEIVED_1 = 0x1E, - TPS_RECEIVED_0 = 0x1F, - TPS_CURRENT_1 = 0x20, - TPS_CURRENT_0 = 0x21, - TPS_CELL_ID_1 = 0x22, - TPS_CELL_ID_0 = 0x23, - TPS_MISC_DATA_2 = 0x24, - TPS_MISC_DATA_1 = 0x25, - TPS_MISC_DATA_0 = 0x26, - RESET = 0x50, - TPS_GIVEN_1 = 0x51, - TPS_GIVEN_0 = 0x52, - ACQ_CTL = 0x53, - TRL_NOMINAL_RATE_1 = 0x54, - TRL_NOMINAL_RATE_0 = 0x55, - INPUT_FREQ_1 = 0x56, - INPUT_FREQ_0 = 0x57, - TUNER_ADDR = 0x58, - CHAN_START_1 = 0x59, - CHAN_START_0 = 0x5A, - CONT_1 = 0x5B, - CONT_0 = 0x5C, - TUNER_GO = 0x5D, - STATUS_EN_0 = 0x5F, - STATUS_EN_1 = 0x60, - INTERRUPT_EN_0 = 0x61, - INTERRUPT_EN_1 = 0x62, - INTERRUPT_EN_2 = 0x63, - INTERRUPT_EN_3 = 0x64, - AGC_TARGET = 0x67, - AGC_CTL = 0x68, - CAPT_RANGE = 0x75, - SNR_SELECT_1 = 0x79, - SNR_SELECT_0 = 0x7A, - RS_ERR_PER_1 = 0x7C, - RS_ERR_PER_0 = 0x7D, - CHIP_ID = 0x7F, - CHAN_STOP_1 = 0x80, - CHAN_STOP_0 = 0x81, - CHAN_STEP_1 = 0x82, - CHAN_STEP_0 = 0x83, - FEC_LOCK_TIME = 0x85, - OFDM_LOCK_TIME = 0x86, - ACQ_DELAY = 0x87, - SCAN_CTL = 0x88, - CLOCK_CTL = 0x89, - CONFIG = 0x8A, - MCLK_RATIO = 0x8B, - GPP_CTL = 0x8C, - ADC_CTL_1 = 0x8E, - ADC_CTL_0 = 0x8F -}; - -/* here we assume 1/6MHz == 166.66kHz stepsize */ -#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ - -#endif /* _MT352_PRIV_ */ diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c deleted file mode 100644 index a8429ebfa8a..00000000000 --- a/drivers/media/dvb/frontends/nxt200x.c +++ /dev/null @@ -1,1239 +0,0 @@ -/* - * Support for NXT2002 and NXT2004 - VSB/QAM - * - * Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com> - * Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net> - * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> - * and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com> - * - * 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. - * -*/ - -/* - * NOTES ABOUT THIS DRIVER - * - * This Linux driver supports: - * B2C2/BBTI Technisat Air2PC - ATSC (NXT2002) - * AverTVHD MCE A180 (NXT2004) - * ATI HDTV Wonder (NXT2004) - * - * This driver needs external firmware. Please use the command - * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" or - * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to - * download/extract the appropriate firmware, and then copy it to - * /usr/lib/hotplug/firmware/ or /lib/firmware/ - * (depending on configuration of firmware hotplug). - */ -#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" -#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw" -#define CRC_CCIT_MASK 0x1021 - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/string.h> - -#include "dvb_frontend.h" -#include "nxt200x.h" - -struct nxt200x_state { - - struct i2c_adapter* i2c; - const struct nxt200x_config* config; - struct dvb_frontend frontend; - - /* demodulator private data */ - nxt_chip_type demod_chip; - u8 initialised:1; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "nxt200x: " args); \ - } while (0) - -static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len) -{ - int err; - struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len }; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n", - __func__, addr, err); - return -EREMOTEIO; - } - return 0; -} - -static int i2c_readbytes(struct nxt200x_state *state, u8 addr, u8 *buf, u8 len) -{ - int err; - struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len }; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n", - __func__, addr, err); - return -EREMOTEIO; - } - return 0; -} - -static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, - const u8 *buf, u8 len) -{ - u8 buf2 [len+1]; - int err; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 }; - - buf2[0] = reg; - memcpy(&buf2[1], buf, len); - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n", - __func__, state->config->demod_address, err); - return -EREMOTEIO; - } - return 0; -} - -static int nxt200x_readbytes(struct nxt200x_state *state, u8 reg, u8 *buf, u8 len) -{ - u8 reg2 [] = { reg }; - - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } }; - - int err; - - if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) { - printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n", - __func__, state->config->demod_address, err); - return -EREMOTEIO; - } - return 0; -} - -static u16 nxt200x_crc(u16 crc, u8 c) -{ - u8 i; - u16 input = (u16) c & 0xFF; - - input<<=8; - for(i=0; i<8; i++) { - if((crc^input) & 0x8000) - crc=(crc<<1)^CRC_CCIT_MASK; - else - crc<<=1; - input<<=1; - } - return crc; -} - -static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len) -{ - u8 attr, len2, buf; - dprintk("%s\n", __func__); - - /* set mutli register register */ - nxt200x_writebytes(state, 0x35, ®, 1); - - /* send the actual data */ - nxt200x_writebytes(state, 0x36, data, len); - - switch (state->demod_chip) { - case NXT2002: - len2 = len; - buf = 0x02; - break; - case NXT2004: - /* probably not right, but gives correct values */ - attr = 0x02; - if (reg & 0x80) { - attr = attr << 1; - if (reg & 0x04) - attr = attr >> 1; - } - /* set write bit */ - len2 = ((attr << 4) | 0x10) | len; - buf = 0x80; - break; - default: - return -EINVAL; - break; - } - - /* set multi register length */ - nxt200x_writebytes(state, 0x34, &len2, 1); - - /* toggle the multireg write bit */ - nxt200x_writebytes(state, 0x21, &buf, 1); - - nxt200x_readbytes(state, 0x21, &buf, 1); - - switch (state->demod_chip) { - case NXT2002: - if ((buf & 0x02) == 0) - return 0; - break; - case NXT2004: - if (buf == 0) - return 0; - break; - default: - return -EINVAL; - break; - } - - printk(KERN_WARNING "nxt200x: Error writing multireg register 0x%02X\n",reg); - - return 0; -} - -static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len) -{ - int i; - u8 buf, len2, attr; - dprintk("%s\n", __func__); - - /* set mutli register register */ - nxt200x_writebytes(state, 0x35, ®, 1); - - switch (state->demod_chip) { - case NXT2002: - /* set multi register length */ - len2 = len & 0x80; - nxt200x_writebytes(state, 0x34, &len2, 1); - - /* read the actual data */ - nxt200x_readbytes(state, reg, data, len); - return 0; - break; - case NXT2004: - /* probably not right, but gives correct values */ - attr = 0x02; - if (reg & 0x80) { - attr = attr << 1; - if (reg & 0x04) - attr = attr >> 1; - } - - /* set multi register length */ - len2 = (attr << 4) | len; - nxt200x_writebytes(state, 0x34, &len2, 1); - - /* toggle the multireg bit*/ - buf = 0x80; - nxt200x_writebytes(state, 0x21, &buf, 1); - - /* read the actual data */ - for(i = 0; i < len; i++) { - nxt200x_readbytes(state, 0x36 + i, &data[i], 1); - } - return 0; - break; - default: - return -EINVAL; - break; - } -} - -static void nxt200x_microcontroller_stop (struct nxt200x_state* state) -{ - u8 buf, stopval, counter = 0; - dprintk("%s\n", __func__); - - /* set correct stop value */ - switch (state->demod_chip) { - case NXT2002: - stopval = 0x40; - break; - case NXT2004: - stopval = 0x10; - break; - default: - stopval = 0; - break; - } - - buf = 0x80; - nxt200x_writebytes(state, 0x22, &buf, 1); - - while (counter < 20) { - nxt200x_readbytes(state, 0x31, &buf, 1); - if (buf & stopval) - return; - msleep(10); - counter++; - } - - printk(KERN_WARNING "nxt200x: Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n"); - return; -} - -static void nxt200x_microcontroller_start (struct nxt200x_state* state) -{ - u8 buf; - dprintk("%s\n", __func__); - - buf = 0x00; - nxt200x_writebytes(state, 0x22, &buf, 1); -} - -static void nxt2004_microcontroller_init (struct nxt200x_state* state) -{ - u8 buf[9]; - u8 counter = 0; - dprintk("%s\n", __func__); - - buf[0] = 0x00; - nxt200x_writebytes(state, 0x2b, buf, 1); - buf[0] = 0x70; - nxt200x_writebytes(state, 0x34, buf, 1); - buf[0] = 0x04; - nxt200x_writebytes(state, 0x35, buf, 1); - buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89; - buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0; - nxt200x_writebytes(state, 0x36, buf, 9); - buf[0] = 0x80; - nxt200x_writebytes(state, 0x21, buf, 1); - - while (counter < 20) { - nxt200x_readbytes(state, 0x21, buf, 1); - if (buf[0] == 0) - return; - msleep(10); - counter++; - } - - printk(KERN_WARNING "nxt200x: Timeout waiting for nxt2004 to init.\n"); - - return; -} - -static int nxt200x_writetuner (struct nxt200x_state* state, u8* data) -{ - u8 buf, count = 0; - - dprintk("%s\n", __func__); - - dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[1], data[2], data[3], data[4]); - - /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip. - * direct write is required for Philips TUV1236D and ALPS TDHU2 */ - switch (state->demod_chip) { - case NXT2004: - if (i2c_writebytes(state, data[0], data+1, 4)) - printk(KERN_WARNING "nxt200x: error writing to tuner\n"); - /* wait until we have a lock */ - while (count < 20) { - i2c_readbytes(state, data[0], &buf, 1); - if (buf & 0x40) - return 0; - msleep(100); - count++; - } - printk("nxt2004: timeout waiting for tuner lock\n"); - break; - case NXT2002: - /* set the i2c transfer speed to the tuner */ - buf = 0x03; - nxt200x_writebytes(state, 0x20, &buf, 1); - - /* setup to transfer 4 bytes via i2c */ - buf = 0x04; - nxt200x_writebytes(state, 0x34, &buf, 1); - - /* write actual tuner bytes */ - nxt200x_writebytes(state, 0x36, data+1, 4); - - /* set tuner i2c address */ - buf = data[0] << 1; - nxt200x_writebytes(state, 0x35, &buf, 1); - - /* write UC Opmode to begin transfer */ - buf = 0x80; - nxt200x_writebytes(state, 0x21, &buf, 1); - - while (count < 20) { - nxt200x_readbytes(state, 0x21, &buf, 1); - if ((buf & 0x80)== 0x00) - return 0; - msleep(100); - count++; - } - printk("nxt2002: timeout error writing tuner\n"); - break; - default: - return -EINVAL; - break; - } - return 0; -} - -static void nxt200x_agc_reset(struct nxt200x_state* state) -{ - u8 buf; - dprintk("%s\n", __func__); - - switch (state->demod_chip) { - case NXT2002: - buf = 0x08; - nxt200x_writebytes(state, 0x08, &buf, 1); - buf = 0x00; - nxt200x_writebytes(state, 0x08, &buf, 1); - break; - case NXT2004: - nxt200x_readreg_multibyte(state, 0x08, &buf, 1); - buf = 0x08; - nxt200x_writereg_multibyte(state, 0x08, &buf, 1); - buf = 0x00; - nxt200x_writereg_multibyte(state, 0x08, &buf, 1); - break; - default: - break; - } - return; -} - -static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) -{ - - struct nxt200x_state* state = fe->demodulator_priv; - u8 buf[3], written = 0, chunkpos = 0; - u16 rambase, position, crc = 0; - - dprintk("%s\n", __func__); - dprintk("Firmware is %zu bytes\n", fw->size); - - /* Get the RAM base for this nxt2002 */ - nxt200x_readbytes(state, 0x10, buf, 1); - - if (buf[0] & 0x10) - rambase = 0x1000; - else - rambase = 0x0000; - - dprintk("rambase on this nxt2002 is %04X\n", rambase); - - /* Hold the micro in reset while loading firmware */ - buf[0] = 0x80; - nxt200x_writebytes(state, 0x2B, buf, 1); - - for (position = 0; position < fw->size; position++) { - if (written == 0) { - crc = 0; - chunkpos = 0x28; - buf[0] = ((rambase + position) >> 8); - buf[1] = (rambase + position) & 0xFF; - buf[2] = 0x81; - /* write starting address */ - nxt200x_writebytes(state, 0x29, buf, 3); - } - written++; - chunkpos++; - - if ((written % 4) == 0) - nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4); - - crc = nxt200x_crc(crc, fw->data[position]); - - if ((written == 255) || (position+1 == fw->size)) { - /* write remaining bytes of firmware */ - nxt200x_writebytes(state, chunkpos+4-(written %4), - &fw->data[position-(written %4) + 1], - written %4); - buf[0] = crc << 8; - buf[1] = crc & 0xFF; - - /* write crc */ - nxt200x_writebytes(state, 0x2C, buf, 2); - - /* do a read to stop things */ - nxt200x_readbytes(state, 0x2A, buf, 1); - - /* set transfer mode to complete */ - buf[0] = 0x80; - nxt200x_writebytes(state, 0x2B, buf, 1); - - written = 0; - } - } - - return 0; -}; - -static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) -{ - - struct nxt200x_state* state = fe->demodulator_priv; - u8 buf[3]; - u16 rambase, position, crc=0; - - dprintk("%s\n", __func__); - dprintk("Firmware is %zu bytes\n", fw->size); - - /* set rambase */ - rambase = 0x1000; - - /* hold the micro in reset while loading firmware */ - buf[0] = 0x80; - nxt200x_writebytes(state, 0x2B, buf,1); - - /* calculate firmware CRC */ - for (position = 0; position < fw->size; position++) { - crc = nxt200x_crc(crc, fw->data[position]); - } - - buf[0] = rambase >> 8; - buf[1] = rambase & 0xFF; - buf[2] = 0x81; - /* write starting address */ - nxt200x_writebytes(state,0x29,buf,3); - - for (position = 0; position < fw->size;) { - nxt200x_writebytes(state, 0x2C, &fw->data[position], - fw->size-position > 255 ? 255 : fw->size-position); - position += (fw->size-position > 255 ? 255 : fw->size-position); - } - buf[0] = crc >> 8; - buf[1] = crc & 0xFF; - - dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]); - - /* write crc */ - nxt200x_writebytes(state, 0x2C, buf,2); - - /* do a read to stop things */ - nxt200x_readbytes(state, 0x2C, buf, 1); - - /* set transfer mode to complete */ - buf[0] = 0x80; - nxt200x_writebytes(state, 0x2B, buf,1); - - return 0; -}; - -static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) -{ - struct nxt200x_state* state = fe->demodulator_priv; - u8 buf[5]; - - /* stop the micro first */ - nxt200x_microcontroller_stop(state); - - if (state->demod_chip == NXT2004) { - /* make sure demod is set to digital */ - buf[0] = 0x04; - nxt200x_writebytes(state, 0x14, buf, 1); - buf[0] = 0x00; - nxt200x_writebytes(state, 0x17, buf, 1); - } - - /* set additional params */ - switch (p->u.vsb.modulation) { - case QAM_64: - case QAM_256: - /* Set punctured clock for QAM */ - /* This is just a guess since I am unable to test it */ - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 1); - break; - case VSB_8: - /* Set non-punctured clock for VSB */ - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - break; - default: - return -EINVAL; - break; - } - - if (fe->ops.tuner_ops.calc_regs) { - /* get tuning information */ - fe->ops.tuner_ops.calc_regs(fe, p, buf, 5); - - /* write frequency information */ - nxt200x_writetuner(state, buf); - } - - /* reset the agc now that tuning has been completed */ - nxt200x_agc_reset(state); - - /* set target power level */ - switch (p->u.vsb.modulation) { - case QAM_64: - case QAM_256: - buf[0] = 0x74; - break; - case VSB_8: - buf[0] = 0x70; - break; - default: - return -EINVAL; - break; - } - nxt200x_writebytes(state, 0x42, buf, 1); - - /* configure sdm */ - switch (state->demod_chip) { - case NXT2002: - buf[0] = 0x87; - break; - case NXT2004: - buf[0] = 0x07; - break; - default: - return -EINVAL; - break; - } - nxt200x_writebytes(state, 0x57, buf, 1); - - /* write sdm1 input */ - buf[0] = 0x10; - buf[1] = 0x00; - switch (state->demod_chip) { - case NXT2002: - nxt200x_writereg_multibyte(state, 0x58, buf, 2); - break; - case NXT2004: - nxt200x_writebytes(state, 0x58, buf, 2); - break; - default: - return -EINVAL; - break; - } - - /* write sdmx input */ - switch (p->u.vsb.modulation) { - case QAM_64: - buf[0] = 0x68; - break; - case QAM_256: - buf[0] = 0x64; - break; - case VSB_8: - buf[0] = 0x60; - break; - default: - return -EINVAL; - break; - } - buf[1] = 0x00; - switch (state->demod_chip) { - case NXT2002: - nxt200x_writereg_multibyte(state, 0x5C, buf, 2); - break; - case NXT2004: - nxt200x_writebytes(state, 0x5C, buf, 2); - break; - default: - return -EINVAL; - break; - } - - /* write adc power lpf fc */ - buf[0] = 0x05; - nxt200x_writebytes(state, 0x43, buf, 1); - - if (state->demod_chip == NXT2004) { - /* write ??? */ - buf[0] = 0x00; - buf[1] = 0x00; - nxt200x_writebytes(state, 0x46, buf, 2); - } - - /* write accumulator2 input */ - buf[0] = 0x80; - buf[1] = 0x00; - switch (state->demod_chip) { - case NXT2002: - nxt200x_writereg_multibyte(state, 0x4B, buf, 2); - break; - case NXT2004: - nxt200x_writebytes(state, 0x4B, buf, 2); - break; - default: - return -EINVAL; - break; - } - - /* write kg1 */ - buf[0] = 0x00; - nxt200x_writebytes(state, 0x4D, buf, 1); - - /* write sdm12 lpf fc */ - buf[0] = 0x44; - nxt200x_writebytes(state, 0x55, buf, 1); - - /* write agc control reg */ - buf[0] = 0x04; - nxt200x_writebytes(state, 0x41, buf, 1); - - if (state->demod_chip == NXT2004) { - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x24; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - - /* soft reset? */ - nxt200x_readreg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x10; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - nxt200x_readreg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x04; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x81, buf, 1); - buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00; - nxt200x_writereg_multibyte(state, 0x82, buf, 3); - nxt200x_readreg_multibyte(state, 0x88, buf, 1); - buf[0] = 0x11; - nxt200x_writereg_multibyte(state, 0x88, buf, 1); - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x44; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - } - - /* write agc ucgp0 */ - switch (p->u.vsb.modulation) { - case QAM_64: - buf[0] = 0x02; - break; - case QAM_256: - buf[0] = 0x03; - break; - case VSB_8: - buf[0] = 0x00; - break; - default: - return -EINVAL; - break; - } - nxt200x_writebytes(state, 0x30, buf, 1); - - /* write agc control reg */ - buf[0] = 0x00; - nxt200x_writebytes(state, 0x41, buf, 1); - - /* write accumulator2 input */ - buf[0] = 0x80; - buf[1] = 0x00; - switch (state->demod_chip) { - case NXT2002: - nxt200x_writereg_multibyte(state, 0x49, buf, 2); - nxt200x_writereg_multibyte(state, 0x4B, buf, 2); - break; - case NXT2004: - nxt200x_writebytes(state, 0x49, buf, 2); - nxt200x_writebytes(state, 0x4B, buf, 2); - break; - default: - return -EINVAL; - break; - } - - /* write agc control reg */ - buf[0] = 0x04; - nxt200x_writebytes(state, 0x41, buf, 1); - - nxt200x_microcontroller_start(state); - - if (state->demod_chip == NXT2004) { - nxt2004_microcontroller_init(state); - - /* ???? */ - buf[0] = 0xF0; - buf[1] = 0x00; - nxt200x_writebytes(state, 0x5C, buf, 2); - } - - /* adjacent channel detection should be done here, but I don't - have any stations with this need so I cannot test it */ - - return 0; -} - -static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct nxt200x_state* state = fe->demodulator_priv; - u8 lock; - nxt200x_readbytes(state, 0x31, &lock, 1); - - *status = 0; - if (lock & 0x20) { - *status |= FE_HAS_SIGNAL; - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_VITERBI; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_LOCK; - } - return 0; -} - -static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct nxt200x_state* state = fe->demodulator_priv; - u8 b[3]; - - nxt200x_readreg_multibyte(state, 0xE6, b, 3); - - *ber = ((b[0] << 8) + b[1]) * 8; - - return 0; -} - -static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct nxt200x_state* state = fe->demodulator_priv; - u8 b[2]; - u16 temp = 0; - - /* setup to read cluster variance */ - b[0] = 0x00; - nxt200x_writebytes(state, 0xA1, b, 1); - - /* get multreg val */ - nxt200x_readreg_multibyte(state, 0xA6, b, 2); - - temp = (b[0] << 8) | b[1]; - *strength = ((0x7FFF - temp) & 0x0FFF) * 16; - - return 0; -} - -static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr) -{ - - struct nxt200x_state* state = fe->demodulator_priv; - u8 b[2]; - u16 temp = 0, temp2; - u32 snrdb = 0; - - /* setup to read cluster variance */ - b[0] = 0x00; - nxt200x_writebytes(state, 0xA1, b, 1); - - /* get multreg val from 0xA6 */ - nxt200x_readreg_multibyte(state, 0xA6, b, 2); - - temp = (b[0] << 8) | b[1]; - temp2 = 0x7FFF - temp; - - /* snr will be in db */ - if (temp2 > 0x7F00) - snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) ); - else if (temp2 > 0x7EC0) - snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) ); - else if (temp2 > 0x7C00) - snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) ); - else - snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) ); - - /* the value reported back from the frontend will be FFFF=32db 0000=0db */ - *snr = snrdb * (0xFFFF/32000); - - return 0; -} - -static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct nxt200x_state* state = fe->demodulator_priv; - u8 b[3]; - - nxt200x_readreg_multibyte(state, 0xE6, b, 3); - *ucblocks = b[2]; - - return 0; -} - -static int nxt200x_sleep(struct dvb_frontend* fe) -{ - return 0; -} - -static int nxt2002_init(struct dvb_frontend* fe) -{ - struct nxt200x_state* state = fe->demodulator_priv; - const struct firmware *fw; - int ret; - u8 buf[2]; - - /* request the firmware, this will block until someone uploads it */ - printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE); - ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, &state->i2c->dev); - printk("nxt2002: Waiting for firmware upload(2)...\n"); - if (ret) { - printk("nxt2002: No firmware uploaded (timeout or file not found?)\n"); - return ret; - } - - ret = nxt2002_load_firmware(fe, fw); - release_firmware(fw); - if (ret) { - printk("nxt2002: Writing firmware to device failed\n"); - return ret; - } - printk("nxt2002: Firmware upload complete\n"); - - /* Put the micro into reset */ - nxt200x_microcontroller_stop(state); - - /* ensure transfer is complete */ - buf[0]=0x00; - nxt200x_writebytes(state, 0x2B, buf, 1); - - /* Put the micro into reset for real this time */ - nxt200x_microcontroller_stop(state); - - /* soft reset everything (agc,frontend,eq,fec)*/ - buf[0] = 0x0F; - nxt200x_writebytes(state, 0x08, buf, 1); - buf[0] = 0x00; - nxt200x_writebytes(state, 0x08, buf, 1); - - /* write agc sdm configure */ - buf[0] = 0xF1; - nxt200x_writebytes(state, 0x57, buf, 1); - - /* write mod output format */ - buf[0] = 0x20; - nxt200x_writebytes(state, 0x09, buf, 1); - - /* write fec mpeg mode */ - buf[0] = 0x7E; - buf[1] = 0x00; - nxt200x_writebytes(state, 0xE9, buf, 2); - - /* write mux selection */ - buf[0] = 0x00; - nxt200x_writebytes(state, 0xCC, buf, 1); - - return 0; -} - -static int nxt2004_init(struct dvb_frontend* fe) -{ - struct nxt200x_state* state = fe->demodulator_priv; - const struct firmware *fw; - int ret; - u8 buf[3]; - - /* ??? */ - buf[0]=0x00; - nxt200x_writebytes(state, 0x1E, buf, 1); - - /* request the firmware, this will block until someone uploads it */ - printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE); - ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, &state->i2c->dev); - printk("nxt2004: Waiting for firmware upload(2)...\n"); - if (ret) { - printk("nxt2004: No firmware uploaded (timeout or file not found?)\n"); - return ret; - } - - ret = nxt2004_load_firmware(fe, fw); - release_firmware(fw); - if (ret) { - printk("nxt2004: Writing firmware to device failed\n"); - return ret; - } - printk("nxt2004: Firmware upload complete\n"); - - /* ensure transfer is complete */ - buf[0] = 0x01; - nxt200x_writebytes(state, 0x19, buf, 1); - - nxt2004_microcontroller_init(state); - nxt200x_microcontroller_stop(state); - nxt200x_microcontroller_stop(state); - nxt2004_microcontroller_init(state); - nxt200x_microcontroller_stop(state); - - /* soft reset everything (agc,frontend,eq,fec)*/ - buf[0] = 0xFF; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - - /* write agc sdm configure */ - buf[0] = 0xD7; - nxt200x_writebytes(state, 0x57, buf, 1); - - /* ???*/ - buf[0] = 0x07; - buf[1] = 0xfe; - nxt200x_writebytes(state, 0x35, buf, 2); - buf[0] = 0x12; - nxt200x_writebytes(state, 0x34, buf, 1); - buf[0] = 0x80; - nxt200x_writebytes(state, 0x21, buf, 1); - - /* ???*/ - buf[0] = 0x21; - nxt200x_writebytes(state, 0x0A, buf, 1); - - /* ???*/ - buf[0] = 0x01; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - - /* write fec mpeg mode */ - buf[0] = 0x7E; - buf[1] = 0x00; - nxt200x_writebytes(state, 0xE9, buf, 2); - - /* write mux selection */ - buf[0] = 0x00; - nxt200x_writebytes(state, 0xCC, buf, 1); - - /* ???*/ - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - - /* soft reset? */ - nxt200x_readreg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x10; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - nxt200x_readreg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - - /* ???*/ - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x01; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x70; - nxt200x_writereg_multibyte(state, 0x81, buf, 1); - buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66; - nxt200x_writereg_multibyte(state, 0x82, buf, 3); - - nxt200x_readreg_multibyte(state, 0x88, buf, 1); - buf[0] = 0x11; - nxt200x_writereg_multibyte(state, 0x88, buf, 1); - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x40; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - - nxt200x_readbytes(state, 0x10, buf, 1); - buf[0] = 0x10; - nxt200x_writebytes(state, 0x10, buf, 1); - nxt200x_readbytes(state, 0x0A, buf, 1); - buf[0] = 0x21; - nxt200x_writebytes(state, 0x0A, buf, 1); - - nxt2004_microcontroller_init(state); - - buf[0] = 0x21; - nxt200x_writebytes(state, 0x0A, buf, 1); - buf[0] = 0x7E; - nxt200x_writebytes(state, 0xE9, buf, 1); - buf[0] = 0x00; - nxt200x_writebytes(state, 0xEA, buf, 1); - - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - - /* soft reset? */ - nxt200x_readreg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x10; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - nxt200x_readreg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x04; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x81, buf, 1); - buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00; - nxt200x_writereg_multibyte(state, 0x82, buf, 3); - - nxt200x_readreg_multibyte(state, 0x88, buf, 1); - buf[0] = 0x11; - nxt200x_writereg_multibyte(state, 0x88, buf, 1); - - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x44; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - - /* initialize tuner */ - nxt200x_readbytes(state, 0x10, buf, 1); - buf[0] = 0x12; - nxt200x_writebytes(state, 0x10, buf, 1); - buf[0] = 0x04; - nxt200x_writebytes(state, 0x13, buf, 1); - buf[0] = 0x00; - nxt200x_writebytes(state, 0x16, buf, 1); - buf[0] = 0x04; - nxt200x_writebytes(state, 0x14, buf, 1); - buf[0] = 0x00; - nxt200x_writebytes(state, 0x14, buf, 1); - nxt200x_writebytes(state, 0x17, buf, 1); - nxt200x_writebytes(state, 0x14, buf, 1); - nxt200x_writebytes(state, 0x17, buf, 1); - - return 0; -} - -static int nxt200x_init(struct dvb_frontend* fe) -{ - struct nxt200x_state* state = fe->demodulator_priv; - int ret = 0; - - if (!state->initialised) { - switch (state->demod_chip) { - case NXT2002: - ret = nxt2002_init(fe); - break; - case NXT2004: - ret = nxt2004_init(fe); - break; - default: - return -EINVAL; - break; - } - state->initialised = 1; - } - return ret; -} - -static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 500; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static void nxt200x_release(struct dvb_frontend* fe) -{ - struct nxt200x_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops nxt200x_ops; - -struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, - struct i2c_adapter* i2c) -{ - struct nxt200x_state* state = NULL; - u8 buf [] = {0,0,0,0,0}; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct nxt200x_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - - /* read card id */ - nxt200x_readbytes(state, 0x00, buf, 5); - dprintk("NXT info: %02X %02X %02X %02X %02X\n", - buf[0], buf[1], buf[2], buf[3], buf[4]); - - /* set demod chip */ - switch (buf[0]) { - case 0x04: - state->demod_chip = NXT2002; - printk("nxt200x: NXT2002 Detected\n"); - break; - case 0x05: - state->demod_chip = NXT2004; - printk("nxt200x: NXT2004 Detected\n"); - break; - default: - goto error; - } - - /* make sure demod chip is supported */ - switch (state->demod_chip) { - case NXT2002: - if (buf[0] != 0x04) goto error; /* device id */ - if (buf[1] != 0x02) goto error; /* fab id */ - if (buf[2] != 0x11) goto error; /* month */ - if (buf[3] != 0x20) goto error; /* year msb */ - if (buf[4] != 0x00) goto error; /* year lsb */ - break; - case NXT2004: - if (buf[0] != 0x05) goto error; /* device id */ - break; - default: - goto error; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - printk("Unknown/Unsupported NXT chip: %02X %02X %02X %02X %02X\n", - buf[0], buf[1], buf[2], buf[3], buf[4]); - return NULL; -} - -static struct dvb_frontend_ops nxt200x_ops = { - - .info = { - .name = "Nextwave NXT200X VSB/QAM frontend", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 860000000, - .frequency_stepsize = 166666, /* stepsize is just a guess */ - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256 - }, - - .release = nxt200x_release, - - .init = nxt200x_init, - .sleep = nxt200x_sleep, - - .set_frontend = nxt200x_setup_frontend_parameters, - .get_tune_settings = nxt200x_get_tune_settings, - - .read_status = nxt200x_read_status, - .read_ber = nxt200x_read_ber, - .read_signal_strength = nxt200x_read_signal_strength, - .read_snr = nxt200x_read_snr, - .read_ucblocks = nxt200x_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver"); -MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(nxt200x_attach); - diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h deleted file mode 100644 index f3c84583770..00000000000 --- a/drivers/media/dvb/frontends/nxt200x.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Support for NXT2002 and NXT2004 - VSB/QAM - * - * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com) - * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> - * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com) - * - * 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 NXT200X_H -#define NXT200X_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -typedef enum nxt_chip_t { - NXTUNDEFINED, - NXT2002, - NXT2004 -}nxt_chip_type; - -struct nxt200x_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); -}; - -#if defined(CONFIG_DVB_NXT200X) || (defined(CONFIG_DVB_NXT200X_MODULE) && defined(MODULE)) -extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_NXT200X - -#endif /* NXT200X_H */ - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c deleted file mode 100644 index 0eef22dbf8a..00000000000 --- a/drivers/media/dvb/frontends/nxt6000.c +++ /dev/null @@ -1,610 +0,0 @@ -/* - NxtWave Communications - NXT6000 demodulator driver - - Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org> - Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au> - - 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 <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "nxt6000_priv.h" -#include "nxt6000.h" - - - -struct nxt6000_state { - struct i2c_adapter* i2c; - /* configuration settings */ - const struct nxt6000_config* config; - struct dvb_frontend frontend; -}; - -static int debug; -#define dprintk if (debug) printk - -static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 }; - int ret; - - if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) - dprintk("nxt6000: nxt6000_write error (reg: 0x%02X, data: 0x%02X, ret: %d)\n", reg, data, ret); - - return (ret != 1) ? -EFAULT : 0; -} - -static u8 nxt6000_readreg(struct nxt6000_state* state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msgs[] = { - {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1}, - {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} - }; - - ret = i2c_transfer(state->i2c, msgs, 2); - - if (ret != 2) - dprintk("nxt6000: nxt6000_read error (reg: 0x%02X, ret: %d)\n", reg, ret); - - return b1[0]; -} - -static void nxt6000_reset(struct nxt6000_state* state) -{ - u8 val; - - val = nxt6000_readreg(state, OFDM_COR_CTL); - - nxt6000_writereg(state, OFDM_COR_CTL, val & ~COREACT); - nxt6000_writereg(state, OFDM_COR_CTL, val | COREACT); -} - -static int nxt6000_set_bandwidth(struct nxt6000_state* state, fe_bandwidth_t bandwidth) -{ - u16 nominal_rate; - int result; - - switch (bandwidth) { - - case BANDWIDTH_6_MHZ: - nominal_rate = 0x55B7; - break; - - case BANDWIDTH_7_MHZ: - nominal_rate = 0x6400; - break; - - case BANDWIDTH_8_MHZ: - nominal_rate = 0x7249; - break; - - default: - return -EINVAL; - } - - if ((result = nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, nominal_rate & 0xFF)) < 0) - return result; - - return nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, (nominal_rate >> 8) & 0xFF); -} - -static int nxt6000_set_guard_interval(struct nxt6000_state* state, fe_guard_interval_t guard_interval) -{ - switch (guard_interval) { - - case GUARD_INTERVAL_1_32: - return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x00 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03)); - - case GUARD_INTERVAL_1_16: - return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x01 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03)); - - case GUARD_INTERVAL_AUTO: - case GUARD_INTERVAL_1_8: - return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x02 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03)); - - case GUARD_INTERVAL_1_4: - return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x03 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03)); - - default: - return -EINVAL; - } -} - -static int nxt6000_set_inversion(struct nxt6000_state* state, fe_spectral_inversion_t inversion) -{ - switch (inversion) { - - case INVERSION_OFF: - return nxt6000_writereg(state, OFDM_ITB_CTL, 0x00); - - case INVERSION_ON: - return nxt6000_writereg(state, OFDM_ITB_CTL, ITBINV); - - default: - return -EINVAL; - - } -} - -static int nxt6000_set_transmission_mode(struct nxt6000_state* state, fe_transmit_mode_t transmission_mode) -{ - int result; - - switch (transmission_mode) { - - case TRANSMISSION_MODE_2K: - if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x00 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0) - return result; - - return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x00 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04)); - - case TRANSMISSION_MODE_8K: - case TRANSMISSION_MODE_AUTO: - if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x02 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0) - return result; - - return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x01 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04)); - - default: - return -EINVAL; - - } -} - -static void nxt6000_setup(struct dvb_frontend* fe) -{ - struct nxt6000_state* state = fe->demodulator_priv; - - nxt6000_writereg(state, RS_COR_SYNC_PARAM, SYNC_PARAM); - nxt6000_writereg(state, BER_CTRL, /*(1 << 2) | */ (0x01 << 1) | 0x01); - nxt6000_writereg(state, VIT_BERTIME_2, 0x00); // BER Timer = 0x000200 * 256 = 131072 bits - nxt6000_writereg(state, VIT_BERTIME_1, 0x02); // - nxt6000_writereg(state, VIT_BERTIME_0, 0x00); // - nxt6000_writereg(state, VIT_COR_INTEN, 0x98); // Enable BER interrupts - nxt6000_writereg(state, VIT_COR_CTL, 0x82); // Enable BER measurement - nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC | 0x02 ); - nxt6000_writereg(state, OFDM_COR_CTL, (0x01 << 5) | (nxt6000_readreg(state, OFDM_COR_CTL) & 0x0F)); - nxt6000_writereg(state, OFDM_COR_MODEGUARD, FORCEMODE8K | 0x02); - nxt6000_writereg(state, OFDM_AGC_CTL, AGCLAST | INITIAL_AGC_BW); - nxt6000_writereg(state, OFDM_ITB_FREQ_1, 0x06); - nxt6000_writereg(state, OFDM_ITB_FREQ_2, 0x31); - nxt6000_writereg(state, OFDM_CAS_CTL, (0x01 << 7) | (0x02 << 3) | 0x04); - nxt6000_writereg(state, CAS_FREQ, 0xBB); /* CHECKME */ - nxt6000_writereg(state, OFDM_SYR_CTL, 1 << 2); - nxt6000_writereg(state, OFDM_PPM_CTL_1, PPM256); - nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, 0x49); - nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, 0x72); - nxt6000_writereg(state, ANALOG_CONTROL_0, 1 << 5); - nxt6000_writereg(state, EN_DMD_RACQ, (1 << 7) | (3 << 4) | 2); - nxt6000_writereg(state, DIAG_CONFIG, TB_SET); - - if (state->config->clock_inversion) - nxt6000_writereg(state, SUB_DIAG_MODE_SEL, CLKINVERSION); - else - nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0); - - nxt6000_writereg(state, TS_FORMAT, 0); -} - -static void nxt6000_dump_status(struct nxt6000_state *state) -{ - u8 val; - -/* - printk("RS_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, RS_COR_STAT)); - printk("VIT_SYNC_STATUS: 0x%02X\n", nxt6000_readreg(fe, VIT_SYNC_STATUS)); - printk("OFDM_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_COR_STAT)); - printk("OFDM_SYR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_SYR_STAT)); - printk("OFDM_TPS_RCVD_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_1)); - printk("OFDM_TPS_RCVD_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_2)); - printk("OFDM_TPS_RCVD_3: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_3)); - printk("OFDM_TPS_RCVD_4: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_4)); - printk("OFDM_TPS_RESERVED_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_1)); - printk("OFDM_TPS_RESERVED_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_2)); -*/ - printk("NXT6000 status:"); - - val = nxt6000_readreg(state, RS_COR_STAT); - - printk(" DATA DESCR LOCK: %d,", val & 0x01); - printk(" DATA SYNC LOCK: %d,", (val >> 1) & 0x01); - - val = nxt6000_readreg(state, VIT_SYNC_STATUS); - - printk(" VITERBI LOCK: %d,", (val >> 7) & 0x01); - - switch ((val >> 4) & 0x07) { - - case 0x00: - printk(" VITERBI CODERATE: 1/2,"); - break; - - case 0x01: - printk(" VITERBI CODERATE: 2/3,"); - break; - - case 0x02: - printk(" VITERBI CODERATE: 3/4,"); - break; - - case 0x03: - printk(" VITERBI CODERATE: 5/6,"); - break; - - case 0x04: - printk(" VITERBI CODERATE: 7/8,"); - break; - - default: - printk(" VITERBI CODERATE: Reserved,"); - - } - - val = nxt6000_readreg(state, OFDM_COR_STAT); - - printk(" CHCTrack: %d,", (val >> 7) & 0x01); - printk(" TPSLock: %d,", (val >> 6) & 0x01); - printk(" SYRLock: %d,", (val >> 5) & 0x01); - printk(" AGCLock: %d,", (val >> 4) & 0x01); - - switch (val & 0x0F) { - - case 0x00: - printk(" CoreState: IDLE,"); - break; - - case 0x02: - printk(" CoreState: WAIT_AGC,"); - break; - - case 0x03: - printk(" CoreState: WAIT_SYR,"); - break; - - case 0x04: - printk(" CoreState: WAIT_PPM,"); - break; - - case 0x01: - printk(" CoreState: WAIT_TRL,"); - break; - - case 0x05: - printk(" CoreState: WAIT_TPS,"); - break; - - case 0x06: - printk(" CoreState: MONITOR_TPS,"); - break; - - default: - printk(" CoreState: Reserved,"); - - } - - val = nxt6000_readreg(state, OFDM_SYR_STAT); - - printk(" SYRLock: %d,", (val >> 4) & 0x01); - printk(" SYRMode: %s,", (val >> 2) & 0x01 ? "8K" : "2K"); - - switch ((val >> 4) & 0x03) { - - case 0x00: - printk(" SYRGuard: 1/32,"); - break; - - case 0x01: - printk(" SYRGuard: 1/16,"); - break; - - case 0x02: - printk(" SYRGuard: 1/8,"); - break; - - case 0x03: - printk(" SYRGuard: 1/4,"); - break; - } - - val = nxt6000_readreg(state, OFDM_TPS_RCVD_3); - - switch ((val >> 4) & 0x07) { - - case 0x00: - printk(" TPSLP: 1/2,"); - break; - - case 0x01: - printk(" TPSLP: 2/3,"); - break; - - case 0x02: - printk(" TPSLP: 3/4,"); - break; - - case 0x03: - printk(" TPSLP: 5/6,"); - break; - - case 0x04: - printk(" TPSLP: 7/8,"); - break; - - default: - printk(" TPSLP: Reserved,"); - - } - - switch (val & 0x07) { - - case 0x00: - printk(" TPSHP: 1/2,"); - break; - - case 0x01: - printk(" TPSHP: 2/3,"); - break; - - case 0x02: - printk(" TPSHP: 3/4,"); - break; - - case 0x03: - printk(" TPSHP: 5/6,"); - break; - - case 0x04: - printk(" TPSHP: 7/8,"); - break; - - default: - printk(" TPSHP: Reserved,"); - - } - - val = nxt6000_readreg(state, OFDM_TPS_RCVD_4); - - printk(" TPSMode: %s,", val & 0x01 ? "8K" : "2K"); - - switch ((val >> 4) & 0x03) { - - case 0x00: - printk(" TPSGuard: 1/32,"); - break; - - case 0x01: - printk(" TPSGuard: 1/16,"); - break; - - case 0x02: - printk(" TPSGuard: 1/8,"); - break; - - case 0x03: - printk(" TPSGuard: 1/4,"); - break; - - } - - /* Strange magic required to gain access to RF_AGC_STATUS */ - nxt6000_readreg(state, RF_AGC_VAL_1); - val = nxt6000_readreg(state, RF_AGC_STATUS); - val = nxt6000_readreg(state, RF_AGC_STATUS); - - printk(" RF AGC LOCK: %d,", (val >> 4) & 0x01); - printk("\n"); -} - -static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - u8 core_status; - struct nxt6000_state* state = fe->demodulator_priv; - - *status = 0; - - core_status = nxt6000_readreg(state, OFDM_COR_STAT); - - if (core_status & AGCLOCKED) - *status |= FE_HAS_SIGNAL; - - if (nxt6000_readreg(state, OFDM_SYR_STAT) & GI14_SYR_LOCK) - *status |= FE_HAS_CARRIER; - - if (nxt6000_readreg(state, VIT_SYNC_STATUS) & VITINSYNC) - *status |= FE_HAS_VITERBI; - - if (nxt6000_readreg(state, RS_COR_STAT) & RSCORESTATUS) - *status |= FE_HAS_SYNC; - - if ((core_status & TPSLOCKED) && (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))) - *status |= FE_HAS_LOCK; - - if (debug) - nxt6000_dump_status(state); - - return 0; -} - -static int nxt6000_init(struct dvb_frontend* fe) -{ - struct nxt6000_state* state = fe->demodulator_priv; - - nxt6000_reset(state); - nxt6000_setup(fe); - - return 0; -} - -static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *param) -{ - struct nxt6000_state* state = fe->demodulator_priv; - int result; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0) - return result; - if ((result = nxt6000_set_guard_interval(state, param->u.ofdm.guard_interval)) < 0) - return result; - if ((result = nxt6000_set_transmission_mode(state, param->u.ofdm.transmission_mode)) < 0) - return result; - if ((result = nxt6000_set_inversion(state, param->inversion)) < 0) - return result; - - msleep(500); - return 0; -} - -static void nxt6000_release(struct dvb_frontend* fe) -{ - struct nxt6000_state* state = fe->demodulator_priv; - kfree(state); -} - -static int nxt6000_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct nxt6000_state* state = fe->demodulator_priv; - - *snr = nxt6000_readreg( state, OFDM_CHC_SNR) / 8; - - return 0; -} - -static int nxt6000_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct nxt6000_state* state = fe->demodulator_priv; - - nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18 ); - - *ber = (nxt6000_readreg( state, VIT_BER_1 ) << 8 ) | - nxt6000_readreg( state, VIT_BER_0 ); - - nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18); // Clear BER Done interrupts - - return 0; -} - -static int nxt6000_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) -{ - struct nxt6000_state* state = fe->demodulator_priv; - - *signal_strength = (short) (511 - - (nxt6000_readreg(state, AGC_GAIN_1) + - ((nxt6000_readreg(state, AGC_GAIN_2) & 0x03) << 8))); - - return 0; -} - -static int nxt6000_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 500; - return 0; -} - -static int nxt6000_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct nxt6000_state* state = fe->demodulator_priv; - - if (enable) { - return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); - } else { - return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); - } -} - -static struct dvb_frontend_ops nxt6000_ops; - -struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, - struct i2c_adapter* i2c) -{ - struct nxt6000_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct nxt6000_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* check if the demod is there */ - if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops nxt6000_ops = { - - .info = { - .name = "NxtWave NXT6000 DVB-T", - .type = FE_OFDM, - .frequency_min = 0, - .frequency_max = 863250000, - .frequency_stepsize = 62500, - /*.frequency_tolerance = *//* FIXME: 12% of SR */ - .symbol_rate_min = 0, /* FIXME */ - .symbol_rate_max = 9360000, /* FIXME */ - .symbol_rate_tolerance = 4000, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | - FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = nxt6000_release, - - .init = nxt6000_init, - .i2c_gate_ctrl = nxt6000_i2c_gate_ctrl, - - .get_tune_settings = nxt6000_fe_get_tune_settings, - - .set_frontend = nxt6000_set_frontend, - - .read_status = nxt6000_read_status, - .read_ber = nxt6000_read_ber, - .read_signal_strength = nxt6000_read_signal_strength, - .read_snr = nxt6000_read_snr, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("NxtWave NXT6000 DVB-T demodulator driver"); -MODULE_AUTHOR("Florian Schirmer"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(nxt6000_attach); diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h deleted file mode 100644 index 878eb38a075..00000000000 --- a/drivers/media/dvb/frontends/nxt6000.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - NxtWave Communications - NXT6000 demodulator driver - - Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org> - Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au> - - 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 NXT6000_H -#define NXT6000_H - -#include <linux/dvb/frontend.h> - -struct nxt6000_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* should clock inversion be used? */ - u8 clock_inversion:1; -}; - -#if defined(CONFIG_DVB_NXT6000) || (defined(CONFIG_DVB_NXT6000_MODULE) && defined(MODULE)) -extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_NXT6000 - -#endif // NXT6000_H diff --git a/drivers/media/dvb/frontends/nxt6000_priv.h b/drivers/media/dvb/frontends/nxt6000_priv.h deleted file mode 100644 index 0422e580038..00000000000 --- a/drivers/media/dvb/frontends/nxt6000_priv.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Public Include File for DRV6000 users - * (ie. NxtWave Communications - NXT6000 demodulator driver) - * - * Copyright (C) 2001 NxtWave Communications, Inc. - * - */ - -/* Nxt6000 Register Addresses and Bit Masks */ - -/* Maximum Register Number */ -#define MAXNXT6000REG (0x9A) - -/* 0x1B A_VIT_BER_0 aka 0x3A */ -#define A_VIT_BER_0 (0x1B) - -/* 0x1D A_VIT_BER_TIMER_0 aka 0x38 */ -#define A_VIT_BER_TIMER_0 (0x1D) - -/* 0x21 RS_COR_STAT */ -#define RS_COR_STAT (0x21) -#define RSCORESTATUS (0x03) - -/* 0x22 RS_COR_INTEN */ -#define RS_COR_INTEN (0x22) - -/* 0x23 RS_COR_INSTAT */ -#define RS_COR_INSTAT (0x23) -#define INSTAT_ERROR (0x04) -#define LOCK_LOSS_BITS (0x03) - -/* 0x24 RS_COR_SYNC_PARAM */ -#define RS_COR_SYNC_PARAM (0x24) -#define SYNC_PARAM (0x03) - -/* 0x25 BER_CTRL */ -#define BER_CTRL (0x25) -#define BER_ENABLE (0x02) -#define BER_RESET (0x01) - -/* 0x26 BER_PAY */ -#define BER_PAY (0x26) - -/* 0x27 BER_PKT_L */ -#define BER_PKT_L (0x27) -#define BER_PKTOVERFLOW (0x80) - -/* 0x30 VIT_COR_CTL */ -#define VIT_COR_CTL (0x30) -#define BER_CONTROL (0x02) -#define VIT_COR_MASK (0x82) -#define VIT_COR_RESYNC (0x80) - - -/* 0x32 VIT_SYNC_STATUS */ -#define VIT_SYNC_STATUS (0x32) -#define VITINSYNC (0x80) - -/* 0x33 VIT_COR_INTEN */ -#define VIT_COR_INTEN (0x33) -#define GLOBAL_ENABLE (0x80) - -/* 0x34 VIT_COR_INTSTAT */ -#define VIT_COR_INTSTAT (0x34) -#define BER_DONE (0x08) -#define BER_OVERFLOW (0x10) - -/* 0x38 VIT_BERTIME_2 */ -#define VIT_BERTIME_2 (0x38) - -/* 0x39 VIT_BERTIME_1 */ -#define VIT_BERTIME_1 (0x39) - -/* 0x3A VIT_BERTIME_0 */ -#define VIT_BERTIME_0 (0x3a) - - /* 0x38 OFDM_BERTimer *//* Use the alias registers */ -#define A_VIT_BER_TIMER_0 (0x1D) - - /* 0x3A VIT_BER_TIMER_0 *//* Use the alias registers */ -#define A_VIT_BER_0 (0x1B) - -/* 0x3B VIT_BER_1 */ -#define VIT_BER_1 (0x3b) - -/* 0x3C VIT_BER_0 */ -#define VIT_BER_0 (0x3c) - -/* 0x40 OFDM_COR_CTL */ -#define OFDM_COR_CTL (0x40) -#define COREACT (0x20) -#define HOLDSM (0x10) -#define WAIT_AGC (0x02) -#define WAIT_SYR (0x03) - -/* 0x41 OFDM_COR_STAT */ -#define OFDM_COR_STAT (0x41) -#define COR_STATUS (0x0F) -#define MONITOR_TPS (0x06) -#define TPSLOCKED (0x40) -#define AGCLOCKED (0x10) - -/* 0x42 OFDM_COR_INTEN */ -#define OFDM_COR_INTEN (0x42) -#define TPSRCVBAD (0x04) -#define TPSRCVCHANGED (0x02) -#define TPSRCVUPDATE (0x01) - -/* 0x43 OFDM_COR_INSTAT */ -#define OFDM_COR_INSTAT (0x43) - -/* 0x44 OFDM_COR_MODEGUARD */ -#define OFDM_COR_MODEGUARD (0x44) -#define FORCEMODE (0x08) -#define FORCEMODE8K (0x04) - -/* 0x45 OFDM_AGC_CTL */ -#define OFDM_AGC_CTL (0x45) -#define INITIAL_AGC_BW (0x08) -#define AGCNEG (0x02) -#define AGCLAST (0x10) - -/* 0x48 OFDM_AGC_TARGET */ -#define OFDM_AGC_TARGET (0x48) -#define OFDM_AGC_TARGET_DEFAULT (0x28) -#define OFDM_AGC_TARGET_IMPULSE (0x38) - -/* 0x49 OFDM_AGC_GAIN_1 */ -#define OFDM_AGC_GAIN_1 (0x49) - -/* 0x4B OFDM_ITB_CTL */ -#define OFDM_ITB_CTL (0x4B) -#define ITBINV (0x01) - -/* 0x49 AGC_GAIN_1 */ -#define AGC_GAIN_1 (0x49) - -/* 0x4A AGC_GAIN_2 */ -#define AGC_GAIN_2 (0x4A) - -/* 0x4C OFDM_ITB_FREQ_1 */ -#define OFDM_ITB_FREQ_1 (0x4C) - -/* 0x4D OFDM_ITB_FREQ_2 */ -#define OFDM_ITB_FREQ_2 (0x4D) - -/* 0x4E OFDM_CAS_CTL */ -#define OFDM_CAS_CTL (0x4E) -#define ACSDIS (0x40) -#define CCSEN (0x80) - -/* 0x4F CAS_FREQ */ -#define CAS_FREQ (0x4F) - -/* 0x51 OFDM_SYR_CTL */ -#define OFDM_SYR_CTL (0x51) -#define SIXTH_ENABLE (0x80) -#define SYR_TRACKING_DISABLE (0x01) - -/* 0x52 OFDM_SYR_STAT */ -#define OFDM_SYR_STAT (0x52) -#define GI14_2K_SYR_LOCK (0x13) -#define GI14_8K_SYR_LOCK (0x17) -#define GI14_SYR_LOCK (0x10) - -/* 0x55 OFDM_SYR_OFFSET_1 */ -#define OFDM_SYR_OFFSET_1 (0x55) - -/* 0x56 OFDM_SYR_OFFSET_2 */ -#define OFDM_SYR_OFFSET_2 (0x56) - -/* 0x58 OFDM_SCR_CTL */ -#define OFDM_SCR_CTL (0x58) -#define SYR_ADJ_DECAY_MASK (0x70) -#define SYR_ADJ_DECAY (0x30) - -/* 0x59 OFDM_PPM_CTL_1 */ -#define OFDM_PPM_CTL_1 (0x59) -#define PPMMAX_MASK (0x30) -#define PPM256 (0x30) - -/* 0x5B OFDM_TRL_NOMINALRATE_1 */ -#define OFDM_TRL_NOMINALRATE_1 (0x5B) - -/* 0x5C OFDM_TRL_NOMINALRATE_2 */ -#define OFDM_TRL_NOMINALRATE_2 (0x5C) - -/* 0x5D OFDM_TRL_TIME_1 */ -#define OFDM_TRL_TIME_1 (0x5D) - -/* 0x60 OFDM_CRL_FREQ_1 */ -#define OFDM_CRL_FREQ_1 (0x60) - -/* 0x63 OFDM_CHC_CTL_1 */ -#define OFDM_CHC_CTL_1 (0x63) -#define MANMEAN1 (0xF0); -#define CHCFIR (0x01) - -/* 0x64 OFDM_CHC_SNR */ -#define OFDM_CHC_SNR (0x64) - -/* 0x65 OFDM_BDI_CTL */ -#define OFDM_BDI_CTL (0x65) -#define LP_SELECT (0x02) - -/* 0x67 OFDM_TPS_RCVD_1 */ -#define OFDM_TPS_RCVD_1 (0x67) -#define TPSFRAME (0x03) - -/* 0x68 OFDM_TPS_RCVD_2 */ -#define OFDM_TPS_RCVD_2 (0x68) - -/* 0x69 OFDM_TPS_RCVD_3 */ -#define OFDM_TPS_RCVD_3 (0x69) - -/* 0x6A OFDM_TPS_RCVD_4 */ -#define OFDM_TPS_RCVD_4 (0x6A) - -/* 0x6B OFDM_TPS_RESERVED_1 */ -#define OFDM_TPS_RESERVED_1 (0x6B) - -/* 0x6C OFDM_TPS_RESERVED_2 */ -#define OFDM_TPS_RESERVED_2 (0x6C) - -/* 0x73 OFDM_MSC_REV */ -#define OFDM_MSC_REV (0x73) - -/* 0x76 OFDM_SNR_CARRIER_2 */ -#define OFDM_SNR_CARRIER_2 (0x76) -#define MEAN_MASK (0x80) -#define MEANBIT (0x80) - -/* 0x80 ANALOG_CONTROL_0 */ -#define ANALOG_CONTROL_0 (0x80) -#define POWER_DOWN_ADC (0x40) - -/* 0x81 ENABLE_TUNER_IIC */ -#define ENABLE_TUNER_IIC (0x81) -#define ENABLE_TUNER_BIT (0x01) - -/* 0x82 EN_DMD_RACQ */ -#define EN_DMD_RACQ (0x82) -#define EN_DMD_RACQ_REG_VAL (0x81) -#define EN_DMD_RACQ_REG_VAL_14 (0x01) - -/* 0x84 SNR_COMMAND */ -#define SNR_COMMAND (0x84) -#define SNRStat (0x80) - -/* 0x85 SNRCARRIERNUMBER_LSB */ -#define SNRCARRIERNUMBER_LSB (0x85) - -/* 0x87 SNRMINTHRESHOLD_LSB */ -#define SNRMINTHRESHOLD_LSB (0x87) - -/* 0x89 SNR_PER_CARRIER_LSB */ -#define SNR_PER_CARRIER_LSB (0x89) - -/* 0x8B SNRBELOWTHRESHOLD_LSB */ -#define SNRBELOWTHRESHOLD_LSB (0x8B) - -/* 0x91 RF_AGC_VAL_1 */ -#define RF_AGC_VAL_1 (0x91) - -/* 0x92 RF_AGC_STATUS */ -#define RF_AGC_STATUS (0x92) - -/* 0x98 DIAG_CONFIG */ -#define DIAG_CONFIG (0x98) -#define DIAG_MASK (0x70) -#define TB_SET (0x10) -#define TRAN_SELECT (0x07) -#define SERIAL_SELECT (0x01) - -/* 0x99 SUB_DIAG_MODE_SEL */ -#define SUB_DIAG_MODE_SEL (0x99) -#define CLKINVERSION (0x01) - -/* 0x9A TS_FORMAT */ -#define TS_FORMAT (0x9A) -#define ERROR_SENSE (0x08) -#define VALID_SENSE (0x04) -#define SYNC_SENSE (0x02) -#define GATED_CLOCK (0x01) - -#define NXT6000ASICDEVICE (0x0b) diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c deleted file mode 100644 index 5ed32544de3..00000000000 --- a/drivers/media/dvb/frontends/or51132.c +++ /dev/null @@ -1,625 +0,0 @@ -/* - * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM - * - * - * Copyright (C) 2007 Trent Piepho <xyzzy@speakeasy.org> - * - * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> - * - * Based on code from Jack Kelliher (kelliher@xmission.com) - * Copyright (C) 2002 & pcHDTV, inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - * -*/ - -/* - * This driver needs two external firmware files. Please copy - * "dvb-fe-or51132-vsb.fw" and "dvb-fe-or51132-qam.fw" to - * /usr/lib/hotplug/firmware/ or /lib/firmware/ - * (depending on configuration of firmware hotplug). - */ -#define OR51132_VSB_FIRMWARE "dvb-fe-or51132-vsb.fw" -#define OR51132_QAM_FIRMWARE "dvb-fe-or51132-qam.fw" - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <asm/byteorder.h> - -#include "dvb_math.h" -#include "dvb_frontend.h" -#include "or51132.h" - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "or51132: " args); \ - } while (0) - - -struct or51132_state -{ - struct i2c_adapter* i2c; - - /* Configuration settings */ - const struct or51132_config* config; - - struct dvb_frontend frontend; - - /* Demodulator private data */ - fe_modulation_t current_modulation; - u32 snr; /* Result of last SNR calculation */ - - /* Tuner private data */ - u32 current_frequency; -}; - - -/* Write buffer to demod */ -static int or51132_writebuf(struct or51132_state *state, const u8 *buf, int len) -{ - int err; - struct i2c_msg msg = { .addr = state->config->demod_address, - .flags = 0, .buf = (u8*)buf, .len = len }; - - /* msleep(20); */ /* doesn't appear to be necessary */ - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk(KERN_WARNING "or51132: I2C write (addr 0x%02x len %d) error: %d\n", - msg.addr, msg.len, err); - return -EREMOTEIO; - } - return 0; -} - -/* Write constant bytes, e.g. or51132_writebytes(state, 0x04, 0x42, 0x00); - Less code and more efficient that loading a buffer on the stack with - the bytes to send and then calling or51132_writebuf() on that. */ -#define or51132_writebytes(state, data...) \ - ({ static const u8 _data[] = {data}; \ - or51132_writebuf(state, _data, sizeof(_data)); }) - -/* Read data from demod into buffer. Returns 0 on success. */ -static int or51132_readbuf(struct or51132_state *state, u8 *buf, int len) -{ - int err; - struct i2c_msg msg = { .addr = state->config->demod_address, - .flags = I2C_M_RD, .buf = buf, .len = len }; - - /* msleep(20); */ /* doesn't appear to be necessary */ - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk(KERN_WARNING "or51132: I2C read (addr 0x%02x len %d) error: %d\n", - msg.addr, msg.len, err); - return -EREMOTEIO; - } - return 0; -} - -/* Reads a 16-bit demod register. Returns <0 on error. */ -static int or51132_readreg(struct or51132_state *state, u8 reg) -{ - u8 buf[2] = { 0x04, reg }; - struct i2c_msg msg[2] = { - {.addr = state->config->demod_address, .flags = 0, - .buf = buf, .len = 2 }, - {.addr = state->config->demod_address, .flags = I2C_M_RD, - .buf = buf, .len = 2 }}; - int err; - - if ((err = i2c_transfer(state->i2c, msg, 2)) != 2) { - printk(KERN_WARNING "or51132: I2C error reading register %d: %d\n", - reg, err); - return -EREMOTEIO; - } - return buf[0] | (buf[1] << 8); -} - -static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) -{ - struct or51132_state* state = fe->demodulator_priv; - static const u8 run_buf[] = {0x7F,0x01}; - u8 rec_buf[8]; - u32 firmwareAsize, firmwareBsize; - int i,ret; - - dprintk("Firmware is %Zd bytes\n",fw->size); - - /* Get size of firmware A and B */ - firmwareAsize = le32_to_cpu(*((__le32*)fw->data)); - dprintk("FirmwareA is %i bytes\n",firmwareAsize); - firmwareBsize = le32_to_cpu(*((__le32*)(fw->data+4))); - dprintk("FirmwareB is %i bytes\n",firmwareBsize); - - /* Upload firmware */ - if ((ret = or51132_writebuf(state, &fw->data[8], firmwareAsize))) { - printk(KERN_WARNING "or51132: load_firmware error 1\n"); - return ret; - } - if ((ret = or51132_writebuf(state, &fw->data[8+firmwareAsize], - firmwareBsize))) { - printk(KERN_WARNING "or51132: load_firmware error 2\n"); - return ret; - } - - if ((ret = or51132_writebuf(state, run_buf, 2))) { - printk(KERN_WARNING "or51132: load_firmware error 3\n"); - return ret; - } - if ((ret = or51132_writebuf(state, run_buf, 2))) { - printk(KERN_WARNING "or51132: load_firmware error 4\n"); - return ret; - } - - /* 50ms for operation to begin */ - msleep(50); - - /* Read back ucode version to besure we loaded correctly and are really up and running */ - /* Get uCode version */ - if ((ret = or51132_writebytes(state, 0x10, 0x10, 0x00))) { - printk(KERN_WARNING "or51132: load_firmware error a\n"); - return ret; - } - if ((ret = or51132_writebytes(state, 0x04, 0x17))) { - printk(KERN_WARNING "or51132: load_firmware error b\n"); - return ret; - } - if ((ret = or51132_writebytes(state, 0x00, 0x00))) { - printk(KERN_WARNING "or51132: load_firmware error c\n"); - return ret; - } - for (i=0;i<4;i++) { - /* Once upon a time, this command might have had something - to do with getting the firmware version, but it's - not used anymore: - {0x04,0x00,0x30,0x00,i+1} */ - /* Read 8 bytes, two bytes at a time */ - if ((ret = or51132_readbuf(state, &rec_buf[i*2], 2))) { - printk(KERN_WARNING - "or51132: load_firmware error d - %d\n",i); - return ret; - } - } - - printk(KERN_WARNING - "or51132: Version: %02X%02X%02X%02X-%02X%02X%02X%02X (%02X%01X-%01X-%02X%01X-%01X)\n", - rec_buf[1],rec_buf[0],rec_buf[3],rec_buf[2], - rec_buf[5],rec_buf[4],rec_buf[7],rec_buf[6], - rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f, - rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f); - - if ((ret = or51132_writebytes(state, 0x10, 0x00, 0x00))) { - printk(KERN_WARNING "or51132: load_firmware error e\n"); - return ret; - } - return 0; -}; - -static int or51132_init(struct dvb_frontend* fe) -{ - return 0; -} - -static int or51132_read_ber(struct dvb_frontend* fe, u32* ber) -{ - *ber = 0; - return 0; -} - -static int or51132_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - *ucblocks = 0; - return 0; -} - -static int or51132_sleep(struct dvb_frontend* fe) -{ - return 0; -} - -static int or51132_setmode(struct dvb_frontend* fe) -{ - struct or51132_state* state = fe->demodulator_priv; - u8 cmd_buf1[3] = {0x04, 0x01, 0x5f}; - u8 cmd_buf2[3] = {0x1c, 0x00, 0 }; - - dprintk("setmode %d\n",(int)state->current_modulation); - - switch (state->current_modulation) { - case VSB_8: - /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high */ - cmd_buf1[2] = 0x50; - /* REC MODE inv IF spectrum, Normal */ - cmd_buf2[1] = 0x03; - /* Channel MODE ATSC/VSB8 */ - cmd_buf2[2] = 0x06; - break; - /* All QAM modes are: - Auto-deinterleave; MPEGser, MPEG2tr, phase noise-high - REC MODE Normal Carrier Lock */ - case QAM_AUTO: - /* Channel MODE Auto QAM64/256 */ - cmd_buf2[2] = 0x4f; - break; - case QAM_256: - /* Channel MODE QAM256 */ - cmd_buf2[2] = 0x45; - break; - case QAM_64: - /* Channel MODE QAM64 */ - cmd_buf2[2] = 0x43; - break; - default: - printk(KERN_WARNING - "or51132: setmode: Modulation set to unsupported value (%d)\n", - state->current_modulation); - return -EINVAL; - } - - /* Set Receiver 1 register */ - if (or51132_writebuf(state, cmd_buf1, 3)) { - printk(KERN_WARNING "or51132: set_mode error 1\n"); - return -EREMOTEIO; - } - dprintk("set #1 to %02x\n", cmd_buf1[2]); - - /* Set operation mode in Receiver 6 register */ - if (or51132_writebuf(state, cmd_buf2, 3)) { - printk(KERN_WARNING "or51132: set_mode error 2\n"); - return -EREMOTEIO; - } - dprintk("set #6 to 0x%02x%02x\n", cmd_buf2[1], cmd_buf2[2]); - - return 0; -} - -/* Some modulations use the same firmware. This classifies modulations - by the firmware they use. */ -#define MOD_FWCLASS_UNKNOWN 0 -#define MOD_FWCLASS_VSB 1 -#define MOD_FWCLASS_QAM 2 -static int modulation_fw_class(fe_modulation_t modulation) -{ - switch(modulation) { - case VSB_8: - return MOD_FWCLASS_VSB; - case QAM_AUTO: - case QAM_64: - case QAM_256: - return MOD_FWCLASS_QAM; - default: - return MOD_FWCLASS_UNKNOWN; - } -} - -static int or51132_set_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) -{ - int ret; - struct or51132_state* state = fe->demodulator_priv; - const struct firmware *fw; - const char *fwname; - int clock_mode; - - /* Upload new firmware only if we need a different one */ - if (modulation_fw_class(state->current_modulation) != - modulation_fw_class(param->u.vsb.modulation)) { - switch(modulation_fw_class(param->u.vsb.modulation)) { - case MOD_FWCLASS_VSB: - dprintk("set_parameters VSB MODE\n"); - fwname = OR51132_VSB_FIRMWARE; - - /* Set non-punctured clock for VSB */ - clock_mode = 0; - break; - case MOD_FWCLASS_QAM: - dprintk("set_parameters QAM MODE\n"); - fwname = OR51132_QAM_FIRMWARE; - - /* Set punctured clock for QAM */ - clock_mode = 1; - break; - default: - printk("or51132: Modulation type(%d) UNSUPPORTED\n", - param->u.vsb.modulation); - return -1; - } - printk("or51132: Waiting for firmware upload(%s)...\n", - fwname); - ret = request_firmware(&fw, fwname, &state->i2c->dev); - if (ret) { - printk(KERN_WARNING "or51132: No firmware up" - "loaded(timeout or file not found?)\n"); - return ret; - } - ret = or51132_load_firmware(fe, fw); - release_firmware(fw); - if (ret) { - printk(KERN_WARNING "or51132: Writing firmware to " - "device failed!\n"); - return ret; - } - printk("or51132: Firmware upload complete.\n"); - state->config->set_ts_params(fe, clock_mode); - } - /* Change only if we are actually changing the modulation */ - if (state->current_modulation != param->u.vsb.modulation) { - state->current_modulation = param->u.vsb.modulation; - or51132_setmode(fe); - } - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* Set to current mode */ - or51132_setmode(fe); - - /* Update current frequency */ - state->current_frequency = param->frequency; - return 0; -} - -static int or51132_get_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) -{ - struct or51132_state* state = fe->demodulator_priv; - int status; - int retry = 1; - -start: - /* Receiver Status */ - if ((status = or51132_readreg(state, 0x00)) < 0) { - printk(KERN_WARNING "or51132: get_parameters: error reading receiver status\n"); - return -EREMOTEIO; - } - switch(status&0xff) { - case 0x06: param->u.vsb.modulation = VSB_8; break; - case 0x43: param->u.vsb.modulation = QAM_64; break; - case 0x45: param->u.vsb.modulation = QAM_256; break; - default: - if (retry--) goto start; - printk(KERN_WARNING "or51132: unknown status 0x%02x\n", - status&0xff); - return -EREMOTEIO; - } - - /* FIXME: Read frequency from frontend, take AFC into account */ - param->frequency = state->current_frequency; - - /* FIXME: How to read inversion setting? Receiver 6 register? */ - param->inversion = INVERSION_AUTO; - - return 0; -} - -static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct or51132_state* state = fe->demodulator_priv; - int reg; - - /* Receiver Status */ - if ((reg = or51132_readreg(state, 0x00)) < 0) { - printk(KERN_WARNING "or51132: read_status: error reading receiver status: %d\n", reg); - *status = 0; - return -EREMOTEIO; - } - dprintk("%s: read_status %04x\n", __func__, reg); - - if (reg & 0x0100) /* Receiver Lock */ - *status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI| - FE_HAS_SYNC|FE_HAS_LOCK; - else - *status = 0; - return 0; -} - -/* Calculate SNR estimation (scaled by 2^24) - - 8-VSB SNR and QAM equations from Oren datasheets - - For 8-VSB: - SNR[dB] = 10 * log10(897152044.8282 / MSE^2 ) - K - - Where K = 0 if NTSC rejection filter is OFF; and - K = 3 if NTSC rejection filter is ON - - For QAM64: - SNR[dB] = 10 * log10(897152044.8282 / MSE^2 ) - - For QAM256: - SNR[dB] = 10 * log10(907832426.314266 / MSE^2 ) - - We re-write the snr equation as: - SNR * 2^24 = 10*(c - 2*intlog10(MSE)) - Where for QAM256, c = log10(907832426.314266) * 2^24 - and for 8-VSB and QAM64, c = log10(897152044.8282) * 2^24 */ - -static u32 calculate_snr(u32 mse, u32 c) -{ - if (mse == 0) /* No signal */ - return 0; - - mse = 2*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 or51132_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct or51132_state* state = fe->demodulator_priv; - int noise, reg; - u32 c, usK = 0; - int retry = 1; - -start: - /* SNR after Equalizer */ - noise = or51132_readreg(state, 0x02); - if (noise < 0) { - printk(KERN_WARNING "or51132: read_snr: error reading equalizer\n"); - return -EREMOTEIO; - } - dprintk("read_snr noise (%d)\n", noise); - - /* Read status, contains modulation type for QAM_AUTO and - NTSC filter for VSB */ - reg = or51132_readreg(state, 0x00); - if (reg < 0) { - printk(KERN_WARNING "or51132: read_snr: error reading receiver status\n"); - return -EREMOTEIO; - } - - switch (reg&0xff) { - case 0x06: - if (reg & 0x1000) usK = 3 << 24; - /* Fall through to QAM64 case */ - case 0x43: - c = 150204167; - break; - case 0x45: - c = 150290396; - break; - default: - printk(KERN_WARNING "or51132: unknown status 0x%02x\n", reg&0xff); - if (retry--) goto start; - return -EREMOTEIO; - } - dprintk("%s: modulation %02x, NTSC rej O%s\n", __func__, - reg&0xff, reg&0x1000?"n":"ff"); - - /* Calculate SNR using noise, c, and NTSC rejection correction */ - state->snr = calculate_snr(noise, c) - usK; - *snr = (state->snr) >> 16; - - dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise, - state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16); - - return 0; -} - -static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - /* 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 or51132_state* state = (struct or51132_state*) fe->demodulator_priv; - u16 snr; - int ret; - - ret = fe->ops.read_snr(fe, &snr); - if (ret != 0) - return ret; - /* 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; - - return 0; -} - -static int or51132_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings) -{ - fe_tune_settings->min_delay_ms = 500; - fe_tune_settings->step_size = 0; - fe_tune_settings->max_drift = 0; - - return 0; -} - -static void or51132_release(struct dvb_frontend* fe) -{ - struct or51132_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops or51132_ops; - -struct dvb_frontend* or51132_attach(const struct or51132_config* config, - struct i2c_adapter* i2c) -{ - struct or51132_state* state = NULL; - - /* Allocate memory for the internal state */ - state = kmalloc(sizeof(struct or51132_state), GFP_KERNEL); - if (state == NULL) - return NULL; - - /* Setup the state */ - state->config = config; - state->i2c = i2c; - state->current_frequency = -1; - state->current_modulation = -1; - - /* Create dvb_frontend */ - memcpy(&state->frontend.ops, &or51132_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -static struct dvb_frontend_ops or51132_ops = { - - .info = { - .name = "Oren OR51132 VSB/QAM Frontend", - .type = FE_ATSC, - .frequency_min = 44000000, - .frequency_max = 958000000, - .frequency_stepsize = 166666, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO | - FE_CAN_8VSB - }, - - .release = or51132_release, - - .init = or51132_init, - .sleep = or51132_sleep, - - .set_frontend = or51132_set_parameters, - .get_frontend = or51132_get_parameters, - .get_tune_settings = or51132_get_tune_settings, - - .read_status = or51132_read_status, - .read_ber = or51132_read_ber, - .read_signal_strength = or51132_read_signal_strength, - .read_snr = or51132_read_snr, - .read_ucblocks = or51132_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver"); -MODULE_AUTHOR("Kirk Lapray"); -MODULE_AUTHOR("Trent Piepho"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(or51132_attach); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h deleted file mode 100644 index 1b8e04d973c..00000000000 --- a/drivers/media/dvb/frontends/or51132.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM - * - * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> - * - * 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 OR51132_H -#define OR51132_H - -#include <linux/firmware.h> -#include <linux/dvb/frontend.h> - -struct or51132_config -{ - /* The demodulator's i2c address */ - u8 demod_address; - - /* Need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); -}; - -#if defined(CONFIG_DVB_OR51132) || (defined(CONFIG_DVB_OR51132_MODULE) && defined(MODULE)) -extern struct dvb_frontend* or51132_attach(const struct or51132_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* or51132_attach(const struct or51132_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_OR51132 - -#endif // OR51132_H - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c deleted file mode 100644 index 16cf2fdd5d7..00000000000 --- a/drivers/media/dvb/frontends/or51211.c +++ /dev/null @@ -1,582 +0,0 @@ -/* - * Support for OR51211 (pcHDTV HD-2000) - VSB - * - * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> - * - * Based on code from Jack Kelliher (kelliher@xmission.com) - * Copyright (C) 2002 & pcHDTV, inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - * -*/ - -/* - * This driver needs external firmware. Please use the command - * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to - * download/extract it, and then copy it to /usr/lib/hotplug/firmware - * or /lib/firmware (depending on configuration of firmware hotplug). - */ -#define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw" - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/firmware.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <asm/byteorder.h> - -#include "dvb_math.h" -#include "dvb_frontend.h" -#include "or51211.h" - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "or51211: " args); \ - } while (0) - -static u8 run_buf[] = {0x7f,0x01}; -static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC - -struct or51211_state { - - struct i2c_adapter* i2c; - - /* Configuration settings */ - const struct or51211_config* config; - - struct dvb_frontend frontend; - struct bt878* bt; - - /* Demodulator private data */ - u8 initialized:1; - u32 snr; /* Result of last SNR claculation */ - - /* Tuner private data */ - u32 current_frequency; -}; - -static int i2c_writebytes (struct or51211_state* state, u8 reg, const u8 *buf, - int len) -{ - int err; - struct i2c_msg msg; - msg.addr = reg; - msg.flags = 0; - msg.len = len; - msg.buf = (u8 *)buf; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk(KERN_WARNING "or51211: i2c_writebytes error " - "(addr %02x, err == %i)\n", reg, err); - return -EREMOTEIO; - } - - return 0; -} - -static int i2c_readbytes(struct or51211_state *state, u8 reg, u8 *buf, int len) -{ - int err; - struct i2c_msg msg; - msg.addr = reg; - msg.flags = I2C_M_RD; - msg.len = len; - msg.buf = buf; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk(KERN_WARNING "or51211: i2c_readbytes error " - "(addr %02x, err == %i)\n", reg, err); - return -EREMOTEIO; - } - - return 0; -} - -static int or51211_load_firmware (struct dvb_frontend* fe, - const struct firmware *fw) -{ - struct or51211_state* state = fe->demodulator_priv; - u8 tudata[585]; - int i; - - dprintk("Firmware is %zd bytes\n",fw->size); - - /* Get eprom data */ - tudata[0] = 17; - if (i2c_writebytes(state,0x50,tudata,1)) { - printk(KERN_WARNING "or51211:load_firmware error eprom addr\n"); - return -1; - } - if (i2c_readbytes(state,0x50,&tudata[145],192)) { - printk(KERN_WARNING "or51211: load_firmware error eprom\n"); - return -1; - } - - /* Create firmware buffer */ - for (i = 0; i < 145; i++) - tudata[i] = fw->data[i]; - - for (i = 0; i < 248; i++) - tudata[i+337] = fw->data[145+i]; - - state->config->reset(fe); - - if (i2c_writebytes(state,state->config->demod_address,tudata,585)) { - printk(KERN_WARNING "or51211: load_firmware error 1\n"); - return -1; - } - msleep(1); - - if (i2c_writebytes(state,state->config->demod_address, - &fw->data[393],8125)) { - printk(KERN_WARNING "or51211: load_firmware error 2\n"); - return -1; - } - msleep(1); - - if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) { - printk(KERN_WARNING "or51211: load_firmware error 3\n"); - return -1; - } - - /* Wait at least 5 msec */ - msleep(10); - if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) { - printk(KERN_WARNING "or51211: load_firmware error 4\n"); - return -1; - } - msleep(10); - - printk("or51211: Done.\n"); - return 0; -}; - -static int or51211_setmode(struct dvb_frontend* fe, int mode) -{ - struct or51211_state* state = fe->demodulator_priv; - u8 rec_buf[14]; - - state->config->setmode(fe, mode); - - if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) { - printk(KERN_WARNING "or51211: setmode error 1\n"); - return -1; - } - - /* Wait at least 5 msec */ - msleep(10); - if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) { - printk(KERN_WARNING "or51211: setmode error 2\n"); - return -1; - } - - msleep(10); - - /* Set operation mode in Receiver 1 register; - * type 1: - * data 0x50h Automatic sets receiver channel conditions - * Automatic NTSC rejection filter - * Enable MPEG serial data output - * MPEG2tr - * High tuner phase noise - * normal +/-150kHz Carrier acquisition range - */ - if (i2c_writebytes(state,state->config->demod_address,cmd_buf,3)) { - printk(KERN_WARNING "or51211: setmode error 3\n"); - return -1; - } - - rec_buf[0] = 0x04; - rec_buf[1] = 0x00; - rec_buf[2] = 0x03; - rec_buf[3] = 0x00; - msleep(20); - if (i2c_writebytes(state,state->config->demod_address,rec_buf,3)) { - printk(KERN_WARNING "or51211: setmode error 5\n"); - } - msleep(3); - if (i2c_readbytes(state,state->config->demod_address,&rec_buf[10],2)) { - printk(KERN_WARNING "or51211: setmode error 6"); - return -1; - } - dprintk("setmode rec status %02x %02x\n",rec_buf[10],rec_buf[11]); - - return 0; -} - -static int or51211_set_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) -{ - struct or51211_state* state = fe->demodulator_priv; - - /* Change only if we are actually changing the channel */ - if (state->current_frequency != param->frequency) { - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* Set to ATSC mode */ - or51211_setmode(fe,0); - - /* Update current frequency */ - state->current_frequency = param->frequency; - } - return 0; -} - -static int or51211_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct or51211_state* state = fe->demodulator_priv; - unsigned char rec_buf[2]; - unsigned char snd_buf[] = {0x04,0x00,0x03,0x00}; - *status = 0; - - /* Receiver Status */ - if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) { - printk(KERN_WARNING "or51132: read_status write error\n"); - return -1; - } - msleep(3); - if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { - printk(KERN_WARNING "or51132: read_status read error\n"); - return -1; - } - dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]); - - if (rec_buf[0] & 0x01) { /* Receiver Lock */ - *status |= FE_HAS_SIGNAL; - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_VITERBI; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_LOCK; - } - return 0; -} - -/* Calculate SNR estimation (scaled by 2^24) - - 8-VSB SNR equation from Oren datasheets - - For 8-VSB: - SNR[dB] = 10 * log10(219037.9454 / MSE^2 ) - - We re-write the snr equation as: - SNR * 2^24 = 10*(c - 2*intlog10(MSE)) - Where for 8-VSB, c = log10(219037.9454) * 2^24 */ - -static u32 calculate_snr(u32 mse, u32 c) -{ - if (mse == 0) /* No signal */ - return 0; - - mse = 2*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 or51211_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct or51211_state* state = fe->demodulator_priv; - u8 rec_buf[2]; - u8 snd_buf[3]; - - /* SNR after Equalizer */ - snd_buf[0] = 0x04; - snd_buf[1] = 0x00; - snd_buf[2] = 0x04; - - if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) { - printk(KERN_WARNING "%s: error writing snr reg\n", - __func__); - return -1; - } - if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { - printk(KERN_WARNING "%s: read_status read error\n", - __func__); - return -1; - } - - state->snr = calculate_snr(rec_buf[0], 89599047); - *snr = (state->snr) >> 16; - - dprintk("%s: noise = 0x%02x, snr = %d.%02d dB\n", __func__, rec_buf[0], - state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16); - - return 0; -} - -static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - /* 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 or51211_state* state = (struct or51211_state*)fe->demodulator_priv; - u16 snr; - int ret; - - ret = fe->ops.read_snr(fe, &snr); - if (ret != 0) - return ret; - /* 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; - - return 0; -} - -static int or51211_read_ber(struct dvb_frontend* fe, u32* ber) -{ - *ber = -ENOSYS; - return 0; -} - -static int or51211_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - *ucblocks = -ENOSYS; - return 0; -} - -static int or51211_sleep(struct dvb_frontend* fe) -{ - return 0; -} - -static int or51211_init(struct dvb_frontend* fe) -{ - struct or51211_state* state = fe->demodulator_priv; - const struct or51211_config* config = state->config; - const struct firmware* fw; - unsigned char get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00}; - unsigned char rec_buf[14]; - int ret,i; - - if (!state->initialized) { - /* Request the firmware, this will block until it uploads */ - printk(KERN_INFO "or51211: Waiting for firmware upload " - "(%s)...\n", OR51211_DEFAULT_FIRMWARE); - ret = config->request_firmware(fe, &fw, - OR51211_DEFAULT_FIRMWARE); - printk(KERN_INFO "or51211:Got Hotplug firmware\n"); - if (ret) { - printk(KERN_WARNING "or51211: No firmware uploaded " - "(timeout or file not found?)\n"); - return ret; - } - - ret = or51211_load_firmware(fe, fw); - release_firmware(fw); - if (ret) { - printk(KERN_WARNING "or51211: Writing firmware to " - "device failed!\n"); - return ret; - } - printk(KERN_INFO "or51211: Firmware upload complete.\n"); - - /* Set operation mode in Receiver 1 register; - * type 1: - * data 0x50h Automatic sets receiver channel conditions - * Automatic NTSC rejection filter - * Enable MPEG serial data output - * MPEG2tr - * High tuner phase noise - * normal +/-150kHz Carrier acquisition range - */ - if (i2c_writebytes(state,state->config->demod_address, - cmd_buf,3)) { - printk(KERN_WARNING "or51211: Load DVR Error 5\n"); - return -1; - } - - /* Read back ucode version to besure we loaded correctly */ - /* and are really up and running */ - rec_buf[0] = 0x04; - rec_buf[1] = 0x00; - rec_buf[2] = 0x03; - rec_buf[3] = 0x00; - msleep(30); - if (i2c_writebytes(state,state->config->demod_address, - rec_buf,3)) { - printk(KERN_WARNING "or51211: Load DVR Error A\n"); - return -1; - } - msleep(3); - if (i2c_readbytes(state,state->config->demod_address, - &rec_buf[10],2)) { - printk(KERN_WARNING "or51211: Load DVR Error B\n"); - return -1; - } - - rec_buf[0] = 0x04; - rec_buf[1] = 0x00; - rec_buf[2] = 0x01; - rec_buf[3] = 0x00; - msleep(20); - if (i2c_writebytes(state,state->config->demod_address, - rec_buf,3)) { - printk(KERN_WARNING "or51211: Load DVR Error C\n"); - return -1; - } - msleep(3); - if (i2c_readbytes(state,state->config->demod_address, - &rec_buf[12],2)) { - printk(KERN_WARNING "or51211: Load DVR Error D\n"); - return -1; - } - - for (i = 0; i < 8; i++) - rec_buf[i]=0xed; - - for (i = 0; i < 5; i++) { - msleep(30); - get_ver_buf[4] = i+1; - if (i2c_writebytes(state,state->config->demod_address, - get_ver_buf,5)) { - printk(KERN_WARNING "or51211:Load DVR Error 6" - " - %d\n",i); - return -1; - } - msleep(3); - - if (i2c_readbytes(state,state->config->demod_address, - &rec_buf[i*2],2)) { - printk(KERN_WARNING "or51211:Load DVR Error 7" - " - %d\n",i); - return -1; - } - /* If we didn't receive the right index, try again */ - if ((int)rec_buf[i*2+1]!=i+1){ - i--; - } - } - dprintk("read_fwbits %x %x %x %x %x %x %x %x %x %x\n", - rec_buf[0], rec_buf[1], rec_buf[2], rec_buf[3], - rec_buf[4], rec_buf[5], rec_buf[6], rec_buf[7], - rec_buf[8], rec_buf[9]); - - printk(KERN_INFO "or51211: ver TU%02x%02x%02x VSB mode %02x" - " Status %02x\n", - rec_buf[2], rec_buf[4],rec_buf[6], - rec_buf[12],rec_buf[10]); - - rec_buf[0] = 0x04; - rec_buf[1] = 0x00; - rec_buf[2] = 0x03; - rec_buf[3] = 0x00; - msleep(20); - if (i2c_writebytes(state,state->config->demod_address, - rec_buf,3)) { - printk(KERN_WARNING "or51211: Load DVR Error 8\n"); - return -1; - } - msleep(20); - if (i2c_readbytes(state,state->config->demod_address, - &rec_buf[8],2)) { - printk(KERN_WARNING "or51211: Load DVR Error 9\n"); - return -1; - } - state->initialized = 1; - } - - return 0; -} - -static int or51211_get_tune_settings(struct dvb_frontend* fe, - struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 500; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static void or51211_release(struct dvb_frontend* fe) -{ - struct or51211_state* state = fe->demodulator_priv; - state->config->sleep(fe); - kfree(state); -} - -static struct dvb_frontend_ops or51211_ops; - -struct dvb_frontend* or51211_attach(const struct or51211_config* config, - struct i2c_adapter* i2c) -{ - struct or51211_state* state = NULL; - - /* Allocate memory for the internal state */ - state = kmalloc(sizeof(struct or51211_state), GFP_KERNEL); - if (state == NULL) - return NULL; - - /* Setup the state */ - state->config = config; - state->i2c = i2c; - state->initialized = 0; - state->current_frequency = 0; - - /* Create dvb_frontend */ - memcpy(&state->frontend.ops, &or51211_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -static struct dvb_frontend_ops or51211_ops = { - - .info = { - .name = "Oren OR51211 VSB Frontend", - .type = FE_ATSC, - .frequency_min = 44000000, - .frequency_max = 958000000, - .frequency_stepsize = 166666, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_8VSB - }, - - .release = or51211_release, - - .init = or51211_init, - .sleep = or51211_sleep, - - .set_frontend = or51211_set_parameters, - .get_tune_settings = or51211_get_tune_settings, - - .read_status = or51211_read_status, - .read_ber = or51211_read_ber, - .read_signal_strength = or51211_read_signal_strength, - .read_snr = or51211_read_snr, - .read_ucblocks = or51211_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Oren OR51211 VSB [pcHDTV HD-2000] Demodulator Driver"); -MODULE_AUTHOR("Kirk Lapray"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(or51211_attach); - diff --git a/drivers/media/dvb/frontends/or51211.h b/drivers/media/dvb/frontends/or51211.h deleted file mode 100644 index 3ce0508b898..00000000000 --- a/drivers/media/dvb/frontends/or51211.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Support for OR51211 (pcHDTV HD-2000) - VSB - * - * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> - * - * 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 OR51211_H -#define OR51211_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -struct or51211_config -{ - /* The demodulator's i2c address */ - u8 demod_address; - - /* Request firmware for device */ - int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); - void (*setmode)(struct dvb_frontend * fe, int mode); - void (*reset)(struct dvb_frontend * fe); - void (*sleep)(struct dvb_frontend * fe); -}; - -#if defined(CONFIG_DVB_OR51211) || (defined(CONFIG_DVB_OR51211_MODULE) && defined(MODULE)) -extern struct dvb_frontend* or51211_attach(const struct or51211_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* or51211_attach(const struct or51211_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_OR51211 - -#endif // OR51211_H - diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c deleted file mode 100644 index 3e08d985d6e..00000000000 --- a/drivers/media/dvb/frontends/s5h1409.c +++ /dev/null @@ -1,868 +0,0 @@ -/* - Samsung S5H1409 VSB/QAM demodulator driver - - Copyright (C) 2006 Steven Toth <stoth@linuxtv.org> - - 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 <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "s5h1409.h" - -struct s5h1409_state { - - struct i2c_adapter *i2c; - - /* configuration settings */ - const struct s5h1409_config *config; - - struct dvb_frontend frontend; - - /* previous uncorrected block counter */ - fe_modulation_t current_modulation; - - u32 current_frequency; - int if_freq; - - u32 is_qam_locked; - u32 qam_state; -}; - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - -#define dprintk if (debug) printk - -/* Register values to initialise the demod, this will set VSB by default */ -static struct init_tab { - u8 reg; - u16 data; -} init_tab[] = { - { 0x00, 0x0071, }, - { 0x01, 0x3213, }, - { 0x09, 0x0025, }, - { 0x1c, 0x001d, }, - { 0x1f, 0x002d, }, - { 0x20, 0x001d, }, - { 0x22, 0x0022, }, - { 0x23, 0x0020, }, - { 0x29, 0x110f, }, - { 0x2a, 0x10b4, }, - { 0x2b, 0x10ae, }, - { 0x2c, 0x0031, }, - { 0x31, 0x010d, }, - { 0x32, 0x0100, }, - { 0x44, 0x0510, }, - { 0x54, 0x0104, }, - { 0x58, 0x2222, }, - { 0x59, 0x1162, }, - { 0x5a, 0x3211, }, - { 0x5d, 0x0370, }, - { 0x5e, 0x0296, }, - { 0x61, 0x0010, }, - { 0x63, 0x4a00, }, - { 0x65, 0x0800, }, - { 0x71, 0x0003, }, - { 0x72, 0x0470, }, - { 0x81, 0x0002, }, - { 0x82, 0x0600, }, - { 0x86, 0x0002, }, - { 0x8a, 0x2c38, }, - { 0x8b, 0x2a37, }, - { 0x92, 0x302f, }, - { 0x93, 0x3332, }, - { 0x96, 0x000c, }, - { 0x99, 0x0101, }, - { 0x9c, 0x2e37, }, - { 0x9d, 0x2c37, }, - { 0x9e, 0x2c37, }, - { 0xab, 0x0100, }, - { 0xac, 0x1003, }, - { 0xad, 0x103f, }, - { 0xe2, 0x0100, }, - { 0xe3, 0x1000, }, - { 0x28, 0x1010, }, - { 0xb1, 0x000e, }, -}; - -/* VSB SNR lookup table */ -static struct vsb_snr_tab { - u16 val; - u16 data; -} vsb_snr_tab[] = { - { 924, 300, }, - { 923, 300, }, - { 918, 295, }, - { 915, 290, }, - { 911, 285, }, - { 906, 280, }, - { 901, 275, }, - { 896, 270, }, - { 891, 265, }, - { 885, 260, }, - { 879, 255, }, - { 873, 250, }, - { 864, 245, }, - { 858, 240, }, - { 850, 235, }, - { 841, 230, }, - { 832, 225, }, - { 823, 220, }, - { 812, 215, }, - { 802, 210, }, - { 788, 205, }, - { 778, 200, }, - { 767, 195, }, - { 753, 190, }, - { 740, 185, }, - { 725, 180, }, - { 707, 175, }, - { 689, 170, }, - { 671, 165, }, - { 656, 160, }, - { 637, 155, }, - { 616, 150, }, - { 542, 145, }, - { 519, 140, }, - { 507, 135, }, - { 497, 130, }, - { 492, 125, }, - { 474, 120, }, - { 300, 111, }, - { 0, 0, }, -}; - -/* QAM64 SNR lookup table */ -static struct qam64_snr_tab { - u16 val; - u16 data; -} qam64_snr_tab[] = { - { 1, 0, }, - { 12, 300, }, - { 15, 290, }, - { 18, 280, }, - { 22, 270, }, - { 23, 268, }, - { 24, 266, }, - { 25, 264, }, - { 27, 262, }, - { 28, 260, }, - { 29, 258, }, - { 30, 256, }, - { 32, 254, }, - { 33, 252, }, - { 34, 250, }, - { 35, 249, }, - { 36, 248, }, - { 37, 247, }, - { 38, 246, }, - { 39, 245, }, - { 40, 244, }, - { 41, 243, }, - { 42, 241, }, - { 43, 240, }, - { 44, 239, }, - { 45, 238, }, - { 46, 237, }, - { 47, 236, }, - { 48, 235, }, - { 49, 234, }, - { 50, 233, }, - { 51, 232, }, - { 52, 231, }, - { 53, 230, }, - { 55, 229, }, - { 56, 228, }, - { 57, 227, }, - { 58, 226, }, - { 59, 225, }, - { 60, 224, }, - { 62, 223, }, - { 63, 222, }, - { 65, 221, }, - { 66, 220, }, - { 68, 219, }, - { 69, 218, }, - { 70, 217, }, - { 72, 216, }, - { 73, 215, }, - { 75, 214, }, - { 76, 213, }, - { 78, 212, }, - { 80, 211, }, - { 81, 210, }, - { 83, 209, }, - { 84, 208, }, - { 85, 207, }, - { 87, 206, }, - { 89, 205, }, - { 91, 204, }, - { 93, 203, }, - { 95, 202, }, - { 96, 201, }, - { 104, 200, }, - { 255, 0, }, -}; - -/* QAM256 SNR lookup table */ -static struct qam256_snr_tab { - u16 val; - u16 data; -} qam256_snr_tab[] = { - { 1, 0, }, - { 12, 400, }, - { 13, 390, }, - { 15, 380, }, - { 17, 360, }, - { 19, 350, }, - { 22, 348, }, - { 23, 346, }, - { 24, 344, }, - { 25, 342, }, - { 26, 340, }, - { 27, 336, }, - { 28, 334, }, - { 29, 332, }, - { 30, 330, }, - { 31, 328, }, - { 32, 326, }, - { 33, 325, }, - { 34, 322, }, - { 35, 320, }, - { 37, 318, }, - { 39, 316, }, - { 40, 314, }, - { 41, 312, }, - { 42, 310, }, - { 43, 308, }, - { 46, 306, }, - { 47, 304, }, - { 49, 302, }, - { 51, 300, }, - { 53, 298, }, - { 54, 297, }, - { 55, 296, }, - { 56, 295, }, - { 57, 294, }, - { 59, 293, }, - { 60, 292, }, - { 61, 291, }, - { 63, 290, }, - { 64, 289, }, - { 65, 288, }, - { 66, 287, }, - { 68, 286, }, - { 69, 285, }, - { 71, 284, }, - { 72, 283, }, - { 74, 282, }, - { 75, 281, }, - { 76, 280, }, - { 77, 279, }, - { 78, 278, }, - { 81, 277, }, - { 83, 276, }, - { 84, 275, }, - { 86, 274, }, - { 87, 273, }, - { 89, 272, }, - { 90, 271, }, - { 92, 270, }, - { 93, 269, }, - { 95, 268, }, - { 96, 267, }, - { 98, 266, }, - { 100, 265, }, - { 102, 264, }, - { 104, 263, }, - { 105, 262, }, - { 106, 261, }, - { 110, 260, }, - { 255, 0, }, -}; - -/* 8 bit registers, 16 bit values */ -static int s5h1409_writereg(struct s5h1409_state *state, u8 reg, u16 data) -{ - int ret; - u8 buf[] = { reg, data >> 8, data & 0xff }; - - 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(KERN_ERR "%s: error (reg == 0x%02x, val == 0x%04x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static u16 s5h1409_readreg(struct s5h1409_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0, 0 }; - - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, - .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, - .buf = b1, .len = 2 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - printk("%s: readreg error (ret == %i)\n", __func__, ret); - return (b1[0] << 8) | b1[1]; -} - -static int s5h1409_softreset(struct dvb_frontend *fe) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - s5h1409_writereg(state, 0xf5, 0); - s5h1409_writereg(state, 0xf5, 1); - state->is_qam_locked = 0; - state->qam_state = 0; - return 0; -} - -#define S5H1409_VSB_IF_FREQ 5380 -#define S5H1409_QAM_IF_FREQ (state->config->qam_if) - -static int s5h1409_set_if_freq(struct dvb_frontend *fe, int KHz) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(%d KHz)\n", __func__, KHz); - - switch (KHz) { - case 4000: - s5h1409_writereg(state, 0x87, 0x014b); - s5h1409_writereg(state, 0x88, 0x0cb5); - s5h1409_writereg(state, 0x89, 0x03e2); - break; - case 5380: - case 44000: - default: - s5h1409_writereg(state, 0x87, 0x01be); - s5h1409_writereg(state, 0x88, 0x0436); - s5h1409_writereg(state, 0x89, 0x054d); - break; - } - state->if_freq = KHz; - - return 0; -} - -static int s5h1409_set_spectralinversion(struct dvb_frontend *fe, int inverted) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, inverted); - - if (inverted == 1) - return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */ - else - return s5h1409_writereg(state, 0x1b, 0x0110); /* Normal */ -} - -static int s5h1409_enable_modulation(struct dvb_frontend *fe, - fe_modulation_t m) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(0x%08x)\n", __func__, m); - - switch (m) { - case VSB_8: - dprintk("%s() VSB_8\n", __func__); - if (state->if_freq != S5H1409_VSB_IF_FREQ) - s5h1409_set_if_freq(fe, S5H1409_VSB_IF_FREQ); - s5h1409_writereg(state, 0xf4, 0); - break; - case QAM_64: - case QAM_256: - case QAM_AUTO: - dprintk("%s() QAM_AUTO (64/256)\n", __func__); - if (state->if_freq != S5H1409_QAM_IF_FREQ) - s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ); - s5h1409_writereg(state, 0xf4, 1); - s5h1409_writereg(state, 0x85, 0x110); - break; - default: - dprintk("%s() Invalid modulation\n", __func__); - return -EINVAL; - } - - state->current_modulation = m; - s5h1409_softreset(fe); - - return 0; -} - -static int s5h1409_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, enable); - - if (enable) - return s5h1409_writereg(state, 0xf3, 1); - else - return s5h1409_writereg(state, 0xf3, 0); -} - -static int s5h1409_set_gpio(struct dvb_frontend *fe, int enable) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, enable); - - if (enable) - return s5h1409_writereg(state, 0xe3, - s5h1409_readreg(state, 0xe3) | 0x1100); - else - return s5h1409_writereg(state, 0xe3, - s5h1409_readreg(state, 0xe3) & 0xfeff); -} - -static int s5h1409_sleep(struct dvb_frontend *fe, int enable) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, enable); - - return s5h1409_writereg(state, 0xf2, enable); -} - -static int s5h1409_register_reset(struct dvb_frontend *fe) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - return s5h1409_writereg(state, 0xfa, 0); -} - -static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe) -{ - struct s5h1409_state *state = fe->demodulator_priv; - u16 reg; - - if (state->is_qam_locked) - return; - - /* QAM EQ lock check */ - reg = s5h1409_readreg(state, 0xf0); - - if ((reg >> 13) & 0x1) { - - state->is_qam_locked = 1; - reg &= 0xff; - - s5h1409_writereg(state, 0x96, 0x00c); - if ((reg < 0x38) || (reg > 0x68)) { - s5h1409_writereg(state, 0x93, 0x3332); - s5h1409_writereg(state, 0x9e, 0x2c37); - } else { - s5h1409_writereg(state, 0x93, 0x3130); - s5h1409_writereg(state, 0x9e, 0x2836); - } - - } else { - s5h1409_writereg(state, 0x96, 0x0008); - s5h1409_writereg(state, 0x93, 0x3332); - s5h1409_writereg(state, 0x9e, 0x2c37); - } -} - -static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe) -{ - struct s5h1409_state *state = fe->demodulator_priv; - u16 reg, reg1, reg2; - - reg = s5h1409_readreg(state, 0xf1); - - /* Master lock */ - if ((reg >> 15) & 0x1) { - if (state->qam_state != 2) { - state->qam_state = 2; - reg1 = s5h1409_readreg(state, 0xb2); - reg2 = s5h1409_readreg(state, 0xad); - - s5h1409_writereg(state, 0x96, 0x20); - s5h1409_writereg(state, 0xad, - (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff))); - s5h1409_writereg(state, 0xab, - s5h1409_readreg(state, 0xab) & 0xeffe); - } - } else { - if (state->qam_state != 1) { - state->qam_state = 1; - s5h1409_writereg(state, 0x96, 0x08); - s5h1409_writereg(state, 0xab, - s5h1409_readreg(state, 0xab) | 0x1001); - } - } -} - -/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int s5h1409_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(frequency=%d)\n", __func__, p->frequency); - - s5h1409_softreset(fe); - - state->current_frequency = p->frequency; - - s5h1409_enable_modulation(fe, p->u.vsb.modulation); - - if (fe->ops.tuner_ops.set_params) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* Optimize the demod for QAM */ - if (p->u.vsb.modulation != VSB_8) { - s5h1409_set_qam_amhum_mode(fe); - s5h1409_set_qam_interleave_mode(fe); - } - - /* Issue a reset to the demod so it knows to resync against the - newly tuned frequency */ - s5h1409_softreset(fe); - - return 0; -} - -static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode) -{ - struct s5h1409_state *state = fe->demodulator_priv; - u16 val; - - dprintk("%s(%d)\n", __func__, mode); - - val = s5h1409_readreg(state, 0xac) & 0xcfff; - switch (mode) { - case S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK: - val |= 0x0000; - break; - case S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK: - dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode); - val |= 0x1000; - break; - case S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK: - val |= 0x2000; - break; - case S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK: - val |= 0x3000; - break; - default: - return -EINVAL; - } - - /* Configure MPEG Signal Timing charactistics */ - return s5h1409_writereg(state, 0xac, val); -} - -/* Reset the demod hardware and reset all of the configuration registers - to a default state. */ -static int s5h1409_init(struct dvb_frontend *fe) -{ - int i; - - struct s5h1409_state *state = fe->demodulator_priv; - dprintk("%s()\n", __func__); - - s5h1409_sleep(fe, 0); - s5h1409_register_reset(fe); - - for (i = 0; i < ARRAY_SIZE(init_tab); i++) - s5h1409_writereg(state, init_tab[i].reg, init_tab[i].data); - - /* The datasheet says that after initialisation, VSB is default */ - state->current_modulation = VSB_8; - - if (state->config->output_mode == S5H1409_SERIAL_OUTPUT) - s5h1409_writereg(state, 0xab, - s5h1409_readreg(state, 0xab) | 0x100); /* Serial */ - else - s5h1409_writereg(state, 0xab, - s5h1409_readreg(state, 0xab) & 0xfeff); /* Parallel */ - - s5h1409_set_spectralinversion(fe, state->config->inversion); - s5h1409_set_if_freq(fe, state->if_freq); - s5h1409_set_gpio(fe, state->config->gpio); - s5h1409_set_mpeg_timing(fe, state->config->mpeg_timing); - s5h1409_softreset(fe); - - /* Note: Leaving the I2C gate closed. */ - s5h1409_i2c_gate_ctrl(fe, 0); - - return 0; -} - -static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct s5h1409_state *state = fe->demodulator_priv; - u16 reg; - u32 tuner_status = 0; - - *status = 0; - - /* Get the demodulator status */ - reg = s5h1409_readreg(state, 0xf1); - if (reg & 0x1000) - *status |= FE_HAS_VITERBI; - if (reg & 0x8000) - *status |= FE_HAS_LOCK | FE_HAS_SYNC; - - switch (state->config->status_mode) { - case S5H1409_DEMODLOCKING: - if (*status & FE_HAS_VITERBI) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - case S5H1409_TUNERLOCKING: - /* Get the tuner status */ - 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; - } - - dprintk("%s() status 0x%08x\n", __func__, *status); - - return 0; -} - -static int s5h1409_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) { - if (v < qam256_snr_tab[i].val) { - *snr = qam256_snr_tab[i].data; - ret = 0; - break; - } - } - return ret; -} - -static int s5h1409_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) { - if (v < qam64_snr_tab[i].val) { - *snr = qam64_snr_tab[i].data; - ret = 0; - break; - } - } - return ret; -} - -static int s5h1409_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) { - if (v > vsb_snr_tab[i].val) { - *snr = vsb_snr_tab[i].data; - ret = 0; - break; - } - } - dprintk("%s() snr=%d\n", __func__, *snr); - return ret; -} - -static int s5h1409_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct s5h1409_state *state = fe->demodulator_priv; - u16 reg; - dprintk("%s()\n", __func__); - - switch (state->current_modulation) { - case QAM_64: - reg = s5h1409_readreg(state, 0xf0) & 0xff; - return s5h1409_qam64_lookup_snr(fe, snr, reg); - case QAM_256: - reg = s5h1409_readreg(state, 0xf0) & 0xff; - return s5h1409_qam256_lookup_snr(fe, snr, reg); - case VSB_8: - reg = s5h1409_readreg(state, 0xf1) & 0x3ff; - return s5h1409_vsb_lookup_snr(fe, snr, reg); - default: - break; - } - - return -EINVAL; -} - -static int s5h1409_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - return s5h1409_read_snr(fe, signal_strength); -} - -static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - *ucblocks = s5h1409_readreg(state, 0xb5); - - return 0; -} - -static int s5h1409_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - return s5h1409_read_ucblocks(fe, ber); -} - -static int s5h1409_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - p->frequency = state->current_frequency; - p->u.vsb.modulation = state->current_modulation; - - return 0; -} - -static int s5h1409_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void s5h1409_release(struct dvb_frontend *fe) -{ - struct s5h1409_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops s5h1409_ops; - -struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config, - struct i2c_adapter *i2c) -{ - struct s5h1409_state *state = NULL; - u16 reg; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct s5h1409_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->current_modulation = 0; - state->if_freq = S5H1409_VSB_IF_FREQ; - - /* check if the demod exists */ - reg = s5h1409_readreg(state, 0x04); - if ((reg != 0x0066) && (reg != 0x007f)) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &s5h1409_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - if (s5h1409_init(&state->frontend) != 0) { - printk(KERN_ERR "%s: Failed to initialize correctly\n", - __func__); - goto error; - } - - /* Note: Leaving the I2C gate open here. */ - s5h1409_i2c_gate_ctrl(&state->frontend, 1); - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(s5h1409_attach); - -static struct dvb_frontend_ops s5h1409_ops = { - - .info = { - .name = "Samsung S5H1409 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 = s5h1409_init, - .i2c_gate_ctrl = s5h1409_i2c_gate_ctrl, - .set_frontend = s5h1409_set_frontend, - .get_frontend = s5h1409_get_frontend, - .get_tune_settings = s5h1409_get_tune_settings, - .read_status = s5h1409_read_status, - .read_ber = s5h1409_read_ber, - .read_signal_strength = s5h1409_read_signal_strength, - .read_snr = s5h1409_read_snr, - .read_ucblocks = s5h1409_read_ucblocks, - .release = s5h1409_release, -}; - -MODULE_DESCRIPTION("Samsung S5H1409 QAM-B/ATSC Demodulator driver"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); - - -/* - * Local variables: - * c-basic-offset: 8 - */ diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb/frontends/s5h1409.h deleted file mode 100644 index 070d9743e33..00000000000 --- a/drivers/media/dvb/frontends/s5h1409.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - Samsung S5H1409 VSB/QAM demodulator driver - - Copyright (C) 2006 Steven Toth <stoth@linuxtv.org> - - 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 __S5H1409_H__ -#define __S5H1409_H__ - -#include <linux/dvb/frontend.h> - -struct s5h1409_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* serial/parallel output */ -#define S5H1409_PARALLEL_OUTPUT 0 -#define S5H1409_SERIAL_OUTPUT 1 - u8 output_mode; - - /* GPIO Setting */ -#define S5H1409_GPIO_OFF 0 -#define S5H1409_GPIO_ON 1 - u8 gpio; - - /* IF Freq for QAM in KHz, VSB is hardcoded to 5380 */ - u16 qam_if; - - /* Spectral Inversion */ -#define S5H1409_INVERSION_OFF 0 -#define S5H1409_INVERSION_ON 1 - u8 inversion; - - /* Return lock status based on tuner lock, or demod lock */ -#define S5H1409_TUNERLOCKING 0 -#define S5H1409_DEMODLOCKING 1 - u8 status_mode; - - /* MPEG signal timing */ -#define S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0 -#define S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1 -#define S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2 -#define S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3 - u16 mpeg_timing; -}; - -#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \ - && defined(MODULE)) -extern struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *s5h1409_attach( - const struct s5h1409_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_S5H1409 */ - -#endif /* __S5H1409_H__ */ - -/* - * Local variables: - * c-basic-offset: 8 - */ diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c deleted file mode 100644 index 66e2dd6d6fe..00000000000 --- a/drivers/media/dvb/frontends/s5h1411.c +++ /dev/null @@ -1,923 +0,0 @@ -/* - Samsung S5H1411 VSB/QAM demodulator driver - - Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> - - 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 <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "s5h1411.h" - -struct s5h1411_state { - - struct i2c_adapter *i2c; - - /* configuration settings */ - const struct s5h1411_config *config; - - struct dvb_frontend frontend; - - fe_modulation_t current_modulation; - unsigned int first_tune:1; - - u32 current_frequency; - int if_freq; - - u8 inversion; -}; - -static int debug; - -#define dprintk(arg...) do { \ - if (debug) \ - printk(arg); \ - } while (0) - -/* Register values to initialise the demod, defaults to VSB */ -static struct init_tab { - u8 addr; - u8 reg; - u16 data; -} init_tab[] = { - { S5H1411_I2C_TOP_ADDR, 0x00, 0x0071, }, - { S5H1411_I2C_TOP_ADDR, 0x08, 0x0047, }, - { S5H1411_I2C_TOP_ADDR, 0x1c, 0x0400, }, - { S5H1411_I2C_TOP_ADDR, 0x1e, 0x0370, }, - { S5H1411_I2C_TOP_ADDR, 0x1f, 0x342c, }, - { S5H1411_I2C_TOP_ADDR, 0x24, 0x0231, }, - { S5H1411_I2C_TOP_ADDR, 0x25, 0x1011, }, - { S5H1411_I2C_TOP_ADDR, 0x26, 0x0f07, }, - { S5H1411_I2C_TOP_ADDR, 0x27, 0x0f04, }, - { S5H1411_I2C_TOP_ADDR, 0x28, 0x070f, }, - { S5H1411_I2C_TOP_ADDR, 0x29, 0x2820, }, - { S5H1411_I2C_TOP_ADDR, 0x2a, 0x102e, }, - { S5H1411_I2C_TOP_ADDR, 0x2b, 0x0220, }, - { S5H1411_I2C_TOP_ADDR, 0x2e, 0x0d0e, }, - { S5H1411_I2C_TOP_ADDR, 0x2f, 0x1013, }, - { S5H1411_I2C_TOP_ADDR, 0x31, 0x171b, }, - { S5H1411_I2C_TOP_ADDR, 0x32, 0x0e0f, }, - { S5H1411_I2C_TOP_ADDR, 0x33, 0x0f10, }, - { S5H1411_I2C_TOP_ADDR, 0x34, 0x170e, }, - { S5H1411_I2C_TOP_ADDR, 0x35, 0x4b10, }, - { S5H1411_I2C_TOP_ADDR, 0x36, 0x0f17, }, - { S5H1411_I2C_TOP_ADDR, 0x3c, 0x1577, }, - { S5H1411_I2C_TOP_ADDR, 0x3d, 0x081a, }, - { S5H1411_I2C_TOP_ADDR, 0x3e, 0x77ee, }, - { S5H1411_I2C_TOP_ADDR, 0x40, 0x1e09, }, - { S5H1411_I2C_TOP_ADDR, 0x41, 0x0f0c, }, - { S5H1411_I2C_TOP_ADDR, 0x42, 0x1f10, }, - { S5H1411_I2C_TOP_ADDR, 0x4d, 0x0509, }, - { S5H1411_I2C_TOP_ADDR, 0x4e, 0x0a00, }, - { S5H1411_I2C_TOP_ADDR, 0x50, 0x0000, }, - { S5H1411_I2C_TOP_ADDR, 0x5b, 0x0000, }, - { S5H1411_I2C_TOP_ADDR, 0x5c, 0x0008, }, - { S5H1411_I2C_TOP_ADDR, 0x57, 0x1101, }, - { S5H1411_I2C_TOP_ADDR, 0x65, 0x007c, }, - { S5H1411_I2C_TOP_ADDR, 0x68, 0x0512, }, - { S5H1411_I2C_TOP_ADDR, 0x69, 0x0258, }, - { S5H1411_I2C_TOP_ADDR, 0x70, 0x0004, }, - { S5H1411_I2C_TOP_ADDR, 0x71, 0x0007, }, - { S5H1411_I2C_TOP_ADDR, 0x76, 0x00a9, }, - { S5H1411_I2C_TOP_ADDR, 0x78, 0x3141, }, - { S5H1411_I2C_TOP_ADDR, 0x7a, 0x3141, }, - { S5H1411_I2C_TOP_ADDR, 0xb3, 0x8003, }, - { S5H1411_I2C_TOP_ADDR, 0xb5, 0xa6bb, }, - { S5H1411_I2C_TOP_ADDR, 0xb6, 0x0609, }, - { S5H1411_I2C_TOP_ADDR, 0xb7, 0x2f06, }, - { S5H1411_I2C_TOP_ADDR, 0xb8, 0x003f, }, - { S5H1411_I2C_TOP_ADDR, 0xb9, 0x2700, }, - { S5H1411_I2C_TOP_ADDR, 0xba, 0xfac8, }, - { S5H1411_I2C_TOP_ADDR, 0xbe, 0x1003, }, - { S5H1411_I2C_TOP_ADDR, 0xbf, 0x103f, }, - { S5H1411_I2C_TOP_ADDR, 0xce, 0x2000, }, - { S5H1411_I2C_TOP_ADDR, 0xcf, 0x0800, }, - { S5H1411_I2C_TOP_ADDR, 0xd0, 0x0800, }, - { S5H1411_I2C_TOP_ADDR, 0xd1, 0x0400, }, - { S5H1411_I2C_TOP_ADDR, 0xd2, 0x0800, }, - { S5H1411_I2C_TOP_ADDR, 0xd3, 0x2000, }, - { S5H1411_I2C_TOP_ADDR, 0xd4, 0x3000, }, - { S5H1411_I2C_TOP_ADDR, 0xdb, 0x4a9b, }, - { S5H1411_I2C_TOP_ADDR, 0xdc, 0x1000, }, - { S5H1411_I2C_TOP_ADDR, 0xde, 0x0001, }, - { S5H1411_I2C_TOP_ADDR, 0xdf, 0x0000, }, - { S5H1411_I2C_TOP_ADDR, 0xe3, 0x0301, }, - { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0000, }, - { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0001, }, - { S5H1411_I2C_QAM_ADDR, 0x08, 0x0600, }, - { S5H1411_I2C_QAM_ADDR, 0x18, 0x4201, }, - { S5H1411_I2C_QAM_ADDR, 0x1e, 0x6476, }, - { S5H1411_I2C_QAM_ADDR, 0x21, 0x0830, }, - { S5H1411_I2C_QAM_ADDR, 0x0c, 0x5679, }, - { S5H1411_I2C_QAM_ADDR, 0x0d, 0x579b, }, - { S5H1411_I2C_QAM_ADDR, 0x24, 0x0102, }, - { S5H1411_I2C_QAM_ADDR, 0x31, 0x7488, }, - { S5H1411_I2C_QAM_ADDR, 0x32, 0x0a08, }, - { S5H1411_I2C_QAM_ADDR, 0x3d, 0x8689, }, - { S5H1411_I2C_QAM_ADDR, 0x49, 0x0048, }, - { S5H1411_I2C_QAM_ADDR, 0x57, 0x2012, }, - { S5H1411_I2C_QAM_ADDR, 0x5d, 0x7676, }, - { S5H1411_I2C_QAM_ADDR, 0x04, 0x0400, }, - { S5H1411_I2C_QAM_ADDR, 0x58, 0x00c0, }, - { S5H1411_I2C_QAM_ADDR, 0x5b, 0x0100, }, -}; - -/* VSB SNR lookup table */ -static struct vsb_snr_tab { - u16 val; - u16 data; -} vsb_snr_tab[] = { - { 0x39f, 300, }, - { 0x39b, 295, }, - { 0x397, 290, }, - { 0x394, 285, }, - { 0x38f, 280, }, - { 0x38b, 275, }, - { 0x387, 270, }, - { 0x382, 265, }, - { 0x37d, 260, }, - { 0x377, 255, }, - { 0x370, 250, }, - { 0x36a, 245, }, - { 0x364, 240, }, - { 0x35b, 235, }, - { 0x353, 230, }, - { 0x349, 225, }, - { 0x340, 320, }, - { 0x337, 215, }, - { 0x327, 210, }, - { 0x31b, 205, }, - { 0x310, 200, }, - { 0x302, 195, }, - { 0x2f3, 190, }, - { 0x2e4, 185, }, - { 0x2d7, 180, }, - { 0x2cd, 175, }, - { 0x2bb, 170, }, - { 0x2a9, 165, }, - { 0x29e, 160, }, - { 0x284, 155, }, - { 0x27a, 150, }, - { 0x260, 145, }, - { 0x23a, 140, }, - { 0x224, 135, }, - { 0x213, 130, }, - { 0x204, 125, }, - { 0x1fe, 120, }, - { 0, 0, }, -}; - -/* QAM64 SNR lookup table */ -static struct qam64_snr_tab { - u16 val; - u16 data; -} qam64_snr_tab[] = { - { 0x0001, 0, }, - { 0x0af0, 300, }, - { 0x0d80, 290, }, - { 0x10a0, 280, }, - { 0x14b5, 270, }, - { 0x1590, 268, }, - { 0x1680, 266, }, - { 0x17b0, 264, }, - { 0x18c0, 262, }, - { 0x19b0, 260, }, - { 0x1ad0, 258, }, - { 0x1d00, 256, }, - { 0x1da0, 254, }, - { 0x1ef0, 252, }, - { 0x2050, 250, }, - { 0x20f0, 249, }, - { 0x21d0, 248, }, - { 0x22b0, 247, }, - { 0x23a0, 246, }, - { 0x2470, 245, }, - { 0x24f0, 244, }, - { 0x25a0, 243, }, - { 0x26c0, 242, }, - { 0x27b0, 241, }, - { 0x28d0, 240, }, - { 0x29b0, 239, }, - { 0x2ad0, 238, }, - { 0x2ba0, 237, }, - { 0x2c80, 236, }, - { 0x2d20, 235, }, - { 0x2e00, 234, }, - { 0x2f10, 233, }, - { 0x3050, 232, }, - { 0x3190, 231, }, - { 0x3300, 230, }, - { 0x3340, 229, }, - { 0x3200, 228, }, - { 0x3550, 227, }, - { 0x3610, 226, }, - { 0x3600, 225, }, - { 0x3700, 224, }, - { 0x3800, 223, }, - { 0x3920, 222, }, - { 0x3a20, 221, }, - { 0x3b30, 220, }, - { 0x3d00, 219, }, - { 0x3e00, 218, }, - { 0x4000, 217, }, - { 0x4100, 216, }, - { 0x4300, 215, }, - { 0x4400, 214, }, - { 0x4600, 213, }, - { 0x4700, 212, }, - { 0x4800, 211, }, - { 0x4a00, 210, }, - { 0x4b00, 209, }, - { 0x4d00, 208, }, - { 0x4f00, 207, }, - { 0x5050, 206, }, - { 0x5200, 205, }, - { 0x53c0, 204, }, - { 0x5450, 203, }, - { 0x5650, 202, }, - { 0x5820, 201, }, - { 0x6000, 200, }, - { 0xffff, 0, }, -}; - -/* QAM256 SNR lookup table */ -static struct qam256_snr_tab { - u16 val; - u16 data; -} qam256_snr_tab[] = { - { 0x0001, 0, }, - { 0x0970, 400, }, - { 0x0a90, 390, }, - { 0x0b90, 380, }, - { 0x0d90, 370, }, - { 0x0ff0, 360, }, - { 0x1240, 350, }, - { 0x1345, 348, }, - { 0x13c0, 346, }, - { 0x14c0, 344, }, - { 0x1500, 342, }, - { 0x1610, 340, }, - { 0x1700, 338, }, - { 0x1800, 336, }, - { 0x18b0, 334, }, - { 0x1900, 332, }, - { 0x1ab0, 330, }, - { 0x1bc0, 328, }, - { 0x1cb0, 326, }, - { 0x1db0, 324, }, - { 0x1eb0, 322, }, - { 0x2030, 320, }, - { 0x2200, 318, }, - { 0x2280, 316, }, - { 0x2410, 314, }, - { 0x25b0, 312, }, - { 0x27a0, 310, }, - { 0x2840, 308, }, - { 0x29d0, 306, }, - { 0x2b10, 304, }, - { 0x2d30, 302, }, - { 0x2f20, 300, }, - { 0x30c0, 298, }, - { 0x3260, 297, }, - { 0x32c0, 296, }, - { 0x3300, 295, }, - { 0x33b0, 294, }, - { 0x34b0, 293, }, - { 0x35a0, 292, }, - { 0x3650, 291, }, - { 0x3800, 290, }, - { 0x3900, 289, }, - { 0x3a50, 288, }, - { 0x3b30, 287, }, - { 0x3cb0, 286, }, - { 0x3e20, 285, }, - { 0x3fa0, 284, }, - { 0x40a0, 283, }, - { 0x41c0, 282, }, - { 0x42f0, 281, }, - { 0x44a0, 280, }, - { 0x4600, 279, }, - { 0x47b0, 278, }, - { 0x4900, 277, }, - { 0x4a00, 276, }, - { 0x4ba0, 275, }, - { 0x4d00, 274, }, - { 0x4f00, 273, }, - { 0x5000, 272, }, - { 0x51f0, 272, }, - { 0x53a0, 270, }, - { 0x5520, 269, }, - { 0x5700, 268, }, - { 0x5800, 267, }, - { 0x5a00, 266, }, - { 0x5c00, 265, }, - { 0x5d00, 264, }, - { 0x5f00, 263, }, - { 0x6000, 262, }, - { 0x6200, 261, }, - { 0x6400, 260, }, - { 0xffff, 0, }, -}; - -/* 8 bit registers, 16 bit values */ -static int s5h1411_writereg(struct s5h1411_state *state, - u8 addr, u8 reg, u16 data) -{ - int ret; - u8 buf[] = { reg, data >> 8, data & 0xff }; - - struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, " - "ret == %i)\n", __func__, addr, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0, 0 }; - - struct i2c_msg msg[] = { - { .addr = addr, .flags = 0, .buf = b0, .len = 1 }, - { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - printk(KERN_ERR "%s: readreg error (ret == %i)\n", - __func__, ret); - return (b1[0] << 8) | b1[1]; -} - -static int s5h1411_softreset(struct dvb_frontend *fe) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 0); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 1); - return 0; -} - -static int s5h1411_set_if_freq(struct dvb_frontend *fe, int KHz) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s(%d KHz)\n", __func__, KHz); - - switch (KHz) { - case 3250: - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x10d5); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x5342); - s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x10d9); - break; - case 3500: - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1225); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x1e96); - s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1225); - break; - case 4000: - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x14bc); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0xb53e); - s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x14bd); - break; - default: - dprintk("%s(%d KHz) Invalid, defaulting to 5380\n", - __func__, KHz); - /* no break, need to continue */ - case 5380: - case 44000: - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1be4); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x3655); - s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1be4); - break; - } - - state->if_freq = KHz; - - return 0; -} - -static int s5h1411_set_mpeg_timing(struct dvb_frontend *fe, int mode) -{ - struct s5h1411_state *state = fe->demodulator_priv; - u16 val; - - dprintk("%s(%d)\n", __func__, mode); - - val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbe) & 0xcfff; - switch (mode) { - case S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK: - val |= 0x0000; - break; - case S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK: - dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode); - val |= 0x1000; - break; - case S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK: - val |= 0x2000; - break; - case S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK: - val |= 0x3000; - break; - default: - return -EINVAL; - } - - /* Configure MPEG Signal Timing charactistics */ - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbe, val); -} - -static int s5h1411_set_spectralinversion(struct dvb_frontend *fe, int inversion) -{ - struct s5h1411_state *state = fe->demodulator_priv; - u16 val; - - dprintk("%s(%d)\n", __func__, inversion); - val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x24) & ~0x1000; - - if (inversion == 1) - val |= 0x1000; /* Inverted */ - - state->inversion = inversion; - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x24, val); -} - -static int s5h1411_set_serialmode(struct dvb_frontend *fe, int serial) -{ - struct s5h1411_state *state = fe->demodulator_priv; - u16 val; - - dprintk("%s(%d)\n", __func__, serial); - val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbd) & ~0x100; - - if (serial == 1) - val |= 0x100; - - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, val); -} - -static int s5h1411_enable_modulation(struct dvb_frontend *fe, - fe_modulation_t m) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s(0x%08x)\n", __func__, m); - - if ((state->first_tune == 0) && (m == state->current_modulation)) { - dprintk("%s() Already at desired modulation. Skipping...\n", - __func__); - return 0; - } - - switch (m) { - case VSB_8: - dprintk("%s() VSB_8\n", __func__); - s5h1411_set_if_freq(fe, state->config->vsb_if); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x71); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x00); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0xf1); - break; - case QAM_64: - case QAM_256: - case QAM_AUTO: - dprintk("%s() QAM_AUTO (64/256)\n", __func__); - s5h1411_set_if_freq(fe, state->config->qam_if); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x0171); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x0001); - s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x16, 0x1101); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0x00f0); - break; - default: - dprintk("%s() Invalid modulation\n", __func__); - return -EINVAL; - } - - state->current_modulation = m; - state->first_tune = 0; - s5h1411_softreset(fe); - - return 0; -} - -static int s5h1411_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, enable); - - if (enable) - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1); - else - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 0); -} - -static int s5h1411_set_gpio(struct dvb_frontend *fe, int enable) -{ - struct s5h1411_state *state = fe->demodulator_priv; - u16 val; - - dprintk("%s(%d)\n", __func__, enable); - - val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xe0) & ~0x02; - - if (enable) - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, - val | 0x02); - else - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, val); -} - -static int s5h1411_set_powerstate(struct dvb_frontend *fe, int enable) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, enable); - - if (enable) - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 1); - else { - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 0); - s5h1411_softreset(fe); - } - - return 0; -} - -static int s5h1411_sleep(struct dvb_frontend *fe) -{ - return s5h1411_set_powerstate(fe, 1); -} - -static int s5h1411_register_reset(struct dvb_frontend *fe) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf3, 0); -} - -/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int s5h1411_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s(frequency=%d)\n", __func__, p->frequency); - - s5h1411_softreset(fe); - - state->current_frequency = p->frequency; - - s5h1411_enable_modulation(fe, p->u.vsb.modulation); - - if (fe->ops.tuner_ops.set_params) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - fe->ops.tuner_ops.set_params(fe, p); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* Issue a reset to the demod so it knows to resync against the - newly tuned frequency */ - s5h1411_softreset(fe); - - return 0; -} - -/* Reset the demod hardware and reset all of the configuration registers - to a default state. */ -static int s5h1411_init(struct dvb_frontend *fe) -{ - struct s5h1411_state *state = fe->demodulator_priv; - int i; - - dprintk("%s()\n", __func__); - - s5h1411_set_powerstate(fe, 0); - s5h1411_register_reset(fe); - - for (i = 0; i < ARRAY_SIZE(init_tab); i++) - s5h1411_writereg(state, init_tab[i].addr, - init_tab[i].reg, - init_tab[i].data); - - /* The datasheet says that after initialisation, VSB is default */ - state->current_modulation = VSB_8; - - /* Although the datasheet says it's in VSB, empirical evidence - shows problems getting lock on the first tuning request. Make - sure we call enable_modulation the first time around */ - state->first_tune = 1; - - if (state->config->output_mode == S5H1411_SERIAL_OUTPUT) - /* Serial */ - s5h1411_set_serialmode(fe, 1); - else - /* Parallel */ - s5h1411_set_serialmode(fe, 0); - - s5h1411_set_spectralinversion(fe, state->config->inversion); - s5h1411_set_if_freq(fe, state->config->vsb_if); - s5h1411_set_gpio(fe, state->config->gpio); - s5h1411_set_mpeg_timing(fe, state->config->mpeg_timing); - s5h1411_softreset(fe); - - /* Note: Leaving the I2C gate closed. */ - s5h1411_i2c_gate_ctrl(fe, 0); - - return 0; -} - -static int s5h1411_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct s5h1411_state *state = fe->demodulator_priv; - u16 reg; - u32 tuner_status = 0; - - *status = 0; - - /* Register F2 bit 15 = Master Lock, removed */ - - switch (state->current_modulation) { - case QAM_64: - case QAM_256: - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf0); - if (reg & 0x10) /* QAM FEC Lock */ - *status |= FE_HAS_SYNC | FE_HAS_LOCK; - if (reg & 0x100) /* QAM EQ Lock */ - *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL; - - break; - case VSB_8: - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2); - if (reg & 0x1000) /* FEC Lock */ - *status |= FE_HAS_SYNC | FE_HAS_LOCK; - if (reg & 0x2000) /* EQ Lock */ - *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL; - - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x53); - if (reg & 0x1) /* AFC Lock */ - *status |= FE_HAS_SIGNAL; - - break; - default: - return -EINVAL; - } - - switch (state->config->status_mode) { - case S5H1411_DEMODLOCKING: - if (*status & FE_HAS_VITERBI) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - case S5H1411_TUNERLOCKING: - /* Get the tuner status */ - 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; - } - - dprintk("%s() status 0x%08x\n", __func__, *status); - - return 0; -} - -static int s5h1411_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) { - if (v < qam256_snr_tab[i].val) { - *snr = qam256_snr_tab[i].data; - ret = 0; - break; - } - } - return ret; -} - -static int s5h1411_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) { - if (v < qam64_snr_tab[i].val) { - *snr = qam64_snr_tab[i].data; - ret = 0; - break; - } - } - return ret; -} - -static int s5h1411_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) { - if (v > vsb_snr_tab[i].val) { - *snr = vsb_snr_tab[i].data; - ret = 0; - break; - } - } - dprintk("%s() snr=%d\n", __func__, *snr); - return ret; -} - -static int s5h1411_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct s5h1411_state *state = fe->demodulator_priv; - u16 reg; - dprintk("%s()\n", __func__); - - switch (state->current_modulation) { - case QAM_64: - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1); - return s5h1411_qam64_lookup_snr(fe, snr, reg); - case QAM_256: - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1); - return s5h1411_qam256_lookup_snr(fe, snr, reg); - case VSB_8: - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, - 0xf2) & 0x3ff; - return s5h1411_vsb_lookup_snr(fe, snr, reg); - default: - break; - } - - return -EINVAL; -} - -static int s5h1411_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - return s5h1411_read_snr(fe, signal_strength); -} - -static int s5h1411_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - *ucblocks = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xc9); - - return 0; -} - -static int s5h1411_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - return s5h1411_read_ucblocks(fe, ber); -} - -static int s5h1411_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - p->frequency = state->current_frequency; - p->u.vsb.modulation = state->current_modulation; - - return 0; -} - -static int s5h1411_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void s5h1411_release(struct dvb_frontend *fe) -{ - struct s5h1411_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops s5h1411_ops; - -struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config, - struct i2c_adapter *i2c) -{ - struct s5h1411_state *state = NULL; - u16 reg; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct s5h1411_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->current_modulation = VSB_8; - state->inversion = state->config->inversion; - - /* check if the demod exists */ - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x05); - if (reg != 0x0066) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &s5h1411_ops, - sizeof(struct dvb_frontend_ops)); - - state->frontend.demodulator_priv = state; - - if (s5h1411_init(&state->frontend) != 0) { - printk(KERN_ERR "%s: Failed to initialize correctly\n", - __func__); - goto error; - } - - /* Note: Leaving the I2C gate open here. */ - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1); - - /* Put the device into low-power mode until first use */ - s5h1411_set_powerstate(&state->frontend, 1); - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(s5h1411_attach); - -static struct dvb_frontend_ops s5h1411_ops = { - - .info = { - .name = "Samsung S5H1411 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 = s5h1411_init, - .sleep = s5h1411_sleep, - .i2c_gate_ctrl = s5h1411_i2c_gate_ctrl, - .set_frontend = s5h1411_set_frontend, - .get_frontend = s5h1411_get_frontend, - .get_tune_settings = s5h1411_get_tune_settings, - .read_status = s5h1411_read_status, - .read_ber = s5h1411_read_ber, - .read_signal_strength = s5h1411_read_signal_strength, - .read_snr = s5h1411_read_snr, - .read_ucblocks = s5h1411_read_ucblocks, - .release = s5h1411_release, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - -MODULE_DESCRIPTION("Samsung S5H1411 QAM-B/ATSC Demodulator driver"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); - -/* - * Local variables: - * c-basic-offset: 8 - */ diff --git a/drivers/media/dvb/frontends/s5h1411.h b/drivers/media/dvb/frontends/s5h1411.h deleted file mode 100644 index 45ec0f82989..00000000000 --- a/drivers/media/dvb/frontends/s5h1411.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - Samsung S5H1411 VSB/QAM demodulator driver - - Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> - - 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 __S5H1411_H__ -#define __S5H1411_H__ - -#include <linux/dvb/frontend.h> - -#define S5H1411_I2C_TOP_ADDR (0x32 >> 1) -#define S5H1411_I2C_QAM_ADDR (0x34 >> 1) - -struct s5h1411_config { - - /* serial/parallel output */ -#define S5H1411_PARALLEL_OUTPUT 0 -#define S5H1411_SERIAL_OUTPUT 1 - u8 output_mode; - - /* GPIO Setting */ -#define S5H1411_GPIO_OFF 0 -#define S5H1411_GPIO_ON 1 - u8 gpio; - - /* MPEG signal timing */ -#define S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0 -#define S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1 -#define S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2 -#define S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3 - u16 mpeg_timing; - - /* IF Freq for QAM and VSB in KHz */ -#define S5H1411_IF_3250 3250 -#define S5H1411_IF_3500 3500 -#define S5H1411_IF_4000 4000 -#define S5H1411_IF_5380 5380 -#define S5H1411_IF_44000 44000 -#define S5H1411_VSB_IF_DEFAULT S5H1411_IF_44000 -#define S5H1411_QAM_IF_DEFAULT S5H1411_IF_44000 - u16 qam_if; - u16 vsb_if; - - /* Spectral Inversion */ -#define S5H1411_INVERSION_OFF 0 -#define S5H1411_INVERSION_ON 1 - u8 inversion; - - /* Return lock status based on tuner lock, or demod lock */ -#define S5H1411_TUNERLOCKING 0 -#define S5H1411_DEMODLOCKING 1 - u8 status_mode; -}; - -#if defined(CONFIG_DVB_S5H1411) || \ - (defined(CONFIG_DVB_S5H1411_MODULE) && defined(MODULE)) -extern struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *s5h1411_attach( - const struct s5h1411_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_S5H1411 */ - -#endif /* __S5H1411_H__ */ - -/* - * Local variables: - * c-basic-offset: 8 - */ diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c deleted file mode 100644 index 2e9fd2893ed..00000000000 --- a/drivers/media/dvb/frontends/s5h1420.c +++ /dev/null @@ -1,982 +0,0 @@ -/* - * Driver for - * Samsung S5H1420 and - * PnpNetwork PN1010 QPSK Demodulator - * - * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> - * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org> - * - * 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 <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/jiffies.h> -#include <asm/div64.h> - -#include <linux/i2c.h> - - -#include "dvb_frontend.h" -#include "s5h1420.h" -#include "s5h1420_priv.h" - -#define TONE_FREQ 22000 - -struct s5h1420_state { - struct i2c_adapter* i2c; - const struct s5h1420_config* config; - - struct dvb_frontend frontend; - struct i2c_adapter tuner_i2c_adapter; - - u8 CON_1_val; - - u8 postlocked:1; - u32 fclk; - u32 tunedfreq; - fe_code_rate_t fec_inner; - u32 symbol_rate; - - /* FIXME: ugly workaround for flexcop's incapable i2c-controller - * it does not support repeated-start, workaround: write addr-1 - * and then read - */ - u8 shadow[256]; -}; - -static u32 s5h1420_getsymbolrate(struct s5h1420_state* state); -static int s5h1420_get_tune_settings(struct dvb_frontend* fe, - struct dvb_frontend_tune_settings* fesettings); - - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "enable debugging"); - -#define dprintk(x...) do { \ - if (debug) \ - printk(KERN_DEBUG "S5H1420: " x); \ -} while (0) - -static u8 s5h1420_readreg(struct s5h1420_state *state, u8 reg) -{ - int ret; - u8 b[2]; - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = 2 }, - { .addr = state->config->demod_address, .flags = 0, .buf = ®, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = 1 }, - }; - - b[0] = (reg - 1) & 0xff; - b[1] = state->shadow[(reg - 1) & 0xff]; - - if (state->config->repeated_start_workaround) { - ret = i2c_transfer(state->i2c, msg, 3); - if (ret != 3) - return ret; - } else { - ret = i2c_transfer(state->i2c, &msg[1], 1); - if (ret != 1) - return ret; - ret = i2c_transfer(state->i2c, &msg[2], 1); - if (ret != 1) - return ret; - } - - /* dprintk("rd(%02x): %02x %02x\n", state->config->demod_address, reg, b[0]); */ - - return b[0]; -} - -static int s5h1420_writereg (struct s5h1420_state* state, u8 reg, u8 data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - int err; - - /* dprintk("wr(%02x): %02x %02x\n", state->config->demod_address, reg, data); */ - err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - dprintk("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data); - return -EREMOTEIO; - } - state->shadow[reg] = data; - - return 0; -} - -static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - dprintk("enter %s\n", __func__); - - switch(voltage) { - case SEC_VOLTAGE_13: - s5h1420_writereg(state, 0x3c, - (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02); - break; - - case SEC_VOLTAGE_18: - s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) | 0x03); - break; - - case SEC_VOLTAGE_OFF: - s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) & 0xfd); - break; - } - - dprintk("leave %s\n", __func__); - return 0; -} - -static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - dprintk("enter %s\n", __func__); - switch(tone) { - case SEC_TONE_ON: - s5h1420_writereg(state, 0x3b, - (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08); - break; - - case SEC_TONE_OFF: - s5h1420_writereg(state, 0x3b, - (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01); - break; - } - dprintk("leave %s\n", __func__); - - return 0; -} - -static int s5h1420_send_master_cmd (struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd* cmd) -{ - struct s5h1420_state* state = fe->demodulator_priv; - u8 val; - int i; - unsigned long timeout; - int result = 0; - - dprintk("enter %s\n", __func__); - if (cmd->msg_len > 8) - return -EINVAL; - - /* setup for DISEQC */ - val = s5h1420_readreg(state, 0x3b); - s5h1420_writereg(state, 0x3b, 0x02); - msleep(15); - - /* write the DISEQC command bytes */ - for(i=0; i< cmd->msg_len; i++) { - s5h1420_writereg(state, 0x3d + i, cmd->msg[i]); - } - - /* kick off transmission */ - s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | - ((cmd->msg_len-1) << 4) | 0x08); - - /* wait for transmission to complete */ - timeout = jiffies + ((100*HZ) / 1000); - while(time_before(jiffies, timeout)) { - if (!(s5h1420_readreg(state, 0x3b) & 0x08)) - break; - - msleep(5); - } - if (time_after(jiffies, timeout)) - result = -ETIMEDOUT; - - /* restore original settings */ - s5h1420_writereg(state, 0x3b, val); - msleep(15); - dprintk("leave %s\n", __func__); - return result; -} - -static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, - struct dvb_diseqc_slave_reply* reply) -{ - struct s5h1420_state* state = fe->demodulator_priv; - u8 val; - int i; - int length; - unsigned long timeout; - int result = 0; - - /* setup for DISEQC recieve */ - val = s5h1420_readreg(state, 0x3b); - s5h1420_writereg(state, 0x3b, 0x82); /* FIXME: guess - do we need to set DIS_RDY(0x08) in receive mode? */ - msleep(15); - - /* wait for reception to complete */ - timeout = jiffies + ((reply->timeout*HZ) / 1000); - while(time_before(jiffies, timeout)) { - if (!(s5h1420_readreg(state, 0x3b) & 0x80)) /* FIXME: do we test DIS_RDY(0x08) or RCV_EN(0x80)? */ - break; - - msleep(5); - } - if (time_after(jiffies, timeout)) { - result = -ETIMEDOUT; - goto exit; - } - - /* check error flag - FIXME: not sure what this does - docs do not describe - * beyond "error flag for diseqc receive data :( */ - if (s5h1420_readreg(state, 0x49)) { - result = -EIO; - goto exit; - } - - /* check length */ - length = (s5h1420_readreg(state, 0x3b) & 0x70) >> 4; - if (length > sizeof(reply->msg)) { - result = -EOVERFLOW; - goto exit; - } - reply->msg_len = length; - - /* extract data */ - for(i=0; i< length; i++) { - reply->msg[i] = s5h1420_readreg(state, 0x3d + i); - } - -exit: - /* restore original settings */ - s5h1420_writereg(state, 0x3b, val); - msleep(15); - return result; -} - -static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) -{ - struct s5h1420_state* state = fe->demodulator_priv; - u8 val; - int result = 0; - unsigned long timeout; - - /* setup for tone burst */ - val = s5h1420_readreg(state, 0x3b); - s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x70) | 0x01); - - /* set value for B position if requested */ - if (minicmd == SEC_MINI_B) { - s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x04); - } - msleep(15); - - /* start transmission */ - s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08); - - /* wait for transmission to complete */ - timeout = jiffies + ((100*HZ) / 1000); - while(time_before(jiffies, timeout)) { - if (!(s5h1420_readreg(state, 0x3b) & 0x08)) - break; - - msleep(5); - } - if (time_after(jiffies, timeout)) - result = -ETIMEDOUT; - - /* restore original settings */ - s5h1420_writereg(state, 0x3b, val); - msleep(15); - return result; -} - -static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state) -{ - u8 val; - fe_status_t status = 0; - - val = s5h1420_readreg(state, 0x14); - if (val & 0x02) - status |= FE_HAS_SIGNAL; - if (val & 0x01) - status |= FE_HAS_CARRIER; - val = s5h1420_readreg(state, 0x36); - if (val & 0x01) - status |= FE_HAS_VITERBI; - if (val & 0x20) - status |= FE_HAS_SYNC; - if (status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC)) - status |= FE_HAS_LOCK; - - return status; -} - -static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct s5h1420_state* state = fe->demodulator_priv; - u8 val; - - dprintk("enter %s\n", __func__); - - if (status == NULL) - return -EINVAL; - - /* determine lock state */ - *status = s5h1420_get_status_bits(state); - - /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert - the inversion, wait a bit and check again */ - if (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI)) { - val = s5h1420_readreg(state, Vit10); - if ((val & 0x07) == 0x03) { - if (val & 0x08) - s5h1420_writereg(state, Vit09, 0x13); - else - s5h1420_writereg(state, Vit09, 0x1b); - - /* wait a bit then update lock status */ - mdelay(200); - *status = s5h1420_get_status_bits(state); - } - } - - /* perform post lock setup */ - if ((*status & FE_HAS_LOCK) && !state->postlocked) { - - /* calculate the data rate */ - u32 tmp = s5h1420_getsymbolrate(state); - switch (s5h1420_readreg(state, Vit10) & 0x07) { - case 0: tmp = (tmp * 2 * 1) / 2; break; - case 1: tmp = (tmp * 2 * 2) / 3; break; - case 2: tmp = (tmp * 2 * 3) / 4; break; - case 3: tmp = (tmp * 2 * 5) / 6; break; - case 4: tmp = (tmp * 2 * 6) / 7; break; - case 5: tmp = (tmp * 2 * 7) / 8; break; - } - - if (tmp == 0) { - printk(KERN_ERR "s5h1420: avoided division by 0\n"); - tmp = 1; - } - tmp = state->fclk / tmp; - - - /* set the MPEG_CLK_INTL for the calculated data rate */ - if (tmp < 2) - val = 0x00; - else if (tmp < 5) - val = 0x01; - else if (tmp < 9) - val = 0x02; - else if (tmp < 13) - val = 0x03; - else if (tmp < 17) - val = 0x04; - else if (tmp < 25) - val = 0x05; - else if (tmp < 33) - val = 0x06; - else - val = 0x07; - dprintk("for MPEG_CLK_INTL %d %x\n", tmp, val); - - s5h1420_writereg(state, FEC01, 0x18); - s5h1420_writereg(state, FEC01, 0x10); - s5h1420_writereg(state, FEC01, val); - - /* Enable "MPEG_Out" */ - val = s5h1420_readreg(state, Mpeg02); - s5h1420_writereg(state, Mpeg02, val | (1 << 6)); - - /* kicker disable */ - val = s5h1420_readreg(state, QPSK01) & 0x7f; - s5h1420_writereg(state, QPSK01, val); - - /* DC freeze TODO it was never activated by default or it can stay activated */ - - if (s5h1420_getsymbolrate(state) >= 20000000) { - s5h1420_writereg(state, Loop04, 0x8a); - s5h1420_writereg(state, Loop05, 0x6a); - } else { - s5h1420_writereg(state, Loop04, 0x58); - s5h1420_writereg(state, Loop05, 0x27); - } - - /* post-lock processing has been done! */ - state->postlocked = 1; - } - - dprintk("leave %s\n", __func__); - - return 0; -} - -static int s5h1420_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - s5h1420_writereg(state, 0x46, 0x1d); - mdelay(25); - - *ber = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47); - - return 0; -} - -static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - u8 val = s5h1420_readreg(state, 0x15); - - *strength = (u16) ((val << 8) | val); - - return 0; -} - -static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - s5h1420_writereg(state, 0x46, 0x1f); - mdelay(25); - - *ucblocks = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47); - - return 0; -} - -static void s5h1420_reset(struct s5h1420_state* state) -{ - dprintk("%s\n", __func__); - s5h1420_writereg (state, 0x01, 0x08); - s5h1420_writereg (state, 0x01, 0x00); - udelay(10); -} - -static void s5h1420_setsymbolrate(struct s5h1420_state* state, - struct dvb_frontend_parameters *p) -{ - u8 v; - u64 val; - - dprintk("enter %s\n", __func__); - - val = ((u64) p->u.qpsk.symbol_rate / 1000ULL) * (1ULL<<24); - if (p->u.qpsk.symbol_rate < 29000000) - val *= 2; - do_div(val, (state->fclk / 1000)); - - dprintk("symbol rate register: %06llx\n", (unsigned long long)val); - - v = s5h1420_readreg(state, Loop01); - s5h1420_writereg(state, Loop01, v & 0x7f); - s5h1420_writereg(state, Tnco01, val >> 16); - s5h1420_writereg(state, Tnco02, val >> 8); - s5h1420_writereg(state, Tnco03, val & 0xff); - s5h1420_writereg(state, Loop01, v | 0x80); - dprintk("leave %s\n", __func__); -} - -static u32 s5h1420_getsymbolrate(struct s5h1420_state* state) -{ - return state->symbol_rate; -} - -static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset) -{ - int val; - u8 v; - - dprintk("enter %s\n", __func__); - - /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so - * divide fclk by 1000000 to get the correct value. */ - val = -(int) ((freqoffset * (1<<24)) / (state->fclk / 1000000)); - - dprintk("phase rotator/freqoffset: %d %06x\n", freqoffset, val); - - v = s5h1420_readreg(state, Loop01); - s5h1420_writereg(state, Loop01, v & 0xbf); - s5h1420_writereg(state, Pnco01, val >> 16); - s5h1420_writereg(state, Pnco02, val >> 8); - s5h1420_writereg(state, Pnco03, val & 0xff); - s5h1420_writereg(state, Loop01, v | 0x40); - dprintk("leave %s\n", __func__); -} - -static int s5h1420_getfreqoffset(struct s5h1420_state* state) -{ - int val; - - s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08); - val = s5h1420_readreg(state, 0x0e) << 16; - val |= s5h1420_readreg(state, 0x0f) << 8; - val |= s5h1420_readreg(state, 0x10); - s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7); - - if (val & 0x800000) - val |= 0xff000000; - - /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so - * divide fclk by 1000000 to get the correct value. */ - val = (((-val) * (state->fclk/1000000)) / (1<<24)); - - return val; -} - -static void s5h1420_setfec_inversion(struct s5h1420_state* state, - struct dvb_frontend_parameters *p) -{ - u8 inversion = 0; - u8 vit08, vit09; - - dprintk("enter %s\n", __func__); - - if (p->inversion == INVERSION_OFF) - inversion = state->config->invert ? 0x08 : 0; - else if (p->inversion == INVERSION_ON) - inversion = state->config->invert ? 0 : 0x08; - - if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) { - vit08 = 0x3f; - vit09 = 0; - } else { - switch(p->u.qpsk.fec_inner) { - case FEC_1_2: - vit08 = 0x01; vit09 = 0x10; - break; - - case FEC_2_3: - vit08 = 0x02; vit09 = 0x11; - break; - - case FEC_3_4: - vit08 = 0x04; vit09 = 0x12; - break; - - case FEC_5_6: - vit08 = 0x08; vit09 = 0x13; - break; - - case FEC_6_7: - vit08 = 0x10; vit09 = 0x14; - break; - - case FEC_7_8: - vit08 = 0x20; vit09 = 0x15; - break; - - default: - return; - } - } - vit09 |= inversion; - dprintk("fec: %02x %02x\n", vit08, vit09); - s5h1420_writereg(state, Vit08, vit08); - s5h1420_writereg(state, Vit09, vit09); - dprintk("leave %s\n", __func__); -} - -static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state) -{ - switch(s5h1420_readreg(state, 0x32) & 0x07) { - case 0: - return FEC_1_2; - - case 1: - return FEC_2_3; - - case 2: - return FEC_3_4; - - case 3: - return FEC_5_6; - - case 4: - return FEC_6_7; - - case 5: - return FEC_7_8; - } - - return FEC_NONE; -} - -static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state) -{ - if (s5h1420_readreg(state, 0x32) & 0x08) - return INVERSION_ON; - - return INVERSION_OFF; -} - -static int s5h1420_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) -{ - struct s5h1420_state* state = fe->demodulator_priv; - int frequency_delta; - struct dvb_frontend_tune_settings fesettings; - uint8_t clock_settting; - - dprintk("enter %s\n", __func__); - - /* check if we should do a fast-tune */ - memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters)); - s5h1420_get_tune_settings(fe, &fesettings); - frequency_delta = p->frequency - state->tunedfreq; - if ((frequency_delta > -fesettings.max_drift) && - (frequency_delta < fesettings.max_drift) && - (frequency_delta != 0) && - (state->fec_inner == p->u.qpsk.fec_inner) && - (state->symbol_rate == p->u.qpsk.symbol_rate)) { - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - if (fe->ops.tuner_ops.get_frequency) { - u32 tmp; - fe->ops.tuner_ops.get_frequency(fe, &tmp); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - s5h1420_setfreqoffset(state, p->frequency - tmp); - } else { - s5h1420_setfreqoffset(state, 0); - } - dprintk("simple tune\n"); - return 0; - } - dprintk("tuning demod\n"); - - /* first of all, software reset */ - s5h1420_reset(state); - - /* set s5h1420 fclk PLL according to desired symbol rate */ - if (p->u.qpsk.symbol_rate > 33000000) - state->fclk = 80000000; - else if (p->u.qpsk.symbol_rate > 28500000) - state->fclk = 59000000; - else if (p->u.qpsk.symbol_rate > 25000000) - state->fclk = 86000000; - else if (p->u.qpsk.symbol_rate > 1900000) - state->fclk = 88000000; - else - state->fclk = 44000000; - - /* Clock */ - switch (state->fclk) { - default: - case 88000000: - clock_settting = 80; - break; - case 86000000: - clock_settting = 78; - break; - case 80000000: - clock_settting = 72; - break; - case 59000000: - clock_settting = 51; - break; - case 44000000: - clock_settting = 36; - break; - } - dprintk("pll01: %d, ToneFreq: %d\n", state->fclk/1000000 - 8, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32)); - s5h1420_writereg(state, PLL01, state->fclk/1000000 - 8); - s5h1420_writereg(state, PLL02, 0x40); - s5h1420_writereg(state, DiS01, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32)); - - /* TODO DC offset removal, config parameter ? */ - if (p->u.qpsk.symbol_rate > 29000000) - s5h1420_writereg(state, QPSK01, 0xae | 0x10); - else - s5h1420_writereg(state, QPSK01, 0xac | 0x10); - - /* set misc registers */ - s5h1420_writereg(state, CON_1, 0x00); - s5h1420_writereg(state, QPSK02, 0x00); - s5h1420_writereg(state, Pre01, 0xb0); - - s5h1420_writereg(state, Loop01, 0xF0); - s5h1420_writereg(state, Loop02, 0x2a); /* e7 for s5h1420 */ - s5h1420_writereg(state, Loop03, 0x79); /* 78 for s5h1420 */ - if (p->u.qpsk.symbol_rate > 20000000) - s5h1420_writereg(state, Loop04, 0x79); - else - s5h1420_writereg(state, Loop04, 0x58); - s5h1420_writereg(state, Loop05, 0x6b); - - if (p->u.qpsk.symbol_rate >= 8000000) - s5h1420_writereg(state, Post01, (0 << 6) | 0x10); - else if (p->u.qpsk.symbol_rate >= 4000000) - s5h1420_writereg(state, Post01, (1 << 6) | 0x10); - else - s5h1420_writereg(state, Post01, (3 << 6) | 0x10); - - s5h1420_writereg(state, Monitor12, 0x00); /* unfreeze DC compensation */ - - s5h1420_writereg(state, Sync01, 0x33); - s5h1420_writereg(state, Mpeg01, state->config->cdclk_polarity); - s5h1420_writereg(state, Mpeg02, 0x3d); /* Parallel output more, disabled -> enabled later */ - s5h1420_writereg(state, Err01, 0x03); /* 0x1d for s5h1420 */ - - s5h1420_writereg(state, Vit06, 0x6e); /* 0x8e for s5h1420 */ - s5h1420_writereg(state, DiS03, 0x00); - s5h1420_writereg(state, Rf01, 0x61); /* Tuner i2c address - for the gate controller */ - - /* set tuner PLL */ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - s5h1420_setfreqoffset(state, 0); - } - - /* set the reset of the parameters */ - s5h1420_setsymbolrate(state, p); - s5h1420_setfec_inversion(state, p); - - /* start QPSK */ - s5h1420_writereg(state, QPSK01, s5h1420_readreg(state, QPSK01) | 1); - - state->fec_inner = p->u.qpsk.fec_inner; - state->symbol_rate = p->u.qpsk.symbol_rate; - state->postlocked = 0; - state->tunedfreq = p->frequency; - - dprintk("leave %s\n", __func__); - return 0; -} - -static int s5h1420_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - p->frequency = state->tunedfreq + s5h1420_getfreqoffset(state); - p->inversion = s5h1420_getinversion(state); - p->u.qpsk.symbol_rate = s5h1420_getsymbolrate(state); - p->u.qpsk.fec_inner = s5h1420_getfec(state); - - return 0; -} - -static int s5h1420_get_tune_settings(struct dvb_frontend* fe, - struct dvb_frontend_tune_settings* fesettings) -{ - if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) { - fesettings->min_delay_ms = 50; - fesettings->step_size = 2000; - fesettings->max_drift = 8000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) { - fesettings->min_delay_ms = 100; - fesettings->step_size = 1500; - fesettings->max_drift = 9000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) { - fesettings->min_delay_ms = 100; - fesettings->step_size = 1000; - fesettings->max_drift = 8000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) { - fesettings->min_delay_ms = 100; - fesettings->step_size = 500; - fesettings->max_drift = 7000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) { - fesettings->min_delay_ms = 200; - fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); - fesettings->max_drift = 14 * fesettings->step_size; - } else { - fesettings->min_delay_ms = 200; - fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); - fesettings->max_drift = 18 * fesettings->step_size; - } - - return 0; -} - -static int s5h1420_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - if (enable) - return s5h1420_writereg(state, 0x02, state->CON_1_val | 1); - else - return s5h1420_writereg(state, 0x02, state->CON_1_val & 0xfe); -} - -static int s5h1420_init (struct dvb_frontend* fe) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - /* disable power down and do reset */ - state->CON_1_val = state->config->serial_mpeg << 4; - s5h1420_writereg(state, 0x02, state->CON_1_val); - msleep(10); - s5h1420_reset(state); - - return 0; -} - -static int s5h1420_sleep(struct dvb_frontend* fe) -{ - struct s5h1420_state* state = fe->demodulator_priv; - state->CON_1_val = 0x12; - return s5h1420_writereg(state, 0x02, state->CON_1_val); -} - -static void s5h1420_release(struct dvb_frontend* fe) -{ - struct s5h1420_state* state = fe->demodulator_priv; - i2c_del_adapter(&state->tuner_i2c_adapter); - kfree(state); -} - -static u32 s5h1420_tuner_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static int s5h1420_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) -{ - struct s5h1420_state *state = i2c_get_adapdata(i2c_adap); - struct i2c_msg m[1 + num]; - u8 tx_open[2] = { CON_1, state->CON_1_val | 1 }; /* repeater stops once there was a stop condition */ - - memset(m, 0, sizeof(struct i2c_msg) * (1 + num)); - - m[0].addr = state->config->demod_address; - m[0].buf = tx_open; - m[0].len = 2; - - memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); - - return i2c_transfer(state->i2c, m, 1+num) == 1 + num ? num : -EIO; -} - -static struct i2c_algorithm s5h1420_tuner_i2c_algo = { - .master_xfer = s5h1420_tuner_i2c_tuner_xfer, - .functionality = s5h1420_tuner_i2c_func, -}; - -struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe) -{ - struct s5h1420_state *state = fe->demodulator_priv; - return &state->tuner_i2c_adapter; -} -EXPORT_SYMBOL(s5h1420_get_tuner_i2c_adapter); - -static struct dvb_frontend_ops s5h1420_ops; - -struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, - struct i2c_adapter *i2c) -{ - /* allocate memory for the internal state */ - struct s5h1420_state *state = kzalloc(sizeof(struct s5h1420_state), GFP_KERNEL); - u8 i; - - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->postlocked = 0; - state->fclk = 88000000; - state->tunedfreq = 0; - state->fec_inner = FEC_NONE; - state->symbol_rate = 0; - - /* check if the demod is there + identify it */ - i = s5h1420_readreg(state, ID01); - if (i != 0x03) - goto error; - - memset(state->shadow, 0xff, sizeof(state->shadow)); - - for (i = 0; i < 0x50; i++) - state->shadow[i] = s5h1420_readreg(state, i); - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - /* create tuner i2c adapter */ - strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus", - sizeof(state->tuner_i2c_adapter.name)); - state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, - state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo; - state->tuner_i2c_adapter.algo_data = NULL; - i2c_set_adapdata(&state->tuner_i2c_adapter, state); - if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) { - printk(KERN_ERR "S5H1420/PN1010: tuner i2c bus could not be initialized\n"); - goto error; - } - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(s5h1420_attach); - -static struct dvb_frontend_ops s5h1420_ops = { - - .info = { - .name = "Samsung S5H1420/PnpNetwork PN1010 DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - .frequency_tolerance = 29500, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - /* .symbol_rate_tolerance = ???,*/ - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK - }, - - .release = s5h1420_release, - - .init = s5h1420_init, - .sleep = s5h1420_sleep, - .i2c_gate_ctrl = s5h1420_i2c_gate_ctrl, - - .set_frontend = s5h1420_set_frontend, - .get_frontend = s5h1420_get_frontend, - .get_tune_settings = s5h1420_get_tune_settings, - - .read_status = s5h1420_read_status, - .read_ber = s5h1420_read_ber, - .read_signal_strength = s5h1420_read_signal_strength, - .read_ucblocks = s5h1420_read_ucblocks, - - .diseqc_send_master_cmd = s5h1420_send_master_cmd, - .diseqc_recv_slave_reply = s5h1420_recv_slave_reply, - .diseqc_send_burst = s5h1420_send_burst, - .set_tone = s5h1420_set_tone, - .set_voltage = s5h1420_set_voltage, -}; - -MODULE_DESCRIPTION("Samsung S5H1420/PnpNetwork PN1010 DVB-S Demodulator driver"); -MODULE_AUTHOR("Andrew de Quincey, Patrick Boettcher"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h deleted file mode 100644 index ff308136d86..00000000000 --- a/drivers/media/dvb/frontends/s5h1420.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Driver for - * Samsung S5H1420 and - * PnpNetwork PN1010 QPSK Demodulator - * - * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> - * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org> - * - * 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 S5H1420_H -#define S5H1420_H - -#include <linux/dvb/frontend.h> - -struct s5h1420_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* does the inversion require inversion? */ - u8 invert:1; - - u8 repeated_start_workaround:1; - u8 cdclk_polarity:1; /* 1 == falling edge, 0 == raising edge */ - - u8 serial_mpeg:1; -}; - -#if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE)) -extern struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, - struct i2c_adapter *i2c); -extern struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe); -#else -static inline struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} - -static inline struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe) -{ - return NULL; -} -#endif // CONFIG_DVB_S5H1420 - -#endif // S5H1420_H diff --git a/drivers/media/dvb/frontends/s5h1420_priv.h b/drivers/media/dvb/frontends/s5h1420_priv.h deleted file mode 100644 index d9c58d28181..00000000000 --- a/drivers/media/dvb/frontends/s5h1420_priv.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Driver for - * Samsung S5H1420 and - * PnpNetwork PN1010 QPSK Demodulator - * - * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> - * Copyright (C) 2005 Patrick Boettcher <pb@linuxtv.org> - * - * 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 S5H1420_PRIV -#define S5H1420_PRIV - -#include <asm/types.h> - -enum s5h1420_register { - ID01 = 0x00, - CON_0 = 0x01, - CON_1 = 0x02, - PLL01 = 0x03, - PLL02 = 0x04, - QPSK01 = 0x05, - QPSK02 = 0x06, - Pre01 = 0x07, - Post01 = 0x08, - Loop01 = 0x09, - Loop02 = 0x0a, - Loop03 = 0x0b, - Loop04 = 0x0c, - Loop05 = 0x0d, - Pnco01 = 0x0e, - Pnco02 = 0x0f, - Pnco03 = 0x10, - Tnco01 = 0x11, - Tnco02 = 0x12, - Tnco03 = 0x13, - Monitor01 = 0x14, - Monitor02 = 0x15, - Monitor03 = 0x16, - Monitor04 = 0x17, - Monitor05 = 0x18, - Monitor06 = 0x19, - Monitor07 = 0x1a, - Monitor12 = 0x1f, - - FEC01 = 0x22, - Soft01 = 0x23, - Soft02 = 0x24, - Soft03 = 0x25, - Soft04 = 0x26, - Soft05 = 0x27, - Soft06 = 0x28, - Vit01 = 0x29, - Vit02 = 0x2a, - Vit03 = 0x2b, - Vit04 = 0x2c, - Vit05 = 0x2d, - Vit06 = 0x2e, - Vit07 = 0x2f, - Vit08 = 0x30, - Vit09 = 0x31, - Vit10 = 0x32, - Vit11 = 0x33, - Vit12 = 0x34, - Sync01 = 0x35, - Sync02 = 0x36, - Rs01 = 0x37, - Mpeg01 = 0x38, - Mpeg02 = 0x39, - DiS01 = 0x3a, - DiS02 = 0x3b, - DiS03 = 0x3c, - DiS04 = 0x3d, - DiS05 = 0x3e, - DiS06 = 0x3f, - DiS07 = 0x40, - DiS08 = 0x41, - DiS09 = 0x42, - DiS10 = 0x43, - DiS11 = 0x44, - Rf01 = 0x45, - Err01 = 0x46, - Err02 = 0x47, - Err03 = 0x48, - Err04 = 0x49, -}; - - -#endif diff --git a/drivers/media/dvb/frontends/s921_core.c b/drivers/media/dvb/frontends/s921_core.c deleted file mode 100644 index 974b52be9ae..00000000000 --- a/drivers/media/dvb/frontends/s921_core.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Driver for Sharp s921 driver - * - * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de> - * - */ - - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/delay.h> -#include "s921_core.h" - -static int s921_isdb_init(struct s921_isdb_t *dev); -static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params); -static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params); -static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data); - -static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01, - 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, - 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00, - 0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80, - 0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12, - 0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00, - 0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff, - 0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00, - 0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88, - 0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00, - 0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06, - 0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00, - 0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00, - 0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20, - 0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70, - 0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f, - 0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00, - 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, - 0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30, - 0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d, - 0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f, - 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00, - 0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84, - 0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e, - 0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba, - 0xf8, 0xd7 }; - -static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b, - 0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b, - 0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b, - 0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b, - 0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b, - 0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b, - 0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b, - 0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb, - 0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb, - 0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb, - 0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb, - 0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb, - 0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb, - 0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b, - 0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b, - 0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b, - 0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b }; - -int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) { - switch(cmd) { - case ISDB_T_CMD_INIT: - s921_isdb_init(dev); - break; - case ISDB_T_CMD_SET_PARAM: - s921_isdb_set_parameters(dev, data); - break; - case ISDB_T_CMD_TUNE: - s921_isdb_tune(dev, data); - break; - case ISDB_T_CMD_GET_STATUS: - s921_isdb_get_status(dev, data); - break; - default: - printk("unhandled command\n"); - return -EINVAL; - } - return 0; -} - -static int s921_isdb_init(struct s921_isdb_t *dev) { - unsigned int i; - unsigned int ret; - printk("isdb_init\n"); - for (i = 0; i < sizeof(init_table); i+=2) { - ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]); - if (ret != 0) { - printk("i2c write failed\n"); - return ret; - } - } - return 0; -} - -static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) { - - int ret; - /* auto is sufficient for now, lateron this should be reflected in an extra interface */ - - - - ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2); - ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2); - - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7); - if (ret < 0) - return -EINVAL; - - return E_OK; -} - -static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) { - - int ret; - int index; - - index = (params->frequency - 473143000)/6000000; - - if (index > 48) { - return -EINVAL; - } - - dev->i2c_write(dev->priv_dev, 0x47, 0x60); - - ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09); - if (ret < 0) - return -EINVAL; - - dev->i2c_write(dev->priv_dev, 0x01, 0x40); - return 0; -} - -static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) { - unsigned int *ret = (unsigned int*)data; - u8 ifagc_dt; - u8 rfagc_dt; - - mdelay(10); - ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81); - rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82); - if (rfagc_dt == 0x40) { - *ret = 1; - } - return 0; -} diff --git a/drivers/media/dvb/frontends/s921_core.h b/drivers/media/dvb/frontends/s921_core.h deleted file mode 100644 index de2f10a44e7..00000000000 --- a/drivers/media/dvb/frontends/s921_core.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef _S921_CORE_H -#define _S921_CORE_H -//#define u8 unsigned int -//#define u32 unsigned int - - - -//#define EINVAL -1 -#define E_OK 0 - -struct s921_isdb_t { - void *priv_dev; - int (*i2c_write)(void *dev, u8 reg, u8 val); - int (*i2c_read)(void *dev, u8 reg); -}; - -#define ISDB_T_CMD_INIT 0 -#define ISDB_T_CMD_SET_PARAM 1 -#define ISDB_T_CMD_TUNE 2 -#define ISDB_T_CMD_GET_STATUS 3 - -struct s921_isdb_t_tune_params { - u32 frequency; -}; - -struct s921_isdb_t_status { -}; - -struct s921_isdb_t_transmission_mode_params { - u8 mode; - u8 layer_a_mode; -#define ISDB_T_LA_MODE_1 0 -#define ISDB_T_LA_MODE_2 1 -#define ISDB_T_LA_MODE_3 2 - u8 layer_a_carrier_modulation; -#define ISDB_T_LA_CM_DQPSK 0 -#define ISDB_T_LA_CM_QPSK 1 -#define ISDB_T_LA_CM_16QAM 2 -#define ISDB_T_LA_CM_64QAM 3 -#define ISDB_T_LA_CM_NOLAYER 4 - u8 layer_a_code_rate; -#define ISDB_T_LA_CR_1_2 0 -#define ISDB_T_LA_CR_2_3 1 -#define ISDB_T_LA_CR_3_4 2 -#define ISDB_T_LA_CR_5_6 4 -#define ISDB_T_LA_CR_7_8 8 -#define ISDB_T_LA_CR_NOLAYER 16 - u8 layer_a_time_interleave; -#define ISDB_T_LA_TI_0 0 -#define ISDB_T_LA_TI_1 1 -#define ISDB_T_LA_TI_2 2 -#define ISDB_T_LA_TI_4 4 -#define ISDB_T_LA_TI_8 8 -#define ISDB_T_LA_TI_16 16 -#define ISDB_T_LA_TI_32 32 - u8 layer_a_nseg; - - u8 layer_b_mode; -#define ISDB_T_LB_MODE_1 0 -#define ISDB_T_LB_MODE_2 1 -#define ISDB_T_LB_MODE_3 2 - u8 layer_b_carrier_modulation; -#define ISDB_T_LB_CM_DQPSK 0 -#define ISDB_T_LB_CM_QPSK 1 -#define ISDB_T_LB_CM_16QAM 2 -#define ISDB_T_LB_CM_64QAM 3 -#define ISDB_T_LB_CM_NOLAYER 4 - u8 layer_b_code_rate; -#define ISDB_T_LB_CR_1_2 0 -#define ISDB_T_LB_CR_2_3 1 -#define ISDB_T_LB_CR_3_4 2 -#define ISDB_T_LB_CR_5_6 4 -#define ISDB_T_LB_CR_7_8 8 -#define ISDB_T_LB_CR_NOLAYER 16 - u8 layer_b_time_interleave; -#define ISDB_T_LB_TI_0 0 -#define ISDB_T_LB_TI_1 1 -#define ISDB_T_LB_TI_2 2 -#define ISDB_T_LB_TI_4 4 -#define ISDB_T_LB_TI_8 8 -#define ISDB_T_LB_TI_16 16 -#define ISDB_T_LB_TI_32 32 - u8 layer_b_nseg; - - u8 layer_c_mode; -#define ISDB_T_LC_MODE_1 0 -#define ISDB_T_LC_MODE_2 1 -#define ISDB_T_LC_MODE_3 2 - u8 layer_c_carrier_modulation; -#define ISDB_T_LC_CM_DQPSK 0 -#define ISDB_T_LC_CM_QPSK 1 -#define ISDB_T_LC_CM_16QAM 2 -#define ISDB_T_LC_CM_64QAM 3 -#define ISDB_T_LC_CM_NOLAYER 4 - u8 layer_c_code_rate; -#define ISDB_T_LC_CR_1_2 0 -#define ISDB_T_LC_CR_2_3 1 -#define ISDB_T_LC_CR_3_4 2 -#define ISDB_T_LC_CR_5_6 4 -#define ISDB_T_LC_CR_7_8 8 -#define ISDB_T_LC_CR_NOLAYER 16 - u8 layer_c_time_interleave; -#define ISDB_T_LC_TI_0 0 -#define ISDB_T_LC_TI_1 1 -#define ISDB_T_LC_TI_2 2 -#define ISDB_T_LC_TI_4 4 -#define ISDB_T_LC_TI_8 8 -#define ISDB_T_LC_TI_16 16 -#define ISDB_T_LC_TI_32 32 - u8 layer_c_nseg; -}; - -int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data); -#endif diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c deleted file mode 100644 index 3f5a0e1dfdf..00000000000 --- a/drivers/media/dvb/frontends/s921_module.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Driver for Sharp s921 driver - * - * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de> - * - * All rights reserved. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "s921_module.h" -#include "s921_core.h" - -static unsigned int debug = 0; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"s921 debugging (default off)"); - -#define dprintk(fmt, args...) if (debug) do {\ - printk("s921 debug: " fmt, ##args); } while (0) - -struct s921_state -{ - struct dvb_frontend frontend; - fe_modulation_t current_modulation; - __u32 snr; - __u32 current_frequency; - __u8 addr; - struct s921_isdb_t dev; - struct i2c_adapter *i2c; -}; - -static int s921_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { - struct s921_state *state = (struct s921_state *)fe->demodulator_priv; - struct s921_isdb_t_transmission_mode_params params; - struct s921_isdb_t_tune_params tune_params; - - tune_params.frequency = param->frequency; - s921_isdb_cmd(&state->dev, ISDB_T_CMD_SET_PARAM, ¶ms); - s921_isdb_cmd(&state->dev, ISDB_T_CMD_TUNE, &tune_params); - mdelay(100); - return 0; -} - -static int s921_init(struct dvb_frontend *fe) { - printk("s921 init\n"); - return 0; -} - -static int s921_sleep(struct dvb_frontend *fe) { - printk("s921 sleep\n"); - return 0; -} - -static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct s921_state *state = (struct s921_state *)fe->demodulator_priv; - unsigned int ret; - mdelay(5); - s921_isdb_cmd(&state->dev, ISDB_T_CMD_GET_STATUS, &ret); - *status = 0; - - printk("status: %02x\n", ret); - if (ret == 1) { - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_VITERBI; - *status |= FE_HAS_LOCK; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_SIGNAL; - } - - return 0; -} - -static int s921_read_ber(struct dvb_frontend *fe, __u32 *ber) -{ - dprintk("read ber\n"); - return 0; -} - -static int s921_read_snr(struct dvb_frontend *fe, __u16 *snr) -{ - dprintk("read snr\n"); - return 0; -} - -static int s921_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks) -{ - dprintk("read ucblocks\n"); - return 0; -} - -static void s921_release(struct dvb_frontend *fe) -{ - struct s921_state *state = (struct s921_state *)fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops demod_s921={ - .info = { - .name = "SHARP S921", - .type = FE_OFDM, - .frequency_min = 473143000, - .frequency_max = 767143000, - .frequency_stepsize = 6000000, - .frequency_tolerance = 0, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | - FE_CAN_MUTE_TS - }, - .init = s921_init, - .sleep = s921_sleep, - .set_frontend = s921_set_parameters, - .read_snr = s921_read_snr, - .read_ber = s921_read_ber, - .read_status = s921_read_status, - .read_ucblocks = s921_read_ucblocks, - .release = s921_release, -}; - -static int s921_write(void *dev, u8 reg, u8 val) { - struct s921_state *state = dev; - char buf[2]={reg,val}; - int err; - struct i2c_msg i2cmsgs = { - .addr = state->addr, - .flags = 0, - .len = 2, - .buf = buf - }; - - if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) { - printk("%s i2c_transfer error %d\n", __func__, err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - - return 0; -} - -static int s921_read(void *dev, u8 reg) { - struct s921_state *state = dev; - u8 b1; - int ret; - struct i2c_msg msg[2] = { { .addr = state->addr, - .flags = 0, - .buf = ®, .len = 1 }, - { .addr = state->addr, - .flags = I2C_M_RD, - .buf = &b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - if (ret != 2) - return ret; - return b1; -} - -struct dvb_frontend* s921_attach(const struct s921_config *config, - struct i2c_adapter *i2c) -{ - - struct s921_state *state; - state = kzalloc(sizeof(struct s921_state), GFP_KERNEL); - - state->addr = config->i2c_address; - state->i2c = i2c; - state->dev.i2c_write = &s921_write; - state->dev.i2c_read = &s921_read; - state->dev.priv_dev = state; - - s921_isdb_cmd(&state->dev, ISDB_T_CMD_INIT, NULL); - - memcpy(&state->frontend.ops, &demod_s921, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -EXPORT_SYMBOL_GPL(s921_attach); -MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>"); -MODULE_DESCRIPTION("Sharp S921 ISDB-T 1Seg"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/s921_module.h b/drivers/media/dvb/frontends/s921_module.h deleted file mode 100644 index 78660424ba9..00000000000 --- a/drivers/media/dvb/frontends/s921_module.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Driver for DVB-T s921 demodulator - * - * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de> - * - * 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 S921_MODULE_H -#define S921_MODULE_H - -#include <linux/dvb/frontend.h> -#include "s921_core.h" - -int s921_isdb_init(struct s921_isdb_t *dev); -int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data); - -struct s921_config -{ - /* demodulator's I2C address */ - u8 i2c_address; -}; - -#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) && defined(MODULE)) -extern struct dvb_frontend* s921_attach(const struct s921_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend* s921_attach(const struct s921_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_S921 */ - -#endif /* S921_H */ diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c deleted file mode 100644 index 0bd16af8a6c..00000000000 --- a/drivers/media/dvb/frontends/si21xx.c +++ /dev/null @@ -1,973 +0,0 @@ -/* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator -* -* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -*/ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/jiffies.h> -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "si21xx.h" - -#define REVISION_REG 0x00 -#define SYSTEM_MODE_REG 0x01 -#define TS_CTRL_REG_1 0x02 -#define TS_CTRL_REG_2 0x03 -#define PIN_CTRL_REG_1 0x04 -#define PIN_CTRL_REG_2 0x05 -#define LOCK_STATUS_REG_1 0x0f -#define LOCK_STATUS_REG_2 0x10 -#define ACQ_STATUS_REG 0x11 -#define ACQ_CTRL_REG_1 0x13 -#define ACQ_CTRL_REG_2 0x14 -#define PLL_DIVISOR_REG 0x15 -#define COARSE_TUNE_REG 0x16 -#define FINE_TUNE_REG_L 0x17 -#define FINE_TUNE_REG_H 0x18 - -#define ANALOG_AGC_POWER_LEVEL_REG 0x28 -#define CFO_ESTIMATOR_CTRL_REG_1 0x29 -#define CFO_ESTIMATOR_CTRL_REG_2 0x2a -#define CFO_ESTIMATOR_CTRL_REG_3 0x2b - -#define SYM_RATE_ESTIMATE_REG_L 0x31 -#define SYM_RATE_ESTIMATE_REG_M 0x32 -#define SYM_RATE_ESTIMATE_REG_H 0x33 - -#define CFO_ESTIMATOR_OFFSET_REG_L 0x36 -#define CFO_ESTIMATOR_OFFSET_REG_H 0x37 -#define CFO_ERROR_REG_L 0x38 -#define CFO_ERROR_REG_H 0x39 -#define SYM_RATE_ESTIMATOR_CTRL_REG 0x3a - -#define SYM_RATE_REG_L 0x3f -#define SYM_RATE_REG_M 0x40 -#define SYM_RATE_REG_H 0x41 -#define SYM_RATE_ESTIMATOR_MAXIMUM_REG 0x42 -#define SYM_RATE_ESTIMATOR_MINIMUM_REG 0x43 - -#define C_N_ESTIMATOR_CTRL_REG 0x7c -#define C_N_ESTIMATOR_THRSHLD_REG 0x7d -#define C_N_ESTIMATOR_LEVEL_REG_L 0x7e -#define C_N_ESTIMATOR_LEVEL_REG_H 0x7f - -#define BLIND_SCAN_CTRL_REG 0x80 - -#define LSA_CTRL_REG_1 0x8D -#define SPCTRM_TILT_CORR_THRSHLD_REG 0x8f -#define ONE_DB_BNDWDTH_THRSHLD_REG 0x90 -#define TWO_DB_BNDWDTH_THRSHLD_REG 0x91 -#define THREE_DB_BNDWDTH_THRSHLD_REG 0x92 -#define INBAND_POWER_THRSHLD_REG 0x93 -#define REF_NOISE_LVL_MRGN_THRSHLD_REG 0x94 - -#define VIT_SRCH_CTRL_REG_1 0xa0 -#define VIT_SRCH_CTRL_REG_2 0xa1 -#define VIT_SRCH_CTRL_REG_3 0xa2 -#define VIT_SRCH_STATUS_REG 0xa3 -#define VITERBI_BER_COUNT_REG_L 0xab -#define REED_SOLOMON_CTRL_REG 0xb0 -#define REED_SOLOMON_ERROR_COUNT_REG_L 0xb1 -#define PRBS_CTRL_REG 0xb5 - -#define LNB_CTRL_REG_1 0xc0 -#define LNB_CTRL_REG_2 0xc1 -#define LNB_CTRL_REG_3 0xc2 -#define LNB_CTRL_REG_4 0xc3 -#define LNB_CTRL_STATUS_REG 0xc4 -#define LNB_FIFO_REGS_0 0xc5 -#define LNB_FIFO_REGS_1 0xc6 -#define LNB_FIFO_REGS_2 0xc7 -#define LNB_FIFO_REGS_3 0xc8 -#define LNB_FIFO_REGS_4 0xc9 -#define LNB_FIFO_REGS_5 0xca -#define LNB_SUPPLY_CTRL_REG_1 0xcb -#define LNB_SUPPLY_CTRL_REG_2 0xcc -#define LNB_SUPPLY_CTRL_REG_3 0xcd -#define LNB_SUPPLY_CTRL_REG_4 0xce -#define LNB_SUPPLY_STATUS_REG 0xcf - -#define FALSE 0 -#define TRUE 1 -#define FAIL -1 -#define PASS 0 - -#define ALLOWABLE_FS_COUNT 10 -#define STATUS_BER 0 -#define STATUS_UCBLOCKS 1 - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "si21xx: " args); \ - } while (0) - -enum { - ACTIVE_HIGH, - ACTIVE_LOW -}; -enum { - BYTE_WIDE, - BIT_WIDE -}; -enum { - CLK_GAPPED_MODE, - CLK_CONTINUOUS_MODE -}; -enum { - RISING_EDGE, - FALLING_EDGE -}; -enum { - MSB_FIRST, - LSB_FIRST -}; -enum { - SERIAL, - PARALLEL -}; - -struct si21xx_state { - struct i2c_adapter *i2c; - const struct si21xx_config *config; - struct dvb_frontend frontend; - u8 initialised:1; - int errmode; - int fs; /*Sampling rate of the ADC in MHz*/ -}; - -/* register default initialization */ -static u8 serit_sp1511lhb_inittab[] = { - 0x01, 0x28, /* set i2c_inc_disable */ - 0x20, 0x03, - 0x27, 0x20, - 0xe0, 0x45, - 0xe1, 0x08, - 0xfe, 0x01, - 0x01, 0x28, - 0x89, 0x09, - 0x04, 0x80, - 0x05, 0x01, - 0x06, 0x00, - 0x20, 0x03, - 0x24, 0x88, - 0x29, 0x09, - 0x2a, 0x0f, - 0x2c, 0x10, - 0x2d, 0x19, - 0x2e, 0x08, - 0x2f, 0x10, - 0x30, 0x19, - 0x34, 0x20, - 0x35, 0x03, - 0x45, 0x02, - 0x46, 0x45, - 0x47, 0xd0, - 0x48, 0x00, - 0x49, 0x40, - 0x4a, 0x03, - 0x4c, 0xfd, - 0x4f, 0x2e, - 0x50, 0x2e, - 0x51, 0x10, - 0x52, 0x10, - 0x56, 0x92, - 0x59, 0x00, - 0x5a, 0x2d, - 0x5b, 0x33, - 0x5c, 0x1f, - 0x5f, 0x76, - 0x62, 0xc0, - 0x63, 0xc0, - 0x64, 0xf3, - 0x65, 0xf3, - 0x79, 0x40, - 0x6a, 0x40, - 0x6b, 0x0a, - 0x6c, 0x80, - 0x6d, 0x27, - 0x71, 0x06, - 0x75, 0x60, - 0x78, 0x00, - 0x79, 0xb5, - 0x7c, 0x05, - 0x7d, 0x1a, - 0x87, 0x55, - 0x88, 0x72, - 0x8f, 0x08, - 0x90, 0xe0, - 0x94, 0x40, - 0xa0, 0x3f, - 0xa1, 0xc0, - 0xa4, 0xcc, - 0xa5, 0x66, - 0xa6, 0x66, - 0xa7, 0x7b, - 0xa8, 0x7b, - 0xa9, 0x7b, - 0xaa, 0x9a, - 0xed, 0x04, - 0xad, 0x00, - 0xae, 0x03, - 0xcc, 0xab, - 0x01, 0x08, - 0xff, 0xff -}; - -/* low level read/writes */ -static int si21_writeregs(struct si21xx_state *state, u8 reg1, - u8 *data, int len) -{ - int ret; - u8 buf[60];/* = { reg1, data };*/ - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = len + 1 - }; - - msg.buf[0] = reg1; - memcpy(msg.buf + 1, data, len); - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, " - "ret == %i)\n", __func__, reg1, data[0], ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = 2 - }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static int si21_write(struct dvb_frontend *fe, u8 *buf, int len) -{ - struct si21xx_state *state = fe->demodulator_priv; - - if (len != 2) - return -EINVAL; - - return si21_writereg(state, buf[0], buf[1]); -} - -static u8 si21_readreg(struct si21xx_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = b0, - .len = 1 - }, { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = b1, - .len = 1 - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", - __func__, reg, ret); - - return b1[0]; -} - -static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len) -{ - int ret; - struct i2c_msg msg[] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = ®1, - .len = 1 - }, { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = b, - .len = len - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (ret == %i)\n", __func__, ret); - - return ret == 2 ? 0 : -1; -} - -static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout) -{ - unsigned long start = jiffies; - - dprintk("%s\n", __func__); - - while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) { - if (jiffies - start > timeout) { - dprintk("%s: timeout!!\n", __func__); - return -ETIMEDOUT; - } - msleep(10); - }; - - return 0; -} - -static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate) -{ - struct si21xx_state *state = fe->demodulator_priv; - u32 sym_rate, data_rate; - int i; - u8 sym_rate_bytes[3]; - - dprintk("%s : srate = %i\n", __func__ , srate); - - if ((srate < 1000000) || (srate > 45000000)) - return -EINVAL; - - data_rate = srate; - sym_rate = 0; - - for (i = 0; i < 4; ++i) { - sym_rate /= 100; - sym_rate = sym_rate + ((data_rate % 100) * 0x800000) / - state->fs; - data_rate /= 100; - } - for (i = 0; i < 3; ++i) - sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff); - - si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03); - - return 0; -} - -static int si21xx_send_diseqc_msg(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *m) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 lnb_status; - u8 LNB_CTRL_1; - int status; - - dprintk("%s\n", __func__); - - status = PASS; - LNB_CTRL_1 = 0; - - status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01); - status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01); - - /*fill the FIFO*/ - status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len); - - LNB_CTRL_1 = (lnb_status & 0x70); - LNB_CTRL_1 |= m->msg_len; - - LNB_CTRL_1 |= 0x80; /* begin LNB signaling */ - - status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01); - - return status; -} - -static int si21xx_send_diseqc_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 val; - - dprintk("%s\n", __func__); - - if (si21xx_wait_diseqc_idle(state, 100) < 0) - return -ETIMEDOUT; - - val = (0x80 | si21_readreg(state, 0xc1)); - if (si21_writereg(state, LNB_CTRL_REG_1, - burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10))) - return -EREMOTEIO; - - if (si21xx_wait_diseqc_idle(state, 100) < 0) - return -ETIMEDOUT; - - if (si21_writereg(state, LNB_CTRL_REG_1, val)) - return -EREMOTEIO; - - return 0; -} -/* 30.06.2008 */ -static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 val; - - dprintk("%s\n", __func__); - val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1)); - - switch (tone) { - case SEC_TONE_ON: - return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20); - - case SEC_TONE_OFF: - return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20)); - - default: - return -EINVAL; - } -} - -static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) -{ - struct si21xx_state *state = fe->demodulator_priv; - - u8 val; - dprintk("%s: %s\n", __func__, - volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : - volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); - - - val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1)); - - switch (volt) { - case SEC_VOLTAGE_18: - return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40); - break; - case SEC_VOLTAGE_13: - return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40)); - break; - default: - return -EINVAL; - }; -} - -static int si21xx_init(struct dvb_frontend *fe) -{ - struct si21xx_state *state = fe->demodulator_priv; - int i; - int status = 0; - u8 reg1; - u8 val; - u8 reg2[2]; - - dprintk("%s\n", __func__); - - for (i = 0; ; i += 2) { - reg1 = serit_sp1511lhb_inittab[i]; - val = serit_sp1511lhb_inittab[i+1]; - if (reg1 == 0xff && val == 0xff) - break; - si21_writeregs(state, reg1, &val, 1); - } - - /*DVB QPSK SYSTEM MODE REG*/ - reg1 = 0x08; - si21_writeregs(state, SYSTEM_MODE_REG, ®1, 0x01); - - /*transport stream config*/ - /* - mode = PARALLEL; - sdata_form = LSB_FIRST; - clk_edge = FALLING_EDGE; - clk_mode = CLK_GAPPED_MODE; - strt_len = BYTE_WIDE; - sync_pol = ACTIVE_HIGH; - val_pol = ACTIVE_HIGH; - err_pol = ACTIVE_HIGH; - sclk_rate = 0x00; - parity = 0x00 ; - data_delay = 0x00; - clk_delay = 0x00; - pclk_smooth = 0x00; - */ - reg2[0] = - PARALLEL + (LSB_FIRST << 1) - + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3) - + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5) - + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7); - - reg2[1] = 0; - /* sclk_rate + (parity << 2) - + (data_delay << 3) + (clk_delay << 4) - + (pclk_smooth << 5); - */ - status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02); - if (status != 0) - dprintk(" %s : TS Set Error\n", __func__); - - return 0; - -} - -static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 regs_read[2]; - u8 reg_read; - u8 i; - u8 lock; - u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG); - - si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02); - reg_read = 0; - - for (i = 0; i < 7; ++i) - reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i); - - lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80)); - - dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock); - *status = 0; - - if (signal > 10) - *status |= FE_HAS_SIGNAL; - - if (lock & 0x2) - *status |= FE_HAS_CARRIER; - - if (lock & 0x20) - *status |= FE_HAS_VITERBI; - - if (lock & 0x40) - *status |= FE_HAS_SYNC; - - if ((lock & 0x7b) == 0x7b) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct si21xx_state *state = fe->demodulator_priv; - - /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG, - (u8*)agclevel, 0x01);*/ - - u16 signal = (3 * si21_readreg(state, 0x27) * - si21_readreg(state, 0x28)); - - dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__, - si21_readreg(state, 0x27), - si21_readreg(state, 0x28), (int) signal); - - signal <<= 4; - *strength = signal; - - return 0; -} - -static int si21_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct si21xx_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (state->errmode != STATUS_BER) - return 0; - - *ber = (si21_readreg(state, 0x1d) << 8) | - si21_readreg(state, 0x1e); - - return 0; -} - -static int si21_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct si21xx_state *state = fe->demodulator_priv; - - s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) | - si21_readreg(state, 0x25)); - xsnr = 3 * (xsnr - 0xa100); - *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr; - - dprintk("%s\n", __func__); - - return 0; -} - -static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct si21xx_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (state->errmode != STATUS_UCBLOCKS) - *ucblocks = 0; - else - *ucblocks = (si21_readreg(state, 0x1d) << 8) | - si21_readreg(state, 0x1e); - - return 0; -} - -/* initiates a channel acquisition sequence - using the specified symbol rate and code rate */ -static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate, - fe_code_rate_t crate) -{ - - struct si21xx_state *state = fe->demodulator_priv; - u8 coderates[] = { - 0x0, 0x01, 0x02, 0x04, 0x00, - 0x8, 0x10, 0x20, 0x00, 0x3f - }; - - u8 coderate_ptr; - int status; - u8 start_acq = 0x80; - u8 reg, regs[3]; - - dprintk("%s\n", __func__); - - status = PASS; - coderate_ptr = coderates[crate]; - - si21xx_set_symbolrate(fe, symbrate); - - /* write code rates to use in the Viterbi search */ - status |= si21_writeregs(state, - VIT_SRCH_CTRL_REG_1, - &coderate_ptr, 0x01); - - /* clear acq_start bit */ - status |= si21_readregs(state, ACQ_CTRL_REG_2, ®, 0x01); - reg &= ~start_acq; - status |= si21_writeregs(state, ACQ_CTRL_REG_2, ®, 0x01); - - /* use new Carrier Frequency Offset Estimator (QuickLock) */ - regs[0] = 0xCB; - regs[1] = 0x40; - regs[2] = 0xCB; - - status |= si21_writeregs(state, - TWO_DB_BNDWDTH_THRSHLD_REG, - ®s[0], 0x03); - reg = 0x56; - status |= si21_writeregs(state, - LSA_CTRL_REG_1, ®, 1); - reg = 0x05; - status |= si21_writeregs(state, - BLIND_SCAN_CTRL_REG, ®, 1); - /* start automatic acq */ - status |= si21_writeregs(state, - ACQ_CTRL_REG_2, &start_acq, 0x01); - - return status; -} - -static int si21xx_set_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int si21xx_get_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int si21xx_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *dfp) -{ - struct si21xx_state *state = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - /* freq Channel carrier frequency in KHz (i.e. 1550000 KHz) - datarate Channel symbol rate in Sps (i.e. 22500000 Sps)*/ - - /* in MHz */ - unsigned char coarse_tune_freq; - int fine_tune_freq; - unsigned char sample_rate = 0; - /* boolean */ - unsigned int inband_interferer_ind; - - /* INTERMEDIATE VALUES */ - int icoarse_tune_freq; /* MHz */ - int ifine_tune_freq; /* MHz */ - unsigned int band_high; - unsigned int band_low; - unsigned int x1; - unsigned int x2; - int i; - unsigned int inband_interferer_div2[ALLOWABLE_FS_COUNT] = { - FALSE, FALSE, FALSE, FALSE, FALSE, - FALSE, FALSE, FALSE, FALSE, FALSE - }; - unsigned int inband_interferer_div4[ALLOWABLE_FS_COUNT] = { - FALSE, FALSE, FALSE, FALSE, FALSE, - FALSE, FALSE, FALSE, FALSE, FALSE - }; - - int status; - - /* allowable sample rates for ADC in MHz */ - int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195, - 196, 204, 205, 206, 207 - }; - /* in MHz */ - int if_limit_high; - int if_limit_low; - int lnb_lo; - int lnb_uncertanity; - - int rf_freq; - int data_rate; - unsigned char regs[4]; - - dprintk("%s : FE_SET_FRONTEND\n", __func__); - - if (c->delivery_system != SYS_DVBS) { - dprintk("%s: unsupported delivery system selected (%d)\n", - __func__, c->delivery_system); - return -EOPNOTSUPP; - } - - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) - inband_interferer_div2[i] = inband_interferer_div4[i] = FALSE; - - if_limit_high = -700000; - if_limit_low = -100000; - /* in MHz */ - lnb_lo = 0; - lnb_uncertanity = 0; - - rf_freq = 10 * c->frequency ; - data_rate = c->symbol_rate / 100; - - status = PASS; - - band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200) - + (data_rate * 135)) / 200; - - band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200) - + (data_rate * 135)) / 200; - - - icoarse_tune_freq = 100000 * - (((rf_freq - lnb_lo) - - (if_limit_low + if_limit_high) / 2) - / 100000); - - ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ; - - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { - x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) * - (afs[i] * 2500) + afs[i] * 2500; - - x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) * - (afs[i] * 2500); - - if (((band_low < x1) && (x1 < band_high)) || - ((band_low < x2) && (x2 < band_high))) - inband_interferer_div4[i] = TRUE; - - } - - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { - x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) * - (afs[i] * 5000) + afs[i] * 5000; - - x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) * - (afs[i] * 5000); - - if (((band_low < x1) && (x1 < band_high)) || - ((band_low < x2) && (x2 < band_high))) - inband_interferer_div2[i] = TRUE; - } - - inband_interferer_ind = TRUE; - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) - inband_interferer_ind &= inband_interferer_div2[i] | - inband_interferer_div4[i]; - - if (inband_interferer_ind) { - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { - if (inband_interferer_div2[i] == FALSE) { - sample_rate = (u8) afs[i]; - break; - } - } - } else { - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { - if ((inband_interferer_div2[i] | - inband_interferer_div4[i]) == FALSE) { - sample_rate = (u8) afs[i]; - break; - } - } - - } - - if (sample_rate > 207 || sample_rate < 192) - sample_rate = 200; - - fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) / - ((sample_rate) * 1000)); - - coarse_tune_freq = (u8)(icoarse_tune_freq / 100000); - - regs[0] = sample_rate; - regs[1] = coarse_tune_freq; - regs[2] = fine_tune_freq & 0xFF; - regs[3] = fine_tune_freq >> 8 & 0xFF; - - status |= si21_writeregs(state, PLL_DIVISOR_REG, ®s[0], 0x04); - - state->fs = sample_rate;/*ADC MHz*/ - si21xx_setacquire(fe, c->symbol_rate, c->fec_inner); - - return 0; -} - -static int si21xx_sleep(struct dvb_frontend *fe) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 regdata; - - dprintk("%s\n", __func__); - - si21_readregs(state, SYSTEM_MODE_REG, ®data, 0x01); - regdata |= 1 << 6; - si21_writeregs(state, SYSTEM_MODE_REG, ®data, 0x01); - state->initialised = 0; - - return 0; -} - -static void si21xx_release(struct dvb_frontend *fe) -{ - struct si21xx_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - kfree(state); -} - -static struct dvb_frontend_ops si21xx_ops = { - - .info = { - .name = "SL SI21XX DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - .frequency_tolerance = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 500, /* ppm */ - .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_FEC_AUTO - }, - - .release = si21xx_release, - .init = si21xx_init, - .sleep = si21xx_sleep, - .write = si21_write, - .read_status = si21_read_status, - .read_ber = si21_read_ber, - .read_signal_strength = si21_read_signal_strength, - .read_snr = si21_read_snr, - .read_ucblocks = si21_read_ucblocks, - .diseqc_send_master_cmd = si21xx_send_diseqc_msg, - .diseqc_send_burst = si21xx_send_diseqc_burst, - .set_tone = si21xx_set_tone, - .set_voltage = si21xx_set_voltage, - - .set_property = si21xx_set_property, - .get_property = si21xx_get_property, - .set_frontend = si21xx_set_frontend, -}; - -struct dvb_frontend *si21xx_attach(const struct si21xx_config *config, - struct i2c_adapter *i2c) -{ - struct si21xx_state *state = NULL; - int id; - - dprintk("%s\n", __func__); - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct si21xx_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - state->errmode = STATUS_BER; - - /* check if the demod is there */ - id = si21_readreg(state, SYSTEM_MODE_REG); - si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */ - msleep(200); - id = si21_readreg(state, 0x00); - - /* register 0x00 contains: - 0x34 for SI2107 - 0x24 for SI2108 - 0x14 for SI2109 - 0x04 for SI2110 - */ - if (id != 0x04 && id != 0x14) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &si21xx_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(si21xx_attach); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver"); -MODULE_AUTHOR("Igor M. Liplianin"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/si21xx.h b/drivers/media/dvb/frontends/si21xx.h deleted file mode 100644 index 141b5b8a5f6..00000000000 --- a/drivers/media/dvb/frontends/si21xx.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SI21XX_H -#define SI21XX_H - -#include <linux/dvb/frontend.h> -#include "dvb_frontend.h" - -struct si21xx_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* minimum delay before retuning */ - int min_delay_ms; -}; - -#if defined(CONFIG_DVB_SI21XX) || \ - (defined(CONFIG_DVB_SI21XX_MODULE) && defined(MODULE)) -extern struct dvb_frontend *si21xx_attach(const struct si21xx_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *si21xx_attach( - const struct si21xx_config *config, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -static inline int si21xx_writeregister(struct dvb_frontend *fe, u8 reg, u8 val) -{ - int r = 0; - u8 buf[] = {reg, val}; - if (fe->ops.write) - r = fe->ops.write(fe, buf, 2); - return r; -} - -#endif diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c deleted file mode 100644 index 1c9a9b4051b..00000000000 --- a/drivers/media/dvb/frontends/sp8870.c +++ /dev/null @@ -1,619 +0,0 @@ -/* - Driver for Spase SP8870 demodulator - - Copyright (C) 1999 Juergen Peitz - - 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. - -*/ -/* - * This driver needs external firmware. Please use the command - * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to - * download/extract it, and then copy it to /usr/lib/hotplug/firmware - * or /lib/firmware (depending on configuration of firmware hotplug). - */ -#define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw" - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/firmware.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "sp8870.h" - - -struct sp8870_state { - - struct i2c_adapter* i2c; - - const struct sp8870_config* config; - - struct dvb_frontend frontend; - - /* demodulator private data */ - u8 initialised:1; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "sp8870: " args); \ - } while (0) - -/* firmware size for sp8870 */ -#define SP8870_FIRMWARE_SIZE 16382 - -/* starting point for firmware in file 'Sc_main.mc' */ -#define SP8870_FIRMWARE_OFFSET 0x0A - -static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data) -{ - u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 }; - int err; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data); - return -EREMOTEIO; - } - - return 0; -} - -static int sp8870_readreg (struct sp8870_state* state, u16 reg) -{ - int ret; - u8 b0 [] = { reg >> 8 , reg & 0xff }; - u8 b1 [] = { 0, 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 = 2 } }; - - ret = i2c_transfer (state->i2c, msg, 2); - - if (ret != 2) { - dprintk("%s: readreg error (ret == %i)\n", __func__, ret); - return -1; - } - - return (b1[0] << 8 | b1[1]); -} - -static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw) -{ - struct i2c_msg msg; - const char *fw_buf = fw->data; - int fw_pos; - u8 tx_buf[255]; - int tx_len; - int err = 0; - - dprintk ("%s: ...\n", __func__); - - if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET) - return -EINVAL; - - // system controller stop - sp8870_writereg(state, 0x0F00, 0x0000); - - // instruction RAM register hiword - sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF)); - - // instruction RAM MWR - sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16)); - - // do firmware upload - fw_pos = SP8870_FIRMWARE_OFFSET; - while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){ - tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos; - // write register 0xCF0A - tx_buf[0] = 0xCF; - tx_buf[1] = 0x0A; - memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len); - msg.addr = state->config->demod_address; - msg.flags = 0; - msg.buf = tx_buf; - msg.len = tx_len + 2; - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk("%s: firmware upload failed!\n", __func__); - printk ("%s: i2c error (err == %i)\n", __func__, err); - return err; - } - fw_pos += tx_len; - } - - dprintk ("%s: done!\n", __func__); - return 0; -}; - -static void sp8870_microcontroller_stop (struct sp8870_state* state) -{ - sp8870_writereg(state, 0x0F08, 0x000); - sp8870_writereg(state, 0x0F09, 0x000); - - // microcontroller STOP - sp8870_writereg(state, 0x0F00, 0x000); -} - -static void sp8870_microcontroller_start (struct sp8870_state* state) -{ - sp8870_writereg(state, 0x0F08, 0x000); - sp8870_writereg(state, 0x0F09, 0x000); - - // microcontroller START - sp8870_writereg(state, 0x0F00, 0x001); - // not documented but if we don't read 0x0D01 out here - // we don't get a correct data valid signal - sp8870_readreg(state, 0x0D01); -} - -static int sp8870_read_data_valid_signal(struct sp8870_state* state) -{ - return (sp8870_readreg(state, 0x0D02) > 0); -} - -static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05) -{ - int known_parameters = 1; - - *reg0xc05 = 0x000; - - switch (p->u.ofdm.constellation) { - case QPSK: - break; - case QAM_16: - *reg0xc05 |= (1 << 10); - break; - case QAM_64: - *reg0xc05 |= (2 << 10); - break; - case QAM_AUTO: - known_parameters = 0; - break; - default: - return -EINVAL; - }; - - switch (p->u.ofdm.hierarchy_information) { - case HIERARCHY_NONE: - break; - case HIERARCHY_1: - *reg0xc05 |= (1 << 7); - break; - case HIERARCHY_2: - *reg0xc05 |= (2 << 7); - break; - case HIERARCHY_4: - *reg0xc05 |= (3 << 7); - break; - case HIERARCHY_AUTO: - known_parameters = 0; - break; - default: - return -EINVAL; - }; - - switch (p->u.ofdm.code_rate_HP) { - case FEC_1_2: - break; - case FEC_2_3: - *reg0xc05 |= (1 << 3); - break; - case FEC_3_4: - *reg0xc05 |= (2 << 3); - break; - case FEC_5_6: - *reg0xc05 |= (3 << 3); - break; - case FEC_7_8: - *reg0xc05 |= (4 << 3); - break; - case FEC_AUTO: - known_parameters = 0; - break; - default: - return -EINVAL; - }; - - if (known_parameters) - *reg0xc05 |= (2 << 1); /* use specified parameters */ - else - *reg0xc05 |= (1 << 1); /* enable autoprobing */ - - return 0; -} - -static int sp8870_wake_up(struct sp8870_state* state) -{ - // enable TS output and interface pins - return sp8870_writereg(state, 0xC18, 0x00D); -} - -static int sp8870_set_frontend_parameters (struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) -{ - struct sp8870_state* state = fe->demodulator_priv; - int err; - u16 reg0xc05; - - if ((err = configure_reg0xc05(p, ®0xc05))) - return err; - - // system controller stop - sp8870_microcontroller_stop(state); - - // set tuner parameters - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - // sample rate correction bit [23..17] - sp8870_writereg(state, 0x0319, 0x000A); - - // sample rate correction bit [16..0] - sp8870_writereg(state, 0x031A, 0x0AAB); - - // integer carrier offset - sp8870_writereg(state, 0x0309, 0x0400); - - // fractional carrier offset - sp8870_writereg(state, 0x030A, 0x0000); - - // filter for 6/7/8 Mhz channel - if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ) - sp8870_writereg(state, 0x0311, 0x0002); - else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) - sp8870_writereg(state, 0x0311, 0x0001); - else - sp8870_writereg(state, 0x0311, 0x0000); - - // scan order: 2k first = 0x0000, 8k first = 0x0001 - if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K) - sp8870_writereg(state, 0x0338, 0x0000); - else - sp8870_writereg(state, 0x0338, 0x0001); - - sp8870_writereg(state, 0xc05, reg0xc05); - - // read status reg in order to clear pending irqs - sp8870_readreg(state, 0x200); - - // system controller start - sp8870_microcontroller_start(state); - - return 0; -} - -static int sp8870_init (struct dvb_frontend* fe) -{ - struct sp8870_state* state = fe->demodulator_priv; - const struct firmware *fw = NULL; - - sp8870_wake_up(state); - if (state->initialised) return 0; - state->initialised = 1; - - dprintk ("%s\n", __func__); - - - /* request the firmware, this will block until someone uploads it */ - printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE); - if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) { - printk("sp8870: no firmware upload (timeout or file not found?)\n"); - return -EIO; - } - - if (sp8870_firmware_upload(state, fw)) { - printk("sp8870: writing firmware to device failed\n"); - release_firmware(fw); - return -EIO; - } - release_firmware(fw); - printk("sp8870: firmware upload complete\n"); - - /* enable TS output and interface pins */ - sp8870_writereg(state, 0xc18, 0x00d); - - // system controller stop - sp8870_microcontroller_stop(state); - - // ADC mode - sp8870_writereg(state, 0x0301, 0x0003); - - // Reed Solomon parity bytes passed to output - sp8870_writereg(state, 0x0C13, 0x0001); - - // MPEG clock is suppressed if no valid data - sp8870_writereg(state, 0x0C14, 0x0001); - - /* bit 0x010: enable data valid signal */ - sp8870_writereg(state, 0x0D00, 0x010); - sp8870_writereg(state, 0x0D01, 0x000); - - return 0; -} - -static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status) -{ - struct sp8870_state* state = fe->demodulator_priv; - int status; - int signal; - - *fe_status = 0; - - status = sp8870_readreg (state, 0x0200); - if (status < 0) - return -EIO; - - signal = sp8870_readreg (state, 0x0303); - if (signal < 0) - return -EIO; - - if (signal > 0x0F) - *fe_status |= FE_HAS_SIGNAL; - if (status & 0x08) - *fe_status |= FE_HAS_SYNC; - if (status & 0x04) - *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI; - - return 0; -} - -static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber) -{ - struct sp8870_state* state = fe->demodulator_priv; - int ret; - u32 tmp; - - *ber = 0; - - ret = sp8870_readreg(state, 0xC08); - if (ret < 0) - return -EIO; - - tmp = ret & 0x3F; - - ret = sp8870_readreg(state, 0xC07); - if (ret < 0) - return -EIO; - - tmp = ret << 6; - - if (tmp >= 0x3FFF0) - tmp = ~0; - - *ber = tmp; - - return 0; -} - -static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal) -{ - struct sp8870_state* state = fe->demodulator_priv; - int ret; - u16 tmp; - - *signal = 0; - - ret = sp8870_readreg (state, 0x306); - if (ret < 0) - return -EIO; - - tmp = ret << 8; - - ret = sp8870_readreg (state, 0x303); - if (ret < 0) - return -EIO; - - tmp |= ret; - - if (tmp) - *signal = 0xFFFF - tmp; - - return 0; -} - -static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks) -{ - struct sp8870_state* state = fe->demodulator_priv; - int ret; - - *ublocks = 0; - - ret = sp8870_readreg(state, 0xC0C); - if (ret < 0) - return -EIO; - - if (ret == 0xFFFF) - ret = ~0; - - *ublocks = ret; - - return 0; -} - -/* number of trials to recover from lockup */ -#define MAXTRIALS 5 -/* maximum checks for data valid signal */ -#define MAXCHECKS 100 - -/* only for debugging: counter for detected lockups */ -static int lockups; -/* only for debugging: counter for channel switches */ -static int switches; - -static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct sp8870_state* state = fe->demodulator_priv; - - /* - The firmware of the sp8870 sometimes locks up after setting frontend parameters. - We try to detect this by checking the data valid signal. - If it is not set after MAXCHECKS we try to recover the lockup by setting - the frontend parameters again. - */ - - int err = 0; - int valid = 0; - int trials = 0; - int check_count = 0; - - dprintk("%s: frequency = %i\n", __func__, p->frequency); - - for (trials = 1; trials <= MAXTRIALS; trials++) { - - if ((err = sp8870_set_frontend_parameters(fe, p))) - return err; - - for (check_count = 0; check_count < MAXCHECKS; check_count++) { -// valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0); - valid = sp8870_read_data_valid_signal(state); - if (valid) { - dprintk("%s: delay = %i usec\n", - __func__, check_count * 10); - break; - } - udelay(10); - } - if (valid) - break; - } - - if (!valid) { - printk("%s: firmware crash!!!!!!\n", __func__); - return -EIO; - } - - if (debug) { - if (valid) { - if (trials > 1) { - printk("%s: firmware lockup!!!\n", __func__); - printk("%s: recovered after %i trial(s))\n", __func__, trials - 1); - lockups++; - } - } - switches++; - printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups); - } - - return 0; -} - -static int sp8870_sleep(struct dvb_frontend* fe) -{ - struct sp8870_state* state = fe->demodulator_priv; - - // tristate TS output and disable interface pins - return sp8870_writereg(state, 0xC18, 0x000); -} - -static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 350; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct sp8870_state* state = fe->demodulator_priv; - - if (enable) { - return sp8870_writereg(state, 0x206, 0x001); - } else { - return sp8870_writereg(state, 0x206, 0x000); - } -} - -static void sp8870_release(struct dvb_frontend* fe) -{ - struct sp8870_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops sp8870_ops; - -struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, - struct i2c_adapter* i2c) -{ - struct sp8870_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct sp8870_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - - /* check if the demod is there */ - if (sp8870_readreg(state, 0x0200) < 0) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops sp8870_ops = { - - .info = { - .name = "Spase SP8870 DVB-T", - .type = FE_OFDM, - .frequency_min = 470000000, - .frequency_max = 860000000, - .frequency_stepsize = 166666, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | - FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER - }, - - .release = sp8870_release, - - .init = sp8870_init, - .sleep = sp8870_sleep, - .i2c_gate_ctrl = sp8870_i2c_gate_ctrl, - - .set_frontend = sp8870_set_frontend, - .get_tune_settings = sp8870_get_tune_settings, - - .read_status = sp8870_read_status, - .read_ber = sp8870_read_ber, - .read_signal_strength = sp8870_read_signal_strength, - .read_ucblocks = sp8870_read_uncorrected_blocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver"); -MODULE_AUTHOR("Juergen Peitz"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(sp8870_attach); diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h deleted file mode 100644 index a764a793c7d..00000000000 --- a/drivers/media/dvb/frontends/sp8870.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Driver for Spase SP8870 demodulator - - Copyright (C) 1999 Juergen Peitz - - 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 SP8870_H -#define SP8870_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -struct sp8870_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* request firmware for device */ - int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); -}; - -#if defined(CONFIG_DVB_SP8870) || (defined(CONFIG_DVB_SP8870_MODULE) && defined(MODULE)) -extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_SP8870 - -#endif // SP8870_H diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c deleted file mode 100644 index 559509ab4da..00000000000 --- a/drivers/media/dvb/frontends/sp887x.c +++ /dev/null @@ -1,617 +0,0 @@ -/* - Driver for the Spase sp887x demodulator -*/ - -/* - * This driver needs external firmware. Please use the command - * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to - * download/extract it, and then copy it to /usr/lib/hotplug/firmware - * or /lib/firmware (depending on configuration of firmware hotplug). - */ -#define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw" - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/firmware.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "sp887x.h" - - -struct sp887x_state { - struct i2c_adapter* i2c; - const struct sp887x_config* config; - struct dvb_frontend frontend; - - /* demodulator private data */ - u8 initialised:1; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "sp887x: " args); \ - } while (0) - -static int i2c_writebytes (struct sp887x_state* state, u8 *buf, u8 len) -{ - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = len }; - int err; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk ("%s: i2c write error (addr %02x, err == %i)\n", - __func__, state->config->demod_address, err); - return -EREMOTEIO; - } - - return 0; -} - -static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data) -{ - u8 b0 [] = { reg >> 8 , reg & 0xff, data >> 8, data & 0xff }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 4 }; - int ret; - - if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) { - /** - * in case of soft reset we ignore ACK errors... - */ - if (!(reg == 0xf1a && data == 0x000 && - (ret == -EREMOTEIO || ret == -EFAULT))) - { - printk("%s: writereg error " - "(reg %03x, data %03x, ret == %i)\n", - __func__, reg & 0xffff, data & 0xffff, ret); - return ret; - } - } - - return 0; -} - -static int sp887x_readreg (struct sp887x_state* state, u16 reg) -{ - u8 b0 [] = { reg >> 8 , reg & 0xff }; - u8 b1 [2]; - int ret; - 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 = 2 }}; - - if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - printk("%s: readreg error (ret == %i)\n", __func__, ret); - return -1; - } - - return (((b1[0] << 8) | b1[1]) & 0xfff); -} - -static void sp887x_microcontroller_stop (struct sp887x_state* state) -{ - dprintk("%s\n", __func__); - sp887x_writereg(state, 0xf08, 0x000); - sp887x_writereg(state, 0xf09, 0x000); - - /* microcontroller STOP */ - sp887x_writereg(state, 0xf00, 0x000); -} - -static void sp887x_microcontroller_start (struct sp887x_state* state) -{ - dprintk("%s\n", __func__); - sp887x_writereg(state, 0xf08, 0x000); - sp887x_writereg(state, 0xf09, 0x000); - - /* microcontroller START */ - sp887x_writereg(state, 0xf00, 0x001); -} - -static void sp887x_setup_agc (struct sp887x_state* state) -{ - /* setup AGC parameters */ - dprintk("%s\n", __func__); - sp887x_writereg(state, 0x33c, 0x054); - sp887x_writereg(state, 0x33b, 0x04c); - sp887x_writereg(state, 0x328, 0x000); - sp887x_writereg(state, 0x327, 0x005); - sp887x_writereg(state, 0x326, 0x001); - sp887x_writereg(state, 0x325, 0x001); - sp887x_writereg(state, 0x324, 0x001); - sp887x_writereg(state, 0x318, 0x050); - sp887x_writereg(state, 0x317, 0x3fe); - sp887x_writereg(state, 0x316, 0x001); - sp887x_writereg(state, 0x313, 0x005); - sp887x_writereg(state, 0x312, 0x002); - sp887x_writereg(state, 0x306, 0x000); - sp887x_writereg(state, 0x303, 0x000); -} - -#define BLOCKSIZE 30 -#define FW_SIZE 0x4000 -/** - * load firmware and setup MPEG interface... - */ -static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw) -{ - struct sp887x_state* state = fe->demodulator_priv; - u8 buf [BLOCKSIZE+2]; - int i; - int fw_size = fw->size; - const unsigned char *mem = fw->data; - - dprintk("%s\n", __func__); - - /* ignore the first 10 bytes, then we expect 0x4000 bytes of firmware */ - if (fw_size < FW_SIZE+10) - return -ENODEV; - - mem = fw->data + 10; - - /* soft reset */ - sp887x_writereg(state, 0xf1a, 0x000); - - sp887x_microcontroller_stop (state); - - printk ("%s: firmware upload... ", __func__); - - /* setup write pointer to -1 (end of memory) */ - /* bit 0x8000 in address is set to enable 13bit mode */ - sp887x_writereg(state, 0x8f08, 0x1fff); - - /* dummy write (wrap around to start of memory) */ - sp887x_writereg(state, 0x8f0a, 0x0000); - - for (i = 0; i < FW_SIZE; i += BLOCKSIZE) { - int c = BLOCKSIZE; - int err; - - if (i+c > FW_SIZE) - c = FW_SIZE - i; - - /* bit 0x8000 in address is set to enable 13bit mode */ - /* bit 0x4000 enables multibyte read/write transfers */ - /* write register is 0xf0a */ - buf[0] = 0xcf; - buf[1] = 0x0a; - - memcpy(&buf[2], mem + i, c); - - if ((err = i2c_writebytes (state, buf, c+2)) < 0) { - printk ("failed.\n"); - printk ("%s: i2c error (err == %i)\n", __func__, err); - return err; - } - } - - /* don't write RS bytes between packets */ - sp887x_writereg(state, 0xc13, 0x001); - - /* suppress clock if (!data_valid) */ - sp887x_writereg(state, 0xc14, 0x000); - - /* setup MPEG interface... */ - sp887x_writereg(state, 0xc1a, 0x872); - sp887x_writereg(state, 0xc1b, 0x001); - sp887x_writereg(state, 0xc1c, 0x000); /* parallel mode (serial mode == 1) */ - sp887x_writereg(state, 0xc1a, 0x871); - - /* ADC mode, 2 for MT8872, 3 for SP8870/SP8871 */ - sp887x_writereg(state, 0x301, 0x002); - - sp887x_setup_agc(state); - - /* bit 0x010: enable data valid signal */ - sp887x_writereg(state, 0xd00, 0x010); - sp887x_writereg(state, 0x0d1, 0x000); - return 0; -}; - -static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05) -{ - int known_parameters = 1; - - *reg0xc05 = 0x000; - - switch (p->u.ofdm.constellation) { - case QPSK: - break; - case QAM_16: - *reg0xc05 |= (1 << 10); - break; - case QAM_64: - *reg0xc05 |= (2 << 10); - break; - case QAM_AUTO: - known_parameters = 0; - break; - default: - return -EINVAL; - }; - - switch (p->u.ofdm.hierarchy_information) { - case HIERARCHY_NONE: - break; - case HIERARCHY_1: - *reg0xc05 |= (1 << 7); - break; - case HIERARCHY_2: - *reg0xc05 |= (2 << 7); - break; - case HIERARCHY_4: - *reg0xc05 |= (3 << 7); - break; - case HIERARCHY_AUTO: - known_parameters = 0; - break; - default: - return -EINVAL; - }; - - switch (p->u.ofdm.code_rate_HP) { - case FEC_1_2: - break; - case FEC_2_3: - *reg0xc05 |= (1 << 3); - break; - case FEC_3_4: - *reg0xc05 |= (2 << 3); - break; - case FEC_5_6: - *reg0xc05 |= (3 << 3); - break; - case FEC_7_8: - *reg0xc05 |= (4 << 3); - break; - case FEC_AUTO: - known_parameters = 0; - break; - default: - return -EINVAL; - }; - - if (known_parameters) - *reg0xc05 |= (2 << 1); /* use specified parameters */ - else - *reg0xc05 |= (1 << 1); /* enable autoprobing */ - - return 0; -} - -/** - * estimates division of two 24bit numbers, - * derived from the ves1820/stv0299 driver code - */ -static void divide (int n, int d, int *quotient_i, int *quotient_f) -{ - unsigned int q, r; - - r = (n % d) << 8; - q = (r / d); - - if (quotient_i) - *quotient_i = q; - - if (quotient_f) { - r = (r % d) << 8; - q = (q << 8) | (r / d); - r = (r % d) << 8; - *quotient_f = (q << 8) | (r / d); - } -} - -static void sp887x_correct_offsets (struct sp887x_state* state, - struct dvb_frontend_parameters *p, - int actual_freq) -{ - static const u32 srate_correction [] = { 1879617, 4544878, 8098561 }; - int bw_index = p->u.ofdm.bandwidth - BANDWIDTH_8_MHZ; - int freq_offset = actual_freq - p->frequency; - int sysclock = 61003; //[kHz] - int ifreq = 36000000; - int freq; - int frequency_shift; - - if (p->inversion == INVERSION_ON) - freq = ifreq - freq_offset; - else - freq = ifreq + freq_offset; - - divide(freq / 333, sysclock, NULL, &frequency_shift); - - if (p->inversion == INVERSION_ON) - frequency_shift = -frequency_shift; - - /* sample rate correction */ - sp887x_writereg(state, 0x319, srate_correction[bw_index] >> 12); - sp887x_writereg(state, 0x31a, srate_correction[bw_index] & 0xfff); - - /* carrier offset correction */ - sp887x_writereg(state, 0x309, frequency_shift >> 12); - sp887x_writereg(state, 0x30a, frequency_shift & 0xfff); -} - -static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) -{ - struct sp887x_state* state = fe->demodulator_priv; - unsigned actual_freq; - int err; - u16 val, reg0xc05; - - if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ && - p->u.ofdm.bandwidth != BANDWIDTH_7_MHZ && - p->u.ofdm.bandwidth != BANDWIDTH_6_MHZ) - return -EINVAL; - - if ((err = configure_reg0xc05(p, ®0xc05))) - return err; - - sp887x_microcontroller_stop(state); - - /* setup the PLL */ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - if (fe->ops.tuner_ops.get_frequency) { - fe->ops.tuner_ops.get_frequency(fe, &actual_freq); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } else { - actual_freq = p->frequency; - } - - /* read status reg in order to clear <pending irqs */ - sp887x_readreg(state, 0x200); - - sp887x_correct_offsets(state, p, actual_freq); - - /* filter for 6/7/8 Mhz channel */ - if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ) - val = 2; - else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) - val = 1; - else - val = 0; - - sp887x_writereg(state, 0x311, val); - - /* scan order: 2k first = 0, 8k first = 1 */ - if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K) - sp887x_writereg(state, 0x338, 0x000); - else - sp887x_writereg(state, 0x338, 0x001); - - sp887x_writereg(state, 0xc05, reg0xc05); - - if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ) - val = 2 << 3; - else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) - val = 3 << 3; - else - val = 0 << 3; - - /* enable OFDM and SAW bits as lock indicators in sync register 0xf17, - * optimize algorithm for given bandwidth... - */ - sp887x_writereg(state, 0xf14, 0x160 | val); - sp887x_writereg(state, 0xf15, 0x000); - - sp887x_microcontroller_start(state); - return 0; -} - -static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct sp887x_state* state = fe->demodulator_priv; - u16 snr12 = sp887x_readreg(state, 0xf16); - u16 sync0x200 = sp887x_readreg(state, 0x200); - u16 sync0xf17 = sp887x_readreg(state, 0xf17); - - *status = 0; - - if (snr12 > 0x00f) - *status |= FE_HAS_SIGNAL; - - //if (sync0x200 & 0x004) - // *status |= FE_HAS_SYNC | FE_HAS_CARRIER; - - //if (sync0x200 & 0x008) - // *status |= FE_HAS_VITERBI; - - if ((sync0xf17 & 0x00f) == 0x002) { - *status |= FE_HAS_LOCK; - *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_CARRIER; - } - - if (sync0x200 & 0x001) { /* tuner adjustment requested...*/ - int steps = (sync0x200 >> 4) & 0x00f; - if (steps & 0x008) - steps = -steps; - dprintk("sp887x: implement tuner adjustment (%+i steps)!!\n", - steps); - } - - return 0; -} - -static int sp887x_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct sp887x_state* state = fe->demodulator_priv; - - *ber = (sp887x_readreg(state, 0xc08) & 0x3f) | - (sp887x_readreg(state, 0xc07) << 6); - sp887x_writereg(state, 0xc08, 0x000); - sp887x_writereg(state, 0xc07, 0x000); - if (*ber >= 0x3fff0) - *ber = ~0; - - return 0; -} - -static int sp887x_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct sp887x_state* state = fe->demodulator_priv; - - u16 snr12 = sp887x_readreg(state, 0xf16); - u32 signal = 3 * (snr12 << 4); - *strength = (signal < 0xffff) ? signal : 0xffff; - - return 0; -} - -static int sp887x_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct sp887x_state* state = fe->demodulator_priv; - - u16 snr12 = sp887x_readreg(state, 0xf16); - *snr = (snr12 << 4) | (snr12 >> 8); - - return 0; -} - -static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct sp887x_state* state = fe->demodulator_priv; - - *ucblocks = sp887x_readreg(state, 0xc0c); - if (*ucblocks == 0xfff) - *ucblocks = ~0; - - return 0; -} - -static int sp887x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct sp887x_state* state = fe->demodulator_priv; - - if (enable) { - return sp887x_writereg(state, 0x206, 0x001); - } else { - return sp887x_writereg(state, 0x206, 0x000); - } -} - -static int sp887x_sleep(struct dvb_frontend* fe) -{ - struct sp887x_state* state = fe->demodulator_priv; - - /* tristate TS output and disable interface pins */ - sp887x_writereg(state, 0xc18, 0x000); - - return 0; -} - -static int sp887x_init(struct dvb_frontend* fe) -{ - struct sp887x_state* state = fe->demodulator_priv; - const struct firmware *fw = NULL; - int ret; - - if (!state->initialised) { - /* request the firmware, this will block until someone uploads it */ - printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE); - ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE); - if (ret) { - printk("sp887x: no firmware upload (timeout or file not found?)\n"); - return ret; - } - - ret = sp887x_initial_setup(fe, fw); - release_firmware(fw); - if (ret) { - printk("sp887x: writing firmware to device failed\n"); - return ret; - } - printk("sp887x: firmware upload complete\n"); - state->initialised = 1; - } - - /* enable TS output and interface pins */ - sp887x_writereg(state, 0xc18, 0x00d); - - return 0; -} - -static int sp887x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 350; - fesettings->step_size = 166666*2; - fesettings->max_drift = (166666*2)+1; - return 0; -} - -static void sp887x_release(struct dvb_frontend* fe) -{ - struct sp887x_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops sp887x_ops; - -struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, - struct i2c_adapter* i2c) -{ - struct sp887x_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct sp887x_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - - /* check if the demod is there */ - if (sp887x_readreg(state, 0x0200) < 0) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &sp887x_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops sp887x_ops = { - - .info = { - .name = "Spase SP887x DVB-T", - .type = FE_OFDM, - .frequency_min = 50500000, - .frequency_max = 858000000, - .frequency_stepsize = 166666, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_RECOVER - }, - - .release = sp887x_release, - - .init = sp887x_init, - .sleep = sp887x_sleep, - .i2c_gate_ctrl = sp887x_i2c_gate_ctrl, - - .set_frontend = sp887x_setup_frontend_parameters, - .get_tune_settings = sp887x_get_tune_settings, - - .read_status = sp887x_read_status, - .read_ber = sp887x_read_ber, - .read_signal_strength = sp887x_read_signal_strength, - .read_snr = sp887x_read_snr, - .read_ucblocks = sp887x_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Spase sp887x DVB-T demodulator driver"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(sp887x_attach); diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h deleted file mode 100644 index 04eff6e0eef..00000000000 --- a/drivers/media/dvb/frontends/sp887x.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Driver for the Spase sp887x demodulator -*/ - -#ifndef SP887X_H -#define SP887X_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -struct sp887x_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* request firmware for device */ - int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); -}; - -#if defined(CONFIG_DVB_SP887X) || (defined(CONFIG_DVB_SP887X_MODULE) && defined(MODULE)) -extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_SP887X - -#endif // SP887X_H diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c deleted file mode 100644 index 2da55ec2039..00000000000 --- a/drivers/media/dvb/frontends/stb0899_algo.c +++ /dev/null @@ -1,1522 +0,0 @@ -/* - STB0899 Multistandard Frontend driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - 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 "stb0899_drv.h" -#include "stb0899_priv.h" -#include "stb0899_reg.h" - -inline u32 stb0899_do_div(u64 n, u32 d) -{ - /* wrap do_div() for ease of use */ - - do_div(n, d); - return n; -} - -#if 0 -/* These functions are currently unused */ -/* - * stb0899_calc_srate - * Compute symbol rate - */ -static u32 stb0899_calc_srate(u32 master_clk, u8 *sfr) -{ - u64 tmp; - - /* srate = (SFR * master_clk) >> 20 */ - - /* sfr is of size 20 bit, stored with an offset of 4 bit */ - tmp = (((u32)sfr[0]) << 16) | (((u32)sfr[1]) << 8) | sfr[2]; - tmp &= ~0xf; - tmp *= master_clk; - tmp >>= 24; - - return tmp; -} - -/* - * stb0899_get_srate - * Get the current symbol rate - */ -static u32 stb0899_get_srate(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - u8 sfr[3]; - - stb0899_read_regs(state, STB0899_SFRH, sfr, 3); - - return stb0899_calc_srate(internal->master_clk, sfr); -} -#endif - -/* - * stb0899_set_srate - * Set symbol frequency - * MasterClock: master clock frequency (hz) - * SymbolRate: symbol rate (bauds) - * return symbol frequency - */ -static u32 stb0899_set_srate(struct stb0899_state *state, u32 master_clk, u32 srate) -{ - u32 tmp; - u8 sfr[3]; - - dprintk(state->verbose, FE_DEBUG, 1, "-->"); - /* - * in order to have the maximum precision, the symbol rate entered into - * the chip is computed as the closest value of the "true value". - * In this purpose, the symbol rate value is rounded (1 is added on the bit - * below the LSB ) - * - * srate = (SFR * master_clk) >> 20 - * <=> - * SFR = srate << 20 / master_clk - * - * rounded: - * SFR = (srate << 21 + master_clk) / (2 * master_clk) - * - * stored as 20 bit number with an offset of 4 bit: - * sfr = SFR << 4; - */ - - tmp = stb0899_do_div((((u64)srate) << 21) + master_clk, 2 * master_clk); - tmp <<= 4; - - sfr[0] = tmp >> 16; - sfr[1] = tmp >> 8; - sfr[2] = tmp; - - stb0899_write_regs(state, STB0899_SFRH, sfr, 3); - - return srate; -} - -/* - * stb0899_calc_derot_time - * Compute the amount of time needed by the derotator to lock - * SymbolRate: Symbol rate - * return: derotator time constant (ms) - */ -static long stb0899_calc_derot_time(long srate) -{ - if (srate > 0) - return (100000 / (srate / 1000)); - else - return 0; -} - -/* - * stb0899_carr_width - * Compute the width of the carrier - * return: width of carrier (kHz or Mhz) - */ -long stb0899_carr_width(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - - return (internal->srate + (internal->srate * internal->rolloff) / 100); -} - -/* - * stb0899_first_subrange - * Compute the first subrange of the search - */ -static void stb0899_first_subrange(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_params *params = &state->params; - struct stb0899_config *config = state->config; - - int range = 0; - u32 bandwidth = 0; - - if (config->tuner_get_bandwidth) { - stb0899_i2c_gate_ctrl(&state->frontend, 1); - config->tuner_get_bandwidth(&state->frontend, &bandwidth); - stb0899_i2c_gate_ctrl(&state->frontend, 0); - range = bandwidth - stb0899_carr_width(state) / 2; - } - - if (range > 0) - internal->sub_range = min(internal->srch_range, range); - else - internal->sub_range = 0; - - internal->freq = params->freq; - internal->tuner_offst = 0L; - internal->sub_dir = 1; -} - -/* - * stb0899_check_tmg - * check for timing lock - * internal.Ttiming: time to wait for loop lock - */ -static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - int lock; - u8 reg; - s8 timing; - - msleep(internal->t_derot); - - stb0899_write_reg(state, STB0899_RTF, 0xf2); - reg = stb0899_read_reg(state, STB0899_TLIR); - lock = STB0899_GETFIELD(TLIR_TMG_LOCK_IND, reg); - timing = stb0899_read_reg(state, STB0899_RTF); - - if (lock >= 42) { - if ((lock > 48) && (abs(timing) >= 110)) { - internal->status = ANALOGCARRIER; - dprintk(state->verbose, FE_DEBUG, 1, "-->ANALOG Carrier !"); - } else { - internal->status = TIMINGOK; - dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK !"); - } - } else { - internal->status = NOTIMING; - dprintk(state->verbose, FE_DEBUG, 1, "-->NO TIMING !"); - } - return internal->status; -} - -/* - * stb0899_search_tmg - * perform a fs/2 zig-zag to find timing - */ -static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_params *params = &state->params; - - short int derot_step, derot_freq = 0, derot_limit, next_loop = 3; - int index = 0; - u8 cfr[2]; - - internal->status = NOTIMING; - - /* timing loop computation & symbol rate optimisation */ - derot_limit = (internal->sub_range / 2L) / internal->mclk; - derot_step = (params->srate / 2L) / internal->mclk; - - while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) { - index++; - derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */ - - if (abs(derot_freq) > derot_limit) - next_loop--; - - if (next_loop) { - STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq)); - STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq)); - stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */ - } - internal->direction = -internal->direction; /* Change zigzag direction */ - } - - if (internal->status == TIMINGOK) { - stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */ - internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]); - dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK ! Derot Freq = %d", internal->derot_freq); - } - - return internal->status; -} - -/* - * stb0899_check_carrier - * Check for carrier found - */ -static enum stb0899_status stb0899_check_carrier(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - u8 reg; - - msleep(internal->t_derot); /* wait for derotator ok */ - - reg = stb0899_read_reg(state, STB0899_CFD); - STB0899_SETFIELD_VAL(CFD_ON, reg, 1); - stb0899_write_reg(state, STB0899_CFD, reg); - - reg = stb0899_read_reg(state, STB0899_DSTATUS); - dprintk(state->verbose, FE_DEBUG, 1, "--------------------> STB0899_DSTATUS=[0x%02x]", reg); - if (STB0899_GETFIELD(CARRIER_FOUND, reg)) { - internal->status = CARRIEROK; - dprintk(state->verbose, FE_DEBUG, 1, "-------------> CARRIEROK !"); - } else { - internal->status = NOCARRIER; - dprintk(state->verbose, FE_DEBUG, 1, "-------------> NOCARRIER !"); - } - - return internal->status; -} - -/* - * stb0899_search_carrier - * Search for a QPSK carrier with the derotator - */ -static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - - short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3; - int index = 0; - u8 cfr[2]; - u8 reg; - - internal->status = NOCARRIER; - derot_limit = (internal->sub_range / 2L) / internal->mclk; - derot_freq = internal->derot_freq; - - reg = stb0899_read_reg(state, STB0899_CFD); - STB0899_SETFIELD_VAL(CFD_ON, reg, 1); - stb0899_write_reg(state, STB0899_CFD, reg); - - do { - dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk); - if (stb0899_check_carrier(state) == NOCARRIER) { - index++; - last_derot_freq = derot_freq; - derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */ - - if(abs(derot_freq) > derot_limit) - next_loop--; - - if (next_loop) { - reg = stb0899_read_reg(state, STB0899_CFD); - STB0899_SETFIELD_VAL(CFD_ON, reg, 1); - stb0899_write_reg(state, STB0899_CFD, reg); - - STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq)); - STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq)); - stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */ - } - } - - internal->direction = -internal->direction; /* Change zigzag direction */ - } while ((internal->status != CARRIEROK) && next_loop); - - if (internal->status == CARRIEROK) { - stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */ - internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]); - dprintk(state->verbose, FE_DEBUG, 1, "----> CARRIER OK !, Derot Freq=%d", internal->derot_freq); - } else { - internal->derot_freq = last_derot_freq; - } - - return internal->status; -} - -/* - * stb0899_check_data - * Check for data found - */ -static enum stb0899_status stb0899_check_data(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_params *params = &state->params; - - int lock = 0, index = 0, dataTime = 500, loop; - u8 reg; - - internal->status = NODATA; - - /* RESET FEC */ - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESACS, reg, 1); - stb0899_write_reg(state, STB0899_TSTRES, reg); - msleep(1); - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESACS, reg, 0); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - if (params->srate <= 2000000) - dataTime = 2000; - else if (params->srate <= 5000000) - dataTime = 1500; - else if (params->srate <= 15000000) - dataTime = 1000; - else - dataTime = 500; - - stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop */ - while (1) { - /* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP */ - reg = stb0899_read_reg(state, STB0899_VSTATUS); - lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg); - loop = STB0899_GETFIELD(VSTATUS_END_LOOPVIT, reg); - - if (lock || loop || (index > dataTime)) - break; - index++; - } - - if (lock) { /* DATA LOCK indicator */ - internal->status = DATAOK; - dprintk(state->verbose, FE_DEBUG, 1, "-----------------> DATA OK !"); - } - - return internal->status; -} - -/* - * stb0899_search_data - * Search for a QPSK carrier with the derotator - */ -static enum stb0899_status stb0899_search_data(struct stb0899_state *state) -{ - short int derot_freq, derot_step, derot_limit, next_loop = 3; - u8 cfr[2]; - u8 reg; - int index = 1; - - struct stb0899_internal *internal = &state->internal; - struct stb0899_params *params = &state->params; - - derot_step = (params->srate / 4L) / internal->mclk; - derot_limit = (internal->sub_range / 2L) / internal->mclk; - derot_freq = internal->derot_freq; - - do { - if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) { - - derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */ - if (abs(derot_freq) > derot_limit) - next_loop--; - - if (next_loop) { - dprintk(state->verbose, FE_DEBUG, 1, "Derot freq=%d, mclk=%d", derot_freq, internal->mclk); - reg = stb0899_read_reg(state, STB0899_CFD); - STB0899_SETFIELD_VAL(CFD_ON, reg, 1); - stb0899_write_reg(state, STB0899_CFD, reg); - - STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq)); - STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq)); - stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */ - - stb0899_check_carrier(state); - index++; - } - } - internal->direction = -internal->direction; /* change zig zag direction */ - } while ((internal->status != DATAOK) && next_loop); - - if (internal->status == DATAOK) { - stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */ - internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]); - dprintk(state->verbose, FE_DEBUG, 1, "------> DATAOK ! Derot Freq=%d", internal->derot_freq); - } - - return internal->status; -} - -/* - * stb0899_check_range - * check if the found frequency is in the correct range - */ -static enum stb0899_status stb0899_check_range(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_params *params = &state->params; - - int range_offst, tp_freq; - - range_offst = internal->srch_range / 2000; - tp_freq = internal->freq + (internal->derot_freq * internal->mclk) / 1000; - - if ((tp_freq >= params->freq - range_offst) && (tp_freq <= params->freq + range_offst)) { - internal->status = RANGEOK; - dprintk(state->verbose, FE_DEBUG, 1, "----> RANGEOK !"); - } else { - internal->status = OUTOFRANGE; - dprintk(state->verbose, FE_DEBUG, 1, "----> OUT OF RANGE !"); - } - - return internal->status; -} - -/* - * NextSubRange - * Compute the next subrange of the search - */ -static void next_sub_range(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_params *params = &state->params; - - long old_sub_range; - - if (internal->sub_dir > 0) { - old_sub_range = internal->sub_range; - internal->sub_range = min((internal->srch_range / 2) - - (internal->tuner_offst + internal->sub_range / 2), - internal->sub_range); - - if (internal->sub_range < 0) - internal->sub_range = 0; - - internal->tuner_offst += (old_sub_range + internal->sub_range) / 2; - } - - internal->freq = params->freq + (internal->sub_dir * internal->tuner_offst) / 1000; - internal->sub_dir = -internal->sub_dir; -} - -/* - * stb0899_dvbs_algo - * Search for a signal, timing, carrier and data for a - * given frequency in a given range - */ -enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state) -{ - struct stb0899_params *params = &state->params; - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - - u8 bclc, reg; - u8 cfr[2]; - u8 eq_const[10]; - s32 clnI = 3; - u32 bandwidth = 0; - - /* BETA values rated @ 99MHz */ - s32 betaTab[5][4] = { - /* 5 10 20 30MBps */ - { 37, 34, 32, 31 }, /* QPSK 1/2 */ - { 37, 35, 33, 31 }, /* QPSK 2/3 */ - { 37, 35, 33, 31 }, /* QPSK 3/4 */ - { 37, 36, 33, 32 }, /* QPSK 5/6 */ - { 37, 36, 33, 32 } /* QPSK 7/8 */ - }; - - internal->direction = 1; - - stb0899_set_srate(state, internal->master_clk, params->srate); - /* Carrier loop optimization versus symbol rate for acquisition*/ - if (params->srate <= 5000000) { - stb0899_write_reg(state, STB0899_ACLC, 0x89); - bclc = stb0899_read_reg(state, STB0899_BCLC); - STB0899_SETFIELD_VAL(BETA, bclc, 0x1c); - stb0899_write_reg(state, STB0899_BCLC, bclc); - clnI = 0; - } else if (params->srate <= 15000000) { - stb0899_write_reg(state, STB0899_ACLC, 0xc9); - bclc = stb0899_read_reg(state, STB0899_BCLC); - STB0899_SETFIELD_VAL(BETA, bclc, 0x22); - stb0899_write_reg(state, STB0899_BCLC, bclc); - clnI = 1; - } else if(params->srate <= 25000000) { - stb0899_write_reg(state, STB0899_ACLC, 0x89); - bclc = stb0899_read_reg(state, STB0899_BCLC); - STB0899_SETFIELD_VAL(BETA, bclc, 0x27); - stb0899_write_reg(state, STB0899_BCLC, bclc); - clnI = 2; - } else { - stb0899_write_reg(state, STB0899_ACLC, 0xc8); - bclc = stb0899_read_reg(state, STB0899_BCLC); - STB0899_SETFIELD_VAL(BETA, bclc, 0x29); - stb0899_write_reg(state, STB0899_BCLC, bclc); - clnI = 3; - } - - dprintk(state->verbose, FE_DEBUG, 1, "Set the timing loop to acquisition"); - /* Set the timing loop to acquisition */ - stb0899_write_reg(state, STB0899_RTC, 0x46); - stb0899_write_reg(state, STB0899_CFD, 0xee); - - /* !! WARNING !! - * Do not read any status variables while acquisition, - * If any needed, read before the acquisition starts - * querying status while acquiring causes the - * acquisition to go bad and hence no locks. - */ - dprintk(state->verbose, FE_DEBUG, 1, "Derot Percent=%d Srate=%d mclk=%d", - internal->derot_percent, params->srate, internal->mclk); - - /* Initial calculations */ - internal->derot_step = internal->derot_percent * (params->srate / 1000L) / internal->mclk; /* DerotStep/1000 * Fsymbol */ - internal->t_derot = stb0899_calc_derot_time(params->srate); - internal->t_data = 500; - - dprintk(state->verbose, FE_DEBUG, 1, "RESET stream merger"); - /* RESET Stream merger */ - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESRS, reg, 1); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - /* - * Set KDIVIDER to an intermediate value between - * 1/2 and 7/8 for acquisition - */ - reg = stb0899_read_reg(state, STB0899_DEMAPVIT); - STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 60); - stb0899_write_reg(state, STB0899_DEMAPVIT, reg); - - stb0899_write_reg(state, STB0899_EQON, 0x01); /* Equalizer OFF while acquiring */ - stb0899_write_reg(state, STB0899_VITSYNC, 0x19); - - stb0899_first_subrange(state); - do { - /* Initialisations */ - cfr[0] = cfr[1] = 0; - stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* RESET derotator frequency */ - - stb0899_write_reg(state, STB0899_RTF, 0); - reg = stb0899_read_reg(state, STB0899_CFD); - STB0899_SETFIELD_VAL(CFD_ON, reg, 1); - stb0899_write_reg(state, STB0899_CFD, reg); - - internal->derot_freq = 0; - internal->status = NOAGC1; - - /* enable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 1); - - /* Move tuner to frequency */ - dprintk(state->verbose, FE_DEBUG, 1, "Tuner set frequency"); - if (state->config->tuner_set_frequency) - state->config->tuner_set_frequency(&state->frontend, internal->freq); - - if (state->config->tuner_get_frequency) - state->config->tuner_get_frequency(&state->frontend, &internal->freq); - - msleep(internal->t_agc1 + internal->t_agc2 + internal->t_derot); /* AGC1, AGC2 and timing loop */ - dprintk(state->verbose, FE_DEBUG, 1, "current derot freq=%d", internal->derot_freq); - internal->status = AGC1OK; - - /* There is signal in the band */ - if (config->tuner_get_bandwidth) - config->tuner_get_bandwidth(&state->frontend, &bandwidth); - - /* disable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 0); - - if (params->srate <= bandwidth / 2) - stb0899_search_tmg(state); /* For low rates (SCPC) */ - else - stb0899_check_tmg(state); /* For high rates (MCPC) */ - - if (internal->status == TIMINGOK) { - dprintk(state->verbose, FE_DEBUG, 1, - "TIMING OK ! Derot freq=%d, mclk=%d", - internal->derot_freq, internal->mclk); - - if (stb0899_search_carrier(state) == CARRIEROK) { /* Search for carrier */ - dprintk(state->verbose, FE_DEBUG, 1, - "CARRIER OK ! Derot freq=%d, mclk=%d", - internal->derot_freq, internal->mclk); - - if (stb0899_search_data(state) == DATAOK) { /* Check for data */ - dprintk(state->verbose, FE_DEBUG, 1, - "DATA OK ! Derot freq=%d, mclk=%d", - internal->derot_freq, internal->mclk); - - if (stb0899_check_range(state) == RANGEOK) { - dprintk(state->verbose, FE_DEBUG, 1, - "RANGE OK ! derot freq=%d, mclk=%d", - internal->derot_freq, internal->mclk); - - internal->freq = params->freq + ((internal->derot_freq * internal->mclk) / 1000); - reg = stb0899_read_reg(state, STB0899_PLPARM); - internal->fecrate = STB0899_GETFIELD(VITCURPUN, reg); - dprintk(state->verbose, FE_DEBUG, 1, - "freq=%d, internal resultant freq=%d", - params->freq, internal->freq); - - dprintk(state->verbose, FE_DEBUG, 1, - "internal puncture rate=%d", - internal->fecrate); - } - } - } - } - if (internal->status != RANGEOK) - next_sub_range(state); - - } while (internal->sub_range && internal->status != RANGEOK); - - /* Set the timing loop to tracking */ - stb0899_write_reg(state, STB0899_RTC, 0x33); - stb0899_write_reg(state, STB0899_CFD, 0xf7); - /* if locked and range ok, set Kdiv */ - if (internal->status == RANGEOK) { - dprintk(state->verbose, FE_DEBUG, 1, "Locked & Range OK !"); - stb0899_write_reg(state, STB0899_EQON, 0x41); /* Equalizer OFF while acquiring */ - stb0899_write_reg(state, STB0899_VITSYNC, 0x39); /* SN to b'11 for acquisition */ - - /* - * Carrier loop optimization versus - * symbol Rate/Puncture Rate for Tracking - */ - reg = stb0899_read_reg(state, STB0899_BCLC); - switch (internal->fecrate) { - case STB0899_FEC_1_2: /* 13 */ - stb0899_write_reg(state, STB0899_DEMAPVIT, 0x1a); - STB0899_SETFIELD_VAL(BETA, reg, betaTab[0][clnI]); - stb0899_write_reg(state, STB0899_BCLC, reg); - break; - case STB0899_FEC_2_3: /* 18 */ - stb0899_write_reg(state, STB0899_DEMAPVIT, 44); - STB0899_SETFIELD_VAL(BETA, reg, betaTab[1][clnI]); - stb0899_write_reg(state, STB0899_BCLC, reg); - break; - case STB0899_FEC_3_4: /* 21 */ - stb0899_write_reg(state, STB0899_DEMAPVIT, 60); - STB0899_SETFIELD_VAL(BETA, reg, betaTab[2][clnI]); - stb0899_write_reg(state, STB0899_BCLC, reg); - break; - case STB0899_FEC_5_6: /* 24 */ - stb0899_write_reg(state, STB0899_DEMAPVIT, 75); - STB0899_SETFIELD_VAL(BETA, reg, betaTab[3][clnI]); - stb0899_write_reg(state, STB0899_BCLC, reg); - break; - case STB0899_FEC_6_7: /* 25 */ - stb0899_write_reg(state, STB0899_DEMAPVIT, 88); - stb0899_write_reg(state, STB0899_ACLC, 0x88); - stb0899_write_reg(state, STB0899_BCLC, 0x9a); - break; - case STB0899_FEC_7_8: /* 26 */ - stb0899_write_reg(state, STB0899_DEMAPVIT, 94); - STB0899_SETFIELD_VAL(BETA, reg, betaTab[4][clnI]); - stb0899_write_reg(state, STB0899_BCLC, reg); - break; - default: - dprintk(state->verbose, FE_DEBUG, 1, "Unsupported Puncture Rate"); - break; - } - /* release stream merger RESET */ - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESRS, reg, 0); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - /* disable carrier detector */ - reg = stb0899_read_reg(state, STB0899_CFD); - STB0899_SETFIELD_VAL(CFD_ON, reg, 0); - stb0899_write_reg(state, STB0899_CFD, reg); - - stb0899_read_regs(state, STB0899_EQUAI1, eq_const, 10); - } - - return internal->status; -} - -/* - * stb0899_dvbs2_config_uwp - * Configure UWP state machine - */ -static void stb0899_dvbs2_config_uwp(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - u32 uwp1, uwp2, uwp3, reg; - - uwp1 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1); - uwp2 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL2); - uwp3 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL3); - - STB0899_SETFIELD_VAL(UWP_ESN0_AVE, uwp1, config->esno_ave); - STB0899_SETFIELD_VAL(UWP_ESN0_QUANT, uwp1, config->esno_quant); - STB0899_SETFIELD_VAL(UWP_TH_SOF, uwp1, config->uwp_threshold_sof); - - STB0899_SETFIELD_VAL(FE_COARSE_TRK, uwp2, internal->av_frame_coarse); - STB0899_SETFIELD_VAL(FE_FINE_TRK, uwp2, internal->av_frame_fine); - STB0899_SETFIELD_VAL(UWP_MISS_TH, uwp2, config->miss_threshold); - - STB0899_SETFIELD_VAL(UWP_TH_ACQ, uwp3, config->uwp_threshold_acq); - STB0899_SETFIELD_VAL(UWP_TH_TRACK, uwp3, config->uwp_threshold_track); - - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL1, STB0899_OFF0_UWP_CNTRL1, uwp1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL2, STB0899_OFF0_UWP_CNTRL2, uwp2); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL3, STB0899_OFF0_UWP_CNTRL3, uwp3); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, SOF_SRCH_TO); - STB0899_SETFIELD_VAL(SOF_SEARCH_TIMEOUT, reg, config->sof_search_timeout); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_SOF_SRCH_TO, STB0899_OFF0_SOF_SRCH_TO, reg); -} - -/* - * stb0899_dvbs2_config_csm_auto - * Set CSM to AUTO mode - */ -static void stb0899_dvbs2_config_csm_auto(struct stb0899_state *state) -{ - u32 reg; - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1); - STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, reg, 1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, reg); -} - -static long Log2Int(int number) -{ - int i; - - i = 0; - while ((1 << i) <= abs(number)) - i++; - - if (number == 0) - i = 1; - - return i - 1; -} - -/* - * stb0899_dvbs2_calc_srate - * compute BTR_NOM_FREQ for the symbol rate - */ -static u32 stb0899_dvbs2_calc_srate(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - - u32 dec_ratio, dec_rate, decim, remain, intval, btr_nom_freq; - u32 master_clk, srate; - - dec_ratio = (internal->master_clk * 2) / (5 * internal->srate); - dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio; - dec_rate = Log2Int(dec_ratio); - decim = 1 << dec_rate; - master_clk = internal->master_clk / 1000; - srate = internal->srate / 1000; - - if (decim <= 4) { - intval = (decim * (1 << (config->btr_nco_bits - 1))) / master_clk; - remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk; - } else { - intval = (1 << (config->btr_nco_bits - 1)) / (master_clk / 100) * decim / 100; - remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk; - } - btr_nom_freq = (intval * srate) + ((remain * srate) / master_clk); - - return btr_nom_freq; -} - -/* - * stb0899_dvbs2_calc_dev - * compute the correction to be applied to symbol rate - */ -static u32 stb0899_dvbs2_calc_dev(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - u32 dec_ratio, correction, master_clk, srate; - - dec_ratio = (internal->master_clk * 2) / (5 * internal->srate); - dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio; - - master_clk = internal->master_clk / 1000; /* for integer Caculation*/ - srate = internal->srate / 1000; /* for integer Caculation*/ - correction = (512 * master_clk) / (2 * dec_ratio * srate); - - return correction; -} - -/* - * stb0899_dvbs2_set_srate - * Set DVBS2 symbol rate - */ -static void stb0899_dvbs2_set_srate(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - - u32 dec_ratio, dec_rate, win_sel, decim, f_sym, btr_nom_freq; - u32 correction, freq_adj, band_lim, decim_cntrl, reg; - u8 anti_alias; - - /*set decimation to 1*/ - dec_ratio = (internal->master_clk * 2) / (5 * internal->srate); - dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio; - dec_rate = Log2Int(dec_ratio); - - win_sel = 0; - if (dec_rate >= 5) - win_sel = dec_rate - 4; - - decim = (1 << dec_rate); - /* (FSamp/Fsymbol *100) for integer Caculation */ - f_sym = internal->master_clk / ((decim * internal->srate) / 1000); - - if (f_sym <= 2250) /* don't band limit signal going into btr block*/ - band_lim = 1; - else - band_lim = 0; /* band limit signal going into btr block*/ - - decim_cntrl = ((win_sel << 3) & 0x18) + ((band_lim << 5) & 0x20) + (dec_rate & 0x7); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DECIM_CNTRL, STB0899_OFF0_DECIM_CNTRL, decim_cntrl); - - if (f_sym <= 3450) - anti_alias = 0; - else if (f_sym <= 4250) - anti_alias = 1; - else - anti_alias = 2; - - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ANTI_ALIAS_SEL, STB0899_OFF0_ANTI_ALIAS_SEL, anti_alias); - btr_nom_freq = stb0899_dvbs2_calc_srate(state); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_NOM_FREQ, STB0899_OFF0_BTR_NOM_FREQ, btr_nom_freq); - - correction = stb0899_dvbs2_calc_dev(state); - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL); - STB0899_SETFIELD_VAL(BTR_FREQ_CORR, reg, correction); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg); - - /* scale UWP+CSM frequency to sample rate*/ - freq_adj = internal->srate / (internal->master_clk / 4096); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_FREQ_ADJ_SCALE, STB0899_OFF0_FREQ_ADJ_SCALE, freq_adj); -} - -/* - * stb0899_dvbs2_set_btr_loopbw - * set bit timing loop bandwidth as a percentage of the symbol rate - */ -static void stb0899_dvbs2_set_btr_loopbw(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - - u32 sym_peak = 23, zeta = 707, loopbw_percent = 60; - s32 dec_ratio, dec_rate, k_btr1_rshft, k_btr1, k_btr0_rshft; - s32 k_btr0, k_btr2_rshft, k_direct_shift, k_indirect_shift; - u32 decim, K, wn, k_direct, k_indirect; - u32 reg; - - dec_ratio = (internal->master_clk * 2) / (5 * internal->srate); - dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio; - dec_rate = Log2Int(dec_ratio); - decim = (1 << dec_rate); - - sym_peak *= 576000; - K = (1 << config->btr_nco_bits) / (internal->master_clk / 1000); - K *= (internal->srate / 1000000) * decim; /*k=k 10^-8*/ - - if (K != 0) { - K = sym_peak / K; - wn = (4 * zeta * zeta) + 1000000; - wn = (2 * (loopbw_percent * 1000) * 40 * zeta) /wn; /*wn =wn 10^-8*/ - - k_indirect = (wn * wn) / K; - k_indirect = k_indirect; /*kindirect = kindirect 10^-6*/ - k_direct = (2 * wn * zeta) / K; /*kDirect = kDirect 10^-2*/ - k_direct *= 100; - - k_direct_shift = Log2Int(k_direct) - Log2Int(10000) - 2; - k_btr1_rshft = (-1 * k_direct_shift) + config->btr_gain_shift_offset; - k_btr1 = k_direct / (1 << k_direct_shift); - k_btr1 /= 10000; - - k_indirect_shift = Log2Int(k_indirect + 15) - 20 /*- 2*/; - k_btr0_rshft = (-1 * k_indirect_shift) + config->btr_gain_shift_offset; - k_btr0 = k_indirect * (1 << (-k_indirect_shift)); - k_btr0 /= 1000000; - - k_btr2_rshft = 0; - if (k_btr0_rshft > 15) { - k_btr2_rshft = k_btr0_rshft - 15; - k_btr0_rshft = 15; - } - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_LOOP_GAIN); - STB0899_SETFIELD_VAL(KBTR0_RSHFT, reg, k_btr0_rshft); - STB0899_SETFIELD_VAL(KBTR0, reg, k_btr0); - STB0899_SETFIELD_VAL(KBTR1_RSHFT, reg, k_btr1_rshft); - STB0899_SETFIELD_VAL(KBTR1, reg, k_btr1); - STB0899_SETFIELD_VAL(KBTR2_RSHFT, reg, k_btr2_rshft); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, reg); - } else - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, 0xc4c4f); -} - -/* - * stb0899_dvbs2_set_carr_freq - * set nominal frequency for carrier search - */ -static void stb0899_dvbs2_set_carr_freq(struct stb0899_state *state, s32 carr_freq, u32 master_clk) -{ - struct stb0899_config *config = state->config; - s32 crl_nom_freq; - u32 reg; - - crl_nom_freq = (1 << config->crl_nco_bits) / master_clk; - crl_nom_freq *= carr_freq; - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ); - STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, crl_nom_freq); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg); -} - -/* - * stb0899_dvbs2_init_calc - * Initialize DVBS2 UWP, CSM, carrier and timing loops - */ -static void stb0899_dvbs2_init_calc(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - s32 steps, step_size; - u32 range, reg; - - /* config uwp and csm */ - stb0899_dvbs2_config_uwp(state); - stb0899_dvbs2_config_csm_auto(state); - - /* initialize BTR */ - stb0899_dvbs2_set_srate(state); - stb0899_dvbs2_set_btr_loopbw(state); - - if (internal->srate / 1000000 >= 15) - step_size = (1 << 17) / 5; - else if (internal->srate / 1000000 >= 10) - step_size = (1 << 17) / 7; - else if (internal->srate / 1000000 >= 5) - step_size = (1 << 17) / 10; - else - step_size = (1 << 17) / 4; - - range = internal->srch_range / 1000000; - steps = (10 * range * (1 << 17)) / (step_size * (internal->srate / 1000000)); - steps = (steps + 6) / 10; - steps = (steps == 0) ? 1 : steps; - if (steps % 2 == 0) - stb0899_dvbs2_set_carr_freq(state, internal->center_freq - - (internal->step_size * (internal->srate / 20000000)), - (internal->master_clk) / 1000000); - else - stb0899_dvbs2_set_carr_freq(state, internal->center_freq, (internal->master_clk) / 1000000); - - /*Set Carrier Search params (zigzag, num steps and freq step size*/ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, ACQ_CNTRL2); - STB0899_SETFIELD_VAL(ZIGZAG, reg, 1); - STB0899_SETFIELD_VAL(NUM_STEPS, reg, steps); - STB0899_SETFIELD_VAL(FREQ_STEPSIZE, reg, step_size); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQ_CNTRL2, STB0899_OFF0_ACQ_CNTRL2, reg); -} - -/* - * stb0899_dvbs2_btr_init - * initialize the timing loop - */ -static void stb0899_dvbs2_btr_init(struct stb0899_state *state) -{ - u32 reg; - - /* set enable BTR loopback */ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL); - STB0899_SETFIELD_VAL(INTRP_PHS_SENSE, reg, 1); - STB0899_SETFIELD_VAL(BTR_ERR_ENA, reg, 1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg); - - /* fix btr freq accum at 0 */ - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x10000000); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x00000000); - - /* fix btr freq accum at 0 */ - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x10000000); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x00000000); -} - -/* - * stb0899_dvbs2_reacquire - * trigger a DVB-S2 acquisition - */ -static void stb0899_dvbs2_reacquire(struct stb0899_state *state) -{ - u32 reg = 0; - - /* demod soft reset */ - STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg); - - /*Reset Timing Loop */ - stb0899_dvbs2_btr_init(state); - - /* reset Carrier loop */ - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, (1 << 30)); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, 0); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_LOOP_GAIN, STB0899_OFF0_CRL_LOOP_GAIN, 0); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, (1 << 30)); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, 0); - - /*release demod soft reset */ - reg = 0; - STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 0); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg); - - /* start acquisition process */ - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQUIRE_TRIG, STB0899_OFF0_ACQUIRE_TRIG, 1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_LOCK_LOST, STB0899_OFF0_LOCK_LOST, 0); - - /* equalizer Init */ - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 1); - - /*Start equilizer */ - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 0); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL); - STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0); - STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 0); - STB0899_SETFIELD_VAL(EQ_DELAY, reg, 0x05); - STB0899_SETFIELD_VAL(EQ_ADAPT_MODE, reg, 0x01); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg); - - /* RESET Packet delineator */ - stb0899_write_reg(state, STB0899_PDELCTRL, 0x4a); -} - -/* - * stb0899_dvbs2_get_dmd_status - * get DVB-S2 Demod LOCK status - */ -static enum stb0899_status stb0899_dvbs2_get_dmd_status(struct stb0899_state *state, int timeout) -{ - int time = -10, lock = 0, uwp, csm; - u32 reg; - - do { - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STATUS); - dprintk(state->verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg); - if (STB0899_GETFIELD(IF_AGC_LOCK, reg)) - dprintk(state->verbose, FE_DEBUG, 1, "------------->IF AGC LOCKED !"); - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2); - dprintk(state->verbose, FE_DEBUG, 1, "----------->DMD STAT2=[0x%02x]", reg); - uwp = STB0899_GETFIELD(UWP_LOCK, reg); - csm = STB0899_GETFIELD(CSM_LOCK, reg); - if (uwp && csm) - lock = 1; - - time += 10; - msleep(10); - - } while ((!lock) && (time <= timeout)); - - if (lock) { - dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 LOCK !"); - return DVBS2_DEMOD_LOCK; - } else { - return DVBS2_DEMOD_NOLOCK; - } -} - -/* - * stb0899_dvbs2_get_data_lock - * get FEC status - */ -static int stb0899_dvbs2_get_data_lock(struct stb0899_state *state, int timeout) -{ - int time = 0, lock = 0; - u8 reg; - - while ((!lock) && (time < timeout)) { - reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1); - dprintk(state->verbose, FE_DEBUG, 1, "---------> CFGPDELSTATUS=[0x%02x]", reg); - lock = STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg); - time++; - } - - return lock; -} - -/* - * stb0899_dvbs2_get_fec_status - * get DVB-S2 FEC LOCK status - */ -static enum stb0899_status stb0899_dvbs2_get_fec_status(struct stb0899_state *state, int timeout) -{ - int time = 0, Locked; - - do { - Locked = stb0899_dvbs2_get_data_lock(state, 1); - time++; - msleep(1); - - } while ((!Locked) && (time < timeout)); - - if (Locked) { - dprintk(state->verbose, FE_DEBUG, 1, "---------->DVB-S2 FEC LOCK !"); - return DVBS2_FEC_LOCK; - } else { - return DVBS2_FEC_NOLOCK; - } -} - - -/* - * stb0899_dvbs2_init_csm - * set parameters for manual mode - */ -static void stb0899_dvbs2_init_csm(struct stb0899_state *state, int pilots, enum stb0899_modcod modcod) -{ - struct stb0899_internal *internal = &state->internal; - - s32 dvt_tbl = 1, two_pass = 0, agc_gain = 6, agc_shift = 0, loop_shift = 0, phs_diff_thr = 0x80; - s32 gamma_acq, gamma_rho_acq, gamma_trk, gamma_rho_trk, lock_count_thr; - u32 csm1, csm2, csm3, csm4; - - if (((internal->master_clk / internal->srate) <= 4) && (modcod <= 11) && (pilots == 1)) { - switch (modcod) { - case STB0899_QPSK_12: - gamma_acq = 25; - gamma_rho_acq = 2700; - gamma_trk = 12; - gamma_rho_trk = 180; - lock_count_thr = 8; - break; - case STB0899_QPSK_35: - gamma_acq = 38; - gamma_rho_acq = 7182; - gamma_trk = 14; - gamma_rho_trk = 308; - lock_count_thr = 8; - break; - case STB0899_QPSK_23: - gamma_acq = 42; - gamma_rho_acq = 9408; - gamma_trk = 17; - gamma_rho_trk = 476; - lock_count_thr = 8; - break; - case STB0899_QPSK_34: - gamma_acq = 53; - gamma_rho_acq = 16642; - gamma_trk = 19; - gamma_rho_trk = 646; - lock_count_thr = 8; - break; - case STB0899_QPSK_45: - gamma_acq = 53; - gamma_rho_acq = 17119; - gamma_trk = 22; - gamma_rho_trk = 880; - lock_count_thr = 8; - break; - case STB0899_QPSK_56: - gamma_acq = 55; - gamma_rho_acq = 19250; - gamma_trk = 23; - gamma_rho_trk = 989; - lock_count_thr = 8; - break; - case STB0899_QPSK_89: - gamma_acq = 60; - gamma_rho_acq = 24240; - gamma_trk = 24; - gamma_rho_trk = 1176; - lock_count_thr = 8; - break; - case STB0899_QPSK_910: - gamma_acq = 66; - gamma_rho_acq = 29634; - gamma_trk = 24; - gamma_rho_trk = 1176; - lock_count_thr = 8; - break; - default: - gamma_acq = 66; - gamma_rho_acq = 29634; - gamma_trk = 24; - gamma_rho_trk = 1176; - lock_count_thr = 8; - break; - } - - csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1); - STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, csm1, 0); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1); - - csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1); - csm2 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL2); - csm3 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL3); - csm4 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL4); - - STB0899_SETFIELD_VAL(CSM_DVT_TABLE, csm1, dvt_tbl); - STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, two_pass); - STB0899_SETFIELD_VAL(CSM_AGC_GAIN, csm1, agc_gain); - STB0899_SETFIELD_VAL(CSM_AGC_SHIFT, csm1, agc_shift); - STB0899_SETFIELD_VAL(FE_LOOP_SHIFT, csm1, loop_shift); - STB0899_SETFIELD_VAL(CSM_GAMMA_ACQ, csm2, gamma_acq); - STB0899_SETFIELD_VAL(CSM_GAMMA_RHOACQ, csm2, gamma_rho_acq); - STB0899_SETFIELD_VAL(CSM_GAMMA_TRACK, csm3, gamma_trk); - STB0899_SETFIELD_VAL(CSM_GAMMA_RHOTRACK, csm3, gamma_rho_trk); - STB0899_SETFIELD_VAL(CSM_LOCKCOUNT_THRESH, csm4, lock_count_thr); - STB0899_SETFIELD_VAL(CSM_PHASEDIFF_THRESH, csm4, phs_diff_thr); - - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL2, STB0899_OFF0_CSM_CNTRL2, csm2); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL3, STB0899_OFF0_CSM_CNTRL3, csm3); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL4, STB0899_OFF0_CSM_CNTRL4, csm4); - } -} - -/* - * stb0899_dvbs2_get_srate - * get DVB-S2 Symbol Rate - */ -static u32 stb0899_dvbs2_get_srate(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - - u32 bTrNomFreq, srate, decimRate, intval1, intval2, reg; - int div1, div2, rem1, rem2; - - div1 = config->btr_nco_bits / 2; - div2 = config->btr_nco_bits - div1 - 1; - - bTrNomFreq = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_NOM_FREQ); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DECIM_CNTRL); - decimRate = STB0899_GETFIELD(DECIM_RATE, reg); - decimRate = (1 << decimRate); - - intval1 = internal->master_clk / (1 << div1); - intval2 = bTrNomFreq / (1 << div2); - - rem1 = internal->master_clk % (1 << div1); - rem2 = bTrNomFreq % (1 << div2); - /* only for integer calculation */ - srate = (intval1 * intval2) + ((intval1 * rem2) / (1 << div2)) + ((intval2 * rem1) / (1 << div1)); - srate /= decimRate; /*symbrate = (btrnomfreq_register_val*MasterClock)/2^(27+decim_rate_field) */ - - return srate; -} - -/* - * stb0899_dvbs2_algo - * Search for signal, timing, carrier and data for a given - * frequency in a given range - */ -enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - enum stb0899_modcod modcod; - - s32 offsetfreq, searchTime, FecLockTime, pilots, iqSpectrum; - int i = 0; - u32 reg, csm1; - - if (internal->srate <= 2000000) { - searchTime = 5000; /* 5000 ms max time to lock UWP and CSM, SYMB <= 2Mbs */ - FecLockTime = 350; /* 350 ms max time to lock FEC, SYMB <= 2Mbs */ - } else if (internal->srate <= 5000000) { - searchTime = 2500; /* 2500 ms max time to lock UWP and CSM, 2Mbs < SYMB <= 5Mbs */ - FecLockTime = 170; /* 170 ms max time to lock FEC, 2Mbs< SYMB <= 5Mbs */ - } else if (internal->srate <= 10000000) { - searchTime = 1500; /* 1500 ms max time to lock UWP and CSM, 5Mbs <SYMB <= 10Mbs */ - FecLockTime = 80; /* 80 ms max time to lock FEC, 5Mbs< SYMB <= 10Mbs */ - } else if (internal->srate <= 15000000) { - searchTime = 500; /* 500 ms max time to lock UWP and CSM, 10Mbs <SYMB <= 15Mbs */ - FecLockTime = 50; /* 50 ms max time to lock FEC, 10Mbs< SYMB <= 15Mbs */ - } else if (internal->srate <= 20000000) { - searchTime = 300; /* 300 ms max time to lock UWP and CSM, 15Mbs < SYMB <= 20Mbs */ - FecLockTime = 30; /* 50 ms max time to lock FEC, 15Mbs< SYMB <= 20Mbs */ - } else if (internal->srate <= 25000000) { - searchTime = 250; /* 250 ms max time to lock UWP and CSM, 20 Mbs < SYMB <= 25Mbs */ - FecLockTime = 25; /* 25 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs */ - } else { - searchTime = 150; /* 150 ms max time to lock UWP and CSM, SYMB > 25Mbs */ - FecLockTime = 20; /* 20 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs */ - } - - /* Maintain Stream Merger in reset during acquisition */ - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESRS, reg, 1); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - /* enable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 1); - - /* Move tuner to frequency */ - if (state->config->tuner_set_frequency) - state->config->tuner_set_frequency(&state->frontend, internal->freq); - if (state->config->tuner_get_frequency) - state->config->tuner_get_frequency(&state->frontend, &internal->freq); - - /* disable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 0); - - /* Set IF AGC to acquisition */ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL); - STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg, 4); - STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 32); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2); - STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 0); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg); - - /* Initialisation */ - stb0899_dvbs2_init_calc(state); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2); - switch (internal->inversion) { - case IQ_SWAP_OFF: - STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 0); - break; - case IQ_SWAP_ON: - STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1); - break; - case IQ_SWAP_AUTO: /* use last successful search first */ - STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1); - break; - } - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg); - stb0899_dvbs2_reacquire(state); - - /* Wait for demod lock (UWP and CSM) */ - internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime); - - if (internal->status == DVBS2_DEMOD_LOCK) { - dprintk(state->verbose, FE_DEBUG, 1, "------------> DVB-S2 DEMOD LOCK !"); - i = 0; - /* Demod Locked, check FEC status */ - internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime); - - /*If false lock (UWP and CSM Locked but no FEC) try 3 time max*/ - while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) { - /* Read the frequency offset*/ - offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ); - - /* Set the Nominal frequency to the found frequency offset for the next reacquire*/ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ); - STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg); - stb0899_dvbs2_reacquire(state); - internal->status = stb0899_dvbs2_get_fec_status(state, searchTime); - i++; - } - } - - if (internal->status != DVBS2_FEC_LOCK) { - if (internal->inversion == IQ_SWAP_AUTO) { - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2); - iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg); - /* IQ Spectrum Inversion */ - STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg); - /* start acquistion process */ - stb0899_dvbs2_reacquire(state); - - /* Wait for demod lock (UWP and CSM) */ - internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime); - if (internal->status == DVBS2_DEMOD_LOCK) { - i = 0; - /* Demod Locked, check FEC */ - internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime); - /*try thrice for false locks, (UWP and CSM Locked but no FEC) */ - while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) { - /* Read the frequency offset*/ - offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ); - - /* Set the Nominal frequency to the found frequency offset for the next reacquire*/ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ); - STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg); - - stb0899_dvbs2_reacquire(state); - internal->status = stb0899_dvbs2_get_fec_status(state, searchTime); - i++; - } - } -/* - if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED) - pParams->IQLocked = !iqSpectrum; -*/ - } - } - if (internal->status == DVBS2_FEC_LOCK) { - dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 FEC Lock !"); - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2); - modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2; - pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01; - - if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) && - (INRANGE(STB0899_QPSK_23, modcod, STB0899_QPSK_910)) && - (pilots == 1)) { - - stb0899_dvbs2_init_csm(state, pilots, modcod); - /* Wait for UWP,CSM and data LOCK 20ms max */ - internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime); - - i = 0; - while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) { - csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1); - STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1); - csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1); - STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 0); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1); - - internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime); - i++; - } - } - - if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) && - (INRANGE(STB0899_QPSK_12, modcod, STB0899_QPSK_35)) && - (pilots == 1)) { - - /* Equalizer Disable update */ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL); - STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg); - } - - /* slow down the Equalizer once locked */ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL); - STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0x02); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg); - - /* Store signal parameters */ - offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ); - - offsetfreq = offsetfreq / ((1 << 30) / 1000); - offsetfreq *= (internal->master_clk / 1000000); - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2); - if (STB0899_GETFIELD(SPECTRUM_INVERT, reg)) - offsetfreq *= -1; - - internal->freq = internal->freq - offsetfreq; - internal->srate = stb0899_dvbs2_get_srate(state); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2); - internal->modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2; - internal->pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01; - internal->frame_length = (STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 1) & 0x01; - - /* Set IF AGC to tracking */ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL); - STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg, 3); - - /* if QPSK 1/2,QPSK 3/5 or QPSK 2/3 set IF AGC reference to 16 otherwise 32*/ - if (INRANGE(STB0899_QPSK_12, internal->modcod, STB0899_QPSK_23)) - STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 16); - - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2); - STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 7); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg); - } - - /* Release Stream Merger Reset */ - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESRS, reg, 0); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - return internal->status; -} diff --git a/drivers/media/dvb/frontends/stb0899_cfg.h b/drivers/media/dvb/frontends/stb0899_cfg.h deleted file mode 100644 index 0867906d3ff..00000000000 --- a/drivers/media/dvb/frontends/stb0899_cfg.h +++ /dev/null @@ -1,287 +0,0 @@ -/* - STB0899 Multistandard Frontend driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - 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 __STB0899_CFG_H -#define __STB0899_CFG_H - -static const struct stb0899_s2_reg stb0899_s2_init_2[] = { - - { STB0899_OFF0_DMD_STATUS , STB0899_BASE_DMD_STATUS , 0x00000103 }, /* DMDSTATUS */ - { STB0899_OFF0_CRL_FREQ , STB0899_BASE_CRL_FREQ , 0x3ed1da56 }, /* CRLFREQ */ - { STB0899_OFF0_BTR_FREQ , STB0899_BASE_BTR_FREQ , 0x00004000 }, /* BTRFREQ */ - { STB0899_OFF0_IF_AGC_GAIN , STB0899_BASE_IF_AGC_GAIN , 0x00002ade }, /* IFAGCGAIN */ - { STB0899_OFF0_BB_AGC_GAIN , STB0899_BASE_BB_AGC_GAIN , 0x000001bc }, /* BBAGCGAIN */ - { STB0899_OFF0_DC_OFFSET , STB0899_BASE_DC_OFFSET , 0x00000200 }, /* DCOFFSET */ - { STB0899_OFF0_DMD_CNTRL , STB0899_BASE_DMD_CNTRL , 0x0000000f }, /* DMDCNTRL */ - - { STB0899_OFF0_IF_AGC_CNTRL , STB0899_BASE_IF_AGC_CNTRL , 0x03fb4a20 }, /* IFAGCCNTRL */ - { STB0899_OFF0_BB_AGC_CNTRL , STB0899_BASE_BB_AGC_CNTRL , 0x00200c97 }, /* BBAGCCNTRL */ - - { STB0899_OFF0_CRL_CNTRL , STB0899_BASE_CRL_CNTRL , 0x00000016 }, /* CRLCNTRL */ - { STB0899_OFF0_CRL_PHS_INIT , STB0899_BASE_CRL_PHS_INIT , 0x00000000 }, /* CRLPHSINIT */ - { STB0899_OFF0_CRL_FREQ_INIT , STB0899_BASE_CRL_FREQ_INIT , 0x00000000 }, /* CRLFREQINIT */ - { STB0899_OFF0_CRL_LOOP_GAIN , STB0899_BASE_CRL_LOOP_GAIN , 0x00000000 }, /* CRLLOOPGAIN */ - { STB0899_OFF0_CRL_NOM_FREQ , STB0899_BASE_CRL_NOM_FREQ , 0x3ed097b6 }, /* CRLNOMFREQ */ - { STB0899_OFF0_CRL_SWP_RATE , STB0899_BASE_CRL_SWP_RATE , 0x00000000 }, /* CRLSWPRATE */ - { STB0899_OFF0_CRL_MAX_SWP , STB0899_BASE_CRL_MAX_SWP , 0x00000000 }, /* CRLMAXSWP */ - { STB0899_OFF0_CRL_LK_CNTRL , STB0899_BASE_CRL_LK_CNTRL , 0x0f6cdc01 }, /* CRLLKCNTRL */ - { STB0899_OFF0_DECIM_CNTRL , STB0899_BASE_DECIM_CNTRL , 0x00000000 }, /* DECIMCNTRL */ - { STB0899_OFF0_BTR_CNTRL , STB0899_BASE_BTR_CNTRL , 0x00003993 }, /* BTRCNTRL */ - { STB0899_OFF0_BTR_LOOP_GAIN , STB0899_BASE_BTR_LOOP_GAIN , 0x000d3c6f }, /* BTRLOOPGAIN */ - { STB0899_OFF0_BTR_PHS_INIT , STB0899_BASE_BTR_PHS_INIT , 0x00000000 }, /* BTRPHSINIT */ - { STB0899_OFF0_BTR_FREQ_INIT , STB0899_BASE_BTR_FREQ_INIT , 0x00000000 }, /* BTRFREQINIT */ - { STB0899_OFF0_BTR_NOM_FREQ , STB0899_BASE_BTR_NOM_FREQ , 0x0238e38e }, /* BTRNOMFREQ */ - { STB0899_OFF0_BTR_LK_CNTRL , STB0899_BASE_BTR_LK_CNTRL , 0x00000000 }, /* BTRLKCNTRL */ - { STB0899_OFF0_DECN_CNTRL , STB0899_BASE_DECN_CNTRL , 0x00000000 }, /* DECNCNTRL */ - { STB0899_OFF0_TP_CNTRL , STB0899_BASE_TP_CNTRL , 0x00000000 }, /* TPCNTRL */ - { STB0899_OFF0_TP_BUF_STATUS , STB0899_BASE_TP_BUF_STATUS , 0x00000000 }, /* TPBUFSTATUS */ - { STB0899_OFF0_DC_ESTIM , STB0899_BASE_DC_ESTIM , 0x00000000 }, /* DCESTIM */ - { STB0899_OFF0_FLL_CNTRL , STB0899_BASE_FLL_CNTRL , 0x00000000 }, /* FLLCNTRL */ - { STB0899_OFF0_FLL_FREQ_WD , STB0899_BASE_FLL_FREQ_WD , 0x40070000 }, /* FLLFREQWD */ - { STB0899_OFF0_ANTI_ALIAS_SEL , STB0899_BASE_ANTI_ALIAS_SEL , 0x00000001 }, /* ANTIALIASSEL */ - { STB0899_OFF0_RRC_ALPHA , STB0899_BASE_RRC_ALPHA , 0x00000002 }, /* RRCALPHA */ - { STB0899_OFF0_DC_ADAPT_LSHFT , STB0899_BASE_DC_ADAPT_LSHFT , 0x00000000 }, /* DCADAPTISHFT */ - { STB0899_OFF0_IMB_OFFSET , STB0899_BASE_IMB_OFFSET , 0x0000fe01 }, /* IMBOFFSET */ - { STB0899_OFF0_IMB_ESTIMATE , STB0899_BASE_IMB_ESTIMATE , 0x00000000 }, /* IMBESTIMATE */ - { STB0899_OFF0_IMB_CNTRL , STB0899_BASE_IMB_CNTRL , 0x00000001 }, /* IMBCNTRL */ - { STB0899_OFF0_IF_AGC_CNTRL2 , STB0899_BASE_IF_AGC_CNTRL2 , 0x00005007 }, /* IFAGCCNTRL2 */ - { STB0899_OFF0_DMD_CNTRL2 , STB0899_BASE_DMD_CNTRL2 , 0x00000002 }, /* DMDCNTRL2 */ - { STB0899_OFF0_TP_BUFFER , STB0899_BASE_TP_BUFFER , 0x00000000 }, /* TPBUFFER */ - { STB0899_OFF0_TP_BUFFER1 , STB0899_BASE_TP_BUFFER1 , 0x00000000 }, /* TPBUFFER1 */ - { STB0899_OFF0_TP_BUFFER2 , STB0899_BASE_TP_BUFFER2 , 0x00000000 }, /* TPBUFFER2 */ - { STB0899_OFF0_TP_BUFFER3 , STB0899_BASE_TP_BUFFER3 , 0x00000000 }, /* TPBUFFER3 */ - { STB0899_OFF0_TP_BUFFER4 , STB0899_BASE_TP_BUFFER4 , 0x00000000 }, /* TPBUFFER4 */ - { STB0899_OFF0_TP_BUFFER5 , STB0899_BASE_TP_BUFFER5 , 0x00000000 }, /* TPBUFFER5 */ - { STB0899_OFF0_TP_BUFFER6 , STB0899_BASE_TP_BUFFER6 , 0x00000000 }, /* TPBUFFER6 */ - { STB0899_OFF0_TP_BUFFER7 , STB0899_BASE_TP_BUFFER7 , 0x00000000 }, /* TPBUFFER7 */ - { STB0899_OFF0_TP_BUFFER8 , STB0899_BASE_TP_BUFFER8 , 0x00000000 }, /* TPBUFFER8 */ - { STB0899_OFF0_TP_BUFFER9 , STB0899_BASE_TP_BUFFER9 , 0x00000000 }, /* TPBUFFER9 */ - { STB0899_OFF0_TP_BUFFER10 , STB0899_BASE_TP_BUFFER10 , 0x00000000 }, /* TPBUFFER10 */ - { STB0899_OFF0_TP_BUFFER11 , STB0899_BASE_TP_BUFFER11 , 0x00000000 }, /* TPBUFFER11 */ - { STB0899_OFF0_TP_BUFFER12 , STB0899_BASE_TP_BUFFER12 , 0x00000000 }, /* TPBUFFER12 */ - { STB0899_OFF0_TP_BUFFER13 , STB0899_BASE_TP_BUFFER13 , 0x00000000 }, /* TPBUFFER13 */ - { STB0899_OFF0_TP_BUFFER14 , STB0899_BASE_TP_BUFFER14 , 0x00000000 }, /* TPBUFFER14 */ - { STB0899_OFF0_TP_BUFFER15 , STB0899_BASE_TP_BUFFER15 , 0x00000000 }, /* TPBUFFER15 */ - { STB0899_OFF0_TP_BUFFER16 , STB0899_BASE_TP_BUFFER16 , 0x0000ff00 }, /* TPBUFFER16 */ - { STB0899_OFF0_TP_BUFFER17 , STB0899_BASE_TP_BUFFER17 , 0x00000100 }, /* TPBUFFER17 */ - { STB0899_OFF0_TP_BUFFER18 , STB0899_BASE_TP_BUFFER18 , 0x0000fe01 }, /* TPBUFFER18 */ - { STB0899_OFF0_TP_BUFFER19 , STB0899_BASE_TP_BUFFER19 , 0x000004fe }, /* TPBUFFER19 */ - { STB0899_OFF0_TP_BUFFER20 , STB0899_BASE_TP_BUFFER20 , 0x0000cfe7 }, /* TPBUFFER20 */ - { STB0899_OFF0_TP_BUFFER21 , STB0899_BASE_TP_BUFFER21 , 0x0000bec6 }, /* TPBUFFER21 */ - { STB0899_OFF0_TP_BUFFER22 , STB0899_BASE_TP_BUFFER22 , 0x0000c2bf }, /* TPBUFFER22 */ - { STB0899_OFF0_TP_BUFFER23 , STB0899_BASE_TP_BUFFER23 , 0x0000c1c1 }, /* TPBUFFER23 */ - { STB0899_OFF0_TP_BUFFER24 , STB0899_BASE_TP_BUFFER24 , 0x0000c1c1 }, /* TPBUFFER24 */ - { STB0899_OFF0_TP_BUFFER25 , STB0899_BASE_TP_BUFFER25 , 0x0000c1c1 }, /* TPBUFFER25 */ - { STB0899_OFF0_TP_BUFFER26 , STB0899_BASE_TP_BUFFER26 , 0x0000c1c1 }, /* TPBUFFER26 */ - { STB0899_OFF0_TP_BUFFER27 , STB0899_BASE_TP_BUFFER27 , 0x0000c1c0 }, /* TPBUFFER27 */ - { STB0899_OFF0_TP_BUFFER28 , STB0899_BASE_TP_BUFFER28 , 0x0000c0c0 }, /* TPBUFFER28 */ - { STB0899_OFF0_TP_BUFFER29 , STB0899_BASE_TP_BUFFER29 , 0x0000c1c1 }, /* TPBUFFER29 */ - { STB0899_OFF0_TP_BUFFER30 , STB0899_BASE_TP_BUFFER30 , 0x0000c1c1 }, /* TPBUFFER30 */ - { STB0899_OFF0_TP_BUFFER31 , STB0899_BASE_TP_BUFFER31 , 0x0000c0c1 }, /* TPBUFFER31 */ - { STB0899_OFF0_TP_BUFFER32 , STB0899_BASE_TP_BUFFER32 , 0x0000c0c1 }, /* TPBUFFER32 */ - { STB0899_OFF0_TP_BUFFER33 , STB0899_BASE_TP_BUFFER33 , 0x0000c1c1 }, /* TPBUFFER33 */ - { STB0899_OFF0_TP_BUFFER34 , STB0899_BASE_TP_BUFFER34 , 0x0000c1c1 }, /* TPBUFFER34 */ - { STB0899_OFF0_TP_BUFFER35 , STB0899_BASE_TP_BUFFER35 , 0x0000c0c1 }, /* TPBUFFER35 */ - { STB0899_OFF0_TP_BUFFER36 , STB0899_BASE_TP_BUFFER36 , 0x0000c1c1 }, /* TPBUFFER36 */ - { STB0899_OFF0_TP_BUFFER37 , STB0899_BASE_TP_BUFFER37 , 0x0000c0c1 }, /* TPBUFFER37 */ - { STB0899_OFF0_TP_BUFFER38 , STB0899_BASE_TP_BUFFER38 , 0x0000c1c1 }, /* TPBUFFER38 */ - { STB0899_OFF0_TP_BUFFER39 , STB0899_BASE_TP_BUFFER39 , 0x0000c0c0 }, /* TPBUFFER39 */ - { STB0899_OFF0_TP_BUFFER40 , STB0899_BASE_TP_BUFFER40 , 0x0000c1c0 }, /* TPBUFFER40 */ - { STB0899_OFF0_TP_BUFFER41 , STB0899_BASE_TP_BUFFER41 , 0x0000c1c1 }, /* TPBUFFER41 */ - { STB0899_OFF0_TP_BUFFER42 , STB0899_BASE_TP_BUFFER42 , 0x0000c0c0 }, /* TPBUFFER42 */ - { STB0899_OFF0_TP_BUFFER43 , STB0899_BASE_TP_BUFFER43 , 0x0000c1c0 }, /* TPBUFFER43 */ - { STB0899_OFF0_TP_BUFFER44 , STB0899_BASE_TP_BUFFER44 , 0x0000c0c1 }, /* TPBUFFER44 */ - { STB0899_OFF0_TP_BUFFER45 , STB0899_BASE_TP_BUFFER45 , 0x0000c1be }, /* TPBUFFER45 */ - { STB0899_OFF0_TP_BUFFER46 , STB0899_BASE_TP_BUFFER46 , 0x0000c1c9 }, /* TPBUFFER46 */ - { STB0899_OFF0_TP_BUFFER47 , STB0899_BASE_TP_BUFFER47 , 0x0000c0da }, /* TPBUFFER47 */ - { STB0899_OFF0_TP_BUFFER48 , STB0899_BASE_TP_BUFFER48 , 0x0000c0ba }, /* TPBUFFER48 */ - { STB0899_OFF0_TP_BUFFER49 , STB0899_BASE_TP_BUFFER49 , 0x0000c1c4 }, /* TPBUFFER49 */ - { STB0899_OFF0_TP_BUFFER50 , STB0899_BASE_TP_BUFFER50 , 0x0000c1bf }, /* TPBUFFER50 */ - { STB0899_OFF0_TP_BUFFER51 , STB0899_BASE_TP_BUFFER51 , 0x0000c0c1 }, /* TPBUFFER51 */ - { STB0899_OFF0_TP_BUFFER52 , STB0899_BASE_TP_BUFFER52 , 0x0000c1c0 }, /* TPBUFFER52 */ - { STB0899_OFF0_TP_BUFFER53 , STB0899_BASE_TP_BUFFER53 , 0x0000c0c1 }, /* TPBUFFER53 */ - { STB0899_OFF0_TP_BUFFER54 , STB0899_BASE_TP_BUFFER54 , 0x0000c1c1 }, /* TPBUFFER54 */ - { STB0899_OFF0_TP_BUFFER55 , STB0899_BASE_TP_BUFFER55 , 0x0000c1c1 }, /* TPBUFFER55 */ - { STB0899_OFF0_TP_BUFFER56 , STB0899_BASE_TP_BUFFER56 , 0x0000c1c1 }, /* TPBUFFER56 */ - { STB0899_OFF0_TP_BUFFER57 , STB0899_BASE_TP_BUFFER57 , 0x0000c1c1 }, /* TPBUFFER57 */ - { STB0899_OFF0_TP_BUFFER58 , STB0899_BASE_TP_BUFFER58 , 0x0000c1c1 }, /* TPBUFFER58 */ - { STB0899_OFF0_TP_BUFFER59 , STB0899_BASE_TP_BUFFER59 , 0x0000c1c1 }, /* TPBUFFER59 */ - { STB0899_OFF0_TP_BUFFER60 , STB0899_BASE_TP_BUFFER60 , 0x0000c1c1 }, /* TPBUFFER60 */ - { STB0899_OFF0_TP_BUFFER61 , STB0899_BASE_TP_BUFFER61 , 0x0000c1c1 }, /* TPBUFFER61 */ - { STB0899_OFF0_TP_BUFFER62 , STB0899_BASE_TP_BUFFER62 , 0x0000c1c1 }, /* TPBUFFER62 */ - { STB0899_OFF0_TP_BUFFER63 , STB0899_BASE_TP_BUFFER63 , 0x0000c1c0 }, /* TPBUFFER63 */ - { STB0899_OFF0_RESET_CNTRL , STB0899_BASE_RESET_CNTRL , 0x00000001 }, /* RESETCNTRL */ - { STB0899_OFF0_ACM_ENABLE , STB0899_BASE_ACM_ENABLE , 0x00005654 }, /* ACMENABLE */ - { STB0899_OFF0_DESCR_CNTRL , STB0899_BASE_DESCR_CNTRL , 0x00000000 }, /* DESCRCNTRL */ - { STB0899_OFF0_CSM_CNTRL1 , STB0899_BASE_CSM_CNTRL1 , 0x00020019 }, /* CSMCNTRL1 */ - { STB0899_OFF0_CSM_CNTRL2 , STB0899_BASE_CSM_CNTRL2 , 0x004b3237 }, /* CSMCNTRL2 */ - { STB0899_OFF0_CSM_CNTRL3 , STB0899_BASE_CSM_CNTRL3 , 0x0003dd17 }, /* CSMCNTRL3 */ - { STB0899_OFF0_CSM_CNTRL4 , STB0899_BASE_CSM_CNTRL4 , 0x00008008 }, /* CSMCNTRL4 */ - { STB0899_OFF0_UWP_CNTRL1 , STB0899_BASE_UWP_CNTRL1 , 0x002a3106 }, /* UWPCNTRL1 */ - { STB0899_OFF0_UWP_CNTRL2 , STB0899_BASE_UWP_CNTRL2 , 0x0006140a }, /* UWPCNTRL2 */ - { STB0899_OFF0_UWP_STAT1 , STB0899_BASE_UWP_STAT1 , 0x00008000 }, /* UWPSTAT1 */ - { STB0899_OFF0_UWP_STAT2 , STB0899_BASE_UWP_STAT2 , 0x00000000 }, /* UWPSTAT2 */ - { STB0899_OFF0_DMD_STAT2 , STB0899_BASE_DMD_STAT2 , 0x00000000 }, /* DMDSTAT2 */ - { STB0899_OFF0_FREQ_ADJ_SCALE , STB0899_BASE_FREQ_ADJ_SCALE , 0x00000471 }, /* FREQADJSCALE */ - { STB0899_OFF0_UWP_CNTRL3 , STB0899_BASE_UWP_CNTRL3 , 0x017b0465 }, /* UWPCNTRL3 */ - { STB0899_OFF0_SYM_CLK_SEL , STB0899_BASE_SYM_CLK_SEL , 0x00000002 }, /* SYMCLKSEL */ - { STB0899_OFF0_SOF_SRCH_TO , STB0899_BASE_SOF_SRCH_TO , 0x00196464 }, /* SOFSRCHTO */ - { STB0899_OFF0_ACQ_CNTRL1 , STB0899_BASE_ACQ_CNTRL1 , 0x00000603 }, /* ACQCNTRL1 */ - { STB0899_OFF0_ACQ_CNTRL2 , STB0899_BASE_ACQ_CNTRL2 , 0x02046666 }, /* ACQCNTRL2 */ - { STB0899_OFF0_ACQ_CNTRL3 , STB0899_BASE_ACQ_CNTRL3 , 0x10046583 }, /* ACQCNTRL3 */ - { STB0899_OFF0_FE_SETTLE , STB0899_BASE_FE_SETTLE , 0x00010404 }, /* FESETTLE */ - { STB0899_OFF0_AC_DWELL , STB0899_BASE_AC_DWELL , 0x0002aa8a }, /* ACDWELL */ - { STB0899_OFF0_ACQUIRE_TRIG , STB0899_BASE_ACQUIRE_TRIG , 0x00000000 }, /* ACQUIRETRIG */ - { STB0899_OFF0_LOCK_LOST , STB0899_BASE_LOCK_LOST , 0x00000001 }, /* LOCKLOST */ - { STB0899_OFF0_ACQ_STAT1 , STB0899_BASE_ACQ_STAT1 , 0x00000500 }, /* ACQSTAT1 */ - { STB0899_OFF0_ACQ_TIMEOUT , STB0899_BASE_ACQ_TIMEOUT , 0x0028a0a0 }, /* ACQTIMEOUT */ - { STB0899_OFF0_ACQ_TIME , STB0899_BASE_ACQ_TIME , 0x00000000 }, /* ACQTIME */ - { STB0899_OFF0_FINAL_AGC_CNTRL , STB0899_BASE_FINAL_AGC_CNTRL , 0x00800c17 }, /* FINALAGCCNTRL*/ - { STB0899_OFF0_FINAL_AGC_GAIN , STB0899_BASE_FINAL_AGC_GAIN , 0x00000000 }, /* FINALAGCCGAIN*/ - { STB0899_OFF0_EQUALIZER_INIT , STB0899_BASE_EQUALIZER_INIT , 0x00000000 }, /* EQUILIZERINIT*/ - { STB0899_OFF0_EQ_CNTRL , STB0899_BASE_EQ_CNTRL , 0x00054802 }, /* EQCNTL */ - { STB0899_OFF0_EQ_I_INIT_COEFF_0, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF0 */ - { STB0899_OFF1_EQ_I_INIT_COEFF_1, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF1 */ - { STB0899_OFF2_EQ_I_INIT_COEFF_2, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF2 */ - { STB0899_OFF3_EQ_I_INIT_COEFF_3, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF3 */ - { STB0899_OFF4_EQ_I_INIT_COEFF_4, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF4 */ - { STB0899_OFF5_EQ_I_INIT_COEFF_5, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000400 }, /* EQIINITCOEFF5 */ - { STB0899_OFF6_EQ_I_INIT_COEFF_6, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF6 */ - { STB0899_OFF7_EQ_I_INIT_COEFF_7, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF7 */ - { STB0899_OFF8_EQ_I_INIT_COEFF_8, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF8 */ - { STB0899_OFF9_EQ_I_INIT_COEFF_9, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF9 */ - { STB0899_OFFa_EQ_I_INIT_COEFF_10,STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF10*/ - { STB0899_OFF0_EQ_Q_INIT_COEFF_0, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF0 */ - { STB0899_OFF1_EQ_Q_INIT_COEFF_1, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF1 */ - { STB0899_OFF2_EQ_Q_INIT_COEFF_2, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF2 */ - { STB0899_OFF3_EQ_Q_INIT_COEFF_3, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF3 */ - { STB0899_OFF4_EQ_Q_INIT_COEFF_4, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF4 */ - { STB0899_OFF5_EQ_Q_INIT_COEFF_5, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF5 */ - { STB0899_OFF6_EQ_Q_INIT_COEFF_6, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF6 */ - { STB0899_OFF7_EQ_Q_INIT_COEFF_7, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF7 */ - { STB0899_OFF8_EQ_Q_INIT_COEFF_8, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF8 */ - { STB0899_OFF9_EQ_Q_INIT_COEFF_9, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF9 */ - { STB0899_OFFa_EQ_Q_INIT_COEFF_10,STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF10*/ - { STB0899_OFF0_EQ_I_OUT_COEFF_0 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT0 */ - { STB0899_OFF1_EQ_I_OUT_COEFF_1 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT1 */ - { STB0899_OFF2_EQ_I_OUT_COEFF_2 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT2 */ - { STB0899_OFF3_EQ_I_OUT_COEFF_3 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT3 */ - { STB0899_OFF4_EQ_I_OUT_COEFF_4 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT4 */ - { STB0899_OFF5_EQ_I_OUT_COEFF_5 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT5 */ - { STB0899_OFF6_EQ_I_OUT_COEFF_6 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT6 */ - { STB0899_OFF7_EQ_I_OUT_COEFF_7 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT7 */ - { STB0899_OFF8_EQ_I_OUT_COEFF_8 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT8 */ - { STB0899_OFF9_EQ_I_OUT_COEFF_9 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT9 */ - { STB0899_OFFa_EQ_I_OUT_COEFF_10,STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT10*/ - { STB0899_OFF0_EQ_Q_OUT_COEFF_0 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT0 */ - { STB0899_OFF1_EQ_Q_OUT_COEFF_1 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT1 */ - { STB0899_OFF2_EQ_Q_OUT_COEFF_2 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT2 */ - { STB0899_OFF3_EQ_Q_OUT_COEFF_3 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT3 */ - { STB0899_OFF4_EQ_Q_OUT_COEFF_4 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT4 */ - { STB0899_OFF5_EQ_Q_OUT_COEFF_5 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT5 */ - { STB0899_OFF6_EQ_Q_OUT_COEFF_6 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT6 */ - { STB0899_OFF7_EQ_Q_OUT_COEFF_7 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT7 */ - { STB0899_OFF8_EQ_Q_OUT_COEFF_8 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT8 */ - { STB0899_OFF9_EQ_Q_OUT_COEFF_9 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT9 */ - { STB0899_OFFa_EQ_Q_OUT_COEFF_10, STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT10*/ - { 0xffff , 0xffffffff , 0xffffffff }, -}; -static const struct stb0899_s2_reg stb0899_s2_init_4[] = { - { STB0899_OFF0_BLOCK_LNGTH , STB0899_BASE_BLOCK_LNGTH , 0x00000008 }, /* BLOCKLNGTH */ - { STB0899_OFF0_ROW_STR , STB0899_BASE_ROW_STR , 0x000000b4 }, /* ROWSTR */ - { STB0899_OFF0_BN_END_ADDR , STB0899_BASE_BN_END_ADDR , 0x000004b5 }, /* BNANDADDR */ - { STB0899_OFF0_CN_END_ADDR , STB0899_BASE_CN_END_ADDR , 0x00000b4b }, /* CNANDADDR */ - { STB0899_OFF0_INFO_LENGTH , STB0899_BASE_INFO_LENGTH , 0x00000078 }, /* INFOLENGTH */ - { STB0899_OFF0_BOT_ADDR , STB0899_BASE_BOT_ADDR , 0x000001e0 }, /* BOT_ADDR */ - { STB0899_OFF0_BCH_BLK_LN , STB0899_BASE_BCH_BLK_LN , 0x0000a8c0 }, /* BCHBLKLN */ - { STB0899_OFF0_BCH_T , STB0899_BASE_BCH_T , 0x0000000c }, /* BCHT */ - { STB0899_OFF0_CNFG_MODE , STB0899_BASE_CNFG_MODE , 0x00000001 }, /* CNFGMODE */ - { STB0899_OFF0_LDPC_STAT , STB0899_BASE_LDPC_STAT , 0x0000000d }, /* LDPCSTAT */ - { STB0899_OFF0_ITER_SCALE , STB0899_BASE_ITER_SCALE , 0x00000040 }, /* ITERSCALE */ - { STB0899_OFF0_INPUT_MODE , STB0899_BASE_INPUT_MODE , 0x00000000 }, /* INPUTMODE */ - { STB0899_OFF0_LDPCDECRST , STB0899_BASE_LDPCDECRST , 0x00000000 }, /* LDPCDECRST */ - { STB0899_OFF0_CLK_PER_BYTE_RW , STB0899_BASE_CLK_PER_BYTE_RW , 0x00000008 }, /* CLKPERBYTE */ - { STB0899_OFF0_BCH_ERRORS , STB0899_BASE_BCH_ERRORS , 0x00000000 }, /* BCHERRORS */ - { STB0899_OFF0_LDPC_ERRORS , STB0899_BASE_LDPC_ERRORS , 0x00000000 }, /* LDPCERRORS */ - { STB0899_OFF0_BCH_MODE , STB0899_BASE_BCH_MODE , 0x00000000 }, /* BCHMODE */ - { STB0899_OFF0_ERR_ACC_PER , STB0899_BASE_ERR_ACC_PER , 0x00000008 }, /* ERRACCPER */ - { STB0899_OFF0_BCH_ERR_ACC , STB0899_BASE_BCH_ERR_ACC , 0x00000000 }, /* BCHERRACC */ - { STB0899_OFF0_FEC_TP_SEL , STB0899_BASE_FEC_TP_SEL , 0x00000000 }, /* FECTPSEL */ - { 0xffff , 0xffffffff , 0xffffffff }, -}; - -static const struct stb0899_s1_reg stb0899_s1_init_5[] = { - { STB0899_TSTCK , 0x00 }, - { STB0899_TSTRES , 0x00 }, - { STB0899_TSTOUT , 0x00 }, - { STB0899_TSTIN , 0x00 }, - { STB0899_TSTSYS , 0x00 }, - { STB0899_TSTCHIP , 0x00 }, - { STB0899_TSTFREE , 0x00 }, - { STB0899_TSTI2C , 0x00 }, - { STB0899_BITSPEEDM , 0x00 }, - { STB0899_BITSPEEDL , 0x00 }, - { STB0899_TBUSBIT , 0x00 }, - { STB0899_TSTDIS , 0x00 }, - { STB0899_TSTDISRX , 0x00 }, - { STB0899_TSTJETON , 0x00 }, - { STB0899_TSTDCADJ , 0x00 }, - { STB0899_TSTAGC1 , 0x00 }, - { STB0899_TSTAGC1N , 0x00 }, - { STB0899_TSTPOLYPH , 0x00 }, - { STB0899_TSTR , 0x00 }, - { STB0899_TSTAGC2 , 0x00 }, - { STB0899_TSTCTL1 , 0x00 }, - { STB0899_TSTCTL2 , 0x00 }, - { STB0899_TSTCTL3 , 0x00 }, - { STB0899_TSTDEMAP , 0x00 }, - { STB0899_TSTDEMAP2 , 0x00 }, - { STB0899_TSTDEMMON , 0x00 }, - { STB0899_TSTRATE , 0x00 }, - { STB0899_TSTSELOUT , 0x00 }, - { STB0899_TSYNC , 0x00 }, - { STB0899_TSTERR , 0x00 }, - { STB0899_TSTRAM1 , 0x00 }, - { STB0899_TSTVSELOUT , 0x00 }, - { STB0899_TSTFORCEIN , 0x00 }, - { STB0899_TSTRS1 , 0x00 }, - { STB0899_TSTRS2 , 0x00 }, - { STB0899_TSTRS3 , 0x00 }, - { STB0899_GHOSTREG , 0x81 }, - { 0xffff , 0xff }, -}; - -#define STB0899_DVBS2_ESNO_AVE 3 -#define STB0899_DVBS2_ESNO_QUANT 32 -#define STB0899_DVBS2_AVFRAMES_COARSE 10 -#define STB0899_DVBS2_AVFRAMES_FINE 20 -#define STB0899_DVBS2_MISS_THRESHOLD 6 -#define STB0899_DVBS2_UWP_THRESHOLD_ACQ 1125 -#define STB0899_DVBS2_UWP_THRESHOLD_TRACK 758 -#define STB0899_DVBS2_UWP_THRESHOLD_SOF 1350 -#define STB0899_DVBS2_SOF_SEARCH_TIMEOUT 1664100 - -#define STB0899_DVBS2_BTR_NCO_BITS 28 -#define STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET 15 -#define STB0899_DVBS2_CRL_NCO_BITS 30 -#define STB0899_DVBS2_LDPC_MAX_ITER 70 - -#endif //__STB0899_CFG_H diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c deleted file mode 100644 index a04c782fff8..00000000000 --- a/drivers/media/dvb/frontends/stb0899_drv.c +++ /dev/null @@ -1,1685 +0,0 @@ -/* - STB0899 Multistandard Frontend driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - 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 <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> - -#include <linux/dvb/frontend.h> -#include "dvb_frontend.h" - -#include "stb0899_drv.h" -#include "stb0899_priv.h" -#include "stb0899_reg.h" - -static unsigned int verbose = 0;//1; -module_param(verbose, int, 0644); - -/* C/N in dB/10, NIRM/NIRL */ -static const struct stb0899_tab stb0899_cn_tab[] = { - { 200, 2600 }, - { 190, 2700 }, - { 180, 2860 }, - { 170, 3020 }, - { 160, 3210 }, - { 150, 3440 }, - { 140, 3710 }, - { 130, 4010 }, - { 120, 4360 }, - { 110, 4740 }, - { 100, 5190 }, - { 90, 5670 }, - { 80, 6200 }, - { 70, 6770 }, - { 60, 7360 }, - { 50, 7970 }, - { 40, 8250 }, - { 30, 9000 }, - { 20, 9450 }, - { 15, 9600 }, -}; - -/* DVB-S AGCIQ_VALUE vs. signal level in dBm/10. - * As measured, connected to a modulator. - * -8.0 to -50.0 dBm directly connected, - * -52.0 to -74.8 with extra attenuation. - * Cut-off to AGCIQ_VALUE = 0x80 below -74.8dBm. - * Crude linear extrapolation below -84.8dBm and above -8.0dBm. - */ -static const struct stb0899_tab stb0899_dvbsrf_tab[] = { - { -950, -128 }, - { -748, -94 }, - { -745, -92 }, - { -735, -90 }, - { -720, -87 }, - { -670, -77 }, - { -640, -70 }, - { -610, -62 }, - { -600, -60 }, - { -590, -56 }, - { -560, -41 }, - { -540, -25 }, - { -530, -17 }, - { -520, -11 }, - { -500, 1 }, - { -490, 6 }, - { -480, 10 }, - { -440, 22 }, - { -420, 27 }, - { -400, 31 }, - { -380, 34 }, - { -340, 40 }, - { -320, 43 }, - { -280, 48 }, - { -250, 52 }, - { -230, 55 }, - { -180, 61 }, - { -140, 66 }, - { -90, 73 }, - { -80, 74 }, - { 500, 127 } -}; - -/* DVB-S2 IF_AGC_GAIN vs. signal level in dBm/10. - * As measured, connected to a modulator. - * -8.0 to -50.1 dBm directly connected, - * -53.0 to -76.6 with extra attenuation. - * Cut-off to IF_AGC_GAIN = 0x3fff below -76.6dBm. - * Crude linear extrapolation below -76.6dBm and above -8.0dBm. - */ -static const struct stb0899_tab stb0899_dvbs2rf_tab[] = { - { 700, 0 }, - { -80, 3217 }, - { -150, 3893 }, - { -190, 4217 }, - { -240, 4621 }, - { -280, 4945 }, - { -320, 5273 }, - { -350, 5545 }, - { -370, 5741 }, - { -410, 6147 }, - { -450, 6671 }, - { -490, 7413 }, - { -501, 7665 }, - { -530, 8767 }, - { -560, 10219 }, - { -580, 10939 }, - { -590, 11518 }, - { -600, 11723 }, - { -650, 12659 }, - { -690, 13219 }, - { -730, 13645 }, - { -750, 13909 }, - { -766, 14153 }, - { -999, 16383 } -}; - -/* DVB-S2 Es/N0 quant in dB/100 vs read value * 100*/ -static struct stb0899_tab stb0899_quant_tab[] = { - { 0, 0 }, - { 0, 100 }, - { 600, 200 }, - { 950, 299 }, - { 1200, 398 }, - { 1400, 501 }, - { 1560, 603 }, - { 1690, 700 }, - { 1810, 804 }, - { 1910, 902 }, - { 2000, 1000 }, - { 2080, 1096 }, - { 2160, 1202 }, - { 2230, 1303 }, - { 2350, 1496 }, - { 2410, 1603 }, - { 2460, 1698 }, - { 2510, 1799 }, - { 2600, 1995 }, - { 2650, 2113 }, - { 2690, 2213 }, - { 2720, 2291 }, - { 2760, 2399 }, - { 2800, 2512 }, - { 2860, 2692 }, - { 2930, 2917 }, - { 2960, 3020 }, - { 3010, 3199 }, - { 3040, 3311 }, - { 3060, 3388 }, - { 3120, 3631 }, - { 3190, 3936 }, - { 3400, 5012 }, - { 3610, 6383 }, - { 3800, 7943 }, - { 4210, 12735 }, - { 4500, 17783 }, - { 4690, 22131 }, - { 4810, 25410 } -}; - -/* DVB-S2 Es/N0 estimate in dB/100 vs read value */ -static struct stb0899_tab stb0899_est_tab[] = { - { 0, 0 }, - { 0, 1 }, - { 301, 2 }, - { 1204, 16 }, - { 1806, 64 }, - { 2408, 256 }, - { 2709, 512 }, - { 3010, 1023 }, - { 3311, 2046 }, - { 3612, 4093 }, - { 3823, 6653 }, - { 3913, 8185 }, - { 4010, 10233 }, - { 4107, 12794 }, - { 4214, 16368 }, - { 4266, 18450 }, - { 4311, 20464 }, - { 4353, 22542 }, - { 4391, 24604 }, - { 4425, 26607 }, - { 4457, 28642 }, - { 4487, 30690 }, - { 4515, 32734 }, - { 4612, 40926 }, - { 4692, 49204 }, - { 4816, 65464 }, - { 4913, 81846 }, - { 4993, 98401 }, - { 5060, 114815 }, - { 5118, 131220 }, - { 5200, 158489 }, - { 5300, 199526 }, - { 5400, 251189 }, - { 5500, 316228 }, - { 5600, 398107 }, - { 5720, 524807 }, - { 5721, 526017 }, -}; - -static int _stb0899_read_reg(struct stb0899_state *state, unsigned int reg) -{ - int ret; - - u8 b0[] = { reg >> 8, reg & 0xff }; - u8 buf; - - 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 = &buf, - .len = 1 - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - if (ret != 2) { - if (ret != -ERESTARTSYS) - dprintk(state->verbose, FE_ERROR, 1, - "Read error, Reg=[0x%02x], Status=%d", - reg, ret); - - return ret < 0 ? ret : -EREMOTEIO; - } - if (unlikely(*state->verbose >= FE_DEBUGREG)) - dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%02x], data=%02x", - reg, buf); - - return (unsigned int)buf; -} - -int stb0899_read_reg(struct stb0899_state *state, unsigned int reg) -{ - int result; - - result = _stb0899_read_reg(state, reg); - /* - * Bug ID 9: - * access to 0xf2xx/0xf6xx - * must be followed by read from 0xf2ff/0xf6ff. - */ - if ((reg != 0xf2ff) && (reg != 0xf6ff) && - (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600))) - _stb0899_read_reg(state, (reg | 0x00ff)); - - return result; -} - -u32 _stb0899_read_s2reg(struct stb0899_state *state, - u32 stb0899_i2cdev, - u32 stb0899_base_addr, - u16 stb0899_reg_offset) -{ - int status; - u32 data; - u8 buf[7] = { 0 }; - u16 tmpaddr; - - u8 buf_0[] = { - GETBYTE(stb0899_i2cdev, BYTE1), /* 0xf3 S2 Base Address (MSB) */ - GETBYTE(stb0899_i2cdev, BYTE0), /* 0xfc S2 Base Address (LSB) */ - GETBYTE(stb0899_base_addr, BYTE0), /* 0x00 Base Address (LSB) */ - GETBYTE(stb0899_base_addr, BYTE1), /* 0x04 Base Address (LSB) */ - GETBYTE(stb0899_base_addr, BYTE2), /* 0x00 Base Address (MSB) */ - GETBYTE(stb0899_base_addr, BYTE3), /* 0x00 Base Address (MSB) */ - }; - u8 buf_1[] = { - 0x00, /* 0xf3 Reg Offset */ - 0x00, /* 0x44 Reg Offset */ - }; - - struct i2c_msg msg_0 = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf_0, - .len = 6 - }; - - struct i2c_msg msg_1 = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf_1, - .len = 2 - }; - - struct i2c_msg msg_r = { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = buf, - .len = 4 - }; - - tmpaddr = stb0899_reg_offset & 0xff00; - if (!(stb0899_reg_offset & 0x8)) - tmpaddr = stb0899_reg_offset | 0x20; - - buf_1[0] = GETBYTE(tmpaddr, BYTE1); - buf_1[1] = GETBYTE(tmpaddr, BYTE0); - - status = i2c_transfer(state->i2c, &msg_0, 1); - if (status < 1) { - if (status != -ERESTARTSYS) - printk(KERN_ERR "%s ERR(1), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status); - - goto err; - } - - /* Dummy */ - status = i2c_transfer(state->i2c, &msg_1, 1); - if (status < 1) - goto err; - - status = i2c_transfer(state->i2c, &msg_r, 1); - if (status < 1) - goto err; - - buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1); - buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0); - - /* Actual */ - status = i2c_transfer(state->i2c, &msg_1, 1); - if (status < 1) { - if (status != -ERESTARTSYS) - printk(KERN_ERR "%s ERR(2), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status); - goto err; - } - - status = i2c_transfer(state->i2c, &msg_r, 1); - if (status < 1) { - if (status != -ERESTARTSYS) - printk(KERN_ERR "%s ERR(3), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status); - return status < 0 ? status : -EREMOTEIO; - } - - data = MAKEWORD32(buf[3], buf[2], buf[1], buf[0]); - if (unlikely(*state->verbose >= FE_DEBUGREG)) - printk(KERN_DEBUG "%s Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, data); - - return data; - -err: - return status < 0 ? status : -EREMOTEIO; -} - -int stb0899_write_s2reg(struct stb0899_state *state, - u32 stb0899_i2cdev, - u32 stb0899_base_addr, - u16 stb0899_reg_offset, - u32 stb0899_data) -{ - int status; - - /* Base Address Setup */ - u8 buf_0[] = { - GETBYTE(stb0899_i2cdev, BYTE1), /* 0xf3 S2 Base Address (MSB) */ - GETBYTE(stb0899_i2cdev, BYTE0), /* 0xfc S2 Base Address (LSB) */ - GETBYTE(stb0899_base_addr, BYTE0), /* 0x00 Base Address (LSB) */ - GETBYTE(stb0899_base_addr, BYTE1), /* 0x04 Base Address (LSB) */ - GETBYTE(stb0899_base_addr, BYTE2), /* 0x00 Base Address (MSB) */ - GETBYTE(stb0899_base_addr, BYTE3), /* 0x00 Base Address (MSB) */ - }; - u8 buf_1[] = { - 0x00, /* 0xf3 Reg Offset */ - 0x00, /* 0x44 Reg Offset */ - 0x00, /* data */ - 0x00, /* data */ - 0x00, /* data */ - 0x00, /* data */ - }; - - struct i2c_msg msg_0 = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf_0, - .len = 6 - }; - - struct i2c_msg msg_1 = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf_1, - .len = 6 - }; - - buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1); - buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0); - buf_1[2] = GETBYTE(stb0899_data, BYTE0); - buf_1[3] = GETBYTE(stb0899_data, BYTE1); - buf_1[4] = GETBYTE(stb0899_data, BYTE2); - buf_1[5] = GETBYTE(stb0899_data, BYTE3); - - if (unlikely(*state->verbose >= FE_DEBUGREG)) - printk(KERN_DEBUG "%s Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data); - - status = i2c_transfer(state->i2c, &msg_0, 1); - if (unlikely(status < 1)) { - if (status != -ERESTARTSYS) - printk(KERN_ERR "%s ERR (1), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status); - goto err; - } - status = i2c_transfer(state->i2c, &msg_1, 1); - if (unlikely(status < 1)) { - if (status != -ERESTARTSYS) - printk(KERN_ERR "%s ERR (2), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status); - - return status < 0 ? status : -EREMOTEIO; - } - - return 0; - -err: - return status < 0 ? status : -EREMOTEIO; -} - -int stb0899_read_regs(struct stb0899_state *state, unsigned int reg, u8 *buf, u32 count) -{ - int status; - - u8 b0[] = { reg >> 8, reg & 0xff }; - - 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 = buf, - .len = count - } - }; - - status = i2c_transfer(state->i2c, msg, 2); - if (status != 2) { - if (status != -ERESTARTSYS) - printk(KERN_ERR "%s Read error, Reg=[0x%04x], Count=%u, Status=%d\n", - __func__, reg, count, status); - goto err; - } - /* - * Bug ID 9: - * access to 0xf2xx/0xf6xx - * must be followed by read from 0xf2ff/0xf6ff. - */ - if ((reg != 0xf2ff) && (reg != 0xf6ff) && - (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600))) - _stb0899_read_reg(state, (reg | 0x00ff)); - - if (unlikely(*state->verbose >= FE_DEBUGREG)) { - int i; - - printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); - for (i = 0; i < count; i++) { - printk(" %02x", buf[i]); - } - printk("\n"); - } - - return 0; -err: - return status < 0 ? status : -EREMOTEIO; -} - -int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, u32 count) -{ - int ret; - u8 buf[2 + count]; - struct i2c_msg i2c_msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = 2 + count - }; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - memcpy(&buf[2], data, count); - - if (unlikely(*state->verbose >= FE_DEBUGREG)) { - int i; - - printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); - for (i = 0; i < count; i++) - printk(" %02x", data[i]); - printk("\n"); - } - ret = i2c_transfer(state->i2c, &i2c_msg, 1); - - /* - * Bug ID 9: - * access to 0xf2xx/0xf6xx - * must be followed by read from 0xf2ff/0xf6ff. - */ - if ((((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600))) - stb0899_read_reg(state, (reg | 0x00ff)); - - if (ret != 1) { - if (ret != -ERESTARTSYS) - dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d", - reg, data[0], count, ret); - return ret < 0 ? ret : -EREMOTEIO; - } - - return 0; -} - -int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data) -{ - return stb0899_write_regs(state, reg, &data, 1); -} - -/* - * stb0899_get_mclk - * Get STB0899 master clock frequency - * ExtClk: external clock frequency (Hz) - */ -static u32 stb0899_get_mclk(struct stb0899_state *state) -{ - u32 mclk = 0, div = 0; - - div = stb0899_read_reg(state, STB0899_NCOARSE); - mclk = (div + 1) * state->config->xtal_freq / 6; - dprintk(state->verbose, FE_DEBUG, 1, "div=%d, mclk=%d", div, mclk); - - return mclk; -} - -/* - * stb0899_set_mclk - * Set STB0899 master Clock frequency - * Mclk: demodulator master clock - * ExtClk: external clock frequency (Hz) - */ -static void stb0899_set_mclk(struct stb0899_state *state, u32 Mclk) -{ - struct stb0899_internal *internal = &state->internal; - u8 mdiv = 0; - - dprintk(state->verbose, FE_DEBUG, 1, "state->config=%p", state->config); - mdiv = ((6 * Mclk) / state->config->xtal_freq) - 1; - dprintk(state->verbose, FE_DEBUG, 1, "mdiv=%d", mdiv); - - stb0899_write_reg(state, STB0899_NCOARSE, mdiv); - internal->master_clk = stb0899_get_mclk(state); - - dprintk(state->verbose, FE_DEBUG, 1, "MasterCLOCK=%d", internal->master_clk); -} - -static int stb0899_postproc(struct stb0899_state *state, u8 ctl, int enable) -{ - struct stb0899_config *config = state->config; - const struct stb0899_postproc *postproc = config->postproc; - - /* post process event */ - if (postproc) { - if (enable) { - if (postproc[ctl].level == STB0899_GPIOPULLUP) - stb0899_write_reg(state, postproc[ctl].gpio, 0x02); - else - stb0899_write_reg(state, postproc[ctl].gpio, 0x82); - } else { - if (postproc[ctl].level == STB0899_GPIOPULLUP) - stb0899_write_reg(state, postproc[ctl].gpio, 0x82); - else - stb0899_write_reg(state, postproc[ctl].gpio, 0x02); - } - } - return 0; -} - -static void stb0899_release(struct dvb_frontend *fe) -{ - struct stb0899_state *state = fe->demodulator_priv; - - dprintk(state->verbose, FE_DEBUG, 1, "Release Frontend"); - /* post process event */ - stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0); - kfree(state); -} - -/* - * stb0899_get_alpha - * return: rolloff - */ -static int stb0899_get_alpha(struct stb0899_state *state) -{ - u8 mode_coeff; - - mode_coeff = stb0899_read_reg(state, STB0899_DEMOD); - - if (STB0899_GETFIELD(MODECOEFF, mode_coeff) == 1) - return 20; - else - return 35; -} - -/* - * stb0899_init_calc - */ -static void stb0899_init_calc(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - int master_clk; - u8 agc[2]; - u8 agc1cn; - u32 reg; - - /* Read registers (in burst mode) */ - agc1cn = stb0899_read_reg(state, STB0899_AGC1CN); - stb0899_read_regs(state, STB0899_AGC1REF, agc, 2); /* AGC1R and AGC2O */ - - /* Initial calculations */ - master_clk = stb0899_get_mclk(state); - internal->t_agc1 = 0; - internal->t_agc2 = 0; - internal->master_clk = master_clk; - internal->mclk = master_clk / 65536L; - internal->rolloff = stb0899_get_alpha(state); - - /* DVBS2 Initial calculations */ - /* Set AGC value to the middle */ - internal->agc_gain = 8154; - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL); - STB0899_SETFIELD_VAL(IF_GAIN_INIT, reg, internal->agc_gain); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, RRC_ALPHA); - internal->rrc_alpha = STB0899_GETFIELD(RRC_ALPHA, reg); - - internal->center_freq = 0; - internal->av_frame_coarse = 10; - internal->av_frame_fine = 20; - internal->step_size = 2; -/* - if ((pParams->SpectralInv == FE_IQ_NORMAL) || (pParams->SpectralInv == FE_IQ_AUTO)) - pParams->IQLocked = 0; - else - pParams->IQLocked = 1; -*/ -} - -static int stb0899_wait_diseqc_fifo_empty(struct stb0899_state *state, int timeout) -{ - u8 reg = 0; - unsigned long start = jiffies; - - while (1) { - reg = stb0899_read_reg(state, STB0899_DISSTATUS); - if (!STB0899_GETFIELD(FIFOFULL, reg)) - break; - if ((jiffies - start) > timeout) { - dprintk(state->verbose, FE_ERROR, 1, "timed out !!"); - return -ETIMEDOUT; - } - } - - return 0; -} - -static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd) -{ - struct stb0899_state *state = fe->demodulator_priv; - u8 reg, i; - - if (cmd->msg_len > 8) - return -EINVAL; - - /* enable FIFO precharge */ - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); - STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 1); - stb0899_write_reg(state, STB0899_DISCNTRL1, reg); - for (i = 0; i < cmd->msg_len; i++) { - /* wait for FIFO empty */ - if (stb0899_wait_diseqc_fifo_empty(state, 10) < 0) - return -ETIMEDOUT; - - stb0899_write_reg(state, STB0899_DISFIFO, cmd->msg[i]); - } - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); - STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0); - stb0899_write_reg(state, STB0899_DISCNTRL1, reg); - - return 0; -} - -static int stb0899_wait_diseqc_rxidle(struct stb0899_state *state, int timeout) -{ - u8 reg = 0; - unsigned long start = jiffies; - - while (!STB0899_GETFIELD(RXEND, reg)) { - reg = stb0899_read_reg(state, STB0899_DISRX_ST0); - if (jiffies - start > timeout) { - dprintk(state->verbose, FE_ERROR, 1, "timed out!!"); - return -ETIMEDOUT; - } - msleep(10); - } - - return 0; -} - -static int stb0899_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply) -{ - struct stb0899_state *state = fe->demodulator_priv; - u8 reg, length = 0, i; - int result; - - if (stb0899_wait_diseqc_rxidle(state, 100) < 0) - return -ETIMEDOUT; - - reg = stb0899_read_reg(state, STB0899_DISRX_ST0); - if (STB0899_GETFIELD(RXEND, reg)) { - - reg = stb0899_read_reg(state, STB0899_DISRX_ST1); - length = STB0899_GETFIELD(FIFOBYTENBR, reg); - - if (length > sizeof (reply->msg)) { - result = -EOVERFLOW; - goto exit; - } - reply->msg_len = length; - - /* extract data */ - for (i = 0; i < length; i++) - reply->msg[i] = stb0899_read_reg(state, STB0899_DISFIFO); - } - - return 0; -exit: - - return result; -} - -static int stb0899_wait_diseqc_txidle(struct stb0899_state *state, int timeout) -{ - u8 reg = 0; - unsigned long start = jiffies; - - while (!STB0899_GETFIELD(TXIDLE, reg)) { - reg = stb0899_read_reg(state, STB0899_DISSTATUS); - if (jiffies - start > timeout) { - dprintk(state->verbose, FE_ERROR, 1, "timed out!!"); - return -ETIMEDOUT; - } - msleep(10); - } - return 0; -} - -static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) -{ - struct stb0899_state *state = fe->demodulator_priv; - u8 reg, old_state; - - /* wait for diseqc idle */ - if (stb0899_wait_diseqc_txidle(state, 100) < 0) - return -ETIMEDOUT; - - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); - old_state = reg; - /* set to burst mode */ - STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x03); - STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x01); - stb0899_write_reg(state, STB0899_DISCNTRL1, reg); - switch (burst) { - case SEC_MINI_A: - /* unmodulated */ - stb0899_write_reg(state, STB0899_DISFIFO, 0x00); - break; - case SEC_MINI_B: - /* modulated */ - stb0899_write_reg(state, STB0899_DISFIFO, 0xff); - break; - } - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); - STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x00); - stb0899_write_reg(state, STB0899_DISCNTRL1, reg); - /* wait for diseqc idle */ - if (stb0899_wait_diseqc_txidle(state, 100) < 0) - return -ETIMEDOUT; - - /* restore state */ - stb0899_write_reg(state, STB0899_DISCNTRL1, old_state); - - return 0; -} - -static int stb0899_diseqc_init(struct stb0899_state *state) -{ - struct dvb_diseqc_master_cmd tx_data; -/* - struct dvb_diseqc_slave_reply rx_data; -*/ - u8 f22_tx, f22_rx, reg; - - u32 mclk, tx_freq = 22000;/* count = 0, i; */ - tx_data.msg[0] = 0xe2; - tx_data.msg_len = 3; - reg = stb0899_read_reg(state, STB0899_DISCNTRL2); - STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0); - stb0899_write_reg(state, STB0899_DISCNTRL2, reg); - - /* disable Tx spy */ - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); - STB0899_SETFIELD_VAL(DISEQCRESET, reg, 1); - stb0899_write_reg(state, STB0899_DISCNTRL1, reg); - - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); - STB0899_SETFIELD_VAL(DISEQCRESET, reg, 0); - stb0899_write_reg(state, STB0899_DISCNTRL1, reg); - - mclk = stb0899_get_mclk(state); - f22_tx = mclk / (tx_freq * 32); - stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* DiSEqC Tx freq */ - state->rx_freq = 20000; - f22_rx = mclk / (state->rx_freq * 32); - - return 0; -} - -static int stb0899_sleep(struct dvb_frontend *fe) -{ - struct stb0899_state *state = fe->demodulator_priv; -/* - u8 reg; -*/ - dprintk(state->verbose, FE_DEBUG, 1, "Going to Sleep .. (Really tired .. :-))"); - /* post process event */ - stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0); - - return 0; -} - -static int stb0899_wakeup(struct dvb_frontend *fe) -{ - int rc; - struct stb0899_state *state = fe->demodulator_priv; - - if ((rc = stb0899_write_reg(state, STB0899_SYNTCTRL, STB0899_SELOSCI))) - return rc; - /* Activate all clocks; DVB-S2 registers are inaccessible otherwise. */ - if ((rc = stb0899_write_reg(state, STB0899_STOPCLK1, 0x00))) - return rc; - if ((rc = stb0899_write_reg(state, STB0899_STOPCLK2, 0x00))) - return rc; - - /* post process event */ - stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 1); - - return 0; -} - -static int stb0899_init(struct dvb_frontend *fe) -{ - int i; - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_config *config = state->config; - - dprintk(state->verbose, FE_DEBUG, 1, "Initializing STB0899 ... "); - - /* init device */ - dprintk(state->verbose, FE_DEBUG, 1, "init device"); - for (i = 0; config->init_dev[i].address != 0xffff; i++) - stb0899_write_reg(state, config->init_dev[i].address, config->init_dev[i].data); - - dprintk(state->verbose, FE_DEBUG, 1, "init S2 demod"); - /* init S2 demod */ - for (i = 0; config->init_s2_demod[i].offset != 0xffff; i++) - stb0899_write_s2reg(state, STB0899_S2DEMOD, - config->init_s2_demod[i].base_address, - config->init_s2_demod[i].offset, - config->init_s2_demod[i].data); - - dprintk(state->verbose, FE_DEBUG, 1, "init S1 demod"); - /* init S1 demod */ - for (i = 0; config->init_s1_demod[i].address != 0xffff; i++) - stb0899_write_reg(state, config->init_s1_demod[i].address, config->init_s1_demod[i].data); - - dprintk(state->verbose, FE_DEBUG, 1, "init S2 FEC"); - /* init S2 fec */ - for (i = 0; config->init_s2_fec[i].offset != 0xffff; i++) - stb0899_write_s2reg(state, STB0899_S2FEC, - config->init_s2_fec[i].base_address, - config->init_s2_fec[i].offset, - config->init_s2_fec[i].data); - - dprintk(state->verbose, FE_DEBUG, 1, "init TST"); - /* init test */ - for (i = 0; config->init_tst[i].address != 0xffff; i++) - stb0899_write_reg(state, config->init_tst[i].address, config->init_tst[i].data); - - stb0899_init_calc(state); - stb0899_diseqc_init(state); - - return 0; -} - -static int stb0899_table_lookup(const struct stb0899_tab *tab, int max, int val) -{ - int res = 0; - int min = 0, med; - - if (val < tab[min].read) - res = tab[min].real; - else if (val >= tab[max].read) - res = tab[max].real; - else { - while ((max - min) > 1) { - med = (max + min) / 2; - if (val >= tab[min].read && val < tab[med].read) - max = med; - else - min = med; - } - res = ((val - tab[min].read) * - (tab[max].real - tab[min].real) / - (tab[max].read - tab[min].read)) + - tab[min].real; - } - - return res; -} - -static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_internal *internal = &state->internal; - - int val; - u32 reg; - switch (state->delsys) { - case SYS_DVBS: - case SYS_DSS: - if (internal->lock) { - reg = stb0899_read_reg(state, STB0899_VSTATUS); - if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) { - - reg = stb0899_read_reg(state, STB0899_AGCIQIN); - val = (s32)(s8)STB0899_GETFIELD(AGCIQVALUE, reg); - - *strength = stb0899_table_lookup(stb0899_dvbsrf_tab, ARRAY_SIZE(stb0899_dvbsrf_tab) - 1, val); - *strength += 750; - dprintk(state->verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm", - val & 0xff, *strength); - } - } - break; - case SYS_DVBS2: - if (internal->lock) { - reg = STB0899_READ_S2REG(STB0899_DEMOD, IF_AGC_GAIN); - val = STB0899_GETFIELD(IF_AGC_GAIN, reg); - - *strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val); - *strength += 750; - dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm", - val & 0x3fff, *strength); - } - break; - default: - dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system"); - return -EINVAL; - } - - return 0; -} - -static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_internal *internal = &state->internal; - - unsigned int val, quant, quantn = -1, est, estn = -1; - u8 buf[2]; - u32 reg; - - reg = stb0899_read_reg(state, STB0899_VSTATUS); - switch (state->delsys) { - case SYS_DVBS: - case SYS_DSS: - if (internal->lock) { - if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) { - - stb0899_read_regs(state, STB0899_NIRM, buf, 2); - val = MAKEWORD16(buf[0], buf[1]); - - *snr = stb0899_table_lookup(stb0899_cn_tab, ARRAY_SIZE(stb0899_cn_tab) - 1, val); - dprintk(state->verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n", - buf[0], buf[1], val, *snr); - } - } - break; - case SYS_DVBS2: - if (internal->lock) { - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1); - quant = STB0899_GETFIELD(UWP_ESN0_QUANT, reg); - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2); - est = STB0899_GETFIELD(ESN0_EST, reg); - if (est == 1) - val = 301; /* C/N = 30.1 dB */ - else if (est == 2) - val = 270; /* C/N = 27.0 dB */ - else { - /* quantn = 100 * log(quant^2) */ - quantn = stb0899_table_lookup(stb0899_quant_tab, ARRAY_SIZE(stb0899_quant_tab) - 1, quant * 100); - /* estn = 100 * log(est) */ - estn = stb0899_table_lookup(stb0899_est_tab, ARRAY_SIZE(stb0899_est_tab) - 1, est); - /* snr(dBm/10) = -10*(log(est)-log(quant^2)) => snr(dBm/10) = (100*log(quant^2)-100*log(est))/10 */ - val = (quantn - estn) / 10; - } - *snr = val; - dprintk(state->verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm", - quant, quantn, est, estn, val); - } - break; - default: - dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system"); - return -EINVAL; - } - - return 0; -} - -static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_internal *internal = &state->internal; - u8 reg; - *status = 0; - - switch (state->delsys) { - case SYS_DVBS: - case SYS_DSS: - dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S/DSS"); - if (internal->lock) { - reg = stb0899_read_reg(state, STB0899_VSTATUS); - if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) { - dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_CARRIER | FE_HAS_LOCK"); - *status |= FE_HAS_CARRIER | FE_HAS_LOCK; - - reg = stb0899_read_reg(state, STB0899_PLPARM); - if (STB0899_GETFIELD(VITCURPUN, reg)) { - dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_VITERBI | FE_HAS_SYNC"); - *status |= FE_HAS_VITERBI | FE_HAS_SYNC; - /* post process event */ - stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1); - } - } - } - break; - case SYS_DVBS2: - dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S2"); - if (internal->lock) { - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2); - if (STB0899_GETFIELD(UWP_LOCK, reg) && STB0899_GETFIELD(CSM_LOCK, reg)) { - *status |= FE_HAS_CARRIER; - dprintk(state->verbose, FE_DEBUG, 1, - "UWP & CSM Lock ! ---> DVB-S2 FE_HAS_CARRIER"); - - reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1); - if (STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg)) { - *status |= FE_HAS_LOCK; - dprintk(state->verbose, FE_DEBUG, 1, - "Packet Delineator Locked ! -----> DVB-S2 FE_HAS_LOCK"); - - } - if (STB0899_GETFIELD(CONTINUOUS_STREAM, reg)) { - *status |= FE_HAS_VITERBI; - dprintk(state->verbose, FE_DEBUG, 1, - "Packet Delineator found VITERBI ! -----> DVB-S2 FE_HAS_VITERBI"); - } - if (STB0899_GETFIELD(ACCEPTED_STREAM, reg)) { - *status |= FE_HAS_SYNC; - dprintk(state->verbose, FE_DEBUG, 1, - "Packet Delineator found SYNC ! -----> DVB-S2 FE_HAS_SYNC"); - /* post process event */ - stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1); - } - } - } - break; - default: - dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system"); - return -EINVAL; - } - return 0; -} - -/* - * stb0899_get_error - * viterbi error for DVB-S/DSS - * packet error for DVB-S2 - * Bit Error Rate or Packet Error Rate * 10 ^ 7 - */ -static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_internal *internal = &state->internal; - - u8 lsb, msb; - u32 i; - - *ber = 0; - - switch (state->delsys) { - case SYS_DVBS: - case SYS_DSS: - if (internal->lock) { - /* average 5 BER values */ - for (i = 0; i < 5; i++) { - msleep(100); - lsb = stb0899_read_reg(state, STB0899_ECNT1L); - msb = stb0899_read_reg(state, STB0899_ECNT1M); - *ber += MAKEWORD16(msb, lsb); - } - *ber /= 5; - /* Viterbi Check */ - if (STB0899_GETFIELD(VSTATUS_PRFVIT, internal->v_status)) { - /* Error Rate */ - *ber *= 9766; - /* ber = ber * 10 ^ 7 */ - *ber /= (-1 + (1 << (2 * STB0899_GETFIELD(NOE, internal->err_ctrl)))); - *ber /= 8; - } - } - break; - case SYS_DVBS2: - if (internal->lock) { - /* Average 5 PER values */ - for (i = 0; i < 5; i++) { - msleep(100); - lsb = stb0899_read_reg(state, STB0899_ECNT1L); - msb = stb0899_read_reg(state, STB0899_ECNT1M); - *ber += MAKEWORD16(msb, lsb); - } - /* ber = ber * 10 ^ 7 */ - *ber *= 10000000; - *ber /= (-1 + (1 << (4 + 2 * STB0899_GETFIELD(NOE, internal->err_ctrl)))); - } - break; - default: - dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system"); - return -EINVAL; - } - - return 0; -} - -static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct stb0899_state *state = fe->demodulator_priv; - - switch (voltage) { - case SEC_VOLTAGE_13: - stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82); - stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02); - stb0899_write_reg(state, STB0899_GPIO02CFG, 0x00); - break; - case SEC_VOLTAGE_18: - stb0899_write_reg(state, STB0899_GPIO00CFG, 0x02); - stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02); - stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82); - break; - case SEC_VOLTAGE_OFF: - stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82); - stb0899_write_reg(state, STB0899_GPIO01CFG, 0x82); - stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_internal *internal = &state->internal; - - u8 div, reg; - - /* wait for diseqc idle */ - if (stb0899_wait_diseqc_txidle(state, 100) < 0) - return -ETIMEDOUT; - - switch (tone) { - case SEC_TONE_ON: - div = (internal->master_clk / 100) / 5632; - div = (div + 5) / 10; - stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x66); - reg = stb0899_read_reg(state, STB0899_ACRPRESC); - STB0899_SETFIELD_VAL(ACRPRESC, reg, 0x03); - stb0899_write_reg(state, STB0899_ACRPRESC, reg); - stb0899_write_reg(state, STB0899_ACRDIV1, div); - break; - case SEC_TONE_OFF: - stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x20); - break; - default: - return -EINVAL; - } - return 0; -} - -int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - int i2c_stat; - struct stb0899_state *state = fe->demodulator_priv; - - i2c_stat = stb0899_read_reg(state, STB0899_I2CRPT); - if (i2c_stat < 0) - goto err; - - if (enable) { - dprintk(state->verbose, FE_DEBUG, 1, "Enabling I2C Repeater ..."); - i2c_stat |= STB0899_I2CTON; - if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0) - goto err; - } else { - dprintk(state->verbose, FE_DEBUG, 1, "Disabling I2C Repeater ..."); - i2c_stat &= ~STB0899_I2CTON; - if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0) - goto err; - } - return 0; -err: - dprintk(state->verbose, FE_ERROR, 1, "I2C Repeater control failed"); - return -EREMOTEIO; -} - - -static inline void CONVERT32(u32 x, char *str) -{ - *str++ = (x >> 24) & 0xff; - *str++ = (x >> 16) & 0xff; - *str++ = (x >> 8) & 0xff; - *str++ = (x >> 0) & 0xff; - *str = '\0'; -} - -int stb0899_get_dev_id(struct stb0899_state *state) -{ - u8 chip_id, release; - u16 id; - u32 demod_ver = 0, fec_ver = 0; - char demod_str[5] = { 0 }; - char fec_str[5] = { 0 }; - - id = stb0899_read_reg(state, STB0899_DEV_ID); - dprintk(state->verbose, FE_DEBUG, 1, "ID reg=[0x%02x]", id); - chip_id = STB0899_GETFIELD(CHIP_ID, id); - release = STB0899_GETFIELD(CHIP_REL, id); - - dprintk(state->verbose, FE_ERROR, 1, "Device ID=[%d], Release=[%d]", - chip_id, release); - - CONVERT32(STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CORE_ID), (char *)&demod_str); - - demod_ver = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_VERSION_ID); - dprintk(state->verbose, FE_ERROR, 1, "Demodulator Core ID=[%s], Version=[%d]", (char *) &demod_str, demod_ver); - CONVERT32(STB0899_READ_S2REG(STB0899_S2FEC, FEC_CORE_ID_REG), (char *)&fec_str); - fec_ver = STB0899_READ_S2REG(STB0899_S2FEC, FEC_VER_ID_REG); - if (! (chip_id > 0)) { - dprintk(state->verbose, FE_ERROR, 1, "couldn't find a STB 0899"); - - return -ENODEV; - } - dprintk(state->verbose, FE_ERROR, 1, "FEC Core ID=[%s], Version=[%d]", (char*) &fec_str, fec_ver); - - return 0; -} - -static void stb0899_set_delivery(struct stb0899_state *state) -{ - u8 reg; - u8 stop_clk[2]; - - stop_clk[0] = stb0899_read_reg(state, STB0899_STOPCLK1); - stop_clk[1] = stb0899_read_reg(state, STB0899_STOPCLK2); - - switch (state->delsys) { - case SYS_DVBS: - dprintk(state->verbose, FE_DEBUG, 1, "Delivery System -- DVB-S"); - /* FECM/Viterbi ON */ - reg = stb0899_read_reg(state, STB0899_FECM); - STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0); - STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1); - stb0899_write_reg(state, STB0899_FECM, reg); - - stb0899_write_reg(state, STB0899_RSULC, 0xb1); - stb0899_write_reg(state, STB0899_TSULC, 0x40); - stb0899_write_reg(state, STB0899_RSLLC, 0x42); - stb0899_write_reg(state, STB0899_TSLPL, 0x12); - - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESLDPC, reg, 1); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1); - STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1); - STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1); - - STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1); - STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1); - - STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 1); - STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0); - - STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1); - break; - case SYS_DVBS2: - /* FECM/Viterbi OFF */ - reg = stb0899_read_reg(state, STB0899_FECM); - STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0); - STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 0); - stb0899_write_reg(state, STB0899_FECM, reg); - - stb0899_write_reg(state, STB0899_RSULC, 0xb1); - stb0899_write_reg(state, STB0899_TSULC, 0x42); - stb0899_write_reg(state, STB0899_RSLLC, 0x40); - stb0899_write_reg(state, STB0899_TSLPL, 0x02); - - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESLDPC, reg, 0); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1); - STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 0); - STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 0); - - STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 0); - STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 0); - - STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 0); - STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0); - - STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 0); - break; - case SYS_DSS: - /* FECM/Viterbi ON */ - reg = stb0899_read_reg(state, STB0899_FECM); - STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 1); - STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1); - stb0899_write_reg(state, STB0899_FECM, reg); - - stb0899_write_reg(state, STB0899_RSULC, 0xa1); - stb0899_write_reg(state, STB0899_TSULC, 0x61); - stb0899_write_reg(state, STB0899_RSLLC, 0x42); - - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESLDPC, reg, 1); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1); - STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1); - STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1); - - STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1); - STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1); - - STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0); - - STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1); - break; - default: - dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); - break; - } - STB0899_SETFIELD_VAL(STOP_CKADCI108, stop_clk[0], 0); - stb0899_write_regs(state, STB0899_STOPCLK1, stop_clk, 2); -} - -/* - * stb0899_set_iterations - * set the LDPC iteration scale function - */ -static void stb0899_set_iterations(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - - s32 iter_scale; - u32 reg; - - iter_scale = 17 * (internal->master_clk / 1000); - iter_scale += 410000; - iter_scale /= (internal->srate / 1000000); - iter_scale /= 1000; - - if (iter_scale > config->ldpc_max_iter) - iter_scale = config->ldpc_max_iter; - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, MAX_ITER); - STB0899_SETFIELD_VAL(MAX_ITERATIONS, reg, iter_scale); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_MAX_ITER, STB0899_OFF0_MAX_ITER, reg); -} - -static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_params *i_params = &state->params; - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - struct dtv_frontend_properties *props = &fe->dtv_property_cache; - - u32 SearchRange, gain; - - i_params->freq = p->frequency; - i_params->srate = p->u.qpsk.symbol_rate; - state->delsys = props->delivery_system; - dprintk(state->verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys); - - SearchRange = 10000000; - dprintk(state->verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate); - /* checking Search Range is meaningless for a fixed 3 Mhz */ - if (INRANGE(i_params->srate, 1000000, 45000000)) { - dprintk(state->verbose, FE_DEBUG, 1, "Parameters IN RANGE"); - stb0899_set_delivery(state); - - if (state->config->tuner_set_rfsiggain) { - if (internal->srate > 15000000) - gain = 8; /* 15Mb < srate < 45Mb, gain = 8dB */ - else if (internal->srate > 5000000) - gain = 12; /* 5Mb < srate < 15Mb, gain = 12dB */ - else - gain = 14; /* 1Mb < srate < 5Mb, gain = 14db */ - state->config->tuner_set_rfsiggain(fe, gain); - } - - if (i_params->srate <= 5000000) - stb0899_set_mclk(state, config->lo_clk); - else - stb0899_set_mclk(state, config->hi_clk); - - switch (state->delsys) { - case SYS_DVBS: - case SYS_DSS: - dprintk(state->verbose, FE_DEBUG, 1, "DVB-S delivery system"); - internal->freq = i_params->freq; - internal->srate = i_params->srate; - /* - * search = user search range + - * 500Khz + - * 2 * Tuner_step_size + - * 10% of the symbol rate - */ - internal->srch_range = SearchRange + 1500000 + (i_params->srate / 5); - internal->derot_percent = 30; - - /* What to do for tuners having no bandwidth setup ? */ - /* enable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 1); - - if (state->config->tuner_set_bandwidth) - state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + SearchRange)) / 10); - if (state->config->tuner_get_bandwidth) - state->config->tuner_get_bandwidth(fe, &internal->tuner_bw); - - /* disable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 0); - - /* Set DVB-S1 AGC */ - stb0899_write_reg(state, STB0899_AGCRFCFG, 0x11); - - /* Run the search algorithm */ - dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S search algo .."); - if (stb0899_dvbs_algo(state) == RANGEOK) { - internal->lock = 1; - dprintk(state->verbose, FE_DEBUG, 1, - "-------------------------------------> DVB-S LOCK !"); - -// stb0899_write_reg(state, STB0899_ERRCTRL1, 0x3d); /* Viterbi Errors */ -// internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS); -// internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1); -// dprintk(state->verbose, FE_DEBUG, 1, "VSTATUS=0x%02x", internal->v_status); -// dprintk(state->verbose, FE_DEBUG, 1, "ERR_CTRL=0x%02x", internal->err_ctrl); - - return DVBFE_ALGO_SEARCH_SUCCESS; - } else { - internal->lock = 0; - - return DVBFE_ALGO_SEARCH_FAILED; - } - break; - case SYS_DVBS2: - internal->freq = i_params->freq; - internal->srate = i_params->srate; - internal->srch_range = SearchRange; - - /* enable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 1); - - if (state->config->tuner_set_bandwidth) - state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + SearchRange)); - if (state->config->tuner_get_bandwidth) - state->config->tuner_get_bandwidth(fe, &internal->tuner_bw); - - /* disable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 0); - -// pParams->SpectralInv = pSearch->IQ_Inversion; - - /* Set DVB-S2 AGC */ - stb0899_write_reg(state, STB0899_AGCRFCFG, 0x1c); - - /* Set IterScale =f(MCLK,SYMB) */ - stb0899_set_iterations(state); - - /* Run the search algorithm */ - dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S2 search algo .."); - if (stb0899_dvbs2_algo(state) == DVBS2_FEC_LOCK) { - internal->lock = 1; - dprintk(state->verbose, FE_DEBUG, 1, - "-------------------------------------> DVB-S2 LOCK !"); - -// stb0899_write_reg(state, STB0899_ERRCTRL1, 0xb6); /* Packet Errors */ -// internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS); -// internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1); - - return DVBFE_ALGO_SEARCH_SUCCESS; - } else { - internal->lock = 0; - - return DVBFE_ALGO_SEARCH_FAILED; - } - break; - default: - dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); - return DVBFE_ALGO_SEARCH_INVALID; - } - } - - return DVBFE_ALGO_SEARCH_ERROR; -} -/* - * stb0899_track - * periodically check the signal level against a specified - * threshold level and perform derotator centering. - * called once we have a lock from a succesful search - * event. - * - * Will be called periodically called to maintain the - * lock. - * - * Will be used to get parameters as well as info from - * the decoded baseband header - * - * Once a new lock has established, the internal state - * frequency (internal->freq) is updated - */ -static int stb0899_track(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - return 0; -} - -static int stb0899_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_internal *internal = &state->internal; - - dprintk(state->verbose, FE_DEBUG, 1, "Get params"); - p->u.qpsk.symbol_rate = internal->srate; - - return 0; -} - -static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe) -{ - return DVBFE_ALGO_CUSTOM; -} - -static struct dvb_frontend_ops stb0899_ops = { - - .info = { - .name = "STB0899 Multistandard", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 0, - .frequency_tolerance = 0, - .symbol_rate_min = 5000000, - .symbol_rate_max = 45000000, - - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_AUTO | - FE_CAN_2G_MODULATION | - FE_CAN_QPSK - }, - - .release = stb0899_release, - .init = stb0899_init, - .sleep = stb0899_sleep, -// .wakeup = stb0899_wakeup, - - .i2c_gate_ctrl = stb0899_i2c_gate_ctrl, - - .get_frontend_algo = stb0899_frontend_algo, - .search = stb0899_search, - .track = stb0899_track, - .get_frontend = stb0899_get_frontend, - - - .read_status = stb0899_read_status, - .read_snr = stb0899_read_snr, - .read_signal_strength = stb0899_read_signal_strength, - .read_ber = stb0899_read_ber, - - .set_voltage = stb0899_set_voltage, - .set_tone = stb0899_set_tone, - - .diseqc_send_master_cmd = stb0899_send_diseqc_msg, - .diseqc_recv_slave_reply = stb0899_recv_slave_reply, - .diseqc_send_burst = stb0899_send_diseqc_burst, -}; - -struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c) -{ - struct stb0899_state *state = NULL; - enum stb0899_inversion inversion; - - state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL); - if (state == NULL) - goto error; - - inversion = config->inversion; - state->verbose = &verbose; - state->config = config; - state->i2c = i2c; - state->frontend.ops = stb0899_ops; - state->frontend.demodulator_priv = state; - state->internal.inversion = inversion; - - stb0899_wakeup(&state->frontend); - if (stb0899_get_dev_id(state) == -ENODEV) { - printk("%s: Exiting .. !\n", __func__); - goto error; - } - - printk("%s: Attaching STB0899 \n", __func__); - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(stb0899_attach); -MODULE_PARM_DESC(verbose, "Set Verbosity level"); -MODULE_AUTHOR("Manu Abraham"); -MODULE_DESCRIPTION("STB0899 Multi-Std frontend"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/stb0899_drv.h b/drivers/media/dvb/frontends/stb0899_drv.h deleted file mode 100644 index 98b200ce0c3..00000000000 --- a/drivers/media/dvb/frontends/stb0899_drv.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - STB0899 Multistandard Frontend driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - 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 __STB0899_DRV_H -#define __STB0899_DRV_H - -#include <linux/kernel.h> -#include <linux/module.h> - -#include "dvb_frontend.h" - -#define STB0899_TSMODE_SERIAL 1 -#define STB0899_CLKPOL_FALLING 2 -#define STB0899_CLKNULL_PARITY 3 -#define STB0899_SYNC_FORCED 4 -#define STB0899_FECMODE_DSS 5 - -struct stb0899_s1_reg { - u16 address; - u8 data; -}; - -struct stb0899_s2_reg { - u16 offset; - u32 base_address; - u32 data; -}; - -enum stb0899_inversion { - IQ_SWAP_OFF = 0, - IQ_SWAP_ON, - IQ_SWAP_AUTO -}; - -#define STB0899_GPIO00 0xf140 -#define STB0899_GPIO01 0xf141 -#define STB0899_GPIO02 0xf142 -#define STB0899_GPIO03 0xf143 -#define STB0899_GPIO04 0xf144 -#define STB0899_GPIO05 0xf145 -#define STB0899_GPIO06 0xf146 -#define STB0899_GPIO07 0xf147 -#define STB0899_GPIO08 0xf148 -#define STB0899_GPIO09 0xf149 -#define STB0899_GPIO10 0xf14a -#define STB0899_GPIO11 0xf14b -#define STB0899_GPIO12 0xf14c -#define STB0899_GPIO13 0xf14d -#define STB0899_GPIO14 0xf14e -#define STB0899_GPIO15 0xf14f -#define STB0899_GPIO16 0xf150 -#define STB0899_GPIO17 0xf151 -#define STB0899_GPIO18 0xf152 -#define STB0899_GPIO19 0xf153 -#define STB0899_GPIO20 0xf154 - -#define STB0899_GPIOPULLUP 0x01 /* Output device is connected to Vdd */ -#define STB0899_GPIOPULLDN 0x00 /* Output device is connected to Vss */ - -#define STB0899_POSTPROC_GPIO_POWER 0x00 -#define STB0899_POSTPROC_GPIO_LOCK 0x01 - -/* - * Post process output configuration control - * 1. POWER ON/OFF (index 0) - * 2. FE_HAS_LOCK/LOCK_LOSS (index 1) - * - * @gpio = one of the above listed GPIO's - * @level = output state: pulled up or low - */ -struct stb0899_postproc { - u16 gpio; - u8 level; -}; - -struct stb0899_config { - const struct stb0899_s1_reg *init_dev; - const struct stb0899_s2_reg *init_s2_demod; - const struct stb0899_s1_reg *init_s1_demod; - const struct stb0899_s2_reg *init_s2_fec; - const struct stb0899_s1_reg *init_tst; - - const struct stb0899_postproc *postproc; - - enum stb0899_inversion inversion; - - u32 xtal_freq; - - u8 demod_address; - u8 ts_output_mode; - u8 block_sync_mode; - u8 ts_pfbit_toggle; - - u8 clock_polarity; - u8 data_clk_parity; - u8 fec_mode; - u8 data_output_ctl; - u8 data_fifo_mode; - u8 out_rate_comp; - u8 i2c_repeater; -// int inversion; - int lo_clk; - int hi_clk; - - u32 esno_ave; - u32 esno_quant; - u32 avframes_coarse; - u32 avframes_fine; - u32 miss_threshold; - u32 uwp_threshold_acq; - u32 uwp_threshold_track; - u32 uwp_threshold_sof; - u32 sof_search_timeout; - - u32 btr_nco_bits; - u32 btr_gain_shift_offset; - u32 crl_nco_bits; - u32 ldpc_max_iter; - - int (*tuner_set_frequency)(struct dvb_frontend *fe, u32 frequency); - int (*tuner_get_frequency)(struct dvb_frontend *fe, u32 *frequency); - int (*tuner_set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); - int (*tuner_get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth); - int (*tuner_set_rfsiggain)(struct dvb_frontend *fe, u32 rf_gain); -}; - -#if defined(CONFIG_DVB_STB0899) || (defined(CONFIG_DVB_STB0899_MODULE) && defined(MODULE)) - -extern struct dvb_frontend *stb0899_attach(struct stb0899_config *config, - struct i2c_adapter *i2c); - -#else - -static inline struct dvb_frontend *stb0899_attach(struct stb0899_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); - return NULL; -} - -#endif //CONFIG_DVB_STB0899 - - -#endif diff --git a/drivers/media/dvb/frontends/stb0899_priv.h b/drivers/media/dvb/frontends/stb0899_priv.h deleted file mode 100644 index 82395b91281..00000000000 --- a/drivers/media/dvb/frontends/stb0899_priv.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - STB0899 Multistandard Frontend driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - 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 __STB0899_PRIV_H -#define __STB0899_PRIV_H - -#include "dvb_frontend.h" -#include "stb0899_drv.h" - -#define FE_ERROR 0 -#define FE_NOTICE 1 -#define FE_INFO 2 -#define FE_DEBUG 3 -#define FE_DEBUGREG 4 - -#define dprintk(x, y, z, format, arg...) do { \ - if (z) { \ - if ((*x > FE_ERROR) && (*x > y)) \ - printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ - else if ((*x > FE_NOTICE) && (*x > y)) \ - printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ - else if ((*x > FE_INFO) && (*x > y)) \ - printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ - else if ((*x > FE_DEBUG) && (*x > y)) \ - printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ - } else { \ - if (*x > y) \ - printk(format, ##arg); \ - } \ -} while(0) - -#define INRANGE(val, x, y) (((x <= val) && (val <= y)) || \ - ((y <= val) && (val <= x)) ? 1 : 0) - -#define BYTE0 0 -#define BYTE1 8 -#define BYTE2 16 -#define BYTE3 24 - -#define GETBYTE(x, y) (((x) >> (y)) & 0xff) -#define MAKEWORD32(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) -#define MAKEWORD16(a, b) (((a) << 8) | (b)) - -#define LSB(x) ((x & 0xff)) -#define MSB(y) ((y >> 8) & 0xff) - - -#define STB0899_GETFIELD(bitf, val) ((val >> STB0899_OFFST_##bitf) & ((1 << STB0899_WIDTH_##bitf) - 1)) - - -#define STB0899_SETFIELD(mask, val, width, offset) (mask & (~(((1 << width) - 1) << \ - offset))) | ((val & \ - ((1 << width) - 1)) << offset) - -#define STB0899_SETFIELD_VAL(bitf, mask, val) (mask = (mask & (~(((1 << STB0899_WIDTH_##bitf) - 1) <<\ - STB0899_OFFST_##bitf))) | \ - (val << STB0899_OFFST_##bitf)) - - -enum stb0899_status { - NOAGC1 = 0, - AGC1OK, - NOTIMING, - ANALOGCARRIER, - TIMINGOK, - NOAGC2, - AGC2OK, - NOCARRIER, - CARRIEROK, - NODATA, - FALSELOCK, - DATAOK, - OUTOFRANGE, - RANGEOK, - DVBS2_DEMOD_LOCK, - DVBS2_DEMOD_NOLOCK, - DVBS2_FEC_LOCK, - DVBS2_FEC_NOLOCK -}; - -enum stb0899_modcod { - STB0899_DUMMY_PLF, - STB0899_QPSK_14, - STB0899_QPSK_13, - STB0899_QPSK_25, - STB0899_QPSK_12, - STB0899_QPSK_35, - STB0899_QPSK_23, - STB0899_QPSK_34, - STB0899_QPSK_45, - STB0899_QPSK_56, - STB0899_QPSK_89, - STB0899_QPSK_910, - STB0899_8PSK_35, - STB0899_8PSK_23, - STB0899_8PSK_34, - STB0899_8PSK_56, - STB0899_8PSK_89, - STB0899_8PSK_910, - STB0899_16APSK_23, - STB0899_16APSK_34, - STB0899_16APSK_45, - STB0899_16APSK_56, - STB0899_16APSK_89, - STB0899_16APSK_910, - STB0899_32APSK_34, - STB0899_32APSK_45, - STB0899_32APSK_56, - STB0899_32APSK_89, - STB0899_32APSK_910 -}; - -enum stb0899_frame { - STB0899_LONG_FRAME, - STB0899_SHORT_FRAME -}; - -enum stb0899_alpha { - RRC_20, - RRC_25, - RRC_35 -}; - -struct stb0899_tab { - s32 real; - s32 read; -}; - -enum stb0899_fec { - STB0899_FEC_1_2 = 13, - STB0899_FEC_2_3 = 18, - STB0899_FEC_3_4 = 21, - STB0899_FEC_5_6 = 24, - STB0899_FEC_6_7 = 25, - STB0899_FEC_7_8 = 26 -}; - -struct stb0899_params { - u32 freq; /* Frequency */ - u32 srate; /* Symbol rate */ - enum fe_code_rate fecrate; -}; - -struct stb0899_internal { - u32 master_clk; - u32 freq; /* Demod internal Frequency */ - u32 srate; /* Demod internal Symbol rate */ - enum stb0899_fec fecrate; /* Demod internal FEC rate */ - s32 srch_range; /* Demod internal Search Range */ - s32 sub_range; /* Demod current sub range (Hz) */ - s32 tuner_step; /* Tuner step (Hz) */ - s32 tuner_offst; /* Relative offset to carrier (Hz) */ - u32 tuner_bw; /* Current bandwidth of the tuner (Hz) */ - - s32 mclk; /* Masterclock Divider factor (binary) */ - s32 rolloff; /* Current RollOff of the filter (x100) */ - - s16 derot_freq; /* Current derotator frequency (Hz) */ - s16 derot_percent; - - s16 direction; /* Current derotator search direction */ - s16 derot_step; /* Derotator step (binary value) */ - s16 t_derot; /* Derotator time constant (ms) */ - s16 t_data; /* Data recovery time constant (ms) */ - s16 sub_dir; /* Direction of the next sub range */ - - s16 t_agc1; /* Agc1 time constant (ms) */ - s16 t_agc2; /* Agc2 time constant (ms) */ - - u32 lock; /* Demod internal lock state */ - enum stb0899_status status; /* Demod internal status */ - - /* DVB-S2 */ - s32 agc_gain; /* RF AGC Gain */ - s32 center_freq; /* Nominal carrier frequency */ - s32 av_frame_coarse; /* Coarse carrier freq search frames */ - s32 av_frame_fine; /* Fine carrier freq search frames */ - - s16 step_size; /* Carrier frequency search step size */ - - enum stb0899_alpha rrc_alpha; - enum stb0899_inversion inversion; - enum stb0899_modcod modcod; - u8 pilots; /* Pilots found */ - - enum stb0899_frame frame_length; - u8 v_status; /* VSTATUS */ - u8 err_ctrl; /* ERRCTRLn */ -}; - -struct stb0899_state { - struct i2c_adapter *i2c; - struct stb0899_config *config; - struct dvb_frontend frontend; - - u32 *verbose; /* Cached module verbosity level */ - - struct stb0899_internal internal; /* Device internal parameters */ - - /* cached params from API */ - enum fe_delivery_system delsys; - struct stb0899_params params; - - u32 rx_freq; /* DiSEqC 2.0 receiver freq */ - struct mutex search_lock; -}; -/* stb0899.c */ -extern int stb0899_read_reg(struct stb0899_state *state, - unsigned int reg); - -extern u32 _stb0899_read_s2reg(struct stb0899_state *state, - u32 stb0899_i2cdev, - u32 stb0899_base_addr, - u16 stb0899_reg_offset); - -extern int stb0899_read_regs(struct stb0899_state *state, - unsigned int reg, u8 *buf, - u32 count); - -extern int stb0899_write_regs(struct stb0899_state *state, - unsigned int reg, u8 *data, - u32 count); - -extern int stb0899_write_reg(struct stb0899_state *state, - unsigned int reg, - u8 data); - -extern int stb0899_write_s2reg(struct stb0899_state *state, - u32 stb0899_i2cdev, - u32 stb0899_base_addr, - u16 stb0899_reg_offset, - u32 stb0899_data); - -extern int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable); - - -#define STB0899_READ_S2REG(DEVICE, REG) (_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG)) -//#define STB0899_WRITE_S2REG(DEVICE, REG, DATA) (_stb0899_write_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG, DATA)) - -/* stb0899_algo.c */ -extern enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state); -extern enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state); -extern long stb0899_carr_width(struct stb0899_state *state); - -#endif //__STB0899_PRIV_H diff --git a/drivers/media/dvb/frontends/stb0899_reg.h b/drivers/media/dvb/frontends/stb0899_reg.h deleted file mode 100644 index ba1ed56304a..00000000000 --- a/drivers/media/dvb/frontends/stb0899_reg.h +++ /dev/null @@ -1,2027 +0,0 @@ -/* - STB0899 Multistandard Frontend driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - 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 __STB0899_REG_H -#define __STB0899_REG_H - -/* S1 */ -#define STB0899_DEV_ID 0xf000 -#define STB0899_CHIP_ID (0x0f << 4) -#define STB0899_OFFST_CHIP_ID 4 -#define STB0899_WIDTH_CHIP_ID 4 -#define STB0899_CHIP_REL (0x0f << 0) -#define STB0899_OFFST_CHIP_REL 0 -#define STB0899_WIDTH_CHIP_REL 4 - -#define STB0899_DEMOD 0xf40e -#define STB0899_MODECOEFF (0x01 << 0) -#define STB0899_OFFST_MODECOEFF 0 -#define STB0899_WIDTH_MODECOEFF 1 - -#define STB0899_RCOMPC 0xf410 -#define STB0899_AGC1CN 0xf412 -#define STB0899_AGC1REF 0xf413 -#define STB0899_RTC 0xf417 -#define STB0899_TMGCFG 0xf418 -#define STB0899_AGC2REF 0xf419 -#define STB0899_TLSR 0xf41a - -#define STB0899_CFD 0xf41b -#define STB0899_CFD_ON (0x01 << 7) -#define STB0899_OFFST_CFD_ON 7 -#define STB0899_WIDTH_CFD_ON 1 - -#define STB0899_ACLC 0xf41c - -#define STB0899_BCLC 0xf41d -#define STB0899_OFFST_ALGO 6 -#define STB0899_WIDTH_ALGO_QPSK2 2 -#define STB0899_ALGO_QPSK2 (2 << 6) -#define STB0899_ALGO_QPSK1 (1 << 6) -#define STB0899_ALGO_BPSK (0 << 6) -#define STB0899_OFFST_BETA 0 -#define STB0899_WIDTH_BETA 6 - -#define STB0899_EQON 0xf41e -#define STB0899_LDT 0xf41f -#define STB0899_LDT2 0xf420 -#define STB0899_EQUALREF 0xf425 -#define STB0899_TMGRAMP 0xf426 -#define STB0899_TMGTHD 0xf427 -#define STB0899_IDCCOMP 0xf428 -#define STB0899_QDCCOMP 0xf429 -#define STB0899_POWERI 0xf42a -#define STB0899_POWERQ 0xf42b -#define STB0899_RCOMP 0xf42c - -#define STB0899_AGCIQIN 0xf42e -#define STB0899_AGCIQVALUE (0xff << 0) -#define STB0899_OFFST_AGCIQVALUE 0 -#define STB0899_WIDTH_AGCIQVALUE 8 - -#define STB0899_AGC2I1 0xf436 -#define STB0899_AGC2I2 0xf437 - -#define STB0899_TLIR 0xf438 -#define STB0899_TLIR_TMG_LOCK_IND (0xff << 0) -#define STB0899_OFFST_TLIR_TMG_LOCK_IND 0 -#define STB0899_WIDTH_TLIR_TMG_LOCK_IND 8 - -#define STB0899_RTF 0xf439 -#define STB0899_RTF_TIMING_LOOP_FREQ (0xff << 0) -#define STB0899_OFFST_RTF_TIMING_LOOP_FREQ 0 -#define STB0899_WIDTH_RTF_TIMING_LOOP_FREQ 8 - -#define STB0899_DSTATUS 0xf43a -#define STB0899_CARRIER_FOUND (0x01 << 7) -#define STB0899_OFFST_CARRIER_FOUND 7 -#define STB0899_WIDTH_CARRIER_FOUND 1 -#define STB0899_TMG_LOCK (0x01 << 6) -#define STB0899_OFFST_TMG_LOCK 6 -#define STB0899_WIDTH_TMG_LOCK 1 -#define STB0899_DEMOD_LOCK (0x01 << 5) -#define STB0899_OFFST_DEMOD_LOCK 5 -#define STB0899_WIDTH_DEMOD_LOCK 1 -#define STB0899_TMG_AUTO (0x01 << 4) -#define STB0899_OFFST_TMG_AUTO 4 -#define STB0899_WIDTH_TMG_AUTO 1 -#define STB0899_END_MAIN (0x01 << 3) -#define STB0899_OFFST_END_MAIN 3 -#define STB0899_WIDTH_END_MAIN 1 - -#define STB0899_LDI 0xf43b -#define STB0899_OFFST_LDI 0 -#define STB0899_WIDTH_LDI 8 - -#define STB0899_CFRM 0xf43e -#define STB0899_OFFST_CFRM 0 -#define STB0899_WIDTH_CFRM 8 - -#define STB0899_CFRL 0xf43f -#define STB0899_OFFST_CFRL 0 -#define STB0899_WIDTH_CFRL 8 - -#define STB0899_NIRM 0xf440 -#define STB0899_OFFST_NIRM 0 -#define STB0899_WIDTH_NIRM 8 - -#define STB0899_NIRL 0xf441 -#define STB0899_OFFST_NIRL 0 -#define STB0899_WIDTH_NIRL 8 - -#define STB0899_ISYMB 0xf444 -#define STB0899_QSYMB 0xf445 - -#define STB0899_SFRH 0xf446 -#define STB0899_OFFST_SFRH 0 -#define STB0899_WIDTH_SFRH 8 - -#define STB0899_SFRM 0xf447 -#define STB0899_OFFST_SFRM 0 -#define STB0899_WIDTH_SFRM 8 - -#define STB0899_SFRL 0xf448 -#define STB0899_OFFST_SFRL 4 -#define STB0899_WIDTH_SFRL 4 - -#define STB0899_SFRUPH 0xf44c -#define STB0899_SFRUPM 0xf44d -#define STB0899_SFRUPL 0xf44e - -#define STB0899_EQUAI1 0xf4e0 -#define STB0899_EQUAQ1 0xf4e1 -#define STB0899_EQUAI2 0xf4e2 -#define STB0899_EQUAQ2 0xf4e3 -#define STB0899_EQUAI3 0xf4e4 -#define STB0899_EQUAQ3 0xf4e5 -#define STB0899_EQUAI4 0xf4e6 -#define STB0899_EQUAQ4 0xf4e7 -#define STB0899_EQUAI5 0xf4e8 -#define STB0899_EQUAQ5 0xf4e9 - -#define STB0899_DSTATUS2 0xf50c -#define STB0899_DS2_TMG_AUTOSRCH (0x01 << 7) -#define STB8999_OFFST_DS2_TMG_AUTOSRCH 7 -#define STB0899_WIDTH_DS2_TMG_AUTOSRCH 1 -#define STB0899_DS2_END_MAINLOOP (0x01 << 6) -#define STB0899_OFFST_DS2_END_MAINLOOP 6 -#define STB0899_WIDTH_DS2_END_MAINLOOP 1 -#define STB0899_DS2_CFSYNC (0x01 << 5) -#define STB0899_OFFST_DS2_CFSYNC 5 -#define STB0899_WIDTH_DS2_CFSYNC 1 -#define STB0899_DS2_TMGLOCK (0x01 << 4) -#define STB0899_OFFST_DS2_TMGLOCK 4 -#define STB0899_WIDTH_DS2_TMGLOCK 1 -#define STB0899_DS2_DEMODWAIT (0x01 << 3) -#define STB0899_OFFST_DS2_DEMODWAIT 3 -#define STB0899_WIDTH_DS2_DEMODWAIT 1 -#define STB0899_DS2_FECON (0x01 << 1) -#define STB0899_OFFST_DS2_FECON 1 -#define STB0899_WIDTH_DS2_FECON 1 - -/* S1 FEC */ -#define STB0899_VSTATUS 0xf50d -#define STB0899_VSTATUS_VITERBI_ON (0x01 << 7) -#define STB0899_OFFST_VSTATUS_VITERBI_ON 7 -#define STB0899_WIDTH_VSTATUS_VITERBI_ON 1 -#define STB0899_VSTATUS_END_LOOPVIT (0x01 << 6) -#define STB0899_OFFST_VSTATUS_END_LOOPVIT 6 -#define STB0899_WIDTH_VSTATUS_END_LOOPVIT 1 -#define STB0899_VSTATUS_PRFVIT (0x01 << 4) -#define STB0899_OFFST_VSTATUS_PRFVIT 4 -#define STB0899_WIDTH_VSTATUS_PRFVIT 1 -#define STB0899_VSTATUS_LOCKEDVIT (0x01 << 3) -#define STB0899_OFFST_VSTATUS_LOCKEDVIT 3 -#define STB0899_WIDTH_VSTATUS_LOCKEDVIT 1 - -#define STB0899_VERROR 0xf50f - -#define STB0899_IQSWAP 0xf523 -#define STB0899_SYM (0x01 << 3) -#define STB0899_OFFST_SYM 3 -#define STB0899_WIDTH_SYM 1 - -#define STB0899_FECAUTO1 0xf530 -#define STB0899_DSSSRCH (0x01 << 3) -#define STB0899_OFFST_DSSSRCH 3 -#define STB0899_WIDTH_DSSSRCH 1 -#define STB0899_SYMSRCH (0x01 << 2) -#define STB0899_OFFST_SYMSRCH 2 -#define STB0899_WIDTH_SYMSRCH 1 -#define STB0899_QPSKSRCH (0x01 << 1) -#define STB0899_OFFST_QPSKSRCH 1 -#define STB0899_WIDTH_QPSKSRCH 1 -#define STB0899_BPSKSRCH (0x01 << 0) -#define STB0899_OFFST_BPSKSRCH 0 -#define STB0899_WIDTH_BPSKSRCH 1 - -#define STB0899_FECM 0xf533 -#define STB0899_FECM_NOT_DVB (0x01 << 7) -#define STB0899_OFFST_FECM_NOT_DVB 7 -#define STB0899_WIDTH_FECM_NOT_DVB 1 -#define STB0899_FECM_RSVD1 (0x07 << 4) -#define STB0899_OFFST_FECM_RSVD1 4 -#define STB0899_WIDTH_FECM_RSVD1 3 -#define STB0899_FECM_VITERBI_ON (0x01 << 3) -#define STB0899_OFFST_FECM_VITERBI_ON 3 -#define STB0899_WIDTH_FECM_VITERBI_ON 1 -#define STB0899_FECM_RSVD0 (0x01 << 2) -#define STB0899_OFFST_FECM_RSVD0 2 -#define STB0899_WIDTH_FECM_RSVD0 1 -#define STB0899_FECM_SYNCDIS (0x01 << 1) -#define STB0899_OFFST_FECM_SYNCDIS 1 -#define STB0899_WIDTH_FECM_SYNCDIS 1 -#define STB0899_FECM_SYMI (0x01 << 0) -#define STB0899_OFFST_FECM_SYMI 0 -#define STB0899_WIDTH_FECM_SYMI 1 - -#define STB0899_VTH12 0xf534 -#define STB0899_VTH23 0xf535 -#define STB0899_VTH34 0xf536 -#define STB0899_VTH56 0xf537 -#define STB0899_VTH67 0xf538 -#define STB0899_VTH78 0xf539 - -#define STB0899_PRVIT 0xf53c -#define STB0899_PR_7_8 (0x01 << 5) -#define STB0899_OFFST_PR_7_8 5 -#define STB0899_WIDTH_PR_7_8 1 -#define STB0899_PR_6_7 (0x01 << 4) -#define STB0899_OFFST_PR_6_7 4 -#define STB0899_WIDTH_PR_6_7 1 -#define STB0899_PR_5_6 (0x01 << 3) -#define STB0899_OFFST_PR_5_6 3 -#define STB0899_WIDTH_PR_5_6 1 -#define STB0899_PR_3_4 (0x01 << 2) -#define STB0899_OFFST_PR_3_4 2 -#define STB0899_WIDTH_PR_3_4 1 -#define STB0899_PR_2_3 (0x01 << 1) -#define STB0899_OFFST_PR_2_3 1 -#define STB0899_WIDTH_PR_2_3 1 -#define STB0899_PR_1_2 (0x01 << 0) -#define STB0899_OFFST_PR_1_2 0 -#define STB0899_WIDTH_PR_1_2 1 - -#define STB0899_VITSYNC 0xf53d -#define STB0899_AM (0x01 << 7) -#define STB0899_OFFST_AM 7 -#define STB0899_WIDTH_AM 1 -#define STB0899_FREEZE (0x01 << 6) -#define STB0899_OFFST_FREEZE 6 -#define STB0899_WIDTH_FREEZE 1 -#define STB0899_SN_65536 (0x03 << 4) -#define STB0899_OFFST_SN_65536 4 -#define STB0899_WIDTH_SN_65536 2 -#define STB0899_SN_16384 (0x01 << 5) -#define STB0899_OFFST_SN_16384 5 -#define STB0899_WIDTH_SN_16384 1 -#define STB0899_SN_4096 (0x01 << 4) -#define STB0899_OFFST_SN_4096 4 -#define STB0899_WIDTH_SN_4096 1 -#define STB0899_SN_1024 (0x00 << 4) -#define STB0899_OFFST_SN_1024 4 -#define STB0899_WIDTH_SN_1024 0 -#define STB0899_TO_128 (0x03 << 2) -#define STB0899_OFFST_TO_128 2 -#define STB0899_WIDTH_TO_128 2 -#define STB0899_TO_64 (0x01 << 3) -#define STB0899_OFFST_TO_64 3 -#define STB0899_WIDTH_TO_64 1 -#define STB0899_TO_32 (0x01 << 2) -#define STB0899_OFFST_TO_32 2 -#define STB0899_WIDTH_TO_32 1 -#define STB0899_TO_16 (0x00 << 2) -#define STB0899_OFFST_TO_16 2 -#define STB0899_WIDTH_TO_16 0 -#define STB0899_HYST_128 (0x03 << 1) -#define STB0899_OFFST_HYST_128 1 -#define STB0899_WIDTH_HYST_128 2 -#define STB0899_HYST_64 (0x01 << 1) -#define STB0899_OFFST_HYST_64 1 -#define STB0899_WIDTH_HYST_64 1 -#define STB0899_HYST_32 (0x01 << 0) -#define STB0899_OFFST_HYST_32 0 -#define STB0899_WIDTH_HYST_32 1 -#define STB0899_HYST_16 (0x00 << 0) -#define STB0899_OFFST_HYST_16 0 -#define STB0899_WIDTH_HYST_16 0 - -#define STB0899_RSULC 0xf548 -#define STB0899_ULDIL_ON (0x01 << 7) -#define STB0899_OFFST_ULDIL_ON 7 -#define STB0899_WIDTH_ULDIL_ON 1 -#define STB0899_ULAUTO_ON (0x01 << 6) -#define STB0899_OFFST_ULAUTO_ON 6 -#define STB0899_WIDTH_ULAUTO_ON 1 -#define STB0899_ULRS_ON (0x01 << 5) -#define STB0899_OFFST_ULRS_ON 5 -#define STB0899_WIDTH_ULRS_ON 1 -#define STB0899_ULDESCRAM_ON (0x01 << 4) -#define STB0899_OFFST_ULDESCRAM_ON 4 -#define STB0899_WIDTH_ULDESCRAM_ON 1 -#define STB0899_UL_DISABLE (0x01 << 2) -#define STB0899_OFFST_UL_DISABLE 2 -#define STB0899_WIDTH_UL_DISABLE 1 -#define STB0899_NOFTHRESHOLD (0x01 << 0) -#define STB0899_OFFST_NOFTHRESHOLD 0 -#define STB0899_WIDTH_NOFTHRESHOLD 1 - -#define STB0899_RSLLC 0xf54a -#define STB0899_DEMAPVIT 0xf583 -#define STB0899_DEMAPVIT_RSVD (0x01 << 7) -#define STB0899_OFFST_DEMAPVIT_RSVD 7 -#define STB0899_WIDTH_DEMAPVIT_RSVD 1 -#define STB0899_DEMAPVIT_KDIVIDER (0x7f << 0) -#define STB0899_OFFST_DEMAPVIT_KDIVIDER 0 -#define STB0899_WIDTH_DEMAPVIT_KDIVIDER 7 - -#define STB0899_PLPARM 0xf58c -#define STB0899_VITMAPPING (0x07 << 5) -#define STB0899_OFFST_VITMAPPING 5 -#define STB0899_WIDTH_VITMAPPING 3 -#define STB0899_VITMAPPING_BPSK (0x01 << 5) -#define STB0899_OFFST_VITMAPPING_BPSK 5 -#define STB0899_WIDTH_VITMAPPING_BPSK 1 -#define STB0899_VITMAPPING_QPSK (0x00 << 5) -#define STB0899_OFFST_VITMAPPING_QPSK 5 -#define STB0899_WIDTH_VITMAPPING_QPSK 0 -#define STB0899_VITCURPUN (0x1f << 0) -#define STB0899_OFFST_VITCURPUN 0 -#define STB0899_WIDTH_VITCURPUN 5 -#define STB0899_VITCURPUN_1_2 (0x0d << 0) -#define STB0899_VITCURPUN_2_3 (0x12 << 0) -#define STB0899_VITCURPUN_3_4 (0x15 << 0) -#define STB0899_VITCURPUN_5_6 (0x18 << 0) -#define STB0899_VITCURPUN_6_7 (0x19 << 0) -#define STB0899_VITCURPUN_7_8 (0x1a << 0) - -/* S2 DEMOD */ -#define STB0899_OFF0_DMD_STATUS 0xf300 -#define STB0899_BASE_DMD_STATUS 0x00000000 -#define STB0899_IF_AGC_LOCK (0x01 << 8) -#define STB0899_OFFST_IF_AGC_LOCK 0 -#define STB0899_WIDTH_IF_AGC_LOCK 1 - -#define STB0899_OFF0_CRL_FREQ 0xf304 -#define STB0899_BASE_CRL_FREQ 0x00000000 -#define STB0899_CARR_FREQ (0x3fffffff << 0) -#define STB0899_OFFST_CARR_FREQ 0 -#define STB0899_WIDTH_CARR_FREQ 30 - -#define STB0899_OFF0_BTR_FREQ 0xf308 -#define STB0899_BASE_BTR_FREQ 0x00000000 -#define STB0899_BTR_FREQ (0xfffffff << 0) -#define STB0899_OFFST_BTR_FREQ 0 -#define STB0899_WIDTH_BTR_FREQ 28 - -#define STB0899_OFF0_IF_AGC_GAIN 0xf30c -#define STB0899_BASE_IF_AGC_GAIN 0x00000000 -#define STB0899_IF_AGC_GAIN (0x3fff < 0) -#define STB0899_OFFST_IF_AGC_GAIN 0 -#define STB0899_WIDTH_IF_AGC_GAIN 14 - -#define STB0899_OFF0_BB_AGC_GAIN 0xf310 -#define STB0899_BASE_BB_AGC_GAIN 0x00000000 -#define STB0899_BB_AGC_GAIN (0x3fff < 0) -#define STB0899_OFFST_BB_AGC_GAIN 0 -#define STB0899_WIDTH_BB_AGC_GAIN 14 - -#define STB0899_OFF0_DC_OFFSET 0xf314 -#define STB0899_BASE_DC_OFFSET 0x00000000 -#define STB0899_I (0xff < 8) -#define STB0899_OFFST_I 8 -#define STB0899_WIDTH_I 8 -#define STB0899_Q (0xff < 0) -#define STB0899_OFFST_Q 8 -#define STB0899_WIDTH_Q 8 - -#define STB0899_OFF0_DMD_CNTRL 0xf31c -#define STB0899_BASE_DMD_CNTRL 0x00000000 -#define STB0899_ADC0_PINS1IN (0x01 << 6) -#define STB0899_OFFST_ADC0_PINS1IN 6 -#define STB0899_WIDTH_ADC0_PINS1IN 1 -#define STB0899_IN2COMP1_OFFBIN0 (0x01 << 3) -#define STB0899_OFFST_IN2COMP1_OFFBIN0 3 -#define STB0899_WIDTH_IN2COMP1_OFFBIN0 1 -#define STB0899_DC_COMP (0x01 << 2) -#define STB0899_OFFST_DC_COMP 2 -#define STB0899_WIDTH_DC_COMP 1 -#define STB0899_MODMODE (0x03 << 0) -#define STB0899_OFFST_MODMODE 0 -#define STB0899_WIDTH_MODMODE 2 - -#define STB0899_OFF0_IF_AGC_CNTRL 0xf320 -#define STB0899_BASE_IF_AGC_CNTRL 0x00000000 -#define STB0899_IF_GAIN_INIT (0x3fff << 13) -#define STB0899_OFFST_IF_GAIN_INIT 13 -#define STB0899_WIDTH_IF_GAIN_INIT 14 -#define STB0899_IF_GAIN_SENSE (0x01 << 12) -#define STB0899_OFFST_IF_GAIN_SENSE 12 -#define STB0899_WIDTH_IF_GAIN_SENSE 1 -#define STB0899_IF_LOOP_GAIN (0x0f << 8) -#define STB0899_OFFST_IF_LOOP_GAIN 8 -#define STB0899_WIDTH_IF_LOOP_GAIN 4 -#define STB0899_IF_LD_GAIN_INIT (0x01 << 7) -#define STB0899_OFFST_IF_LD_GAIN_INIT 7 -#define STB0899_WIDTH_IF_LD_GAIN_INIT 1 -#define STB0899_IF_AGC_REF (0x7f << 0) -#define STB0899_OFFST_IF_AGC_REF 0 -#define STB0899_WIDTH_IF_AGC_REF 7 - -#define STB0899_OFF0_BB_AGC_CNTRL 0xf324 -#define STB0899_BASE_BB_AGC_CNTRL 0x00000000 -#define STB0899_BB_GAIN_INIT (0x3fff << 12) -#define STB0899_OFFST_BB_GAIN_INIT 12 -#define STB0899_WIDTH_BB_GAIN_INIT 14 -#define STB0899_BB_LOOP_GAIN (0x0f << 8) -#define STB0899_OFFST_BB_LOOP_GAIN 8 -#define STB0899_WIDTH_BB_LOOP_GAIN 4 -#define STB0899_BB_LD_GAIN_INIT (0x01 << 7) -#define STB0899_OFFST_BB_LD_GAIN_INIT 7 -#define STB0899_WIDTH_BB_LD_GAIN_INIT 1 -#define STB0899_BB_AGC_REF (0x7f << 0) -#define STB0899_OFFST_BB_AGC_REF 0 -#define STB0899_WIDTH_BB_AGC_REF 7 - -#define STB0899_OFF0_CRL_CNTRL 0xf328 -#define STB0899_BASE_CRL_CNTRL 0x00000000 -#define STB0899_CRL_LOCK_CLEAR (0x01 << 5) -#define STB0899_OFFST_CRL_LOCK_CLEAR 5 -#define STB0899_WIDTH_CRL_LOCK_CLEAR 1 -#define STB0899_CRL_SWPR_CLEAR (0x01 << 4) -#define STB0899_OFFST_CRL_SWPR_CLEAR 4 -#define STB0899_WIDTH_CRL_SWPR_CLEAR 1 -#define STB0899_CRL_SWP_ENA (0x01 << 3) -#define STB0899_OFFST_CRL_SWP_ENA 3 -#define STB0899_WIDTH_CRL_SWP_ENA 1 -#define STB0899_CRL_DET_SEL (0x01 << 2) -#define STB0899_OFFST_CRL_DET_SEL 2 -#define STB0899_WIDTH_CRL_DET_SEL 1 -#define STB0899_CRL_SENSE (0x01 << 1) -#define STB0899_OFFST_CRL_SENSE 1 -#define STB0899_WIDTH_CRL_SENSE 1 -#define STB0899_CRL_PHSERR_CLEAR (0x01 << 0) -#define STB0899_OFFST_CRL_PHSERR_CLEAR 0 -#define STB0899_WIDTH_CRL_PHSERR_CLEAR 1 - -#define STB0899_OFF0_CRL_PHS_INIT 0xf32c -#define STB0899_BASE_CRL_PHS_INIT 0x00000000 -#define STB0899_CRL_PHS_INIT_31 (0x1 << 30) -#define STB0899_OFFST_CRL_PHS_INIT_31 30 -#define STB0899_WIDTH_CRL_PHS_INIT_31 1 -#define STB0899_CRL_LD_INIT_PHASE (0x1 << 24) -#define STB0899_OFFST_CRL_LD_INIT_PHASE 24 -#define STB0899_WIDTH_CRL_LD_INIT_PHASE 1 -#define STB0899_CRL_INIT_PHASE (0xffffff << 0) -#define STB0899_OFFST_CRL_INIT_PHASE 0 -#define STB0899_WIDTH_CRL_INIT_PHASE 24 - -#define STB0899_OFF0_CRL_FREQ_INIT 0xf330 -#define STB0899_BASE_CRL_FREQ_INIT 0x00000000 -#define STB0899_CRL_FREQ_INIT_31 (0x1 << 30) -#define STB0899_OFFST_CRL_FREQ_INIT_31 30 -#define STB0899_WIDTH_CRL_FREQ_INIT_31 1 -#define STB0899_CRL_LD_FREQ_INIT (0x1 << 24) -#define STB0899_OFFST_CRL_LD_FREQ_INIT 24 -#define STB0899_WIDTH_CRL_LD_FREQ_INIT 1 -#define STB0899_CRL_FREQ_INIT (0xffffff << 0) -#define STB0899_OFFST_CRL_FREQ_INIT 0 -#define STB0899_WIDTH_CRL_FREQ_INIT 24 - -#define STB0899_OFF0_CRL_LOOP_GAIN 0xf334 -#define STB0899_BASE_CRL_LOOP_GAIN 0x00000000 -#define STB0899_KCRL2_RSHFT (0xf << 16) -#define STB0899_OFFST_KCRL2_RSHFT 16 -#define STB0899_WIDTH_KCRL2_RSHFT 4 -#define STB0899_KCRL1 (0xf << 12) -#define STB0899_OFFST_KCRL1 12 -#define STB0899_WIDTH_KCRL1 4 -#define STB0899_KCRL1_RSHFT (0xf << 8) -#define STB0899_OFFST_KCRL1_RSHFT 8 -#define STB0899_WIDTH_KCRL1_RSHFT 4 -#define STB0899_KCRL0 (0xf << 4) -#define STB0899_OFFST_KCRL0 4 -#define STB0899_WIDTH_KCRL0 4 -#define STB0899_KCRL0_RSHFT (0xf << 0) -#define STB0899_OFFST_KCRL0_RSHFT 0 -#define STB0899_WIDTH_KCRL0_RSHFT 4 - -#define STB0899_OFF0_CRL_NOM_FREQ 0xf338 -#define STB0899_BASE_CRL_NOM_FREQ 0x00000000 -#define STB0899_CRL_NOM_FREQ (0x3fffffff << 0) -#define STB0899_OFFST_CRL_NOM_FREQ 0 -#define STB0899_WIDTH_CRL_NOM_FREQ 30 - -#define STB0899_OFF0_CRL_SWP_RATE 0xf33c -#define STB0899_BASE_CRL_SWP_RATE 0x00000000 -#define STB0899_CRL_SWP_RATE (0x3fffffff << 0) -#define STB0899_OFFST_CRL_SWP_RATE 0 -#define STB0899_WIDTH_CRL_SWP_RATE 30 - -#define STB0899_OFF0_CRL_MAX_SWP 0xf340 -#define STB0899_BASE_CRL_MAX_SWP 0x00000000 -#define STB0899_CRL_MAX_SWP (0x3fffffff << 0) -#define STB0899_OFFST_CRL_MAX_SWP 0 -#define STB0899_WIDTH_CRL_MAX_SWP 30 - -#define STB0899_OFF0_CRL_LK_CNTRL 0xf344 -#define STB0899_BASE_CRL_LK_CNTRL 0x00000000 - -#define STB0899_OFF0_DECIM_CNTRL 0xf348 -#define STB0899_BASE_DECIM_CNTRL 0x00000000 -#define STB0899_BAND_LIMIT_B (0x01 << 5) -#define STB0899_OFFST_BAND_LIMIT_B 5 -#define STB0899_WIDTH_BAND_LIMIT_B 1 -#define STB0899_WIN_SEL (0x03 << 3) -#define STB0899_OFFST_WIN_SEL 3 -#define STB0899_WIDTH_WIN_SEL 2 -#define STB0899_DECIM_RATE (0x07 << 0) -#define STB0899_OFFST_DECIM_RATE 0 -#define STB0899_WIDTH_DECIM_RATE 3 - -#define STB0899_OFF0_BTR_CNTRL 0xf34c -#define STB0899_BASE_BTR_CNTRL 0x00000000 -#define STB0899_BTR_FREQ_CORR (0x7ff << 4) -#define STB0899_OFFST_BTR_FREQ_CORR 4 -#define STB0899_WIDTH_BTR_FREQ_CORR 11 -#define STB0899_BTR_CLR_LOCK (0x01 << 3) -#define STB0899_OFFST_BTR_CLR_LOCK 3 -#define STB0899_WIDTH_BTR_CLR_LOCK 1 -#define STB0899_BTR_SENSE (0x01 << 2) -#define STB0899_OFFST_BTR_SENSE 2 -#define STB0899_WIDTH_BTR_SENSE 1 -#define STB0899_BTR_ERR_ENA (0x01 << 1) -#define STB0899_OFFST_BTR_ERR_ENA 1 -#define STB0899_WIDTH_BTR_ERR_ENA 1 -#define STB0899_INTRP_PHS_SENSE (0x01 << 0) -#define STB0899_OFFST_INTRP_PHS_SENSE 0 -#define STB0899_WIDTH_INTRP_PHS_SENSE 1 - -#define STB0899_OFF0_BTR_LOOP_GAIN 0xf350 -#define STB0899_BASE_BTR_LOOP_GAIN 0x00000000 -#define STB0899_KBTR2_RSHFT (0x0f << 16) -#define STB0899_OFFST_KBTR2_RSHFT 16 -#define STB0899_WIDTH_KBTR2_RSHFT 4 -#define STB0899_KBTR1 (0x0f << 12) -#define STB0899_OFFST_KBTR1 12 -#define STB0899_WIDTH_KBTR1 4 -#define STB0899_KBTR1_RSHFT (0x0f << 8) -#define STB0899_OFFST_KBTR1_RSHFT 8 -#define STB0899_WIDTH_KBTR1_RSHFT 4 -#define STB0899_KBTR0 (0x0f << 4) -#define STB0899_OFFST_KBTR0 4 -#define STB0899_WIDTH_KBTR0 4 -#define STB0899_KBTR0_RSHFT (0x0f << 0) -#define STB0899_OFFST_KBTR0_RSHFT 0 -#define STB0899_WIDTH_KBTR0_RSHFT 4 - -#define STB0899_OFF0_BTR_PHS_INIT 0xf354 -#define STB0899_BASE_BTR_PHS_INIT 0x00000000 -#define STB0899_BTR_LD_PHASE_INIT (0x01 << 28) -#define STB0899_OFFST_BTR_LD_PHASE_INIT 28 -#define STB0899_WIDTH_BTR_LD_PHASE_INIT 1 -#define STB0899_BTR_INIT_PHASE (0xfffffff << 0) -#define STB0899_OFFST_BTR_INIT_PHASE 0 -#define STB0899_WIDTH_BTR_INIT_PHASE 28 - -#define STB0899_OFF0_BTR_FREQ_INIT 0xf358 -#define STB0899_BASE_BTR_FREQ_INIT 0x00000000 -#define STB0899_BTR_LD_FREQ_INIT (1 << 28) -#define STB0899_OFFST_BTR_LD_FREQ_INIT 28 -#define STB0899_WIDTH_BTR_LD_FREQ_INIT 1 -#define STB0899_BTR_FREQ_INIT (0xfffffff << 0) -#define STB0899_OFFST_BTR_FREQ_INIT 0 -#define STB0899_WIDTH_BTR_FREQ_INIT 28 - -#define STB0899_OFF0_BTR_NOM_FREQ 0xf35c -#define STB0899_BASE_BTR_NOM_FREQ 0x00000000 -#define STB0899_BTR_NOM_FREQ (0xfffffff << 0) -#define STB0899_OFFST_BTR_NOM_FREQ 0 -#define STB0899_WIDTH_BTR_NOM_FREQ 28 - -#define STB0899_OFF0_BTR_LK_CNTRL 0xf360 -#define STB0899_BASE_BTR_LK_CNTRL 0x00000000 -#define STB0899_BTR_MIN_ENERGY (0x0f << 24) -#define STB0899_OFFST_BTR_MIN_ENERGY 24 -#define STB0899_WIDTH_BTR_MIN_ENERGY 4 -#define STB0899_BTR_LOCK_TH_LO (0xff << 16) -#define STB0899_OFFST_BTR_LOCK_TH_LO 16 -#define STB0899_WIDTH_BTR_LOCK_TH_LO 8 -#define STB0899_BTR_LOCK_TH_HI (0xff << 8) -#define STB0899_OFFST_BTR_LOCK_TH_HI 8 -#define STB0899_WIDTH_BTR_LOCK_TH_HI 8 -#define STB0899_BTR_LOCK_GAIN (0x03 << 6) -#define STB0899_OFFST_BTR_LOCK_GAIN 6 -#define STB0899_WIDTH_BTR_LOCK_GAIN 2 -#define STB0899_BTR_LOCK_LEAK (0x3f << 0) -#define STB0899_OFFST_BTR_LOCK_LEAK 0 -#define STB0899_WIDTH_BTR_LOCK_LEAK 6 - -#define STB0899_OFF0_DECN_CNTRL 0xf364 -#define STB0899_BASE_DECN_CNTRL 0x00000000 - -#define STB0899_OFF0_TP_CNTRL 0xf368 -#define STB0899_BASE_TP_CNTRL 0x00000000 - -#define STB0899_OFF0_TP_BUF_STATUS 0xf36c -#define STB0899_BASE_TP_BUF_STATUS 0x00000000 -#define STB0899_TP_BUFFER_FULL (1 << 0) - -#define STB0899_OFF0_DC_ESTIM 0xf37c -#define STB0899_BASE_DC_ESTIM 0x0000 -#define STB0899_I_DC_ESTIMATE (0xff << 8) -#define STB0899_OFFST_I_DC_ESTIMATE 8 -#define STB0899_WIDTH_I_DC_ESTIMATE 8 -#define STB0899_Q_DC_ESTIMATE (0xff << 0) -#define STB0899_OFFST_Q_DC_ESTIMATE 0 -#define STB0899_WIDTH_Q_DC_ESTIMATE 8 - -#define STB0899_OFF0_FLL_CNTRL 0xf310 -#define STB0899_BASE_FLL_CNTRL 0x00000020 -#define STB0899_CRL_FLL_ACC (0x01 << 4) -#define STB0899_OFFST_CRL_FLL_ACC 4 -#define STB0899_WIDTH_CRL_FLL_ACC 1 -#define STB0899_FLL_AVG_PERIOD (0x0f << 0) -#define STB0899_OFFST_FLL_AVG_PERIOD 0 -#define STB0899_WIDTH_FLL_AVG_PERIOD 4 - -#define STB0899_OFF0_FLL_FREQ_WD 0xf314 -#define STB0899_BASE_FLL_FREQ_WD 0x00000020 -#define STB0899_FLL_FREQ_WD (0xffffffff << 0) -#define STB0899_OFFST_FLL_FREQ_WD 0 -#define STB0899_WIDTH_FLL_FREQ_WD 32 - -#define STB0899_OFF0_ANTI_ALIAS_SEL 0xf358 -#define STB0899_BASE_ANTI_ALIAS_SEL 0x00000020 -#define STB0899_ANTI_ALIAS_SELB (0x03 << 0) -#define STB0899_OFFST_ANTI_ALIAS_SELB 0 -#define STB0899_WIDTH_ANTI_ALIAS_SELB 2 - -#define STB0899_OFF0_RRC_ALPHA 0xf35c -#define STB0899_BASE_RRC_ALPHA 0x00000020 -#define STB0899_RRC_ALPHA (0x03 << 0) -#define STB0899_OFFST_RRC_ALPHA 0 -#define STB0899_WIDTH_RRC_ALPHA 2 - -#define STB0899_OFF0_DC_ADAPT_LSHFT 0xf360 -#define STB0899_BASE_DC_ADAPT_LSHFT 0x00000020 -#define STB0899_DC_ADAPT_LSHFT (0x077 << 0) -#define STB0899_OFFST_DC_ADAPT_LSHFT 0 -#define STB0899_WIDTH_DC_ADAPT_LSHFT 3 - -#define STB0899_OFF0_IMB_OFFSET 0xf364 -#define STB0899_BASE_IMB_OFFSET 0x00000020 -#define STB0899_PHS_IMB_COMP (0xff << 8) -#define STB0899_OFFST_PHS_IMB_COMP 8 -#define STB0899_WIDTH_PHS_IMB_COMP 8 -#define STB0899_AMPL_IMB_COMP (0xff << 0) -#define STB0899_OFFST_AMPL_IMB_COMP 0 -#define STB0899_WIDTH_AMPL_IMB_COMP 8 - -#define STB0899_OFF0_IMB_ESTIMATE 0xf368 -#define STB0899_BASE_IMB_ESTIMATE 0x00000020 -#define STB0899_PHS_IMB_ESTIMATE (0xff << 8) -#define STB0899_OFFST_PHS_IMB_ESTIMATE 8 -#define STB0899_WIDTH_PHS_IMB_ESTIMATE 8 -#define STB0899_AMPL_IMB_ESTIMATE (0xff << 0) -#define STB0899_OFFST_AMPL_IMB_ESTIMATE 0 -#define STB0899_WIDTH_AMPL_IMB_ESTIMATE 8 - -#define STB0899_OFF0_IMB_CNTRL 0xf36c -#define STB0899_BASE_IMB_CNTRL 0x00000020 -#define STB0899_PHS_ADAPT_LSHFT (0x07 << 4) -#define STB0899_OFFST_PHS_ADAPT_LSHFT 4 -#define STB0899_WIDTH_PHS_ADAPT_LSHFT 3 -#define STB0899_AMPL_ADAPT_LSHFT (0x07 << 1) -#define STB0899_OFFST_AMPL_ADAPT_LSHFT 1 -#define STB0899_WIDTH_AMPL_ADAPT_LSHFT 3 -#define STB0899_IMB_COMP (0x01 << 0) -#define STB0899_OFFST_IMB_COMP 0 -#define STB0899_WIDTH_IMB_COMP 1 - -#define STB0899_OFF0_IF_AGC_CNTRL2 0xf374 -#define STB0899_BASE_IF_AGC_CNTRL2 0x00000020 -#define STB0899_IF_AGC_LOCK_TH (0xff << 11) -#define STB0899_OFFST_IF_AGC_LOCK_TH 11 -#define STB0899_WIDTH_IF_AGC_LOCK_TH 8 -#define STB0899_IF_AGC_SD_DIV (0xff << 3) -#define STB0899_OFFST_IF_AGC_SD_DIV 3 -#define STB0899_WIDTH_IF_AGC_SD_DIV 8 -#define STB0899_IF_AGC_DUMP_PER (0x07 << 0) -#define STB0899_OFFST_IF_AGC_DUMP_PER 0 -#define STB0899_WIDTH_IF_AGC_DUMP_PER 3 - -#define STB0899_OFF0_DMD_CNTRL2 0xf378 -#define STB0899_BASE_DMD_CNTRL2 0x00000020 -#define STB0899_SPECTRUM_INVERT (0x01 << 2) -#define STB0899_OFFST_SPECTRUM_INVERT 2 -#define STB0899_WIDTH_SPECTRUM_INVERT 1 -#define STB0899_AGC_MODE (0x01 << 1) -#define STB0899_OFFST_AGC_MODE 1 -#define STB0899_WIDTH_AGC_MODE 1 -#define STB0899_CRL_FREQ_ADJ (0x01 << 0) -#define STB0899_OFFST_CRL_FREQ_ADJ 0 -#define STB0899_WIDTH_CRL_FREQ_ADJ 1 - -#define STB0899_OFF0_TP_BUFFER 0xf300 -#define STB0899_BASE_TP_BUFFER 0x00000040 -#define STB0899_TP_BUFFER_IN (0xffff << 0) -#define STB0899_OFFST_TP_BUFFER_IN 0 -#define STB0899_WIDTH_TP_BUFFER_IN 16 - -#define STB0899_OFF0_TP_BUFFER1 0xf304 -#define STB0899_BASE_TP_BUFFER1 0x00000040 -#define STB0899_OFF0_TP_BUFFER2 0xf308 -#define STB0899_BASE_TP_BUFFER2 0x00000040 -#define STB0899_OFF0_TP_BUFFER3 0xf30c -#define STB0899_BASE_TP_BUFFER3 0x00000040 -#define STB0899_OFF0_TP_BUFFER4 0xf310 -#define STB0899_BASE_TP_BUFFER4 0x00000040 -#define STB0899_OFF0_TP_BUFFER5 0xf314 -#define STB0899_BASE_TP_BUFFER5 0x00000040 -#define STB0899_OFF0_TP_BUFFER6 0xf318 -#define STB0899_BASE_TP_BUFFER6 0x00000040 -#define STB0899_OFF0_TP_BUFFER7 0xf31c -#define STB0899_BASE_TP_BUFFER7 0x00000040 -#define STB0899_OFF0_TP_BUFFER8 0xf320 -#define STB0899_BASE_TP_BUFFER8 0x00000040 -#define STB0899_OFF0_TP_BUFFER9 0xf324 -#define STB0899_BASE_TP_BUFFER9 0x00000040 -#define STB0899_OFF0_TP_BUFFER10 0xf328 -#define STB0899_BASE_TP_BUFFER10 0x00000040 -#define STB0899_OFF0_TP_BUFFER11 0xf32c -#define STB0899_BASE_TP_BUFFER11 0x00000040 -#define STB0899_OFF0_TP_BUFFER12 0xf330 -#define STB0899_BASE_TP_BUFFER12 0x00000040 -#define STB0899_OFF0_TP_BUFFER13 0xf334 -#define STB0899_BASE_TP_BUFFER13 0x00000040 -#define STB0899_OFF0_TP_BUFFER14 0xf338 -#define STB0899_BASE_TP_BUFFER14 0x00000040 -#define STB0899_OFF0_TP_BUFFER15 0xf33c -#define STB0899_BASE_TP_BUFFER15 0x00000040 -#define STB0899_OFF0_TP_BUFFER16 0xf340 -#define STB0899_BASE_TP_BUFFER16 0x00000040 -#define STB0899_OFF0_TP_BUFFER17 0xf344 -#define STB0899_BASE_TP_BUFFER17 0x00000040 -#define STB0899_OFF0_TP_BUFFER18 0xf348 -#define STB0899_BASE_TP_BUFFER18 0x00000040 -#define STB0899_OFF0_TP_BUFFER19 0xf34c -#define STB0899_BASE_TP_BUFFER19 0x00000040 -#define STB0899_OFF0_TP_BUFFER20 0xf350 -#define STB0899_BASE_TP_BUFFER20 0x00000040 -#define STB0899_OFF0_TP_BUFFER21 0xf354 -#define STB0899_BASE_TP_BUFFER21 0x00000040 -#define STB0899_OFF0_TP_BUFFER22 0xf358 -#define STB0899_BASE_TP_BUFFER22 0x00000040 -#define STB0899_OFF0_TP_BUFFER23 0xf35c -#define STB0899_BASE_TP_BUFFER23 0x00000040 -#define STB0899_OFF0_TP_BUFFER24 0xf360 -#define STB0899_BASE_TP_BUFFER24 0x00000040 -#define STB0899_OFF0_TP_BUFFER25 0xf364 -#define STB0899_BASE_TP_BUFFER25 0x00000040 -#define STB0899_OFF0_TP_BUFFER26 0xf368 -#define STB0899_BASE_TP_BUFFER26 0x00000040 -#define STB0899_OFF0_TP_BUFFER27 0xf36c -#define STB0899_BASE_TP_BUFFER27 0x00000040 -#define STB0899_OFF0_TP_BUFFER28 0xf370 -#define STB0899_BASE_TP_BUFFER28 0x00000040 -#define STB0899_OFF0_TP_BUFFER29 0xf374 -#define STB0899_BASE_TP_BUFFER29 0x00000040 -#define STB0899_OFF0_TP_BUFFER30 0xf378 -#define STB0899_BASE_TP_BUFFER30 0x00000040 -#define STB0899_OFF0_TP_BUFFER31 0xf37c -#define STB0899_BASE_TP_BUFFER31 0x00000040 -#define STB0899_OFF0_TP_BUFFER32 0xf300 -#define STB0899_BASE_TP_BUFFER32 0x00000060 -#define STB0899_OFF0_TP_BUFFER33 0xf304 -#define STB0899_BASE_TP_BUFFER33 0x00000060 -#define STB0899_OFF0_TP_BUFFER34 0xf308 -#define STB0899_BASE_TP_BUFFER34 0x00000060 -#define STB0899_OFF0_TP_BUFFER35 0xf30c -#define STB0899_BASE_TP_BUFFER35 0x00000060 -#define STB0899_OFF0_TP_BUFFER36 0xf310 -#define STB0899_BASE_TP_BUFFER36 0x00000060 -#define STB0899_OFF0_TP_BUFFER37 0xf314 -#define STB0899_BASE_TP_BUFFER37 0x00000060 -#define STB0899_OFF0_TP_BUFFER38 0xf318 -#define STB0899_BASE_TP_BUFFER38 0x00000060 -#define STB0899_OFF0_TP_BUFFER39 0xf31c -#define STB0899_BASE_TP_BUFFER39 0x00000060 -#define STB0899_OFF0_TP_BUFFER40 0xf320 -#define STB0899_BASE_TP_BUFFER40 0x00000060 -#define STB0899_OFF0_TP_BUFFER41 0xf324 -#define STB0899_BASE_TP_BUFFER41 0x00000060 -#define STB0899_OFF0_TP_BUFFER42 0xf328 -#define STB0899_BASE_TP_BUFFER42 0x00000060 -#define STB0899_OFF0_TP_BUFFER43 0xf32c -#define STB0899_BASE_TP_BUFFER43 0x00000060 -#define STB0899_OFF0_TP_BUFFER44 0xf330 -#define STB0899_BASE_TP_BUFFER44 0x00000060 -#define STB0899_OFF0_TP_BUFFER45 0xf334 -#define STB0899_BASE_TP_BUFFER45 0x00000060 -#define STB0899_OFF0_TP_BUFFER46 0xf338 -#define STB0899_BASE_TP_BUFFER46 0x00000060 -#define STB0899_OFF0_TP_BUFFER47 0xf33c -#define STB0899_BASE_TP_BUFFER47 0x00000060 -#define STB0899_OFF0_TP_BUFFER48 0xf340 -#define STB0899_BASE_TP_BUFFER48 0x00000060 -#define STB0899_OFF0_TP_BUFFER49 0xf344 -#define STB0899_BASE_TP_BUFFER49 0x00000060 -#define STB0899_OFF0_TP_BUFFER50 0xf348 -#define STB0899_BASE_TP_BUFFER50 0x00000060 -#define STB0899_OFF0_TP_BUFFER51 0xf34c -#define STB0899_BASE_TP_BUFFER51 0x00000060 -#define STB0899_OFF0_TP_BUFFER52 0xf350 -#define STB0899_BASE_TP_BUFFER52 0x00000060 -#define STB0899_OFF0_TP_BUFFER53 0xf354 -#define STB0899_BASE_TP_BUFFER53 0x00000060 -#define STB0899_OFF0_TP_BUFFER54 0xf358 -#define STB0899_BASE_TP_BUFFER54 0x00000060 -#define STB0899_OFF0_TP_BUFFER55 0xf35c -#define STB0899_BASE_TP_BUFFER55 0x00000060 -#define STB0899_OFF0_TP_BUFFER56 0xf360 -#define STB0899_BASE_TP_BUFFER56 0x00000060 -#define STB0899_OFF0_TP_BUFFER57 0xf364 -#define STB0899_BASE_TP_BUFFER57 0x00000060 -#define STB0899_OFF0_TP_BUFFER58 0xf368 -#define STB0899_BASE_TP_BUFFER58 0x00000060 -#define STB0899_OFF0_TP_BUFFER59 0xf36c -#define STB0899_BASE_TP_BUFFER59 0x00000060 -#define STB0899_OFF0_TP_BUFFER60 0xf370 -#define STB0899_BASE_TP_BUFFER60 0x00000060 -#define STB0899_OFF0_TP_BUFFER61 0xf374 -#define STB0899_BASE_TP_BUFFER61 0x00000060 -#define STB0899_OFF0_TP_BUFFER62 0xf378 -#define STB0899_BASE_TP_BUFFER62 0x00000060 -#define STB0899_OFF0_TP_BUFFER63 0xf37c -#define STB0899_BASE_TP_BUFFER63 0x00000060 - -#define STB0899_OFF0_RESET_CNTRL 0xf300 -#define STB0899_BASE_RESET_CNTRL 0x00000400 -#define STB0899_DVBS2_RESET (0x01 << 0) -#define STB0899_OFFST_DVBS2_RESET 0 -#define STB0899_WIDTH_DVBS2_RESET 1 - -#define STB0899_OFF0_ACM_ENABLE 0xf304 -#define STB0899_BASE_ACM_ENABLE 0x00000400 -#define STB0899_ACM_ENABLE 1 - -#define STB0899_OFF0_DESCR_CNTRL 0xf30c -#define STB0899_BASE_DESCR_CNTRL 0x00000400 -#define STB0899_OFFST_DESCR_CNTRL 0 -#define STB0899_WIDTH_DESCR_CNTRL 16 - -#define STB0899_OFF0_UWP_CNTRL1 0xf320 -#define STB0899_BASE_UWP_CNTRL1 0x00000400 -#define STB0899_UWP_TH_SOF (0x7fff << 11) -#define STB0899_OFFST_UWP_TH_SOF 11 -#define STB0899_WIDTH_UWP_TH_SOF 15 -#define STB0899_UWP_ESN0_QUANT (0xff << 3) -#define STB0899_OFFST_UWP_ESN0_QUANT 3 -#define STB0899_WIDTH_UWP_ESN0_QUANT 8 -#define STB0899_UWP_ESN0_AVE (0x03 << 1) -#define STB0899_OFFST_UWP_ESN0_AVE 1 -#define STB0899_WIDTH_UWP_ESN0_AVE 2 -#define STB0899_UWP_START (0x01 << 0) -#define STB0899_OFFST_UWP_START 0 -#define STB0899_WIDTH_UWP_START 1 - -#define STB0899_OFF0_UWP_CNTRL2 0xf324 -#define STB0899_BASE_UWP_CNTRL2 0x00000400 -#define STB0899_UWP_MISS_TH (0xff << 16) -#define STB0899_OFFST_UWP_MISS_TH 16 -#define STB0899_WIDTH_UWP_MISS_TH 8 -#define STB0899_FE_FINE_TRK (0xff << 8) -#define STB0899_OFFST_FE_FINE_TRK 8 -#define STB0899_WIDTH_FE_FINE_TRK 8 -#define STB0899_FE_COARSE_TRK (0xff << 0) -#define STB0899_OFFST_FE_COARSE_TRK 0 -#define STB0899_WIDTH_FE_COARSE_TRK 8 - -#define STB0899_OFF0_UWP_STAT1 0xf328 -#define STB0899_BASE_UWP_STAT1 0x00000400 -#define STB0899_UWP_STATE (0x03ff << 15) -#define STB0899_OFFST_UWP_STATE 15 -#define STB0899_WIDTH_UWP_STATE 10 -#define STB0899_UW_MAX_PEAK (0x7fff << 0) -#define STB0899_OFFST_UW_MAX_PEAK 0 -#define STB0899_WIDTH_UW_MAX_PEAK 15 - -#define STB0899_OFF0_UWP_STAT2 0xf32c -#define STB0899_BASE_UWP_STAT2 0x00000400 -#define STB0899_ESNO_EST (0x07ffff << 7) -#define STB0899_OFFST_ESN0_EST 7 -#define STB0899_WIDTH_ESN0_EST 19 -#define STB0899_UWP_DECODE_MOD (0x7f << 0) -#define STB0899_OFFST_UWP_DECODE_MOD 0 -#define STB0899_WIDTH_UWP_DECODE_MOD 7 - -#define STB0899_OFF0_DMD_CORE_ID 0xf334 -#define STB0899_BASE_DMD_CORE_ID 0x00000400 -#define STB0899_CORE_ID (0xffffffff << 0) -#define STB0899_OFFST_CORE_ID 0 -#define STB0899_WIDTH_CORE_ID 32 - -#define STB0899_OFF0_DMD_VERSION_ID 0xf33c -#define STB0899_BASE_DMD_VERSION_ID 0x00000400 -#define STB0899_VERSION_ID (0xff << 0) -#define STB0899_OFFST_VERSION_ID 0 -#define STB0899_WIDTH_VERSION_ID 8 - -#define STB0899_OFF0_DMD_STAT2 0xf340 -#define STB0899_BASE_DMD_STAT2 0x00000400 -#define STB0899_CSM_LOCK (0x01 << 1) -#define STB0899_OFFST_CSM_LOCK 1 -#define STB0899_WIDTH_CSM_LOCK 1 -#define STB0899_UWP_LOCK (0x01 << 0) -#define STB0899_OFFST_UWP_LOCK 0 -#define STB0899_WIDTH_UWP_LOCK 1 - -#define STB0899_OFF0_FREQ_ADJ_SCALE 0xf344 -#define STB0899_BASE_FREQ_ADJ_SCALE 0x00000400 -#define STB0899_FREQ_ADJ_SCALE (0x0fff << 0) -#define STB0899_OFFST_FREQ_ADJ_SCALE 0 -#define STB0899_WIDTH_FREQ_ADJ_SCALE 12 - -#define STB0899_OFF0_UWP_CNTRL3 0xf34c -#define STB0899_BASE_UWP_CNTRL3 0x00000400 -#define STB0899_UWP_TH_TRACK (0x7fff << 15) -#define STB0899_OFFST_UWP_TH_TRACK 15 -#define STB0899_WIDTH_UWP_TH_TRACK 15 -#define STB0899_UWP_TH_ACQ (0x7fff << 0) -#define STB0899_OFFST_UWP_TH_ACQ 0 -#define STB0899_WIDTH_UWP_TH_ACQ 15 - -#define STB0899_OFF0_SYM_CLK_SEL 0xf350 -#define STB0899_BASE_SYM_CLK_SEL 0x00000400 -#define STB0899_SYM_CLK_SEL (0x03 << 0) -#define STB0899_OFFST_SYM_CLK_SEL 0 -#define STB0899_WIDTH_SYM_CLK_SEL 2 - -#define STB0899_OFF0_SOF_SRCH_TO 0xf354 -#define STB0899_BASE_SOF_SRCH_TO 0x00000400 -#define STB0899_SOF_SEARCH_TIMEOUT (0x3fffff << 0) -#define STB0899_OFFST_SOF_SEARCH_TIMEOUT 0 -#define STB0899_WIDTH_SOF_SEARCH_TIMEOUT 22 - -#define STB0899_OFF0_ACQ_CNTRL1 0xf358 -#define STB0899_BASE_ACQ_CNTRL1 0x00000400 -#define STB0899_FE_FINE_ACQ (0xff << 8) -#define STB0899_OFFST_FE_FINE_ACQ 8 -#define STB0899_WIDTH_FE_FINE_ACQ 8 -#define STB0899_FE_COARSE_ACQ (0xff << 0) -#define STB0899_OFFST_FE_COARSE_ACQ 0 -#define STB0899_WIDTH_FE_COARSE_ACQ 8 - -#define STB0899_OFF0_ACQ_CNTRL2 0xf35c -#define STB0899_BASE_ACQ_CNTRL2 0x00000400 -#define STB0899_ZIGZAG (0x01 << 25) -#define STB0899_OFFST_ZIGZAG 25 -#define STB0899_WIDTH_ZIGZAG 1 -#define STB0899_NUM_STEPS (0xff << 17) -#define STB0899_OFFST_NUM_STEPS 17 -#define STB0899_WIDTH_NUM_STEPS 8 -#define STB0899_FREQ_STEPSIZE (0x1ffff << 0) -#define STB0899_OFFST_FREQ_STEPSIZE 0 -#define STB0899_WIDTH_FREQ_STEPSIZE 17 - -#define STB0899_OFF0_ACQ_CNTRL3 0xf360 -#define STB0899_BASE_ACQ_CNTRL3 0x00000400 -#define STB0899_THRESHOLD_SCL (0x3f << 23) -#define STB0899_OFFST_THRESHOLD_SCL 23 -#define STB0899_WIDTH_THRESHOLD_SCL 6 -#define STB0899_UWP_TH_SRCH (0x7fff << 8) -#define STB0899_OFFST_UWP_TH_SRCH 8 -#define STB0899_WIDTH_UWP_TH_SRCH 15 -#define STB0899_AUTO_REACQUIRE (0x01 << 7) -#define STB0899_OFFST_AUTO_REACQUIRE 7 -#define STB0899_WIDTH_AUTO_REACQUIRE 1 -#define STB0899_TRACK_LOCK_SEL (0x01 << 6) -#define STB0899_OFFST_TRACK_LOCK_SEL 6 -#define STB0899_WIDTH_TRACK_LOCK_SEL 1 -#define STB0899_ACQ_SEARCH_MODE (0x03 << 4) -#define STB0899_OFFST_ACQ_SEARCH_MODE 4 -#define STB0899_WIDTH_ACQ_SEARCH_MODE 2 -#define STB0899_CONFIRM_FRAMES (0x0f << 0) -#define STB0899_OFFST_CONFIRM_FRAMES 0 -#define STB0899_WIDTH_CONFIRM_FRAMES 4 - -#define STB0899_OFF0_FE_SETTLE 0xf364 -#define STB0899_BASE_FE_SETTLE 0x00000400 -#define STB0899_SETTLING_TIME (0x3fffff << 0) -#define STB0899_OFFST_SETTLING_TIME 0 -#define STB0899_WIDTH_SETTLING_TIME 22 - -#define STB0899_OFF0_AC_DWELL 0xf368 -#define STB0899_BASE_AC_DWELL 0x00000400 -#define STB0899_DWELL_TIME (0x3fffff << 0) -#define STB0899_OFFST_DWELL_TIME 0 -#define STB0899_WIDTH_DWELL_TIME 22 - -#define STB0899_OFF0_ACQUIRE_TRIG 0xf36c -#define STB0899_BASE_ACQUIRE_TRIG 0x00000400 -#define STB0899_ACQUIRE (0x01 << 0) -#define STB0899_OFFST_ACQUIRE 0 -#define STB0899_WIDTH_ACQUIRE 1 - -#define STB0899_OFF0_LOCK_LOST 0xf370 -#define STB0899_BASE_LOCK_LOST 0x00000400 -#define STB0899_LOCK_LOST (0x01 << 0) -#define STB0899_OFFST_LOCK_LOST 0 -#define STB0899_WIDTH_LOCK_LOST 1 - -#define STB0899_OFF0_ACQ_STAT1 0xf374 -#define STB0899_BASE_ACQ_STAT1 0x00000400 -#define STB0899_STEP_FREQ (0x1fffff << 11) -#define STB0899_OFFST_STEP_FREQ 11 -#define STB0899_WIDTH_STEP_FREQ 21 -#define STB0899_ACQ_STATE (0x07 << 8) -#define STB0899_OFFST_ACQ_STATE 8 -#define STB0899_WIDTH_ACQ_STATE 3 -#define STB0899_UW_DETECT_COUNT (0xff << 0) -#define STB0899_OFFST_UW_DETECT_COUNT 0 -#define STB0899_WIDTH_UW_DETECT_COUNT 8 - -#define STB0899_OFF0_ACQ_TIMEOUT 0xf378 -#define STB0899_BASE_ACQ_TIMEOUT 0x00000400 -#define STB0899_ACQ_TIMEOUT (0x3fffff << 0) -#define STB0899_OFFST_ACQ_TIMEOUT 0 -#define STB0899_WIDTH_ACQ_TIMEOUT 22 - -#define STB0899_OFF0_ACQ_TIME 0xf37c -#define STB0899_BASE_ACQ_TIME 0x00000400 -#define STB0899_ACQ_TIME_SYM (0xffffff << 0) -#define STB0899_OFFST_ACQ_TIME_SYM 0 -#define STB0899_WIDTH_ACQ_TIME_SYM 24 - -#define STB0899_OFF0_FINAL_AGC_CNTRL 0xf308 -#define STB0899_BASE_FINAL_AGC_CNTRL 0x00000440 -#define STB0899_FINAL_GAIN_INIT (0x3fff << 12) -#define STB0899_OFFST_FINAL_GAIN_INIT 12 -#define STB0899_WIDTH_FINAL_GAIN_INIT 14 -#define STB0899_FINAL_LOOP_GAIN (0x0f << 8) -#define STB0899_OFFST_FINAL_LOOP_GAIN 8 -#define STB0899_WIDTH_FINAL_LOOP_GAIN 4 -#define STB0899_FINAL_LD_GAIN_INIT (0x01 << 7) -#define STB0899_OFFST_FINAL_LD_GAIN_INIT 7 -#define STB0899_WIDTH_FINAL_LD_GAIN_INIT 1 -#define STB0899_FINAL_AGC_REF (0x7f << 0) -#define STB0899_OFFST_FINAL_AGC_REF 0 -#define STB0899_WIDTH_FINAL_AGC_REF 7 - -#define STB0899_OFF0_FINAL_AGC_GAIN 0xf30c -#define STB0899_BASE_FINAL_AGC_GAIN 0x00000440 -#define STB0899_FINAL_AGC_GAIN (0x3fff << 0) -#define STB0899_OFFST_FINAL_AGC_GAIN 0 -#define STB0899_WIDTH_FINAL_AGC_GAIN 14 - -#define STB0899_OFF0_EQUALIZER_INIT 0xf310 -#define STB0899_BASE_EQUALIZER_INIT 0x00000440 -#define STB0899_EQ_SRST (0x01 << 1) -#define STB0899_OFFST_EQ_SRST 1 -#define STB0899_WIDTH_EQ_SRST 1 -#define STB0899_EQ_INIT (0x01 << 0) -#define STB0899_OFFST_EQ_INIT 0 -#define STB0899_WIDTH_EQ_INIT 1 - -#define STB0899_OFF0_EQ_CNTRL 0xf314 -#define STB0899_BASE_EQ_CNTRL 0x00000440 -#define STB0899_EQ_ADAPT_MODE (0x01 << 18) -#define STB0899_OFFST_EQ_ADAPT_MODE 18 -#define STB0899_WIDTH_EQ_ADAPT_MODE 1 -#define STB0899_EQ_DELAY (0x0f << 14) -#define STB0899_OFFST_EQ_DELAY 14 -#define STB0899_WIDTH_EQ_DELAY 4 -#define STB0899_EQ_QUANT_LEVEL (0xff << 6) -#define STB0899_OFFST_EQ_QUANT_LEVEL 6 -#define STB0899_WIDTH_EQ_QUANT_LEVEL 8 -#define STB0899_EQ_DISABLE_UPDATE (0x01 << 5) -#define STB0899_OFFST_EQ_DISABLE_UPDATE 5 -#define STB0899_WIDTH_EQ_DISABLE_UPDATE 1 -#define STB0899_EQ_BYPASS (0x01 << 4) -#define STB0899_OFFST_EQ_BYPASS 4 -#define STB0899_WIDTH_EQ_BYPASS 1 -#define STB0899_EQ_SHIFT (0x0f << 0) -#define STB0899_OFFST_EQ_SHIFT 0 -#define STB0899_WIDTH_EQ_SHIFT 4 - -#define STB0899_OFF0_EQ_I_INIT_COEFF_0 0xf320 -#define STB0899_OFF1_EQ_I_INIT_COEFF_1 0xf324 -#define STB0899_OFF2_EQ_I_INIT_COEFF_2 0xf328 -#define STB0899_OFF3_EQ_I_INIT_COEFF_3 0xf32c -#define STB0899_OFF4_EQ_I_INIT_COEFF_4 0xf330 -#define STB0899_OFF5_EQ_I_INIT_COEFF_5 0xf334 -#define STB0899_OFF6_EQ_I_INIT_COEFF_6 0xf338 -#define STB0899_OFF7_EQ_I_INIT_COEFF_7 0xf33c -#define STB0899_OFF8_EQ_I_INIT_COEFF_8 0xf340 -#define STB0899_OFF9_EQ_I_INIT_COEFF_9 0xf344 -#define STB0899_OFFa_EQ_I_INIT_COEFF_10 0xf348 -#define STB0899_BASE_EQ_I_INIT_COEFF_N 0x00000440 -#define STB0899_EQ_I_INIT_COEFF_N (0x0fff << 0) -#define STB0899_OFFST_EQ_I_INIT_COEFF_N 0 -#define STB0899_WIDTH_EQ_I_INIT_COEFF_N 12 - -#define STB0899_OFF0_EQ_Q_INIT_COEFF_0 0xf350 -#define STB0899_OFF1_EQ_Q_INIT_COEFF_1 0xf354 -#define STB0899_OFF2_EQ_Q_INIT_COEFF_2 0xf358 -#define STB0899_OFF3_EQ_Q_INIT_COEFF_3 0xf35c -#define STB0899_OFF4_EQ_Q_INIT_COEFF_4 0xf360 -#define STB0899_OFF5_EQ_Q_INIT_COEFF_5 0xf364 -#define STB0899_OFF6_EQ_Q_INIT_COEFF_6 0xf368 -#define STB0899_OFF7_EQ_Q_INIT_COEFF_7 0xf36c -#define STB0899_OFF8_EQ_Q_INIT_COEFF_8 0xf370 -#define STB0899_OFF9_EQ_Q_INIT_COEFF_9 0xf374 -#define STB0899_OFFa_EQ_Q_INIT_COEFF_10 0xf378 -#define STB0899_BASE_EQ_Q_INIT_COEFF_N 0x00000440 -#define STB0899_EQ_Q_INIT_COEFF_N (0x0fff << 0) -#define STB0899_OFFST_EQ_Q_INIT_COEFF_N 0 -#define STB0899_WIDTH_EQ_Q_INIT_COEFF_N 12 - -#define STB0899_OFF0_EQ_I_OUT_COEFF_0 0xf300 -#define STB0899_OFF1_EQ_I_OUT_COEFF_1 0xf304 -#define STB0899_OFF2_EQ_I_OUT_COEFF_2 0xf308 -#define STB0899_OFF3_EQ_I_OUT_COEFF_3 0xf30c -#define STB0899_OFF4_EQ_I_OUT_COEFF_4 0xf310 -#define STB0899_OFF5_EQ_I_OUT_COEFF_5 0xf314 -#define STB0899_OFF6_EQ_I_OUT_COEFF_6 0xf318 -#define STB0899_OFF7_EQ_I_OUT_COEFF_7 0xf31c -#define STB0899_OFF8_EQ_I_OUT_COEFF_8 0xf320 -#define STB0899_OFF9_EQ_I_OUT_COEFF_9 0xf324 -#define STB0899_OFFa_EQ_I_OUT_COEFF_10 0xf328 -#define STB0899_BASE_EQ_I_OUT_COEFF_N 0x00000460 -#define STB0899_EQ_I_OUT_COEFF_N (0x0fff << 0) -#define STB0899_OFFST_EQ_I_OUT_COEFF_N 0 -#define STB0899_WIDTH_EQ_I_OUT_COEFF_N 12 - -#define STB0899_OFF0_EQ_Q_OUT_COEFF_0 0xf330 -#define STB0899_OFF1_EQ_Q_OUT_COEFF_1 0xf334 -#define STB0899_OFF2_EQ_Q_OUT_COEFF_2 0xf338 -#define STB0899_OFF3_EQ_Q_OUT_COEFF_3 0xf33c -#define STB0899_OFF4_EQ_Q_OUT_COEFF_4 0xf340 -#define STB0899_OFF5_EQ_Q_OUT_COEFF_5 0xf344 -#define STB0899_OFF6_EQ_Q_OUT_COEFF_6 0xf348 -#define STB0899_OFF7_EQ_Q_OUT_COEFF_7 0xf34c -#define STB0899_OFF8_EQ_Q_OUT_COEFF_8 0xf350 -#define STB0899_OFF9_EQ_Q_OUT_COEFF_9 0xf354 -#define STB0899_OFFa_EQ_Q_OUT_COEFF_10 0xf358 -#define STB0899_BASE_EQ_Q_OUT_COEFF_N 0x00000460 -#define STB0899_EQ_Q_OUT_COEFF_N (0x0fff << 0) -#define STB0899_OFFST_EQ_Q_OUT_COEFF_N 0 -#define STB0899_WIDTH_EQ_Q_OUT_COEFF_N 12 - -/* S2 FEC */ -#define STB0899_OFF0_BLOCK_LNGTH 0xfa04 -#define STB0899_BASE_BLOCK_LNGTH 0x00000000 -#define STB0899_BLOCK_LENGTH (0xff << 0) -#define STB0899_OFFST_BLOCK_LENGTH 0 -#define STB0899_WIDTH_BLOCK_LENGTH 8 - -#define STB0899_OFF0_ROW_STR 0xfa08 -#define STB0899_BASE_ROW_STR 0x00000000 -#define STB0899_ROW_STRIDE (0xff << 0) -#define STB0899_OFFST_ROW_STRIDE 0 -#define STB0899_WIDTH_ROW_STRIDE 8 - -#define STB0899_OFF0_MAX_ITER 0xfa0c -#define STB0899_BASE_MAX_ITER 0x00000000 -#define STB0899_MAX_ITERATIONS (0xff << 0) -#define STB0899_OFFST_MAX_ITERATIONS 0 -#define STB0899_WIDTH_MAX_ITERATIONS 8 - -#define STB0899_OFF0_BN_END_ADDR 0xfa10 -#define STB0899_BASE_BN_END_ADDR 0x00000000 -#define STB0899_BN_END_ADDR (0x0fff << 0) -#define STB0899_OFFST_BN_END_ADDR 0 -#define STB0899_WIDTH_BN_END_ADDR 12 - -#define STB0899_OFF0_CN_END_ADDR 0xfa14 -#define STB0899_BASE_CN_END_ADDR 0x00000000 -#define STB0899_CN_END_ADDR (0x0fff << 0) -#define STB0899_OFFST_CN_END_ADDR 0 -#define STB0899_WIDTH_CN_END_ADDR 12 - -#define STB0899_OFF0_INFO_LENGTH 0xfa1c -#define STB0899_BASE_INFO_LENGTH 0x00000000 -#define STB0899_INFO_LENGTH (0xff << 0) -#define STB0899_OFFST_INFO_LENGTH 0 -#define STB0899_WIDTH_INFO_LENGTH 8 - -#define STB0899_OFF0_BOT_ADDR 0xfa20 -#define STB0899_BASE_BOT_ADDR 0x00000000 -#define STB0899_BOTTOM_BASE_ADDR (0x03ff << 0) -#define STB0899_OFFST_BOTTOM_BASE_ADDR 0 -#define STB0899_WIDTH_BOTTOM_BASE_ADDR 10 - -#define STB0899_OFF0_BCH_BLK_LN 0xfa24 -#define STB0899_BASE_BCH_BLK_LN 0x00000000 -#define STB0899_BCH_BLOCK_LENGTH (0xffff << 0) -#define STB0899_OFFST_BCH_BLOCK_LENGTH 0 -#define STB0899_WIDTH_BCH_BLOCK_LENGTH 16 - -#define STB0899_OFF0_BCH_T 0xfa28 -#define STB0899_BASE_BCH_T 0x00000000 -#define STB0899_BCH_T (0x0f << 0) -#define STB0899_OFFST_BCH_T 0 -#define STB0899_WIDTH_BCH_T 4 - -#define STB0899_OFF0_CNFG_MODE 0xfa00 -#define STB0899_BASE_CNFG_MODE 0x00000800 -#define STB0899_MODCOD (0x1f << 2) -#define STB0899_OFFST_MODCOD 2 -#define STB0899_WIDTH_MODCOD 5 -#define STB0899_MODCOD_SEL (0x01 << 1) -#define STB0899_OFFST_MODCOD_SEL 1 -#define STB0899_WIDTH_MODCOD_SEL 1 -#define STB0899_CONFIG_MODE (0x01 << 0) -#define STB0899_OFFST_CONFIG_MODE 0 -#define STB0899_WIDTH_CONFIG_MODE 1 - -#define STB0899_OFF0_LDPC_STAT 0xfa04 -#define STB0899_BASE_LDPC_STAT 0x00000800 -#define STB0899_ITERATION (0xff << 3) -#define STB0899_OFFST_ITERATION 3 -#define STB0899_WIDTH_ITERATION 8 -#define STB0899_LDPC_DEC_STATE (0x07 << 0) -#define STB0899_OFFST_LDPC_DEC_STATE 0 -#define STB0899_WIDTH_LDPC_DEC_STATE 3 - -#define STB0899_OFF0_ITER_SCALE 0xfa08 -#define STB0899_BASE_ITER_SCALE 0x00000800 -#define STB0899_ITERATION_SCALE (0xff << 0) -#define STB0899_OFFST_ITERATION_SCALE 0 -#define STB0899_WIDTH_ITERATION_SCALE 8 - -#define STB0899_OFF0_INPUT_MODE 0xfa0c -#define STB0899_BASE_INPUT_MODE 0x00000800 -#define STB0899_SD_BLOCK1_STREAM0 (0x01 << 0) -#define STB0899_OFFST_SD_BLOCK1_STREAM0 0 -#define STB0899_WIDTH_SD_BLOCK1_STREAM0 1 - -#define STB0899_OFF0_LDPCDECRST 0xfa10 -#define STB0899_BASE_LDPCDECRST 0x00000800 -#define STB0899_LDPC_DEC_RST (0x01 << 0) -#define STB0899_OFFST_LDPC_DEC_RST 0 -#define STB0899_WIDTH_LDPC_DEC_RST 1 - -#define STB0899_OFF0_CLK_PER_BYTE_RW 0xfa14 -#define STB0899_BASE_CLK_PER_BYTE_RW 0x00000800 -#define STB0899_CLKS_PER_BYTE (0x0f << 0) -#define STB0899_OFFST_CLKS_PER_BYTE 0 -#define STB0899_WIDTH_CLKS_PER_BYTE 5 - -#define STB0899_OFF0_BCH_ERRORS 0xfa18 -#define STB0899_BASE_BCH_ERRORS 0x00000800 -#define STB0899_BCH_ERRORS (0x0f << 0) -#define STB0899_OFFST_BCH_ERRORS 0 -#define STB0899_WIDTH_BCH_ERRORS 4 - -#define STB0899_OFF0_LDPC_ERRORS 0xfa1c -#define STB0899_BASE_LDPC_ERRORS 0x00000800 -#define STB0899_LDPC_ERRORS (0xffff << 0) -#define STB0899_OFFST_LDPC_ERRORS 0 -#define STB0899_WIDTH_LDPC_ERRORS 16 - -#define STB0899_OFF0_BCH_MODE 0xfa20 -#define STB0899_BASE_BCH_MODE 0x00000800 -#define STB0899_BCH_CORRECT_N (0x01 << 1) -#define STB0899_OFFST_BCH_CORRECT_N 1 -#define STB0899_WIDTH_BCH_CORRECT_N 1 -#define STB0899_FULL_BYPASS (0x01 << 0) -#define STB0899_OFFST_FULL_BYPASS 0 -#define STB0899_WIDTH_FULL_BYPASS 1 - -#define STB0899_OFF0_ERR_ACC_PER 0xfa24 -#define STB0899_BASE_ERR_ACC_PER 0x00000800 -#define STB0899_BCH_ERR_ACC_PERIOD (0x0f << 0) -#define STB0899_OFFST_BCH_ERR_ACC_PERIOD 0 -#define STB0899_WIDTH_BCH_ERR_ACC_PERIOD 4 - -#define STB0899_OFF0_BCH_ERR_ACC 0xfa28 -#define STB0899_BASE_BCH_ERR_ACC 0x00000800 -#define STB0899_BCH_ERR_ACCUM (0xff << 0) -#define STB0899_OFFST_BCH_ERR_ACCUM 0 -#define STB0899_WIDTH_BCH_ERR_ACCUM 8 - -#define STB0899_OFF0_FEC_CORE_ID_REG 0xfa2c -#define STB0899_BASE_FEC_CORE_ID_REG 0x00000800 -#define STB0899_FEC_CORE_ID (0xffffffff << 0) -#define STB0899_OFFST_FEC_CORE_ID 0 -#define STB0899_WIDTH_FEC_CORE_ID 32 - -#define STB0899_OFF0_FEC_VER_ID_REG 0xfa34 -#define STB0899_BASE_FEC_VER_ID_REG 0x00000800 -#define STB0899_FEC_VER_ID (0xff << 0) -#define STB0899_OFFST_FEC_VER_ID 0 -#define STB0899_WIDTH_FEC_VER_ID 8 - -#define STB0899_OFF0_FEC_TP_SEL 0xfa38 -#define STB0899_BASE_FEC_TP_SEL 0x00000800 - -#define STB0899_OFF0_CSM_CNTRL1 0xf310 -#define STB0899_BASE_CSM_CNTRL1 0x00000400 -#define STB0899_CSM_FORCE_FREQLOCK (0x01 << 19) -#define STB0899_OFFST_CSM_FORCE_FREQLOCK 19 -#define STB0899_WIDTH_CSM_FORCE_FREQLOCK 1 -#define STB0899_CSM_FREQ_LOCKSTATE (0x01 << 18) -#define STB0899_OFFST_CSM_FREQ_LOCKSTATE 18 -#define STB0899_WIDTH_CSM_FREQ_LOCKSTATE 1 -#define STB0899_CSM_AUTO_PARAM (0x01 << 17) -#define STB0899_OFFST_CSM_AUTO_PARAM 17 -#define STB0899_WIDTH_CSM_AUTO_PARAM 1 -#define STB0899_FE_LOOP_SHIFT (0x07 << 14) -#define STB0899_OFFST_FE_LOOP_SHIFT 14 -#define STB0899_WIDTH_FE_LOOP_SHIFT 3 -#define STB0899_CSM_AGC_SHIFT (0x07 << 11) -#define STB0899_OFFST_CSM_AGC_SHIFT 11 -#define STB0899_WIDTH_CSM_AGC_SHIFT 3 -#define STB0899_CSM_AGC_GAIN (0x1ff << 2) -#define STB0899_OFFST_CSM_AGC_GAIN 2 -#define STB0899_WIDTH_CSM_AGC_GAIN 9 -#define STB0899_CSM_TWO_PASS (0x01 << 1) -#define STB0899_OFFST_CSM_TWO_PASS 1 -#define STB0899_WIDTH_CSM_TWO_PASS 1 -#define STB0899_CSM_DVT_TABLE (0x01 << 0) -#define STB0899_OFFST_CSM_DVT_TABLE 0 -#define STB0899_WIDTH_CSM_DVT_TABLE 1 - -#define STB0899_OFF0_CSM_CNTRL2 0xf314 -#define STB0899_BASE_CSM_CNTRL2 0x00000400 -#define STB0899_CSM_GAMMA_RHO_ACQ (0x1ff << 9) -#define STB0899_OFFST_CSM_GAMMA_RHOACQ 9 -#define STB0899_WIDTH_CSM_GAMMA_RHOACQ 9 -#define STB0899_CSM_GAMMA_ACQ (0x1ff << 0) -#define STB0899_OFFST_CSM_GAMMA_ACQ 0 -#define STB0899_WIDTH_CSM_GAMMA_ACQ 9 - -#define STB0899_OFF0_CSM_CNTRL3 0xf318 -#define STB0899_BASE_CSM_CNTRL3 0x00000400 -#define STB0899_CSM_GAMMA_RHO_TRACK (0x1ff << 9) -#define STB0899_OFFST_CSM_GAMMA_RHOTRACK 9 -#define STB0899_WIDTH_CSM_GAMMA_RHOTRACK 9 -#define STB0899_CSM_GAMMA_TRACK (0x1ff << 0) -#define STB0899_OFFST_CSM_GAMMA_TRACK 0 -#define STB0899_WIDTH_CSM_GAMMA_TRACK 9 - -#define STB0899_OFF0_CSM_CNTRL4 0xf31c -#define STB0899_BASE_CSM_CNTRL4 0x00000400 -#define STB0899_CSM_PHASEDIFF_THRESH (0x0f << 8) -#define STB0899_OFFST_CSM_PHASEDIFF_THRESH 8 -#define STB0899_WIDTH_CSM_PHASEDIFF_THRESH 4 -#define STB0899_CSM_LOCKCOUNT_THRESH (0xff << 0) -#define STB0899_OFFST_CSM_LOCKCOUNT_THRESH 0 -#define STB0899_WIDTH_CSM_LOCKCOUNT_THRESH 8 - -/* Check on chapter 8 page 42 */ -#define STB0899_ERRCTRL1 0xf574 -#define STB0899_ERRCTRL2 0xf575 -#define STB0899_ERRCTRL3 0xf576 -#define STB0899_ERR_SRC_S1 (0x1f << 3) -#define STB0899_OFFST_ERR_SRC_S1 3 -#define STB0899_WIDTH_ERR_SRC_S1 5 -#define STB0899_ERR_SRC_S2 (0x0f << 0) -#define STB0899_OFFST_ERR_SRC_S2 0 -#define STB0899_WIDTH_ERR_SRC_S2 4 -#define STB0899_NOE (0x07 << 0) -#define STB0899_OFFST_NOE 0 -#define STB0899_WIDTH_NOE 3 - -#define STB0899_ECNT1M 0xf524 -#define STB0899_ECNT1L 0xf525 -#define STB0899_ECNT2M 0xf526 -#define STB0899_ECNT2L 0xf527 -#define STB0899_ECNT3M 0xf528 -#define STB0899_ECNT3L 0xf529 - -#define STB0899_DMONMSK1 0xf57b -#define STB0899_DMONMSK1_WAIT_1STEP (1 << 7) -#define STB0899_DMONMSK1_FREE_14 (1 << 6) -#define STB0899_DMONMSK1_AVRGVIT_CALC (1 << 5) -#define STB0899_DMONMSK1_FREE_12 (1 << 4) -#define STB0899_DMONMSK1_FREE_11 (1 << 3) -#define STB0899_DMONMSK1_B0DIV_CALC (1 << 2) -#define STB0899_DMONMSK1_KDIVB1_CALC (1 << 1) -#define STB0899_DMONMSK1_KDIVB2_CALC (1 << 0) - -#define STB0899_DMONMSK0 0xf57c -#define STB0899_DMONMSK0_SMOTTH_CALC (1 << 7) -#define STB0899_DMONMSK0_FREE_6 (1 << 6) -#define STB0899_DMONMSK0_SIGPOWER_CALC (1 << 5) -#define STB0899_DMONMSK0_QSEUIL_CALC (1 << 4) -#define STB0899_DMONMSK0_FREE_3 (1 << 3) -#define STB0899_DMONMSK0_FREE_2 (1 << 2) -#define STB0899_DMONMSK0_KVDIVB1_CALC (1 << 1) -#define STB0899_DMONMSK0_KVDIVB2_CALC (1 << 0) - -#define STB0899_TSULC 0xf549 -#define STB0899_ULNOSYNCBYTES (0x01 << 7) -#define STB0899_OFFST_ULNOSYNCBYTES 7 -#define STB0899_WIDTH_ULNOSYNCBYTES 1 -#define STB0899_ULPARITY_ON (0x01 << 6) -#define STB0899_OFFST_ULPARITY_ON 6 -#define STB0899_WIDTH_ULPARITY_ON 1 -#define STB0899_ULSYNCOUTRS (0x01 << 5) -#define STB0899_OFFST_ULSYNCOUTRS 5 -#define STB0899_WIDTH_ULSYNCOUTRS 1 -#define STB0899_ULDSS_PACKETS (0x01 << 0) -#define STB0899_OFFST_ULDSS_PACKETS 0 -#define STB0899_WIDTH_ULDSS_PACKETS 1 - -#define STB0899_TSLPL 0xf54b -#define STB0899_LLDVBS2_MODE (0x01 << 4) -#define STB0899_OFFST_LLDVBS2_MODE 4 -#define STB0899_WIDTH_LLDVBS2_MODE 1 -#define STB0899_LLISSYI_ON (0x01 << 3) -#define STB0899_OFFST_LLISSYI_ON 3 -#define STB0899_WIDTH_LLISSYI_ON 1 -#define STB0899_LLNPD_ON (0x01 << 2) -#define STB0899_OFFST_LLNPD_ON 2 -#define STB0899_WIDTH_LLNPD_ON 1 -#define STB0899_LLCRC8_ON (0x01 << 1) -#define STB0899_OFFST_LLCRC8_ON 1 -#define STB0899_WIDTH_LLCRC8_ON 1 - -#define STB0899_TSCFGH 0xf54c -#define STB0899_OUTRS_PS (0x01 << 6) -#define STB0899_OFFST_OUTRS_PS 6 -#define STB0899_WIDTH_OUTRS_PS 1 -#define STB0899_SYNCBYTE (0x01 << 5) -#define STB0899_OFFST_SYNCBYTE 5 -#define STB0899_WIDTH_SYNCBYTE 1 -#define STB0899_PFBIT (0x01 << 4) -#define STB0899_OFFST_PFBIT 4 -#define STB0899_WIDTH_PFBIT 1 -#define STB0899_ERR_BIT (0x01 << 3) -#define STB0899_OFFST_ERR_BIT 3 -#define STB0899_WIDTH_ERR_BIT 1 -#define STB0899_MPEG (0x01 << 2) -#define STB0899_OFFST_MPEG 2 -#define STB0899_WIDTH_MPEG 1 -#define STB0899_CLK_POL (0x01 << 1) -#define STB0899_OFFST_CLK_POL 1 -#define STB0899_WIDTH_CLK_POL 1 -#define STB0899_FORCE0 (0x01 << 0) -#define STB0899_OFFST_FORCE0 0 -#define STB0899_WIDTH_FORCE0 1 - -#define STB0899_TSCFGM 0xf54d -#define STB0899_LLPRIORITY (0x01 << 3) -#define STB0899_OFFST_LLPRIORIY 3 -#define STB0899_WIDTH_LLPRIORITY 1 -#define STB0899_EN188 (0x01 << 2) -#define STB0899_OFFST_EN188 2 -#define STB0899_WIDTH_EN188 1 - -#define STB0899_TSCFGL 0xf54e -#define STB0899_DEL_ERRPCK (0x01 << 7) -#define STB0899_OFFST_DEL_ERRPCK 7 -#define STB0899_WIDTH_DEL_ERRPCK 1 -#define STB0899_ERRFLAGSTD (0x01 << 5) -#define STB0899_OFFST_ERRFLAGSTD 5 -#define STB0899_WIDTH_ERRFLAGSTD 1 -#define STB0899_MPEGERR (0x01 << 4) -#define STB0899_OFFST_MPEGERR 4 -#define STB0899_WIDTH_MPEGERR 1 -#define STB0899_BCH_CHK (0x01 << 3) -#define STB0899_OFFST_BCH_CHK 5 -#define STB0899_WIDTH_BCH_CHK 1 -#define STB0899_CRC8CHK (0x01 << 2) -#define STB0899_OFFST_CRC8CHK 2 -#define STB0899_WIDTH_CRC8CHK 1 -#define STB0899_SPEC_INFO (0x01 << 1) -#define STB0899_OFFST_SPEC_INFO 1 -#define STB0899_WIDTH_SPEC_INFO 1 -#define STB0899_LOW_PRIO_CLK (0x01 << 0) -#define STB0899_OFFST_LOW_PRIO_CLK 0 -#define STB0899_WIDTH_LOW_PRIO_CLK 1 -#define STB0899_ERROR_NORM (0x00 << 0) -#define STB0899_OFFST_ERROR_NORM 0 -#define STB0899_WIDTH_ERROR_NORM 0 - -#define STB0899_TSOUT 0xf54f -#define STB0899_RSSYNCDEL 0xf550 -#define STB0899_TSINHDELH 0xf551 -#define STB0899_TSINHDELM 0xf552 -#define STB0899_TSINHDELL 0xf553 -#define STB0899_TSLLSTKM 0xf55a -#define STB0899_TSLLSTKL 0xf55b -#define STB0899_TSULSTKM 0xf55c -#define STB0899_TSULSTKL 0xf55d -#define STB0899_TSSTATUS 0xf561 - -#define STB0899_PDELCTRL 0xf600 -#define STB0899_INVERT_RES (0x01 << 7) -#define STB0899_OFFST_INVERT_RES 7 -#define STB0899_WIDTH_INVERT_RES 1 -#define STB0899_FORCE_ACCEPTED (0x01 << 6) -#define STB0899_OFFST_FORCE_ACCEPTED 6 -#define STB0899_WIDTH_FORCE_ACCEPTED 1 -#define STB0899_FILTER_EN (0x01 << 5) -#define STB0899_OFFST_FILTER_EN 5 -#define STB0899_WIDTH_FILTER_EN 1 -#define STB0899_LOCKFALL_THRESH (0x01 << 4) -#define STB0899_OFFST_LOCKFALL_THRESH 4 -#define STB0899_WIDTH_LOCKFALL_THRESH 1 -#define STB0899_HYST_EN (0x01 << 3) -#define STB0899_OFFST_HYST_EN 3 -#define STB0899_WIDTH_HYST_EN 1 -#define STB0899_HYST_SWRST (0x01 << 2) -#define STB0899_OFFST_HYST_SWRST 2 -#define STB0899_WIDTH_HYST_SWRST 1 -#define STB0899_ALGO_EN (0x01 << 1) -#define STB0899_OFFST_ALGO_EN 1 -#define STB0899_WIDTH_ALGO_EN 1 -#define STB0899_ALGO_SWRST (0x01 << 0) -#define STB0899_OFFST_ALGO_SWRST 0 -#define STB0899_WIDTH_ALGO_SWRST 1 - -#define STB0899_PDELCTRL2 0xf601 -#define STB0899_BBHCTRL1 0xf602 -#define STB0899_BBHCTRL2 0xf603 -#define STB0899_HYSTTHRESH 0xf604 - -#define STB0899_MATCSTM 0xf605 -#define STB0899_MATCSTL 0xf606 -#define STB0899_UPLCSTM 0xf607 -#define STB0899_UPLCSTL 0xf608 -#define STB0899_DFLCSTM 0xf609 -#define STB0899_DFLCSTL 0xf60a -#define STB0899_SYNCCST 0xf60b -#define STB0899_SYNCDCSTM 0xf60c -#define STB0899_SYNCDCSTL 0xf60d -#define STB0899_ISI_ENTRY 0xf60e -#define STB0899_ISI_BIT_EN 0xf60f -#define STB0899_MATSTRM 0xf610 -#define STB0899_MATSTRL 0xf611 -#define STB0899_UPLSTRM 0xf612 -#define STB0899_UPLSTRL 0xf613 -#define STB0899_DFLSTRM 0xf614 -#define STB0899_DFLSTRL 0xf615 -#define STB0899_SYNCSTR 0xf616 -#define STB0899_SYNCDSTRM 0xf617 -#define STB0899_SYNCDSTRL 0xf618 - -#define STB0899_CFGPDELSTATUS1 0xf619 -#define STB0899_BADDFL (0x01 << 6) -#define STB0899_OFFST_BADDFL 6 -#define STB0899_WIDTH_BADDFL 1 -#define STB0899_CONTINUOUS_STREAM (0x01 << 5) -#define STB0899_OFFST_CONTINUOUS_STREAM 5 -#define STB0899_WIDTH_CONTINUOUS_STREAM 1 -#define STB0899_ACCEPTED_STREAM (0x01 << 4) -#define STB0899_OFFST_ACCEPTED_STREAM 4 -#define STB0899_WIDTH_ACCEPTED_STREAM 1 -#define STB0899_BCH_ERRFLAG (0x01 << 3) -#define STB0899_OFFST_BCH_ERRFLAG 3 -#define STB0899_WIDTH_BCH_ERRFLAG 1 -#define STB0899_CRCRES (0x01 << 2) -#define STB0899_OFFST_CRCRES 2 -#define STB0899_WIDTH_CRCRES 1 -#define STB0899_CFGPDELSTATUS_LOCK (0x01 << 1) -#define STB0899_OFFST_CFGPDELSTATUS_LOCK 1 -#define STB0899_WIDTH_CFGPDELSTATUS_LOCK 1 -#define STB0899_1STLOCK (0x01 << 0) -#define STB0899_OFFST_1STLOCK 0 -#define STB0899_WIDTH_1STLOCK 1 - -#define STB0899_CFGPDELSTATUS2 0xf61a -#define STB0899_BBFERRORM 0xf61b -#define STB0899_BBFERRORL 0xf61c -#define STB0899_UPKTERRORM 0xf61d -#define STB0899_UPKTERRORL 0xf61e - -#define STB0899_TSTCK 0xff10 - -#define STB0899_TSTRES 0xff11 -#define STB0899_FRESLDPC (0x01 << 7) -#define STB0899_OFFST_FRESLDPC 7 -#define STB0899_WIDTH_FRESLDPC 1 -#define STB0899_FRESRS (0x01 << 6) -#define STB0899_OFFST_FRESRS 6 -#define STB0899_WIDTH_FRESRS 1 -#define STB0899_FRESVIT (0x01 << 5) -#define STB0899_OFFST_FRESVIT 5 -#define STB0899_WIDTH_FRESVIT 1 -#define STB0899_FRESMAS1_2 (0x01 << 4) -#define STB0899_OFFST_FRESMAS1_2 4 -#define STB0899_WIDTH_FRESMAS1_2 1 -#define STB0899_FRESACS (0x01 << 3) -#define STB0899_OFFST_FRESACS 3 -#define STB0899_WIDTH_FRESACS 1 -#define STB0899_FRESSYM (0x01 << 2) -#define STB0899_OFFST_FRESSYM 2 -#define STB0899_WIDTH_FRESSYM 1 -#define STB0899_FRESMAS (0x01 << 1) -#define STB0899_OFFST_FRESMAS 1 -#define STB0899_WIDTH_FRESMAS 1 -#define STB0899_FRESINT (0x01 << 0) -#define STB0899_OFFST_FRESINIT 0 -#define STB0899_WIDTH_FRESINIT 1 - -#define STB0899_TSTOUT 0xff12 -#define STB0899_EN_SIGNATURE (0x01 << 7) -#define STB0899_OFFST_EN_SIGNATURE 7 -#define STB0899_WIDTH_EN_SIGNATURE 1 -#define STB0899_BCLK_CLK (0x01 << 6) -#define STB0899_OFFST_BCLK_CLK 6 -#define STB0899_WIDTH_BCLK_CLK 1 -#define STB0899_SGNL_OUT (0x01 << 5) -#define STB0899_OFFST_SGNL_OUT 5 -#define STB0899_WIDTH_SGNL_OUT 1 -#define STB0899_TS (0x01 << 4) -#define STB0899_OFFST_TS 4 -#define STB0899_WIDTH_TS 1 -#define STB0899_CTEST (0x01 << 0) -#define STB0899_OFFST_CTEST 0 -#define STB0899_WIDTH_CTEST 1 - -#define STB0899_TSTIN 0xff13 -#define STB0899_TEST_IN (0x01 << 7) -#define STB0899_OFFST_TEST_IN 7 -#define STB0899_WIDTH_TEST_IN 1 -#define STB0899_EN_ADC (0x01 << 6) -#define STB0899_OFFST_EN_ADC 6 -#define STB0899_WIDTH_ENADC 1 -#define STB0899_SGN_ADC (0x01 << 5) -#define STB0899_OFFST_SGN_ADC 5 -#define STB0899_WIDTH_SGN_ADC 1 -#define STB0899_BCLK_IN (0x01 << 4) -#define STB0899_OFFST_BCLK_IN 4 -#define STB0899_WIDTH_BCLK_IN 1 -#define STB0899_JETONIN_MODE (0x01 << 3) -#define STB0899_OFFST_JETONIN_MODE 3 -#define STB0899_WIDTH_JETONIN_MODE 1 -#define STB0899_BCLK_VALUE (0x01 << 2) -#define STB0899_OFFST_BCLK_VALUE 2 -#define STB0899_WIDTH_BCLK_VALUE 1 -#define STB0899_SGNRST_T12 (0x01 << 1) -#define STB0899_OFFST_SGNRST_T12 1 -#define STB0899_WIDTH_SGNRST_T12 1 -#define STB0899_LOWSP_ENAX (0x01 << 0) -#define STB0899_OFFST_LOWSP_ENAX 0 -#define STB0899_WIDTH_LOWSP_ENAX 1 - -#define STB0899_TSTSYS 0xff14 -#define STB0899_TSTCHIP 0xff15 -#define STB0899_TSTFREE 0xff16 -#define STB0899_TSTI2C 0xff17 -#define STB0899_BITSPEEDM 0xff1c -#define STB0899_BITSPEEDL 0xff1d -#define STB0899_TBUSBIT 0xff1e -#define STB0899_TSTDIS 0xff24 -#define STB0899_TSTDISRX 0xff25 -#define STB0899_TSTJETON 0xff28 -#define STB0899_TSTDCADJ 0xff40 -#define STB0899_TSTAGC1 0xff41 -#define STB0899_TSTAGC1N 0xff42 -#define STB0899_TSTPOLYPH 0xff48 -#define STB0899_TSTR 0xff49 -#define STB0899_TSTAGC2 0xff4a -#define STB0899_TSTCTL1 0xff4b -#define STB0899_TSTCTL2 0xff4c -#define STB0899_TSTCTL3 0xff4d -#define STB0899_TSTDEMAP 0xff50 -#define STB0899_TSTDEMAP2 0xff51 -#define STB0899_TSTDEMMON 0xff52 -#define STB0899_TSTRATE 0xff53 -#define STB0899_TSTSELOUT 0xff54 -#define STB0899_TSYNC 0xff55 -#define STB0899_TSTERR 0xff56 -#define STB0899_TSTRAM1 0xff58 -#define STB0899_TSTVSELOUT 0xff59 -#define STB0899_TSTFORCEIN 0xff5a -#define STB0899_TSTRS1 0xff5c -#define STB0899_TSTRS2 0xff5d -#define STB0899_TSTRS3 0xff53 - -#define STB0899_INTBUFSTATUS 0xf200 -#define STB0899_INTBUFCTRL 0xf201 -#define STB0899_PCKLENUL 0xf55e -#define STB0899_PCKLENLL 0xf55f -#define STB0899_RSPCKLEN 0xf560 - -/* 2 registers */ -#define STB0899_SYNCDCST 0xf60c - -/* DiSEqC */ -#define STB0899_DISCNTRL1 0xf0a0 -#define STB0899_TIMOFF (0x01 << 7) -#define STB0899_OFFST_TIMOFF 7 -#define STB0899_WIDTH_TIMOFF 1 -#define STB0899_DISEQCRESET (0x01 << 6) -#define STB0899_OFFST_DISEQCRESET 6 -#define STB0899_WIDTH_DISEQCRESET 1 -#define STB0899_TIMCMD (0x03 << 4) -#define STB0899_OFFST_TIMCMD 4 -#define STB0899_WIDTH_TIMCMD 2 -#define STB0899_DISPRECHARGE (0x01 << 2) -#define STB0899_OFFST_DISPRECHARGE 2 -#define STB0899_WIDTH_DISPRECHARGE 1 -#define STB0899_DISEQCMODE (0x03 << 0) -#define STB0899_OFFST_DISEQCMODE 0 -#define STB0899_WIDTH_DISEQCMODE 2 - -#define STB0899_DISCNTRL2 0xf0a1 -#define STB0899_RECEIVER_ON (0x01 << 7) -#define STB0899_OFFST_RECEIVER_ON 7 -#define STB0899_WIDTH_RECEIVER_ON 1 -#define STB0899_IGNO_SHORT_22K (0x01 << 6) -#define STB0899_OFFST_IGNO_SHORT_22K 6 -#define STB0899_WIDTH_IGNO_SHORT_22K 1 -#define STB0899_ONECHIP_TRX (0x01 << 5) -#define STB0899_OFFST_ONECHIP_TRX 5 -#define STB0899_WIDTH_ONECHIP_TRX 1 -#define STB0899_EXT_ENVELOP (0x01 << 4) -#define STB0899_OFFST_EXT_ENVELOP 4 -#define STB0899_WIDTH_EXT_ENVELOP 1 -#define STB0899_PIN_SELECT (0x03 << 2) -#define STB0899_OFFST_PIN_SELCT 2 -#define STB0899_WIDTH_PIN_SELCT 2 -#define STB0899_IRQ_RXEND (0x01 << 1) -#define STB0899_OFFST_IRQ_RXEND 1 -#define STB0899_WIDTH_IRQ_RXEND 1 -#define STB0899_IRQ_4NBYTES (0x01 << 0) -#define STB0899_OFFST_IRQ_4NBYTES 0 -#define STB0899_WIDTH_IRQ_4NBYTES 1 - -#define STB0899_DISRX_ST0 0xf0a4 -#define STB0899_RXEND (0x01 << 7) -#define STB0899_OFFST_RXEND 7 -#define STB0899_WIDTH_RXEND 1 -#define STB0899_RXACTIVE (0x01 << 6) -#define STB0899_OFFST_RXACTIVE 6 -#define STB0899_WIDTH_RXACTIVE 1 -#define STB0899_SHORT22K (0x01 << 5) -#define STB0899_OFFST_SHORT22K 5 -#define STB0899_WIDTH_SHORT22K 1 -#define STB0899_CONTTONE (0x01 << 4) -#define STB0899_OFFST_CONTTONE 4 -#define STB0899_WIDTH_CONTONE 1 -#define STB0899_4BFIFOREDY (0x01 << 3) -#define STB0899_OFFST_4BFIFOREDY 3 -#define STB0899_WIDTH_4BFIFOREDY 1 -#define STB0899_FIFOEMPTY (0x01 << 2) -#define STB0899_OFFST_FIFOEMPTY 2 -#define STB0899_WIDTH_FIFOEMPTY 1 -#define STB0899_ABORTTRX (0x01 << 0) -#define STB0899_OFFST_ABORTTRX 0 -#define STB0899_WIDTH_ABORTTRX 1 - -#define STB0899_DISRX_ST1 0xf0a5 -#define STB0899_RXFAIL (0x01 << 7) -#define STB0899_OFFST_RXFAIL 7 -#define STB0899_WIDTH_RXFAIL 1 -#define STB0899_FIFOPFAIL (0x01 << 6) -#define STB0899_OFFST_FIFOPFAIL 6 -#define STB0899_WIDTH_FIFOPFAIL 1 -#define STB0899_RXNONBYTES (0x01 << 5) -#define STB0899_OFFST_RXNONBYTES 5 -#define STB0899_WIDTH_RXNONBYTES 1 -#define STB0899_FIFOOVF (0x01 << 4) -#define STB0899_OFFST_FIFOOVF 4 -#define STB0899_WIDTH_FIFOOVF 1 -#define STB0899_FIFOBYTENBR (0x0f << 0) -#define STB0899_OFFST_FIFOBYTENBR 0 -#define STB0899_WIDTH_FIFOBYTENBR 4 - -#define STB0899_DISPARITY 0xf0a6 - -#define STB0899_DISFIFO 0xf0a7 - -#define STB0899_DISSTATUS 0xf0a8 -#define STB0899_FIFOFULL (0x01 << 6) -#define STB0899_OFFST_FIFOFULL 6 -#define STB0899_WIDTH_FIFOFULL 1 -#define STB0899_TXIDLE (0x01 << 5) -#define STB0899_OFFST_TXIDLE 5 -#define STB0899_WIDTH_TXIDLE 1 -#define STB0899_GAPBURST (0x01 << 4) -#define STB0899_OFFST_GAPBURST 4 -#define STB0899_WIDTH_GAPBURST 1 -#define STB0899_TXFIFOBYTES (0x0f << 0) -#define STB0899_OFFST_TXFIFOBYTES 0 -#define STB0899_WIDTH_TXFIFOBYTES 4 -#define STB0899_DISF22 0xf0a9 - -#define STB0899_DISF22RX 0xf0aa - -/* General Purpose */ -#define STB0899_SYSREG 0xf101 -#define STB0899_ACRPRESC 0xf110 -#define STB0899_OFFST_RSVD2 7 -#define STB0899_WIDTH_RSVD2 1 -#define STB0899_OFFST_ACRPRESC 4 -#define STB0899_WIDTH_ACRPRESC 3 -#define STB0899_OFFST_RSVD1 3 -#define STB0899_WIDTH_RSVD1 1 -#define STB0899_OFFST_ACRPRESC2 0 -#define STB0899_WIDTH_ACRPRESC2 3 - -#define STB0899_ACRDIV1 0xf111 -#define STB0899_ACRDIV2 0xf112 -#define STB0899_DACR1 0xf113 -#define STB0899_DACR2 0xf114 -#define STB0899_OUTCFG 0xf11c -#define STB0899_MODECFG 0xf11d -#define STB0899_NCOARSE 0xf1b3 - -#define STB0899_SYNTCTRL 0xf1b6 -#define STB0899_STANDBY (0x01 << 7) -#define STB0899_OFFST_STANDBY 7 -#define STB0899_WIDTH_STANDBY 1 -#define STB0899_BYPASSPLL (0x01 << 6) -#define STB0899_OFFST_BYPASSPLL 6 -#define STB0899_WIDTH_BYPASSPLL 1 -#define STB0899_SEL1XRATIO (0x01 << 5) -#define STB0899_OFFST_SEL1XRATIO 5 -#define STB0899_WIDTH_SEL1XRATIO 1 -#define STB0899_SELOSCI (0x01 << 1) -#define STB0899_OFFST_SELOSCI 1 -#define STB0899_WIDTH_SELOSCI 1 - -#define STB0899_FILTCTRL 0xf1b7 -#define STB0899_SYSCTRL 0xf1b8 - -#define STB0899_STOPCLK1 0xf1c2 -#define STB0899_STOP_CKINTBUF108 (0x01 << 7) -#define STB0899_OFFST_STOP_CKINTBUF108 7 -#define STB0899_WIDTH_STOP_CKINTBUF108 1 -#define STB0899_STOP_CKINTBUF216 (0x01 << 6) -#define STB0899_OFFST_STOP_CKINTBUF216 6 -#define STB0899_WIDTH_STOP_CKINTBUF216 1 -#define STB0899_STOP_CHK8PSK (0x01 << 5) -#define STB0899_OFFST_STOP_CHK8PSK 5 -#define STB0899_WIDTH_STOP_CHK8PSK 1 -#define STB0899_STOP_CKFEC108 (0x01 << 4) -#define STB0899_OFFST_STOP_CKFEC108 4 -#define STB0899_WIDTH_STOP_CKFEC108 1 -#define STB0899_STOP_CKFEC216 (0x01 << 3) -#define STB0899_OFFST_STOP_CKFEC216 3 -#define STB0899_WIDTH_STOP_CKFEC216 1 -#define STB0899_STOP_CKCORE216 (0x01 << 2) -#define STB0899_OFFST_STOP_CKCORE216 2 -#define STB0899_WIDTH_STOP_CKCORE216 1 -#define STB0899_STOP_CKADCI108 (0x01 << 1) -#define STB0899_OFFST_STOP_CKADCI108 1 -#define STB0899_WIDTH_STOP_CKADCI108 1 -#define STB0899_STOP_INVCKADCI108 (0x01 << 0) -#define STB0899_OFFST_STOP_INVCKADCI108 0 -#define STB0899_WIDTH_STOP_INVCKADCI108 1 - -#define STB0899_STOPCLK2 0xf1c3 -#define STB0899_STOP_CKS2DMD108 (0x01 << 2) -#define STB0899_OFFST_STOP_CKS2DMD108 2 -#define STB0899_WIDTH_STOP_CKS2DMD108 1 -#define STB0899_STOP_CKPKDLIN108 (0x01 << 1) -#define STB0899_OFFST_STOP_CKPKDLIN108 1 -#define STB0899_WIDTH_STOP_CKPKDLIN108 1 -#define STB0899_STOP_CKPKDLIN216 (0x01 << 0) -#define STB0899_OFFST_STOP_CKPKDLIN216 0 -#define STB0899_WIDTH_STOP_CKPKDLIN216 1 - -#define STB0899_TSTTNR1 0xf1e0 -#define STB0899_BYPASS_ADC (0x01 << 7) -#define STB0899_OFFST_BYPASS_ADC 7 -#define STB0899_WIDTH_BYPASS_ADC 1 -#define STB0899_INVADCICKOUT (0x01 << 6) -#define STB0899_OFFST_INVADCICKOUT 6 -#define STB0899_WIDTH_INVADCICKOUT 1 -#define STB0899_ADCTEST_VOLTAGE (0x03 << 4) -#define STB0899_OFFST_ADCTEST_VOLTAGE 4 -#define STB0899_WIDTH_ADCTEST_VOLTAGE 1 -#define STB0899_ADC_RESET (0x01 << 3) -#define STB0899_OFFST_ADC_RESET 3 -#define STB0899_WIDTH_ADC_RESET 1 -#define STB0899_TSTTNR1_2 (0x01 << 2) -#define STB0899_OFFST_TSTTNR1_2 2 -#define STB0899_WIDTH_TSTTNR1_2 1 -#define STB0899_ADCPON (0x01 << 1) -#define STB0899_OFFST_ADCPON 1 -#define STB0899_WIDTH_ADCPON 1 -#define STB0899_ADCIN_MODE (0x01 << 0) -#define STB0899_OFFST_ADCIN_MODE 0 -#define STB0899_WIDTH_ADCIN_MODE 1 - -#define STB0899_TSTTNR2 0xf1e1 -#define STB0899_TSTTNR2_7 (0x01 << 7) -#define STB0899_OFFST_TSTTNR2_7 7 -#define STB0899_WIDTH_TSTTNR2_7 1 -#define STB0899_NOT_DISRX_WIRED (0x01 << 6) -#define STB0899_OFFST_NOT_DISRX_WIRED 6 -#define STB0899_WIDTH_NOT_DISRX_WIRED 1 -#define STB0899_DISEQC_DCURRENT (0x01 << 5) -#define STB0899_OFFST_DISEQC_DCURRENT 5 -#define STB0899_WIDTH_DISEQC_DCURRENT 1 -#define STB0899_DISEQC_ZCURRENT (0x01 << 4) -#define STB0899_OFFST_DISEQC_ZCURRENT 4 -#define STB0899_WIDTH_DISEQC_ZCURRENT 1 -#define STB0899_DISEQC_SINC_SOURCE (0x03 << 2) -#define STB0899_OFFST_DISEQC_SINC_SOURCE 2 -#define STB0899_WIDTH_DISEQC_SINC_SOURCE 2 -#define STB0899_SELIQSRC (0x03 << 0) -#define STB0899_OFFST_SELIQSRC 0 -#define STB0899_WIDTH_SELIQSRC 2 - -#define STB0899_TSTTNR3 0xf1e2 - -#define STB0899_I2CCFG 0xf129 -#define STB0899_I2CCFGRSVD (0x0f << 4) -#define STB0899_OFFST_I2CCFGRSVD 4 -#define STB0899_WIDTH_I2CCFGRSVD 4 -#define STB0899_I2CFASTMODE (0x01 << 3) -#define STB0899_OFFST_I2CFASTMODE 3 -#define STB0899_WIDTH_I2CFASTMODE 1 -#define STB0899_STATUSWR (0x01 << 2) -#define STB0899_OFFST_STATUSWR 2 -#define STB0899_WIDTH_STATUSWR 1 -#define STB0899_I2CADDRINC (0x03 << 0) -#define STB0899_OFFST_I2CADDRINC 0 -#define STB0899_WIDTH_I2CADDRINC 2 - -#define STB0899_I2CRPT 0xf12a -#define STB0899_I2CTON (0x01 << 7) -#define STB0899_OFFST_I2CTON 7 -#define STB0899_WIDTH_I2CTON 1 -#define STB0899_ENARPTLEVEL (0x01 << 6) -#define STB0899_OFFST_ENARPTLEVEL 6 -#define STB0899_WIDTH_ENARPTLEVEL 2 -#define STB0899_SCLTDELAY (0x01 << 3) -#define STB0899_OFFST_SCLTDELAY 3 -#define STB0899_WIDTH_SCLTDELAY 1 -#define STB0899_STOPENA (0x01 << 2) -#define STB0899_OFFST_STOPENA 2 -#define STB0899_WIDTH_STOPENA 1 -#define STB0899_STOPSDAT2SDA (0x01 << 1) -#define STB0899_OFFST_STOPSDAT2SDA 1 -#define STB0899_WIDTH_STOPSDAT2SDA 1 - -#define STB0899_IOPVALUE8 0xf136 -#define STB0899_IOPVALUE7 0xf137 -#define STB0899_IOPVALUE6 0xf138 -#define STB0899_IOPVALUE5 0xf139 -#define STB0899_IOPVALUE4 0xf13a -#define STB0899_IOPVALUE3 0xf13b -#define STB0899_IOPVALUE2 0xf13c -#define STB0899_IOPVALUE1 0xf13d -#define STB0899_IOPVALUE0 0xf13e - -#define STB0899_GPIO00CFG 0xf140 - -#define STB0899_GPIO01CFG 0xf141 -#define STB0899_GPIO02CFG 0xf142 -#define STB0899_GPIO03CFG 0xf143 -#define STB0899_GPIO04CFG 0xf144 -#define STB0899_GPIO05CFG 0xf145 -#define STB0899_GPIO06CFG 0xf146 -#define STB0899_GPIO07CFG 0xf147 -#define STB0899_GPIO08CFG 0xf148 -#define STB0899_GPIO09CFG 0xf149 -#define STB0899_GPIO10CFG 0xf14a -#define STB0899_GPIO11CFG 0xf14b -#define STB0899_GPIO12CFG 0xf14c -#define STB0899_GPIO13CFG 0xf14d -#define STB0899_GPIO14CFG 0xf14e -#define STB0899_GPIO15CFG 0xf14f -#define STB0899_GPIO16CFG 0xf150 -#define STB0899_GPIO17CFG 0xf151 -#define STB0899_GPIO18CFG 0xf152 -#define STB0899_GPIO19CFG 0xf153 -#define STB0899_GPIO20CFG 0xf154 - -#define STB0899_SDATCFG 0xf155 -#define STB0899_SCLTCFG 0xf156 -#define STB0899_AGCRFCFG 0xf157 -#define STB0899_GPIO22 0xf158 /* AGCBB2CFG */ -#define STB0899_GPIO21 0xf159 /* AGCBB1CFG */ -#define STB0899_DIRCLKCFG 0xf15a -#define STB0899_CLKOUT27CFG 0xf15b -#define STB0899_STDBYCFG 0xf15c -#define STB0899_CS0CFG 0xf15d -#define STB0899_CS1CFG 0xf15e -#define STB0899_DISEQCOCFG 0xf15f - -#define STB0899_GPIO32CFG 0xf160 -#define STB0899_GPIO33CFG 0xf161 -#define STB0899_GPIO34CFG 0xf162 -#define STB0899_GPIO35CFG 0xf163 -#define STB0899_GPIO36CFG 0xf164 -#define STB0899_GPIO37CFG 0xf165 -#define STB0899_GPIO38CFG 0xf166 -#define STB0899_GPIO39CFG 0xf167 - -#define STB0899_IRQSTATUS_3 0xf120 -#define STB0899_IRQSTATUS_2 0xf121 -#define STB0899_IRQSTATUS_1 0xf122 -#define STB0899_IRQSTATUS_0 0xf123 - -#define STB0899_IRQMSK_3 0xf124 -#define STB0899_IRQMSK_2 0xf125 -#define STB0899_IRQMSK_1 0xf126 -#define STB0899_IRQMSK_0 0xf127 - -#define STB0899_IRQCFG 0xf128 - -#define STB0899_GHOSTREG 0xf000 - -#define STB0899_S2DEMOD 0xf3fc -#define STB0899_S2FEC 0xfafc - - -#endif diff --git a/drivers/media/dvb/frontends/stb6000.c b/drivers/media/dvb/frontends/stb6000.c deleted file mode 100644 index 0e2cb0df144..00000000000 --- a/drivers/media/dvb/frontends/stb6000.c +++ /dev/null @@ -1,255 +0,0 @@ - /* - Driver for ST STB6000 DVBS Silicon tuner - - Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; 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 <linux/module.h> -#include <linux/dvb/frontend.h> -#include <asm/types.h> - -#include "stb6000.h" - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "stb6000: " args); \ - } while (0) - -struct stb6000_priv { - /* i2c details */ - int i2c_address; - struct i2c_adapter *i2c; - u32 frequency; -}; - -static int stb6000_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static int stb6000_sleep(struct dvb_frontend *fe) -{ - struct stb6000_priv *priv = fe->tuner_priv; - int ret; - u8 buf[] = { 10, 0 }; - struct i2c_msg msg = { - .addr = priv->i2c_address, - .flags = 0, - .buf = buf, - .len = 2 - }; - - dprintk("%s:\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - ret = i2c_transfer(priv->i2c, &msg, 1); - if (ret != 1) - dprintk("%s: i2c error\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return (ret == 1) ? 0 : ret; -} - -static int stb6000_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct stb6000_priv *priv = fe->tuner_priv; - unsigned int n, m; - int ret; - u32 freq_mhz; - int bandwidth; - u8 buf[12]; - struct i2c_msg msg = { - .addr = priv->i2c_address, - .flags = 0, - .buf = buf, - .len = 12 - }; - - dprintk("%s:\n", __func__); - - freq_mhz = params->frequency / 1000; - bandwidth = params->u.qpsk.symbol_rate / 1000000; - - if (bandwidth > 31) - bandwidth = 31; - - if ((freq_mhz > 949) && (freq_mhz < 2151)) { - buf[0] = 0x01; - buf[1] = 0xac; - if (freq_mhz < 1950) - buf[1] = 0xaa; - if (freq_mhz < 1800) - buf[1] = 0xa8; - if (freq_mhz < 1650) - buf[1] = 0xa6; - if (freq_mhz < 1530) - buf[1] = 0xa5; - if (freq_mhz < 1470) - buf[1] = 0xa4; - if (freq_mhz < 1370) - buf[1] = 0xa2; - if (freq_mhz < 1300) - buf[1] = 0xa1; - if (freq_mhz < 1200) - buf[1] = 0xa0; - if (freq_mhz < 1075) - buf[1] = 0xbc; - if (freq_mhz < 1000) - buf[1] = 0xba; - if (freq_mhz < 1075) { - n = freq_mhz / 8; /* vco=lo*4 */ - m = 2; - } else { - n = freq_mhz / 16; /* vco=lo*2 */ - m = 1; - } - buf[2] = n >> 1; - buf[3] = (unsigned char)(((n & 1) << 7) | - (m * freq_mhz - n * 16) | 0x60); - buf[4] = 0x04; - buf[5] = 0x0e; - - buf[6] = (unsigned char)(bandwidth); - - buf[7] = 0xd8; - buf[8] = 0xd0; - buf[9] = 0x50; - buf[10] = 0xeb; - buf[11] = 0x4f; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - ret = i2c_transfer(priv->i2c, &msg, 1); - if (ret != 1) - dprintk("%s: i2c error\n", __func__); - - udelay(10); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - buf[0] = 0x07; - buf[1] = 0xdf; - buf[2] = 0xd0; - buf[3] = 0x50; - buf[4] = 0xfb; - msg.len = 5; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - ret = i2c_transfer(priv->i2c, &msg, 1); - if (ret != 1) - dprintk("%s: i2c error\n", __func__); - - udelay(10); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - priv->frequency = freq_mhz * 1000; - - return (ret == 1) ? 0 : ret; - } - return -1; -} - -static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct stb6000_priv *priv = fe->tuner_priv; - *frequency = priv->frequency; - return 0; -} - -static struct dvb_tuner_ops stb6000_tuner_ops = { - .info = { - .name = "ST STB6000", - .frequency_min = 950000, - .frequency_max = 2150000 - }, - .release = stb6000_release, - .sleep = stb6000_sleep, - .set_params = stb6000_set_params, - .get_frequency = stb6000_get_frequency, -}; - -struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr, - struct i2c_adapter *i2c) -{ - struct stb6000_priv *priv = NULL; - u8 b0[] = { 0 }; - u8 b1[] = { 0, 0 }; - struct i2c_msg msg[2] = { - { - .addr = addr, - .flags = 0, - .buf = b0, - .len = 0 - }, { - .addr = addr, - .flags = I2C_M_RD, - .buf = b1, - .len = 2 - } - }; - int ret; - - dprintk("%s:\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - /* is some i2c device here ? */ - ret = i2c_transfer(i2c, msg, 2); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - if (ret != 2) - return NULL; - - priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL); - if (priv == NULL) - return NULL; - - priv->i2c_address = addr; - priv->i2c = i2c; - - memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops, - sizeof(struct dvb_tuner_ops)); - - fe->tuner_priv = priv; - - return fe; -} -EXPORT_SYMBOL(stb6000_attach); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("DVB STB6000 driver"); -MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/stb6000.h b/drivers/media/dvb/frontends/stb6000.h deleted file mode 100644 index 7be479c22d5..00000000000 --- a/drivers/media/dvb/frontends/stb6000.h +++ /dev/null @@ -1,51 +0,0 @@ - /* - Driver for ST stb6000 DVBS Silicon tuner - - Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; 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_STB6000_H__ -#define __DVB_STB6000_H__ - -#include <linux/i2c.h> -#include "dvb_frontend.h" - -/** - * Attach a stb6000 tuner to the supplied frontend structure. - * - * @param fe Frontend to attach to. - * @param addr i2c address of the tuner. - * @param i2c i2c adapter to use. - * @return FE pointer on success, NULL on failure. - */ -#if defined(CONFIG_DVB_STB6000) || (defined(CONFIG_DVB_STB6000_MODULE) \ - && defined(MODULE)) -extern struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, - int addr, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_STB6000 */ - -#endif /* __DVB_STB6000_H__ */ diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c deleted file mode 100644 index 1ed5a7db4c5..00000000000 --- a/drivers/media/dvb/frontends/stb6100.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - STB6100 Silicon Tuner - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - 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 <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> - -#include "dvb_frontend.h" -#include "stb6100.h" - -static unsigned int verbose; -module_param(verbose, int, 0644); - - -#define FE_ERROR 0 -#define FE_NOTICE 1 -#define FE_INFO 2 -#define FE_DEBUG 3 - -#define dprintk(x, y, z, format, arg...) do { \ - if (z) { \ - if ((x > FE_ERROR) && (x > y)) \ - printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ - else if ((x > FE_NOTICE) && (x > y)) \ - printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ - else if ((x > FE_INFO) && (x > y)) \ - printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ - else if ((x > FE_DEBUG) && (x > y)) \ - printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ - } else { \ - if (x > y) \ - printk(format, ##arg); \ - } \ -} while(0) - -struct stb6100_lkup { - u32 val_low; - u32 val_high; - u8 reg; -}; - -static int stb6100_release(struct dvb_frontend *fe); - -static const struct stb6100_lkup lkup[] = { - { 0, 950000, 0x0a }, - { 950000, 1000000, 0x0a }, - { 1000000, 1075000, 0x0c }, - { 1075000, 1200000, 0x00 }, - { 1200000, 1300000, 0x01 }, - { 1300000, 1370000, 0x02 }, - { 1370000, 1470000, 0x04 }, - { 1470000, 1530000, 0x05 }, - { 1530000, 1650000, 0x06 }, - { 1650000, 1800000, 0x08 }, - { 1800000, 1950000, 0x0a }, - { 1950000, 2150000, 0x0c }, - { 2150000, 9999999, 0x0c }, - { 0, 0, 0x00 } -}; - -/* Register names for easy debugging. */ -static const char *stb6100_regnames[] = { - [STB6100_LD] = "LD", - [STB6100_VCO] = "VCO", - [STB6100_NI] = "NI", - [STB6100_NF_LSB] = "NF", - [STB6100_K] = "K", - [STB6100_G] = "G", - [STB6100_F] = "F", - [STB6100_DLB] = "DLB", - [STB6100_TEST1] = "TEST1", - [STB6100_FCCK] = "FCCK", - [STB6100_LPEN] = "LPEN", - [STB6100_TEST3] = "TEST3", -}; - -/* Template for normalisation, i.e. setting unused or undocumented - * bits as required according to the documentation. - */ -struct stb6100_regmask { - u8 mask; - u8 set; -}; - -static const struct stb6100_regmask stb6100_template[] = { - [STB6100_LD] = { 0xff, 0x00 }, - [STB6100_VCO] = { 0xff, 0x00 }, - [STB6100_NI] = { 0xff, 0x00 }, - [STB6100_NF_LSB] = { 0xff, 0x00 }, - [STB6100_K] = { 0xc7, 0x38 }, - [STB6100_G] = { 0xef, 0x10 }, - [STB6100_F] = { 0x1f, 0xc0 }, - [STB6100_DLB] = { 0x38, 0xc4 }, - [STB6100_TEST1] = { 0x00, 0x8f }, - [STB6100_FCCK] = { 0x40, 0x0d }, - [STB6100_LPEN] = { 0xf0, 0x0b }, - [STB6100_TEST3] = { 0x00, 0xde }, -}; - -static void stb6100_normalise_regs(u8 regs[]) -{ - int i; - - for (i = 0; i < STB6100_NUMREGS; i++) - regs[i] = (regs[i] & stb6100_template[i].mask) | stb6100_template[i].set; -} - -static int stb6100_read_regs(struct stb6100_state *state, u8 regs[]) -{ - int rc; - struct i2c_msg msg = { - .addr = state->config->tuner_address, - .flags = I2C_M_RD, - .buf = regs, - .len = STB6100_NUMREGS - }; - - rc = i2c_transfer(state->i2c, &msg, 1); - if (unlikely(rc != 1)) { - dprintk(verbose, FE_ERROR, 1, "Read (0x%x) err, rc=[%d]", - state->config->tuner_address, rc); - - return -EREMOTEIO; - } - if (unlikely(verbose > FE_DEBUG)) { - int i; - - dprintk(verbose, FE_DEBUG, 1, " Read from 0x%02x", state->config->tuner_address); - for (i = 0; i < STB6100_NUMREGS; i++) - dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[i], regs[i]); - } - return 0; -} - -static int stb6100_read_reg(struct stb6100_state *state, u8 reg) -{ - u8 regs[STB6100_NUMREGS]; - int rc; - - if (unlikely(reg >= STB6100_NUMREGS)) { - dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg); - return -EINVAL; - } - if ((rc = stb6100_read_regs(state, regs)) < 0) - return rc; - return (unsigned int)regs[reg]; -} - -static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int start, int len) -{ - int rc; - u8 cmdbuf[len + 1]; - struct i2c_msg msg = { - .addr = state->config->tuner_address, - .flags = 0, - .buf = cmdbuf, - .len = len + 1 - }; - - if (unlikely(start < 1 || start + len > STB6100_NUMREGS)) { - dprintk(verbose, FE_ERROR, 1, "Invalid register range %d:%d", - start, len); - return -EINVAL; - } - memcpy(&cmdbuf[1], buf, len); - cmdbuf[0] = start; - - if (unlikely(verbose > FE_DEBUG)) { - int i; - - dprintk(verbose, FE_DEBUG, 1, " Write @ 0x%02x: [%d:%d]", state->config->tuner_address, start, len); - for (i = 0; i < len; i++) - dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[start + i], buf[i]); - } - rc = i2c_transfer(state->i2c, &msg, 1); - if (unlikely(rc != 1)) { - dprintk(verbose, FE_ERROR, 1, "(0x%x) write err [%d:%d], rc=[%d]", - (unsigned int)state->config->tuner_address, start, len, rc); - return -EREMOTEIO; - } - return 0; -} - -static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data) -{ - if (unlikely(reg >= STB6100_NUMREGS)) { - dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg); - return -EREMOTEIO; - } - data = (data & stb6100_template[reg].mask) | stb6100_template[reg].set; - return stb6100_write_reg_range(state, &data, reg, 1); -} - -static int stb6100_write_regs(struct stb6100_state *state, u8 regs[]) -{ - stb6100_normalise_regs(regs); - return stb6100_write_reg_range(state, ®s[1], 1, STB6100_NUMREGS - 1); -} - -static int stb6100_get_status(struct dvb_frontend *fe, u32 *status) -{ - int rc; - struct stb6100_state *state = fe->tuner_priv; - - if ((rc = stb6100_read_reg(state, STB6100_LD)) < 0) - return rc; - - return (rc & STB6100_LD_LOCK) ? TUNER_STATUS_LOCKED : 0; -} - -static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -{ - int rc; - u8 f; - struct stb6100_state *state = fe->tuner_priv; - - if ((rc = stb6100_read_reg(state, STB6100_F)) < 0) - return rc; - f = rc & STB6100_F_F; - - state->status.bandwidth = (f + 5) * 2000; /* x2 for ZIF */ - - *bandwidth = state->bandwidth = state->status.bandwidth * 1000; - dprintk(verbose, FE_DEBUG, 1, "bandwidth = %u Hz", state->bandwidth); - return 0; -} - -static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) -{ - u32 tmp; - int rc; - struct stb6100_state *state = fe->tuner_priv; - - dprintk(verbose, FE_DEBUG, 1, "set bandwidth to %u Hz", bandwidth); - - bandwidth /= 2; /* ZIF */ - - if (bandwidth >= 36000000) /* F[4:0] BW/2 max =31+5=36 mhz for F=31 */ - tmp = 31; - else if (bandwidth <= 5000000) /* bw/2 min = 5Mhz for F=0 */ - tmp = 0; - else /* if 5 < bw/2 < 36 */ - tmp = (bandwidth + 500000) / 1000000 - 5; - - /* Turn on LPF bandwidth setting clock control, - * set bandwidth, wait 10ms, turn off. - */ - if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d | STB6100_FCCK_FCCK)) < 0) - return rc; - if ((rc = stb6100_write_reg(state, STB6100_F, 0xc0 | tmp)) < 0) - return rc; - msleep(1); - if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d)) < 0) - return rc; - - return 0; -} - -static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - int rc; - u32 nint, nfrac, fvco; - int psd2, odiv; - struct stb6100_state *state = fe->tuner_priv; - u8 regs[STB6100_NUMREGS]; - - if ((rc = stb6100_read_regs(state, regs)) < 0) - return rc; - - odiv = (regs[STB6100_VCO] & STB6100_VCO_ODIV) >> STB6100_VCO_ODIV_SHIFT; - psd2 = (regs[STB6100_K] & STB6100_K_PSD2) >> STB6100_K_PSD2_SHIFT; - nint = regs[STB6100_NI]; - nfrac = ((regs[STB6100_K] & STB6100_K_NF_MSB) << 8) | regs[STB6100_NF_LSB]; - fvco = (nfrac * state->reference >> (9 - psd2)) + (nint * state->reference << psd2); - *frequency = state->frequency = fvco >> (odiv + 1); - - dprintk(verbose, FE_DEBUG, 1, - "frequency = %u kHz, odiv = %u, psd2 = %u, fxtal = %u kHz, fvco = %u kHz, N(I) = %u, N(F) = %u", - state->frequency, odiv, psd2, state->reference, fvco, nint, nfrac); - return 0; -} - - -static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency) -{ - int rc; - const struct stb6100_lkup *ptr; - struct stb6100_state *state = fe->tuner_priv; - struct dvb_frontend_parameters p; - - u32 srate = 0, fvco, nint, nfrac; - u8 regs[STB6100_NUMREGS]; - u8 g, psd2, odiv; - - if ((rc = stb6100_read_regs(state, regs)) < 0) - return rc; - - if (fe->ops.get_frontend) { - dprintk(verbose, FE_DEBUG, 1, "Get frontend parameters"); - fe->ops.get_frontend(fe, &p); - } - srate = p.u.qpsk.symbol_rate; - - regs[STB6100_DLB] = 0xdc; - /* Disable LPEN */ - regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL Loop disabled */ - - if ((rc = stb6100_write_regs(state, regs)) < 0) - return rc; - - /* Baseband gain. */ - if (srate >= 15000000) - g = 9; // +4 dB - else if (srate >= 5000000) - g = 11; // +8 dB - else - g = 14; // +14 dB - - regs[STB6100_G] = (regs[STB6100_G] & ~STB6100_G_G) | g; - regs[STB6100_G] &= ~STB6100_G_GCT; /* mask GCT */ - regs[STB6100_G] |= (1 << 5); /* 2Vp-p Mode */ - - /* VCO divide ratio (LO divide ratio, VCO prescaler enable). */ - if (frequency <= 1075000) - odiv = 1; - else - odiv = 0; - regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_ODIV) | (odiv << STB6100_VCO_ODIV_SHIFT); - - if ((frequency > 1075000) && (frequency <= 1325000)) - psd2 = 0; - else - psd2 = 1; - regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_PSD2) | (psd2 << STB6100_K_PSD2_SHIFT); - - /* OSM */ - for (ptr = lkup; - (ptr->val_high != 0) && !CHKRANGE(frequency, ptr->val_low, ptr->val_high); - ptr++); - if (ptr->val_high == 0) { - printk(KERN_ERR "%s: frequency out of range: %u kHz\n", __func__, frequency); - return -EINVAL; - } - regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_OSM) | ptr->reg; - - /* F(VCO) = F(LO) * (ODIV == 0 ? 2 : 4) */ - fvco = frequency << (1 + odiv); - /* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1))) */ - nint = fvco / (state->reference << psd2); - /* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9 */ - nfrac = (((fvco - (nint * state->reference << psd2)) << (9 - psd2)) + state->reference / 2) / state->reference; - dprintk(verbose, FE_DEBUG, 1, - "frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u", - frequency, srate, (unsigned int)g, (unsigned int)odiv, - (unsigned int)psd2, state->reference, - ptr->reg, fvco, nint, nfrac); - regs[STB6100_NI] = nint; - regs[STB6100_NF_LSB] = nfrac; - regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_NF_MSB) | ((nfrac >> 8) & STB6100_K_NF_MSB); - regs[STB6100_VCO] |= STB6100_VCO_OSCH; /* VCO search enabled */ - regs[STB6100_VCO] |= STB6100_VCO_OCK; /* VCO search clock off */ - regs[STB6100_FCCK] |= STB6100_FCCK_FCCK; /* LPF BW setting clock enabled */ - regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL loop disabled */ - /* Power up. */ - regs[STB6100_LPEN] |= STB6100_LPEN_SYNP | STB6100_LPEN_OSCP | STB6100_LPEN_BEN; - - msleep(2); - if ((rc = stb6100_write_regs(state, regs)) < 0) - return rc; - - msleep(2); - regs[STB6100_LPEN] |= STB6100_LPEN_LPEN; /* PLL loop enabled */ - if ((rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN])) < 0) - return rc; - - regs[STB6100_VCO] &= ~STB6100_VCO_OCK; /* VCO fast search */ - if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0) - return rc; - - msleep(10); /* wait for LO to lock */ - regs[STB6100_VCO] &= ~STB6100_VCO_OSCH; /* vco search disabled */ - regs[STB6100_VCO] |= STB6100_VCO_OCK; /* search clock off */ - if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0) - return rc; - regs[STB6100_FCCK] &= ~STB6100_FCCK_FCCK; /* LPF BW clock disabled */ - stb6100_normalise_regs(regs); - if ((rc = stb6100_write_reg_range(state, ®s[1], 1, STB6100_NUMREGS - 3)) < 0) - return rc; - - msleep(100); - - return 0; -} - -static int stb6100_sleep(struct dvb_frontend *fe) -{ - /* TODO: power down */ - return 0; -} - -static int stb6100_init(struct dvb_frontend *fe) -{ - struct stb6100_state *state = fe->tuner_priv; - struct tuner_state *status = &state->status; - - status->tunerstep = 125000; - status->ifreq = 0; - status->refclock = 27000000; /* Hz */ - status->iqsense = 1; - status->bandwidth = 36000; /* kHz */ - state->bandwidth = status->bandwidth * 1000; /* Hz */ - state->reference = status->refclock / 1000; /* kHz */ - - /* Set default bandwidth. */ - return stb6100_set_bandwidth(fe, state->bandwidth); -} - -static int stb6100_get_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *state) -{ - switch (param) { - case DVBFE_TUNER_FREQUENCY: - stb6100_get_frequency(fe, &state->frequency); - break; - case DVBFE_TUNER_TUNERSTEP: - break; - case DVBFE_TUNER_IFFREQ: - break; - case DVBFE_TUNER_BANDWIDTH: - stb6100_get_bandwidth(fe, &state->bandwidth); - break; - case DVBFE_TUNER_REFCLOCK: - break; - default: - break; - } - - return 0; -} - -static int stb6100_set_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *state) -{ - struct stb6100_state *tstate = fe->tuner_priv; - - switch (param) { - case DVBFE_TUNER_FREQUENCY: - stb6100_set_frequency(fe, state->frequency); - tstate->frequency = state->frequency; - break; - case DVBFE_TUNER_TUNERSTEP: - break; - case DVBFE_TUNER_IFFREQ: - break; - case DVBFE_TUNER_BANDWIDTH: - stb6100_set_bandwidth(fe, state->bandwidth); - tstate->bandwidth = state->bandwidth; - break; - case DVBFE_TUNER_REFCLOCK: - break; - default: - break; - } - - return 0; -} - -static struct dvb_tuner_ops stb6100_ops = { - .info = { - .name = "STB6100 Silicon Tuner", - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 0, - }, - - .init = stb6100_init, - .sleep = stb6100_sleep, - .get_status = stb6100_get_status, - .get_state = stb6100_get_state, - .set_state = stb6100_set_state, - .release = stb6100_release -}; - -struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, - struct stb6100_config *config, - struct i2c_adapter *i2c) -{ - struct stb6100_state *state = NULL; - - state = kzalloc(sizeof (struct stb6100_state), GFP_KERNEL); - if (state == NULL) - goto error; - - state->config = config; - state->i2c = i2c; - state->frontend = fe; - state->reference = config->refclock / 1000; /* kHz */ - fe->tuner_priv = state; - fe->ops.tuner_ops = stb6100_ops; - - printk("%s: Attaching STB6100 \n", __func__); - return fe; - -error: - kfree(state); - return NULL; -} - -static int stb6100_release(struct dvb_frontend *fe) -{ - struct stb6100_state *state = fe->tuner_priv; - - fe->tuner_priv = NULL; - kfree(state); - - return 0; -} - -EXPORT_SYMBOL(stb6100_attach); -MODULE_PARM_DESC(verbose, "Set Verbosity level"); - -MODULE_AUTHOR("Manu Abraham"); -MODULE_DESCRIPTION("STB6100 Silicon tuner"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/stb6100.h b/drivers/media/dvb/frontends/stb6100.h deleted file mode 100644 index 395d056599a..00000000000 --- a/drivers/media/dvb/frontends/stb6100.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - STB6100 Silicon Tuner - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - 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 __STB_6100_REG_H -#define __STB_6100_REG_H - -#include <linux/dvb/frontend.h> -#include "dvb_frontend.h" - -#define STB6100_LD 0x00 -#define STB6100_LD_LOCK (1 << 0) - -#define STB6100_VCO 0x01 -#define STB6100_VCO_OSCH (0x01 << 7) -#define STB6100_VCO_OSCH_SHIFT 7 -#define STB6100_VCO_OCK (0x03 << 5) -#define STB6100_VCO_OCK_SHIFT 5 -#define STB6100_VCO_ODIV (0x01 << 4) -#define STB6100_VCO_ODIV_SHIFT 4 -#define STB6100_VCO_OSM (0x0f << 0) - -#define STB6100_NI 0x02 -#define STB6100_NF_LSB 0x03 - -#define STB6100_K 0x04 -#define STB6100_K_PSD2 (0x01 << 2) -#define STB6100_K_PSD2_SHIFT 2 -#define STB6100_K_NF_MSB (0x03 << 0) - -#define STB6100_G 0x05 -#define STB6100_G_G (0x0f << 0) -#define STB6100_G_GCT (0x07 << 5) - -#define STB6100_F 0x06 -#define STB6100_F_F (0x1f << 0) - -#define STB6100_DLB 0x07 - -#define STB6100_TEST1 0x08 - -#define STB6100_FCCK 0x09 -#define STB6100_FCCK_FCCK (0x01 << 6) - -#define STB6100_LPEN 0x0a -#define STB6100_LPEN_LPEN (0x01 << 4) -#define STB6100_LPEN_SYNP (0x01 << 5) -#define STB6100_LPEN_OSCP (0x01 << 6) -#define STB6100_LPEN_BEN (0x01 << 7) - -#define STB6100_TEST3 0x0b - -#define STB6100_NUMREGS 0x0c - - -#define INRANGE(val, x, y) (((x <= val) && (val <= y)) || \ - ((y <= val) && (val <= x)) ? 1 : 0) - -#define CHKRANGE(val, x, y) (((val >= x) && (val < y)) ? 1 : 0) - -struct stb6100_config { - u8 tuner_address; - u32 refclock; -}; - -struct stb6100_state { - struct i2c_adapter *i2c; - - const struct stb6100_config *config; - struct dvb_tuner_ops ops; - struct dvb_frontend *frontend; - struct tuner_state status; - - u32 frequency; - u32 srate; - u32 bandwidth; - u32 reference; -}; - -#if defined(CONFIG_DVB_STB6100) || (defined(CONFIG_DVB_STB6100_MODULE) && defined(MODULE)) - -extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, - struct stb6100_config *config, - struct i2c_adapter *i2c); - -#else - -static inline struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, - struct stb6100_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); - return NULL; -} - -#endif //CONFIG_DVB_STB6100 - -#endif diff --git a/drivers/media/dvb/frontends/stb6100_cfg.h b/drivers/media/dvb/frontends/stb6100_cfg.h deleted file mode 100644 index 6314d18c797..00000000000 --- a/drivers/media/dvb/frontends/stb6100_cfg.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - STB6100 Silicon Tuner - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - 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. -*/ - -static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - struct tuner_state t_state; - int err = 0; - - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->get_state) { - if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - *frequency = t_state.frequency; - } - return 0; -} - -static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency) -{ - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - struct tuner_state t_state; - int err = 0; - - t_state.frequency = frequency; - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->set_state) { - if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - } - return 0; -} - -static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -{ - struct dvb_frontend_ops *frontend_ops = &fe->ops; - struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; - int err = 0; - - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->get_state) { - if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - *bandwidth = t_state.bandwidth; - } - return 0; -} - -static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) -{ - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - struct tuner_state t_state; - int err = 0; - - t_state.bandwidth = bandwidth; - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->set_state) { - if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - } - return 0; -} diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c deleted file mode 100644 index ff1194de34c..00000000000 --- a/drivers/media/dvb/frontends/stv0288.c +++ /dev/null @@ -1,618 +0,0 @@ -/* - Driver for ST STV0288 demodulator - Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de - for Reel Multimedia - Copyright (C) 2008 TurboSight.com, Bob Liu <bob@turbosight.com> - Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by> - Removed stb6000 specific tuner code and revised some - procedures. - - 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 <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/jiffies.h> -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "stv0288.h" - -struct stv0288_state { - struct i2c_adapter *i2c; - const struct stv0288_config *config; - struct dvb_frontend frontend; - - u8 initialised:1; - u32 tuner_frequency; - u32 symbol_rate; - fe_code_rate_t fec_inner; - int errmode; -}; - -#define STATUS_BER 0 -#define STATUS_UCBLOCKS 1 - -static int debug; -static int debug_legacy_dish_switch; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "stv0288: " args); \ - } while (0) - - -static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = 2 - }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static int stv0288_write(struct dvb_frontend *fe, u8 *buf, int len) -{ - struct stv0288_state *state = fe->demodulator_priv; - - if (len != 2) - return -EINVAL; - - return stv0288_writeregI(state, buf[0], buf[1]); -} - -static u8 stv0288_readreg(struct stv0288_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = b0, - .len = 1 - }, { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = b1, - .len = 1 - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", - __func__, reg, ret); - - return b1[0]; -} - -static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate) -{ - struct stv0288_state *state = fe->demodulator_priv; - unsigned int temp; - unsigned char b[3]; - - if ((srate < 1000000) || (srate > 45000000)) - return -EINVAL; - - temp = (unsigned int)srate / 1000; - - temp = temp * 32768; - temp = temp / 25; - temp = temp / 125; - b[0] = (unsigned char)((temp >> 12) & 0xff); - b[1] = (unsigned char)((temp >> 4) & 0xff); - b[2] = (unsigned char)((temp << 4) & 0xf0); - stv0288_writeregI(state, 0x28, 0x80); /* SFRH */ - stv0288_writeregI(state, 0x29, 0); /* SFRM */ - stv0288_writeregI(state, 0x2a, 0); /* SFRL */ - - stv0288_writeregI(state, 0x28, b[0]); - stv0288_writeregI(state, 0x29, b[1]); - stv0288_writeregI(state, 0x2a, b[2]); - dprintk("stv0288: stv0288_set_symbolrate\n"); - - return 0; -} - -static int stv0288_send_diseqc_msg(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *m) -{ - struct stv0288_state *state = fe->demodulator_priv; - - int i; - - dprintk("%s\n", __func__); - - stv0288_writeregI(state, 0x09, 0); - msleep(30); - stv0288_writeregI(state, 0x05, 0x16); - - for (i = 0; i < m->msg_len; i++) { - if (stv0288_writeregI(state, 0x06, m->msg[i])) - return -EREMOTEIO; - msleep(12); - } - - return 0; -} - -static int stv0288_send_diseqc_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) -{ - struct stv0288_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (stv0288_writeregI(state, 0x05, 0x16))/* burst mode */ - return -EREMOTEIO; - - if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff)) - return -EREMOTEIO; - - if (stv0288_writeregI(state, 0x06, 0x12)) - return -EREMOTEIO; - - return 0; -} - -static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct stv0288_state *state = fe->demodulator_priv; - - switch (tone) { - case SEC_TONE_ON: - if (stv0288_writeregI(state, 0x05, 0x10))/* burst mode */ - return -EREMOTEIO; - return stv0288_writeregI(state, 0x06, 0xff); - - case SEC_TONE_OFF: - if (stv0288_writeregI(state, 0x05, 0x13))/* burst mode */ - return -EREMOTEIO; - return stv0288_writeregI(state, 0x06, 0x00); - - default: - return -EINVAL; - } -} - -static u8 stv0288_inittab[] = { - 0x01, 0x15, - 0x02, 0x20, - 0x09, 0x0, - 0x0a, 0x4, - 0x0b, 0x0, - 0x0c, 0x0, - 0x0d, 0x0, - 0x0e, 0xd4, - 0x0f, 0x30, - 0x11, 0x80, - 0x12, 0x03, - 0x13, 0x48, - 0x14, 0x84, - 0x15, 0x45, - 0x16, 0xb7, - 0x17, 0x9c, - 0x18, 0x0, - 0x19, 0xa6, - 0x1a, 0x88, - 0x1b, 0x8f, - 0x1c, 0xf0, - 0x20, 0x0b, - 0x21, 0x54, - 0x22, 0x0, - 0x23, 0x0, - 0x2b, 0xff, - 0x2c, 0xf7, - 0x30, 0x0, - 0x31, 0x1e, - 0x32, 0x14, - 0x33, 0x0f, - 0x34, 0x09, - 0x35, 0x0c, - 0x36, 0x05, - 0x37, 0x2f, - 0x38, 0x16, - 0x39, 0xbe, - 0x3a, 0x0, - 0x3b, 0x13, - 0x3c, 0x11, - 0x3d, 0x30, - 0x40, 0x63, - 0x41, 0x04, - 0x42, 0x60, - 0x43, 0x00, - 0x44, 0x00, - 0x45, 0x00, - 0x46, 0x00, - 0x47, 0x00, - 0x4a, 0x00, - 0x50, 0x10, - 0x51, 0x38, - 0x52, 0x21, - 0x58, 0x54, - 0x59, 0x86, - 0x5a, 0x0, - 0x5b, 0x9b, - 0x5c, 0x08, - 0x5d, 0x7f, - 0x5e, 0x0, - 0x5f, 0xff, - 0x70, 0x0, - 0x71, 0x0, - 0x72, 0x0, - 0x74, 0x0, - 0x75, 0x0, - 0x76, 0x0, - 0x81, 0x0, - 0x82, 0x3f, - 0x83, 0x3f, - 0x84, 0x0, - 0x85, 0x0, - 0x88, 0x0, - 0x89, 0x0, - 0x8a, 0x0, - 0x8b, 0x0, - 0x8c, 0x0, - 0x90, 0x0, - 0x91, 0x0, - 0x92, 0x0, - 0x93, 0x0, - 0x94, 0x1c, - 0x97, 0x0, - 0xa0, 0x48, - 0xa1, 0x0, - 0xb0, 0xb8, - 0xb1, 0x3a, - 0xb2, 0x10, - 0xb3, 0x82, - 0xb4, 0x80, - 0xb5, 0x82, - 0xb6, 0x82, - 0xb7, 0x82, - 0xb8, 0x20, - 0xb9, 0x0, - 0xf0, 0x0, - 0xf1, 0x0, - 0xf2, 0xc0, - 0x51, 0x36, - 0x52, 0x09, - 0x53, 0x94, - 0x54, 0x62, - 0x55, 0x29, - 0x56, 0x64, - 0x57, 0x2b, - 0xff, 0xff, -}; - -static int stv0288_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) -{ - dprintk("%s: %s\n", __func__, - volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : - volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); - - return 0; -} - -static int stv0288_init(struct dvb_frontend *fe) -{ - struct stv0288_state *state = fe->demodulator_priv; - int i; - u8 reg; - u8 val; - - dprintk("stv0288: init chip\n"); - stv0288_writeregI(state, 0x41, 0x04); - msleep(50); - - /* we have default inittab */ - if (state->config->inittab == NULL) { - for (i = 0; !(stv0288_inittab[i] == 0xff && - stv0288_inittab[i + 1] == 0xff); i += 2) - stv0288_writeregI(state, stv0288_inittab[i], - stv0288_inittab[i + 1]); - } else { - for (i = 0; ; i += 2) { - reg = state->config->inittab[i]; - val = state->config->inittab[i+1]; - if (reg == 0xff && val == 0xff) - break; - stv0288_writeregI(state, reg, val); - } - } - return 0; -} - -static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct stv0288_state *state = fe->demodulator_priv; - - u8 sync = stv0288_readreg(state, 0x24); - if (sync == 255) - sync = 0; - - dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync); - - *status = 0; - - if ((sync & 0x08) == 0x08) { - *status |= FE_HAS_LOCK; - dprintk("stv0288 has locked\n"); - } - - return 0; -} - -static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct stv0288_state *state = fe->demodulator_priv; - - if (state->errmode != STATUS_BER) - return 0; - *ber = (stv0288_readreg(state, 0x26) << 8) | - stv0288_readreg(state, 0x27); - dprintk("stv0288_read_ber %d\n", *ber); - - return 0; -} - - -static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct stv0288_state *state = fe->demodulator_priv; - - s32 signal = 0xffff - ((stv0288_readreg(state, 0x10) << 8)); - - - signal = signal * 5 / 4; - *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal; - dprintk("stv0288_read_signal_strength %d\n", *strength); - - return 0; -} -static int stv0288_sleep(struct dvb_frontend *fe) -{ - struct stv0288_state *state = fe->demodulator_priv; - - stv0288_writeregI(state, 0x41, 0x84); - state->initialised = 0; - - return 0; -} -static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct stv0288_state *state = fe->demodulator_priv; - - s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8) - | stv0288_readreg(state, 0x2e)); - xsnr = 3 * (xsnr - 0xa100); - *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr; - dprintk("stv0288_read_snr %d\n", *snr); - - return 0; -} - -static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct stv0288_state *state = fe->demodulator_priv; - - if (state->errmode != STATUS_BER) - return 0; - *ucblocks = (stv0288_readreg(state, 0x26) << 8) | - stv0288_readreg(state, 0x27); - dprintk("stv0288_read_ber %d\n", *ucblocks); - - return 0; -} - -static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int stv0288_get_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int stv0288_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *dfp) -{ - struct stv0288_state *state = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - char tm; - unsigned char tda[3]; - - dprintk("%s : FE_SET_FRONTEND\n", __func__); - - if (c->delivery_system != SYS_DVBS) { - dprintk("%s: unsupported delivery " - "system selected (%d)\n", - __func__, c->delivery_system); - return -EOPNOTSUPP; - } - - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - - /* only frequency & symbol_rate are used for tuner*/ - dfp->frequency = c->frequency; - dfp->u.qpsk.symbol_rate = c->symbol_rate; - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, dfp); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - udelay(10); - stv0288_set_symbolrate(fe, c->symbol_rate); - /* Carrier lock control register */ - stv0288_writeregI(state, 0x15, 0xc5); - - tda[0] = 0x2b; /* CFRM */ - tda[2] = 0x0; /* CFRL */ - for (tm = -6; tm < 7;) { - /* Viterbi status */ - if (stv0288_readreg(state, 0x24) & 0x80) - break; - - tda[2] += 40; - if (tda[2] < 40) - tm++; - tda[1] = (unsigned char)tm; - stv0288_writeregI(state, 0x2b, tda[1]); - stv0288_writeregI(state, 0x2c, tda[2]); - udelay(30); - } - - state->tuner_frequency = c->frequency; - state->fec_inner = FEC_AUTO; - state->symbol_rate = c->symbol_rate; - - return 0; -} - -static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct stv0288_state *state = fe->demodulator_priv; - - if (enable) - stv0288_writeregI(state, 0x01, 0xb5); - else - stv0288_writeregI(state, 0x01, 0x35); - - udelay(1); - - return 0; -} - -static void stv0288_release(struct dvb_frontend *fe) -{ - struct stv0288_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops stv0288_ops = { - - .info = { - .name = "ST STV0288 DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 1000, /* kHz for QPSK frontends */ - .frequency_tolerance = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 500, /* ppm */ - .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_FEC_AUTO - }, - - .release = stv0288_release, - .init = stv0288_init, - .sleep = stv0288_sleep, - .write = stv0288_write, - .i2c_gate_ctrl = stv0288_i2c_gate_ctrl, - .read_status = stv0288_read_status, - .read_ber = stv0288_read_ber, - .read_signal_strength = stv0288_read_signal_strength, - .read_snr = stv0288_read_snr, - .read_ucblocks = stv0288_read_ucblocks, - .diseqc_send_master_cmd = stv0288_send_diseqc_msg, - .diseqc_send_burst = stv0288_send_diseqc_burst, - .set_tone = stv0288_set_tone, - .set_voltage = stv0288_set_voltage, - - .set_property = stv0288_set_property, - .get_property = stv0288_get_property, - .set_frontend = stv0288_set_frontend, -}; - -struct dvb_frontend *stv0288_attach(const struct stv0288_config *config, - struct i2c_adapter *i2c) -{ - struct stv0288_state *state = NULL; - int id; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct stv0288_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - state->tuner_frequency = 0; - state->symbol_rate = 0; - state->fec_inner = 0; - state->errmode = STATUS_BER; - - stv0288_writeregI(state, 0x41, 0x04); - msleep(200); - id = stv0288_readreg(state, 0x00); - dprintk("stv0288 id %x\n", id); - - /* register 0x00 contains 0x11 for STV0288 */ - if (id != 0x11) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &stv0288_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - - return NULL; -} -EXPORT_SYMBOL(stv0288_attach); - -module_param(debug_legacy_dish_switch, int, 0444); -MODULE_PARM_DESC(debug_legacy_dish_switch, - "Enable timing analysis for Dish Network legacy switches"); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver"); -MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/media/dvb/frontends/stv0288.h b/drivers/media/dvb/frontends/stv0288.h deleted file mode 100644 index f2b53db0606..00000000000 --- a/drivers/media/dvb/frontends/stv0288.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Driver for ST STV0288 demodulator - - Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de - for Reel Multimedia - Copyright (C) 2008 TurboSight.com, <bob@turbosight.com> - Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by> - Removed stb6000 specific tuner code and revised some - procedures. - - 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 STV0288_H -#define STV0288_H - -#include <linux/dvb/frontend.h> -#include "dvb_frontend.h" - -struct stv0288_config { - /* the demodulator's i2c address */ - u8 demod_address; - - u8* inittab; - - /* minimum delay before retuning */ - int min_delay_ms; - - int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); -}; - -#if defined(CONFIG_DVB_STV0288) || (defined(CONFIG_DVB_STV0288_MODULE) && \ - defined(MODULE)) -extern struct dvb_frontend *stv0288_attach(const struct stv0288_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *stv0288_attach(const struct stv0288_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_STV0288 */ - -static inline int stv0288_writereg(struct dvb_frontend *fe, u8 reg, u8 val) -{ - int r = 0; - u8 buf[] = { reg, val }; - if (fe->ops.write) - r = fe->ops.write(fe, buf, 2); - return r; -} - -#endif /* STV0288_H */ diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c deleted file mode 100644 index 62caf802ed9..00000000000 --- a/drivers/media/dvb/frontends/stv0297.c +++ /dev/null @@ -1,723 +0,0 @@ -/* - Driver for STV0297 demodulator - - Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net> - Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de> - - 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 <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/delay.h> -#include <linux/jiffies.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "stv0297.h" - -struct stv0297_state { - struct i2c_adapter *i2c; - const struct stv0297_config *config; - struct dvb_frontend frontend; - - unsigned long last_ber; - unsigned long base_freq; -}; - -#if 1 -#define dprintk(x...) printk(x) -#else -#define dprintk(x...) -#endif - -#define STV0297_CLOCK_KHZ 28900 - - -static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static int stv0297_readreg(struct stv0297_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1}, - {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} - }; - - // this device needs a STOP between the register and data - if (state->config->stop_during_read) { - if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret); - return -1; - } - if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret); - return -1; - } - } else { - if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret); - return -1; - } - } - - return b1[0]; -} - -static int stv0297_writereg_mask(struct stv0297_state *state, u8 reg, u8 mask, u8 data) -{ - int val; - - val = stv0297_readreg(state, reg); - val &= ~mask; - val |= (data & mask); - stv0297_writereg(state, reg, val); - - return 0; -} - -static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len) -{ - int ret; - struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = - ®1,.len = 1}, - {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b,.len = len} - }; - - // this device needs a STOP between the register and data - if (state->config->stop_during_read) { - if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret); - return -1; - } - if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret); - return -1; - } - } else { - if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret); - return -1; - } - } - - return 0; -} - -static u32 stv0297_get_symbolrate(struct stv0297_state *state) -{ - u64 tmp; - - tmp = stv0297_readreg(state, 0x55); - tmp |= stv0297_readreg(state, 0x56) << 8; - tmp |= stv0297_readreg(state, 0x57) << 16; - tmp |= stv0297_readreg(state, 0x58) << 24; - - tmp *= STV0297_CLOCK_KHZ; - tmp >>= 32; - - return (u32) tmp; -} - -static void stv0297_set_symbolrate(struct stv0297_state *state, u32 srate) -{ - long tmp; - - tmp = 131072L * srate; /* 131072 = 2^17 */ - tmp = tmp / (STV0297_CLOCK_KHZ / 4); /* 1/4 = 2^-2 */ - tmp = tmp * 8192L; /* 8192 = 2^13 */ - - stv0297_writereg(state, 0x55, (unsigned char) (tmp & 0xFF)); - stv0297_writereg(state, 0x56, (unsigned char) (tmp >> 8)); - stv0297_writereg(state, 0x57, (unsigned char) (tmp >> 16)); - stv0297_writereg(state, 0x58, (unsigned char) (tmp >> 24)); -} - -static void stv0297_set_sweeprate(struct stv0297_state *state, short fshift, long symrate) -{ - long tmp; - - tmp = (long) fshift *262144L; /* 262144 = 2*18 */ - tmp /= symrate; - tmp *= 1024; /* 1024 = 2*10 */ - - // adjust - if (tmp >= 0) { - tmp += 500000; - } else { - tmp -= 500000; - } - tmp /= 1000000; - - stv0297_writereg(state, 0x60, tmp & 0xFF); - stv0297_writereg_mask(state, 0x69, 0xF0, (tmp >> 4) & 0xf0); -} - -static void stv0297_set_carrieroffset(struct stv0297_state *state, long offset) -{ - long tmp; - - /* symrate is hardcoded to 10000 */ - tmp = offset * 26844L; /* (2**28)/10000 */ - if (tmp < 0) - tmp += 0x10000000; - tmp &= 0x0FFFFFFF; - - stv0297_writereg(state, 0x66, (unsigned char) (tmp & 0xFF)); - stv0297_writereg(state, 0x67, (unsigned char) (tmp >> 8)); - stv0297_writereg(state, 0x68, (unsigned char) (tmp >> 16)); - stv0297_writereg_mask(state, 0x69, 0x0F, (tmp >> 24) & 0x0f); -} - -/* -static long stv0297_get_carrieroffset(struct stv0297_state *state) -{ - s64 tmp; - - stv0297_writereg(state, 0x6B, 0x00); - - tmp = stv0297_readreg(state, 0x66); - tmp |= (stv0297_readreg(state, 0x67) << 8); - tmp |= (stv0297_readreg(state, 0x68) << 16); - tmp |= (stv0297_readreg(state, 0x69) & 0x0F) << 24; - - tmp *= stv0297_get_symbolrate(state); - tmp >>= 28; - - return (s32) tmp; -} -*/ - -static void stv0297_set_initialdemodfreq(struct stv0297_state *state, long freq) -{ - s32 tmp; - - if (freq > 10000) - freq -= STV0297_CLOCK_KHZ; - - tmp = (STV0297_CLOCK_KHZ * 1000) / (1 << 16); - tmp = (freq * 1000) / tmp; - if (tmp > 0xffff) - tmp = 0xffff; - - stv0297_writereg_mask(state, 0x25, 0x80, 0x80); - stv0297_writereg(state, 0x21, tmp >> 8); - stv0297_writereg(state, 0x20, tmp); -} - -static int stv0297_set_qam(struct stv0297_state *state, fe_modulation_t modulation) -{ - int val = 0; - - switch (modulation) { - case QAM_16: - val = 0; - break; - - case QAM_32: - val = 1; - break; - - case QAM_64: - val = 4; - break; - - case QAM_128: - val = 2; - break; - - case QAM_256: - val = 3; - break; - - default: - return -EINVAL; - } - - stv0297_writereg_mask(state, 0x00, 0x70, val << 4); - - return 0; -} - -static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_inversion_t inversion) -{ - int val = 0; - - switch (inversion) { - case INVERSION_OFF: - val = 0; - break; - - case INVERSION_ON: - val = 1; - break; - - default: - return -EINVAL; - } - - stv0297_writereg_mask(state, 0x83, 0x08, val << 3); - - return 0; -} - -static int stv0297_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct stv0297_state *state = fe->demodulator_priv; - - if (enable) { - stv0297_writereg(state, 0x87, 0x78); - stv0297_writereg(state, 0x86, 0xc8); - } - - return 0; -} - -static int stv0297_init(struct dvb_frontend *fe) -{ - struct stv0297_state *state = fe->demodulator_priv; - int i; - - /* load init table */ - for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2) - stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]); - msleep(200); - - state->last_ber = 0; - - return 0; -} - -static int stv0297_sleep(struct dvb_frontend *fe) -{ - struct stv0297_state *state = fe->demodulator_priv; - - stv0297_writereg_mask(state, 0x80, 1, 1); - - return 0; -} - -static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status) -{ - struct stv0297_state *state = fe->demodulator_priv; - - u8 sync = stv0297_readreg(state, 0xDF); - - *status = 0; - if (sync & 0x80) - *status |= - FE_HAS_SYNC | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK; - return 0; -} - -static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber) -{ - struct stv0297_state *state = fe->demodulator_priv; - u8 BER[3]; - - stv0297_readregs(state, 0xA0, BER, 3); - if (!(BER[0] & 0x80)) { - state->last_ber = BER[2] << 8 | BER[1]; - stv0297_writereg_mask(state, 0xA0, 0x80, 0x80); - } - - *ber = state->last_ber; - - return 0; -} - - -static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength) -{ - struct stv0297_state *state = fe->demodulator_priv; - u8 STRENGTH[3]; - u16 tmp; - - stv0297_readregs(state, 0x41, STRENGTH, 3); - tmp = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0]; - if (STRENGTH[2] & 0x20) { - if (tmp < 0x200) - tmp = 0; - else - tmp = tmp - 0x200; - } else { - if (tmp > 0x1ff) - tmp = 0; - else - tmp = 0x1ff - tmp; - } - *strength = (tmp << 7) | (tmp >> 2); - return 0; -} - -static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr) -{ - struct stv0297_state *state = fe->demodulator_priv; - u8 SNR[2]; - - stv0297_readregs(state, 0x07, SNR, 2); - *snr = SNR[1] << 8 | SNR[0]; - - return 0; -} - -static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) -{ - struct stv0297_state *state = fe->demodulator_priv; - - stv0297_writereg_mask(state, 0xDF, 0x03, 0x03); /* freeze the counters */ - - *ucblocks = (stv0297_readreg(state, 0xD5) << 8) - | stv0297_readreg(state, 0xD4); - - stv0297_writereg_mask(state, 0xDF, 0x03, 0x02); /* clear the counters */ - stv0297_writereg_mask(state, 0xDF, 0x03, 0x01); /* re-enable the counters */ - - return 0; -} - -static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct stv0297_state *state = fe->demodulator_priv; - int u_threshold; - int initial_u; - int blind_u; - int delay; - int sweeprate; - int carrieroffset; - unsigned long starttime; - unsigned long timeout; - fe_spectral_inversion_t inversion; - - switch (p->u.qam.modulation) { - case QAM_16: - case QAM_32: - case QAM_64: - delay = 100; - sweeprate = 1000; - break; - - case QAM_128: - case QAM_256: - delay = 200; - sweeprate = 500; - break; - - default: - return -EINVAL; - } - - // determine inversion dependant parameters - inversion = p->inversion; - if (state->config->invert) - inversion = (inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON; - carrieroffset = -330; - switch (inversion) { - case INVERSION_OFF: - break; - - case INVERSION_ON: - sweeprate = -sweeprate; - carrieroffset = -carrieroffset; - break; - - default: - return -EINVAL; - } - - stv0297_init(fe); - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* clear software interrupts */ - stv0297_writereg(state, 0x82, 0x0); - - /* set initial demodulation frequency */ - stv0297_set_initialdemodfreq(state, 7250); - - /* setup AGC */ - stv0297_writereg_mask(state, 0x43, 0x10, 0x00); - stv0297_writereg(state, 0x41, 0x00); - stv0297_writereg_mask(state, 0x42, 0x03, 0x01); - stv0297_writereg_mask(state, 0x36, 0x60, 0x00); - stv0297_writereg_mask(state, 0x36, 0x18, 0x00); - stv0297_writereg_mask(state, 0x71, 0x80, 0x80); - stv0297_writereg(state, 0x72, 0x00); - stv0297_writereg(state, 0x73, 0x00); - stv0297_writereg_mask(state, 0x74, 0x0F, 0x00); - stv0297_writereg_mask(state, 0x43, 0x08, 0x00); - stv0297_writereg_mask(state, 0x71, 0x80, 0x00); - - /* setup STL */ - stv0297_writereg_mask(state, 0x5a, 0x20, 0x20); - stv0297_writereg_mask(state, 0x5b, 0x02, 0x02); - stv0297_writereg_mask(state, 0x5b, 0x02, 0x00); - stv0297_writereg_mask(state, 0x5b, 0x01, 0x00); - stv0297_writereg_mask(state, 0x5a, 0x40, 0x40); - - /* disable frequency sweep */ - stv0297_writereg_mask(state, 0x6a, 0x01, 0x00); - - /* reset deinterleaver */ - stv0297_writereg_mask(state, 0x81, 0x01, 0x01); - stv0297_writereg_mask(state, 0x81, 0x01, 0x00); - - /* ??? */ - stv0297_writereg_mask(state, 0x83, 0x20, 0x20); - stv0297_writereg_mask(state, 0x83, 0x20, 0x00); - - /* reset equaliser */ - u_threshold = stv0297_readreg(state, 0x00) & 0xf; - initial_u = stv0297_readreg(state, 0x01) >> 4; - blind_u = stv0297_readreg(state, 0x01) & 0xf; - stv0297_writereg_mask(state, 0x84, 0x01, 0x01); - stv0297_writereg_mask(state, 0x84, 0x01, 0x00); - stv0297_writereg_mask(state, 0x00, 0x0f, u_threshold); - stv0297_writereg_mask(state, 0x01, 0xf0, initial_u << 4); - stv0297_writereg_mask(state, 0x01, 0x0f, blind_u); - - /* data comes from internal A/D */ - stv0297_writereg_mask(state, 0x87, 0x80, 0x00); - - /* clear phase registers */ - stv0297_writereg(state, 0x63, 0x00); - stv0297_writereg(state, 0x64, 0x00); - stv0297_writereg(state, 0x65, 0x00); - stv0297_writereg(state, 0x66, 0x00); - stv0297_writereg(state, 0x67, 0x00); - stv0297_writereg(state, 0x68, 0x00); - stv0297_writereg_mask(state, 0x69, 0x0f, 0x00); - - /* set parameters */ - stv0297_set_qam(state, p->u.qam.modulation); - stv0297_set_symbolrate(state, p->u.qam.symbol_rate / 1000); - stv0297_set_sweeprate(state, sweeprate, p->u.qam.symbol_rate / 1000); - stv0297_set_carrieroffset(state, carrieroffset); - stv0297_set_inversion(state, inversion); - - /* kick off lock */ - /* Disable corner detection for higher QAMs */ - if (p->u.qam.modulation == QAM_128 || - p->u.qam.modulation == QAM_256) - stv0297_writereg_mask(state, 0x88, 0x08, 0x00); - else - stv0297_writereg_mask(state, 0x88, 0x08, 0x08); - - stv0297_writereg_mask(state, 0x5a, 0x20, 0x00); - stv0297_writereg_mask(state, 0x6a, 0x01, 0x01); - stv0297_writereg_mask(state, 0x43, 0x40, 0x40); - stv0297_writereg_mask(state, 0x5b, 0x30, 0x00); - stv0297_writereg_mask(state, 0x03, 0x0c, 0x0c); - stv0297_writereg_mask(state, 0x03, 0x03, 0x03); - stv0297_writereg_mask(state, 0x43, 0x10, 0x10); - - /* wait for WGAGC lock */ - starttime = jiffies; - timeout = jiffies + msecs_to_jiffies(2000); - while (time_before(jiffies, timeout)) { - msleep(10); - if (stv0297_readreg(state, 0x43) & 0x08) - break; - } - if (time_after(jiffies, timeout)) { - goto timeout; - } - msleep(20); - - /* wait for equaliser partial convergence */ - timeout = jiffies + msecs_to_jiffies(500); - while (time_before(jiffies, timeout)) { - msleep(10); - - if (stv0297_readreg(state, 0x82) & 0x04) { - break; - } - } - if (time_after(jiffies, timeout)) { - goto timeout; - } - - /* wait for equaliser full convergence */ - timeout = jiffies + msecs_to_jiffies(delay); - while (time_before(jiffies, timeout)) { - msleep(10); - - if (stv0297_readreg(state, 0x82) & 0x08) { - break; - } - } - if (time_after(jiffies, timeout)) { - goto timeout; - } - - /* disable sweep */ - stv0297_writereg_mask(state, 0x6a, 1, 0); - stv0297_writereg_mask(state, 0x88, 8, 0); - - /* wait for main lock */ - timeout = jiffies + msecs_to_jiffies(20); - while (time_before(jiffies, timeout)) { - msleep(10); - - if (stv0297_readreg(state, 0xDF) & 0x80) { - break; - } - } - if (time_after(jiffies, timeout)) { - goto timeout; - } - msleep(100); - - /* is it still locked after that delay? */ - if (!(stv0297_readreg(state, 0xDF) & 0x80)) { - goto timeout; - } - - /* success!! */ - stv0297_writereg_mask(state, 0x5a, 0x40, 0x00); - state->base_freq = p->frequency; - return 0; - -timeout: - stv0297_writereg_mask(state, 0x6a, 0x01, 0x00); - return 0; -} - -static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct stv0297_state *state = fe->demodulator_priv; - int reg_00, reg_83; - - reg_00 = stv0297_readreg(state, 0x00); - reg_83 = stv0297_readreg(state, 0x83); - - p->frequency = state->base_freq; - p->inversion = (reg_83 & 0x08) ? INVERSION_ON : INVERSION_OFF; - if (state->config->invert) - p->inversion = (p->inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON; - p->u.qam.symbol_rate = stv0297_get_symbolrate(state) * 1000; - p->u.qam.fec_inner = FEC_NONE; - - switch ((reg_00 >> 4) & 0x7) { - case 0: - p->u.qam.modulation = QAM_16; - break; - case 1: - p->u.qam.modulation = QAM_32; - break; - case 2: - p->u.qam.modulation = QAM_128; - break; - case 3: - p->u.qam.modulation = QAM_256; - break; - case 4: - p->u.qam.modulation = QAM_64; - break; - } - - return 0; -} - -static void stv0297_release(struct dvb_frontend *fe) -{ - struct stv0297_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops stv0297_ops; - -struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, - struct i2c_adapter *i2c) -{ - struct stv0297_state *state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct stv0297_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->last_ber = 0; - state->base_freq = 0; - - /* check if the demod is there */ - if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &stv0297_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops stv0297_ops = { - - .info = { - .name = "ST STV0297 DVB-C", - .type = FE_QAM, - .frequency_min = 47000000, - .frequency_max = 862000000, - .frequency_stepsize = 62500, - .symbol_rate_min = 870000, - .symbol_rate_max = 11700000, - .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | - FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO}, - - .release = stv0297_release, - - .init = stv0297_init, - .sleep = stv0297_sleep, - .i2c_gate_ctrl = stv0297_i2c_gate_ctrl, - - .set_frontend = stv0297_set_frontend, - .get_frontend = stv0297_get_frontend, - - .read_status = stv0297_read_status, - .read_ber = stv0297_read_ber, - .read_signal_strength = stv0297_read_signal_strength, - .read_snr = stv0297_read_snr, - .read_ucblocks = stv0297_read_ucblocks, -}; - -MODULE_DESCRIPTION("ST STV0297 DVB-C Demodulator driver"); -MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(stv0297_attach); diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h deleted file mode 100644 index 3f8f9468f38..00000000000 --- a/drivers/media/dvb/frontends/stv0297.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Driver for STV0297 demodulator - - Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de> - - 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 STV0297_H -#define STV0297_H - -#include <linux/dvb/frontend.h> -#include "dvb_frontend.h" - -struct stv0297_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* inittab - array of pairs of values. - * First of each pair is the register, second is the value. - * List should be terminated with an 0xff, 0xff pair. - */ - u8* inittab; - - /* does the "inversion" need inverted? */ - u8 invert:1; - - /* set to 1 if the device requires an i2c STOP during reading */ - u8 stop_during_read:1; -}; - -#if defined(CONFIG_DVB_STV0297) || (defined(CONFIG_DVB_STV0297_MODULE) && defined(MODULE)) -extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_STV0297 - -#endif // STV0297_H diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c deleted file mode 100644 index 6c1cb1973c6..00000000000 --- a/drivers/media/dvb/frontends/stv0299.c +++ /dev/null @@ -1,754 +0,0 @@ -/* - Driver for ST STV0299 demodulator - - Copyright (C) 2001-2002 Convergence Integrated Media GmbH - <ralph@convergence.de>, - <holger@convergence.de>, - <js@convergence.de> - - - Philips SU1278/SH - - Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de> - - - LG TDQF-S001F - - Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net> - & Andreas Oberritter <obi@linuxtv.org> - - - Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B - - Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>: - - Support for Philips SU1278 on Technotrend hardware - - Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net> - - 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 <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/jiffies.h> -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "stv0299.h" - -struct stv0299_state { - struct i2c_adapter* i2c; - const struct stv0299_config* config; - struct dvb_frontend frontend; - - u8 initialised:1; - u32 tuner_frequency; - u32 symbol_rate; - fe_code_rate_t fec_inner; - int errmode; - u32 ucblocks; -}; - -#define STATUS_BER 0 -#define STATUS_UCBLOCKS 1 - -static int debug; -static int debug_legacy_dish_switch; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "stv0299: " args); \ - } while (0) - - -static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data) -{ - int ret; - u8 buf [] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - - ret = i2c_transfer (state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len) -{ - struct stv0299_state* state = fe->demodulator_priv; - - if (len != 2) - return -EINVAL; - - return stv0299_writeregI(state, buf[0], buf[1]); -} - -static u8 stv0299_readreg (struct stv0299_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - ret = i2c_transfer (state->i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", - __func__, reg, ret); - - return b1[0]; -} - -static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len) -{ - int ret; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = ®1, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } }; - - ret = i2c_transfer (state->i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (ret == %i)\n", __func__, ret); - - return ret == 2 ? 0 : ret; -} - -static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) -{ - dprintk ("%s\n", __func__); - - switch (fec) { - case FEC_AUTO: - { - return stv0299_writeregI (state, 0x31, 0x1f); - } - case FEC_1_2: - { - return stv0299_writeregI (state, 0x31, 0x01); - } - case FEC_2_3: - { - return stv0299_writeregI (state, 0x31, 0x02); - } - case FEC_3_4: - { - return stv0299_writeregI (state, 0x31, 0x04); - } - case FEC_5_6: - { - return stv0299_writeregI (state, 0x31, 0x08); - } - case FEC_7_8: - { - return stv0299_writeregI (state, 0x31, 0x10); - } - default: - { - return -EINVAL; - } - } -} - -static fe_code_rate_t stv0299_get_fec (struct stv0299_state* state) -{ - static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6, - FEC_7_8, FEC_1_2 }; - u8 index; - - dprintk ("%s\n", __func__); - - index = stv0299_readreg (state, 0x1b); - index &= 0x7; - - if (index > 4) - return FEC_AUTO; - - return fec_tab [index]; -} - -static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout) -{ - unsigned long start = jiffies; - - dprintk ("%s\n", __func__); - - while (stv0299_readreg(state, 0x0a) & 1) { - if (jiffies - start > timeout) { - dprintk ("%s: timeout!!\n", __func__); - return -ETIMEDOUT; - } - msleep(10); - }; - - return 0; -} - -static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout) -{ - unsigned long start = jiffies; - - dprintk ("%s\n", __func__); - - while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) { - if (jiffies - start > timeout) { - dprintk ("%s: timeout!!\n", __func__); - return -ETIMEDOUT; - } - msleep(10); - }; - - return 0; -} - -static int stv0299_set_symbolrate (struct dvb_frontend* fe, u32 srate) -{ - struct stv0299_state* state = fe->demodulator_priv; - u64 big = srate; - u32 ratio; - - // check rate is within limits - if ((srate < 1000000) || (srate > 45000000)) return -EINVAL; - - // calculate value to program - big = big << 20; - big += (state->config->mclk-1); // round correctly - do_div(big, state->config->mclk); - ratio = big << 4; - - return state->config->set_symbol_rate(fe, srate, ratio); -} - -static int stv0299_get_symbolrate (struct stv0299_state* state) -{ - u32 Mclk = state->config->mclk / 4096L; - u32 srate; - s32 offset; - u8 sfr[3]; - s8 rtf; - - dprintk ("%s\n", __func__); - - stv0299_readregs (state, 0x1f, sfr, 3); - stv0299_readregs (state, 0x1a, (u8 *)&rtf, 1); - - srate = (sfr[0] << 8) | sfr[1]; - srate *= Mclk; - srate /= 16; - srate += (sfr[2] >> 4) * Mclk / 256; - offset = (s32) rtf * (srate / 4096L); - offset /= 128; - - dprintk ("%s : srate = %i\n", __func__, srate); - dprintk ("%s : ofset = %i\n", __func__, offset); - - srate += offset; - - srate += 1000; - srate /= 2000; - srate *= 2000; - - return srate; -} - -static int stv0299_send_diseqc_msg (struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd *m) -{ - struct stv0299_state* state = fe->demodulator_priv; - u8 val; - int i; - - dprintk ("%s\n", __func__); - - if (stv0299_wait_diseqc_idle (state, 100) < 0) - return -ETIMEDOUT; - - val = stv0299_readreg (state, 0x08); - - if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x6)) /* DiSEqC mode */ - return -EREMOTEIO; - - for (i=0; i<m->msg_len; i++) { - if (stv0299_wait_diseqc_fifo (state, 100) < 0) - return -ETIMEDOUT; - - if (stv0299_writeregI (state, 0x09, m->msg[i])) - return -EREMOTEIO; - } - - if (stv0299_wait_diseqc_idle (state, 100) < 0) - return -ETIMEDOUT; - - return 0; -} - -static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) -{ - struct stv0299_state* state = fe->demodulator_priv; - u8 val; - - dprintk ("%s\n", __func__); - - if (stv0299_wait_diseqc_idle (state, 100) < 0) - return -ETIMEDOUT; - - val = stv0299_readreg (state, 0x08); - - if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x2)) /* burst mode */ - return -EREMOTEIO; - - if (stv0299_writeregI (state, 0x09, burst == SEC_MINI_A ? 0x00 : 0xff)) - return -EREMOTEIO; - - if (stv0299_wait_diseqc_idle (state, 100) < 0) - return -ETIMEDOUT; - - if (stv0299_writeregI (state, 0x08, val)) - return -EREMOTEIO; - - return 0; -} - -static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct stv0299_state* state = fe->demodulator_priv; - u8 val; - - if (stv0299_wait_diseqc_idle (state, 100) < 0) - return -ETIMEDOUT; - - val = stv0299_readreg (state, 0x08); - - switch (tone) { - case SEC_TONE_ON: - return stv0299_writeregI (state, 0x08, val | 0x3); - - case SEC_TONE_OFF: - return stv0299_writeregI (state, 0x08, (val & ~0x3) | 0x02); - - default: - return -EINVAL; - } -} - -static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct stv0299_state* state = fe->demodulator_priv; - u8 reg0x08; - u8 reg0x0c; - - dprintk("%s: %s\n", __func__, - voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : - voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); - - reg0x08 = stv0299_readreg (state, 0x08); - reg0x0c = stv0299_readreg (state, 0x0c); - - /** - * H/V switching over OP0, OP1 and OP2 are LNB power enable bits - */ - reg0x0c &= 0x0f; - reg0x08 = (reg0x08 & 0x3f) | (state->config->lock_output << 6); - - switch (voltage) { - case SEC_VOLTAGE_13: - if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0) - reg0x0c |= 0x10; /* OP1 off, OP0 on */ - else - reg0x0c |= 0x40; /* OP1 on, OP0 off */ - break; - case SEC_VOLTAGE_18: - reg0x0c |= 0x50; /* OP1 on, OP0 on */ - break; - case SEC_VOLTAGE_OFF: - /* LNB power off! */ - reg0x08 = 0x00; - reg0x0c = 0x00; - break; - default: - return -EINVAL; - }; - - if (state->config->op0_off) - reg0x0c &= ~0x10; - - stv0299_writeregI(state, 0x08, reg0x08); - return stv0299_writeregI(state, 0x0c, reg0x0c); -} - -static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd) -{ - struct stv0299_state* state = fe->demodulator_priv; - u8 reg0x08; - u8 reg0x0c; - u8 lv_mask = 0x40; - u8 last = 1; - int i; - struct timeval nexttime; - struct timeval tv[10]; - - reg0x08 = stv0299_readreg (state, 0x08); - reg0x0c = stv0299_readreg (state, 0x0c); - reg0x0c &= 0x0f; - stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6)); - if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0) - lv_mask = 0x10; - - cmd = cmd << 1; - if (debug_legacy_dish_switch) - printk ("%s switch command: 0x%04lx\n",__func__, cmd); - - do_gettimeofday (&nexttime); - if (debug_legacy_dish_switch) - memcpy (&tv[0], &nexttime, sizeof (struct timeval)); - stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */ - - dvb_frontend_sleep_until(&nexttime, 32000); - - for (i=0; i<9; i++) { - if (debug_legacy_dish_switch) - do_gettimeofday (&tv[i+1]); - if((cmd & 0x01) != last) { - /* set voltage to (last ? 13V : 18V) */ - stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50)); - last = (last) ? 0 : 1; - } - - cmd = cmd >> 1; - - if (i != 8) - dvb_frontend_sleep_until(&nexttime, 8000); - } - if (debug_legacy_dish_switch) { - printk ("%s(%d): switch delay (should be 32k followed by all 8k\n", - __func__, fe->dvb->num); - for (i = 1; i < 10; i++) - printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i])); - } - - return 0; -} - -static int stv0299_init (struct dvb_frontend* fe) -{ - struct stv0299_state* state = fe->demodulator_priv; - int i; - u8 reg; - u8 val; - - dprintk("stv0299: init chip\n"); - - for (i = 0; ; i += 2) { - reg = state->config->inittab[i]; - val = state->config->inittab[i+1]; - if (reg == 0xff && val == 0xff) - break; - if (reg == 0x0c && state->config->op0_off) - val &= ~0x10; - stv0299_writeregI(state, reg, val); - } - - return 0; -} - -static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct stv0299_state* state = fe->demodulator_priv; - - u8 signal = 0xff - stv0299_readreg (state, 0x18); - u8 sync = stv0299_readreg (state, 0x1b); - - dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync); - *status = 0; - - if (signal > 10) - *status |= FE_HAS_SIGNAL; - - if (sync & 0x80) - *status |= FE_HAS_CARRIER; - - if (sync & 0x10) - *status |= FE_HAS_VITERBI; - - if (sync & 0x08) - *status |= FE_HAS_SYNC; - - if ((sync & 0x98) == 0x98) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct stv0299_state* state = fe->demodulator_priv; - - if (state->errmode != STATUS_BER) - return -ENOSYS; - - *ber = stv0299_readreg(state, 0x1e) | (stv0299_readreg(state, 0x1d) << 8); - - return 0; -} - -static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct stv0299_state* state = fe->demodulator_priv; - - s32 signal = 0xffff - ((stv0299_readreg (state, 0x18) << 8) - | stv0299_readreg (state, 0x19)); - - dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __func__, - stv0299_readreg (state, 0x18), - stv0299_readreg (state, 0x19), (int) signal); - - signal = signal * 5 / 4; - *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal; - - return 0; -} - -static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct stv0299_state* state = fe->demodulator_priv; - - s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8) - | stv0299_readreg (state, 0x25)); - xsnr = 3 * (xsnr - 0xa100); - *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr; - - return 0; -} - -static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct stv0299_state* state = fe->demodulator_priv; - - if (state->errmode != STATUS_UCBLOCKS) - return -ENOSYS; - - state->ucblocks += stv0299_readreg(state, 0x1e); - state->ucblocks += (stv0299_readreg(state, 0x1d) << 8); - *ucblocks = state->ucblocks; - - return 0; -} - -static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p) -{ - struct stv0299_state* state = fe->demodulator_priv; - int invval = 0; - - dprintk ("%s : FE_SET_FRONTEND\n", __func__); - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - - // set the inversion - if (p->inversion == INVERSION_OFF) invval = 0; - else if (p->inversion == INVERSION_ON) invval = 1; - else { - printk("stv0299 does not support auto-inversion\n"); - return -EINVAL; - } - if (state->config->invert) invval = (~invval) & 1; - stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - stv0299_set_FEC (state, p->u.qpsk.fec_inner); - stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); - stv0299_writeregI(state, 0x22, 0x00); - stv0299_writeregI(state, 0x23, 0x00); - - state->tuner_frequency = p->frequency; - state->fec_inner = p->u.qpsk.fec_inner; - state->symbol_rate = p->u.qpsk.symbol_rate; - - return 0; -} - -static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p) -{ - struct stv0299_state* state = fe->demodulator_priv; - s32 derot_freq; - int invval; - - derot_freq = (s32)(s16) ((stv0299_readreg (state, 0x22) << 8) - | stv0299_readreg (state, 0x23)); - - derot_freq *= (state->config->mclk >> 16); - derot_freq += 500; - derot_freq /= 1000; - - p->frequency += derot_freq; - - invval = stv0299_readreg (state, 0x0c) & 1; - if (state->config->invert) invval = (~invval) & 1; - p->inversion = invval ? INVERSION_ON : INVERSION_OFF; - - p->u.qpsk.fec_inner = stv0299_get_fec (state); - p->u.qpsk.symbol_rate = stv0299_get_symbolrate (state); - - return 0; -} - -static int stv0299_sleep(struct dvb_frontend* fe) -{ - struct stv0299_state* state = fe->demodulator_priv; - - stv0299_writeregI(state, 0x02, 0x80); - state->initialised = 0; - - return 0; -} - -static int stv0299_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct stv0299_state* state = fe->demodulator_priv; - - if (enable) { - stv0299_writeregI(state, 0x05, 0xb5); - } else { - stv0299_writeregI(state, 0x05, 0x35); - } - udelay(1); - return 0; -} - -static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - struct stv0299_state* state = fe->demodulator_priv; - - fesettings->min_delay_ms = state->config->min_delay_ms; - if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) { - fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000; - fesettings->max_drift = 5000; - } else { - fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000; - fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000; - } - return 0; -} - -static void stv0299_release(struct dvb_frontend* fe) -{ - struct stv0299_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops stv0299_ops; - -struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, - struct i2c_adapter* i2c) -{ - struct stv0299_state* state = NULL; - int id; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct stv0299_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - state->tuner_frequency = 0; - state->symbol_rate = 0; - state->fec_inner = 0; - state->errmode = STATUS_BER; - - /* check if the demod is there */ - stv0299_writeregI(state, 0x02, 0x34); /* standby off */ - msleep(200); - id = stv0299_readreg(state, 0x00); - - /* register 0x00 contains 0xa1 for STV0299 and STV0299B */ - /* register 0x00 might contain 0x80 when returning from standby */ - if (id != 0xa1 && id != 0x80) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &stv0299_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops stv0299_ops = { - - .info = { - .name = "ST STV0299 DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - .frequency_tolerance = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 500, /* ppm */ - .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_FEC_AUTO - }, - - .release = stv0299_release, - - .init = stv0299_init, - .sleep = stv0299_sleep, - .write = stv0299_write, - .i2c_gate_ctrl = stv0299_i2c_gate_ctrl, - - .set_frontend = stv0299_set_frontend, - .get_frontend = stv0299_get_frontend, - .get_tune_settings = stv0299_get_tune_settings, - - .read_status = stv0299_read_status, - .read_ber = stv0299_read_ber, - .read_signal_strength = stv0299_read_signal_strength, - .read_snr = stv0299_read_snr, - .read_ucblocks = stv0299_read_ucblocks, - - .diseqc_send_master_cmd = stv0299_send_diseqc_msg, - .diseqc_send_burst = stv0299_send_diseqc_burst, - .set_tone = stv0299_set_tone, - .set_voltage = stv0299_set_voltage, - .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd, -}; - -module_param(debug_legacy_dish_switch, int, 0444); -MODULE_PARM_DESC(debug_legacy_dish_switch, "Enable timing analysis for Dish Network legacy switches"); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver"); -MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " - "Andreas Oberritter, Andrew de Quincey, Kenneth Aafly"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(stv0299_attach); diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h deleted file mode 100644 index 0fd96e22b65..00000000000 --- a/drivers/media/dvb/frontends/stv0299.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - Driver for ST STV0299 demodulator - - Copyright (C) 2001-2002 Convergence Integrated Media GmbH - <ralph@convergence.de>, - <holger@convergence.de>, - <js@convergence.de> - - - Philips SU1278/SH - - Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de> - - - LG TDQF-S001F - - Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net> - & Andreas Oberritter <obi@linuxtv.org> - - - Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B - - Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>: - - Support for Philips SU1278 on Technotrend hardware - - Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net> - - 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 STV0299_H -#define STV0299_H - -#include <linux/dvb/frontend.h> -#include "dvb_frontend.h" - -#define STV0299_LOCKOUTPUT_0 0 -#define STV0299_LOCKOUTPUT_1 1 -#define STV0299_LOCKOUTPUT_CF 2 -#define STV0299_LOCKOUTPUT_LK 3 - -#define STV0299_VOLT13_OP0 0 -#define STV0299_VOLT13_OP1 1 - -struct stv0299_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* inittab - array of pairs of values. - * First of each pair is the register, second is the value. - * List should be terminated with an 0xff, 0xff pair. - */ - u8* inittab; - - /* master clock to use */ - u32 mclk; - - /* does the inversion require inversion? */ - u8 invert:1; - - /* Skip reinitialisation? */ - u8 skip_reinit:1; - - /* LOCK OUTPUT setting */ - u8 lock_output:2; - - /* Is 13v controlled by OP0 or OP1? */ - u8 volt13_op0_op1:1; - - /* Turn-off OP0? */ - u8 op0_off:1; - - /* minimum delay before retuning */ - int min_delay_ms; - - /* Set the symbol rate */ - int (*set_symbol_rate)(struct dvb_frontend *fe, u32 srate, u32 ratio); - - /* Set device param to start dma */ - int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); -}; - -#if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE)) -extern struct dvb_frontend *stv0299_attach(const struct stv0299_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *stv0299_attach(const struct stv0299_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_STV0299 - -static inline int stv0299_writereg(struct dvb_frontend *fe, u8 reg, u8 val) { - int r = 0; - u8 buf[] = {reg, val}; - if (fe->ops.write) - r = fe->ops.write(fe, buf, 2); - return r; -} - -#endif // STV0299_H diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h deleted file mode 100644 index 8a1332c2031..00000000000 --- a/drivers/media/dvb/frontends/stv0900.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * stv0900.h - * - * Driver for ST STV0900 satellite demodulator IC. - * - * Copyright (C) ST Microelectronics. - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> - * - * 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 <linux/dvb/frontend.h> -#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_core.c b/drivers/media/dvb/frontends/stv0900_core.c deleted file mode 100644 index 8499bcf7f25..00000000000 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ /dev/null @@ -1,1949 +0,0 @@ -/* - * 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 <liplianin@netup.ru> - * - * 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 <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/i2c.h> - -#include "stv0900.h" -#include "stv0900_reg.h" -#include "stv0900_priv.h" -#include "stv0900_init.h" - -static int stvdebug = 1; -module_param_named(debug, stvdebug, 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; - - } - - 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 < 182; 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_P2_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 = stv0900_carr_get_quality(fe, - (const struct stv0900_table *)&stv0900_s2_cn); - *snr += 30; - *snr *= (16383 / 1030); - - 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: ", __func__); - - 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: ", __func__); - - 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; - - 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"); diff --git a/drivers/media/dvb/frontends/stv0900_init.h b/drivers/media/dvb/frontends/stv0900_init.h deleted file mode 100644 index ff388b47a4e..00000000000 --- a/drivers/media/dvb/frontends/stv0900_init.h +++ /dev/null @@ -1,441 +0,0 @@ -/* - * 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 <liplianin@netup.ru> - * - * 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<SR<=7msps */ - u8 car_loop_cut20_5; /* Cut 2.0, 3<SR<=7msps */ - u8 car_loop_cut12_10; /* Cut 1.2, 7<SR<=15msps */ - u8 car_loop_cut20_10; /* Cut 2.0, 7<SR<=15msps */ - u8 car_loop_cut12_20; /* Cut 1.2, 10<SR<=25msps */ - u8 car_loop_cut20_20; /* Cut 2.0, 10<SR<=25msps */ - u8 car_loop_cut12_30; /* Cut 1.2, 25<SR<=45msps */ - u8 car_loop_cut20_30; /* Cut 2.0, 10<SR<=45msps */ - -}; - -/* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */ -static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = { - /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ - { STV0900_QPSK_12, 0x1C, 0x0D, 0x1B, 0x2C, 0x3A, 0x1C, 0x2A, 0x3B, 0x2A, 0x1B }, - { STV0900_QPSK_35, 0x2C, 0x0D, 0x2B, 0x2C, 0x3A, 0x0C, 0x3A, 0x2B, 0x2A, 0x0B }, - { STV0900_QPSK_23, 0x2C, 0x0D, 0x2B, 0x2C, 0x0B, 0x0C, 0x3A, 0x1B, 0x2A, 0x3A }, - { STV0900_QPSK_34, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A }, - { STV0900_QPSK_45, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A }, - { STV0900_QPSK_56, 0x0D, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A }, - { STV0900_QPSK_89, 0x0D, 0x0D, 0x3B, 0x1C, 0x1B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A }, - { STV0900_QPSK_910, 0x1D, 0x0D, 0x3B, 0x1C, 0x1B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A }, - { STV0900_8PSK_35, 0x29, 0x3B, 0x09, 0x2B, 0x38, 0x0B, 0x18, 0x1A, 0x08, 0x0A }, - { STV0900_8PSK_23, 0x0A, 0x3B, 0x29, 0x2B, 0x19, 0x0B, 0x38, 0x1A, 0x18, 0x0A }, - { STV0900_8PSK_34, 0x3A, 0x3B, 0x2A, 0x2B, 0x39, 0x0B, 0x19, 0x1A, 0x38, 0x0A }, - { STV0900_8PSK_56, 0x1B, 0x3B, 0x0B, 0x2B, 0x1A, 0x0B, 0x39, 0x1A, 0x19, 0x0A }, - { STV0900_8PSK_89, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A, 0x0B, 0x39, 0x1A, 0x29, 0x39 }, - { STV0900_8PSK_910, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A, 0x0B, 0x39, 0x1A, 0x29, 0x39 } -}; - - -/* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */ -static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = { - /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ - { STV0900_QPSK_12, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D, 0x1F, 0x3D, 0x3E, 0x3D, 0x1E }, - { STV0900_QPSK_35, 0x2F, 0x3F, 0x2E, 0x2F, 0x3D, 0x0F, 0x0E, 0x2E, 0x3D, 0x0E }, - { STV0900_QPSK_23, 0x2F, 0x3F, 0x2E, 0x2F, 0x0E, 0x0F, 0x0E, 0x1E, 0x3D, 0x3D }, - { STV0900_QPSK_34, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D }, - { STV0900_QPSK_45, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D }, - { STV0900_QPSK_56, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D }, - { STV0900_QPSK_89, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D }, - { STV0900_QPSK_910, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D }, - { STV0900_8PSK_35, 0x3c, 0x0c, 0x1c, 0x3b, 0x0c, 0x3b, 0x2b, 0x2b, 0x1b, 0x2b }, - { STV0900_8PSK_23, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x3b, 0x0c, 0x2b, 0x2b, 0x2b }, - { STV0900_8PSK_34, 0x0e, 0x1c, 0x3d, 0x0c, 0x0d, 0x3b, 0x2c, 0x3b, 0x0c, 0x2b }, - { STV0900_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d }, - { STV0900_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d }, - { STV0900_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d } -}; - - - -/* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */ -static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = { - /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ - { STV0900_16APSK_23, 0x0C, 0x0C, 0x0C, 0x0C, 0x1D, 0x0C, 0x3C, 0x0C, 0x2C, 0x0C }, - { STV0900_16APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x0C, 0x2D, 0x0C, 0x1D, 0x0C }, - { STV0900_16APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x0C, 0x3D, 0x0C, 0x2D, 0x0C }, - { STV0900_16APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x0C, 0x3D, 0x0C, 0x2D, 0x0C }, - { STV0900_16APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E, 0x0C, 0x0E, 0x0C, 0x3D, 0x0C }, - { STV0900_16APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E, 0x0C, 0x0E, 0x0C, 0x3D, 0x0C }, - { STV0900_32APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C }, - { STV0900_32APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C }, - { STV0900_32APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C }, - { STV0900_32APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C }, - { STV0900_32APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C } -}; - - -/* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */ -static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = { - /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ - { STV0900_QPSK_14, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D, 0x2F, 0x2D, 0x1F, 0x3D, 0x3E }, - { STV0900_QPSK_13, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D, 0x2F, 0x3D, 0x0F, 0x3D, 0x2E }, - { STV0900_QPSK_25, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D, 0x1F, 0x3D, 0x3E, 0x3D, 0x2E } -}; - - -/* Cut 2.0 Tracking carrier loop carrier short Frame, cut 1.2 and 2.0 */ -static const struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = { - /*Mod 2M_cut1.2 2M_cut2.0 5M_cut1.2 5M_cut2.0 10M_cut1.2 10M_cut2.0 20M_cut1.2 20M_cut2.0 30M_cut1.2 30M_cut2.0 */ - { STV0900_QPSK, 0x3C, 0x2F, 0x2B, 0x2E, 0x0B, 0x0E, 0x3A, 0x0E, 0x2A, 0x3D }, - { STV0900_8PSK, 0x0B, 0x3E, 0x2A, 0x0E, 0x0A, 0x2D, 0x19, 0x0D, 0x09, 0x3C }, - { STV0900_16APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B, 0x1E, 0x3A, 0x3D, 0x2A, 0x2D }, - { STV0900_32APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B, 0x1E, 0x3A, 0x3D, 0x2A, 0x2D } -}; - -static const u16 STV0900_InitVal[182][2] = { - { R0900_OUTCFG , 0x00 }, - { R0900_MODECFG , 0xff }, - { R0900_AGCRF1CFG , 0x11 }, - { R0900_AGCRF2CFG , 0x13 }, - { R0900_TSGENERAL1X , 0x14 }, - { R0900_TSTTNR2 , 0x21 }, - { R0900_TSTTNR4 , 0x21 }, - { R0900_P2_DISTXCTL , 0x22 }, - { R0900_P2_F22TX , 0xc0 }, - { R0900_P2_F22RX , 0xc0 }, - { R0900_P2_DISRXCTL , 0x00 }, - { R0900_P2_TNRSTEPS , 0x87 }, - { R0900_P2_TNRGAIN , 0x09 }, - { R0900_P2_DMDCFGMD , 0xF9 }, - { R0900_P2_DEMOD , 0x08 }, - { R0900_P2_DMDCFG3 , 0xc4 }, - { R0900_P2_CARFREQ , 0xed }, - { R0900_P2_TNRCFG2 , 0x02 }, - { R0900_P2_TNRCFG3 , 0x02 }, - { R0900_P2_LDT , 0xd0 }, - { R0900_P2_LDT2 , 0xb8 }, - { R0900_P2_TMGCFG , 0xd2 }, - { R0900_P2_TMGTHRISE , 0x20 }, - { R0900_P2_TMGTHFALL , 0x00 }, - { R0900_P2_FECSPY , 0x88 }, - { R0900_P2_FSPYDATA , 0x3a }, - { R0900_P2_FBERCPT4 , 0x00 }, - { R0900_P2_FSPYBER , 0x10 }, - { R0900_P2_ERRCTRL1 , 0x35 }, - { R0900_P2_ERRCTRL2 , 0xc1 }, - { R0900_P2_CFRICFG , 0xf8 }, - { R0900_P2_NOSCFG , 0x1c }, - { R0900_P2_DMDT0M , 0x20 }, - { R0900_P2_CORRELMANT , 0x70 }, - { R0900_P2_CORRELABS , 0x88 }, - { R0900_P2_AGC2O , 0x5b }, - { R0900_P2_AGC2REF , 0x38 }, - { R0900_P2_CARCFG , 0xe4 }, - { R0900_P2_ACLC , 0x1A }, - { R0900_P2_BCLC , 0x09 }, - { R0900_P2_CARHDR , 0x08 }, - { R0900_P2_KREFTMG , 0xc1 }, - { R0900_P2_SFRUPRATIO , 0xf0 }, - { R0900_P2_SFRLOWRATIO , 0x70 }, - { R0900_P2_SFRSTEP , 0x58 }, - { R0900_P2_TMGCFG2 , 0x01 }, - { R0900_P2_CAR2CFG , 0x26 }, - { R0900_P2_BCLC2S2Q , 0x86 }, - { R0900_P2_BCLC2S28 , 0x86 }, - { R0900_P2_SMAPCOEF7 , 0x77 }, - { R0900_P2_SMAPCOEF6 , 0x85 }, - { R0900_P2_SMAPCOEF5 , 0x77 }, - { R0900_P2_TSCFGL , 0x20 }, - { R0900_P2_DMDCFG2 , 0x3b }, - { R0900_P2_MODCODLST0 , 0xff }, - { R0900_P2_MODCODLST1 , 0xff }, - { R0900_P2_MODCODLST2 , 0xff }, - { R0900_P2_MODCODLST3 , 0xff }, - { R0900_P2_MODCODLST4 , 0xff }, - { R0900_P2_MODCODLST5 , 0xff }, - { R0900_P2_MODCODLST6 , 0xff }, - { R0900_P2_MODCODLST7 , 0xcc }, - { R0900_P2_MODCODLST8 , 0xcc }, - { R0900_P2_MODCODLST9 , 0xcc }, - { R0900_P2_MODCODLSTA , 0xcc }, - { R0900_P2_MODCODLSTB , 0xcc }, - { R0900_P2_MODCODLSTC , 0xcc }, - { R0900_P2_MODCODLSTD , 0xcc }, - { R0900_P2_MODCODLSTE , 0xcc }, - { R0900_P2_MODCODLSTF , 0xcf }, - { R0900_P1_DISTXCTL , 0x22 }, - { R0900_P1_F22TX , 0xc0 }, - { R0900_P1_F22RX , 0xc0 }, - { R0900_P1_DISRXCTL , 0x00 }, - { R0900_P1_TNRSTEPS , 0x87 }, - { R0900_P1_TNRGAIN , 0x09 }, - { R0900_P1_DMDCFGMD , 0xf9 }, - { R0900_P1_DEMOD , 0x08 }, - { R0900_P1_DMDCFG3 , 0xc4 }, - { R0900_P1_DMDT0M , 0x20 }, - { R0900_P1_CARFREQ , 0xed }, - { R0900_P1_TNRCFG2 , 0x82 }, - { R0900_P1_TNRCFG3 , 0x02 }, - { R0900_P1_LDT , 0xd0 }, - { R0900_P1_LDT2 , 0xb8 }, - { R0900_P1_TMGCFG , 0xd2 }, - { R0900_P1_TMGTHRISE , 0x20 }, - { R0900_P1_TMGTHFALL , 0x00 }, - { R0900_P1_SFRUPRATIO , 0xf0 }, - { R0900_P1_SFRLOWRATIO , 0x70 }, - { R0900_P1_TSCFGL , 0x20 }, - { R0900_P1_FECSPY , 0x88 }, - { R0900_P1_FSPYDATA , 0x3a }, - { R0900_P1_FBERCPT4 , 0x00 }, - { R0900_P1_FSPYBER , 0x10 }, - { R0900_P1_ERRCTRL1 , 0x35 }, - { R0900_P1_ERRCTRL2 , 0xc1 }, - { R0900_P1_CFRICFG , 0xf8 }, - { R0900_P1_NOSCFG , 0x1c }, - { R0900_P1_CORRELMANT , 0x70 }, - { R0900_P1_CORRELABS , 0x88 }, - { R0900_P1_AGC2O , 0x5b }, - { R0900_P1_AGC2REF , 0x38 }, - { R0900_P1_CARCFG , 0xe4 }, - { R0900_P1_ACLC , 0x1A }, - { R0900_P1_BCLC , 0x09 }, - { R0900_P1_CARHDR , 0x08 }, - { R0900_P1_KREFTMG , 0xc1 }, - { R0900_P1_SFRSTEP , 0x58 }, - { R0900_P1_TMGCFG2 , 0x01 }, - { R0900_P1_CAR2CFG , 0x26 }, - { R0900_P1_BCLC2S2Q , 0x86 }, - { R0900_P1_BCLC2S28 , 0x86 }, - { R0900_P1_SMAPCOEF7 , 0x77 }, - { R0900_P1_SMAPCOEF6 , 0x85 }, - { R0900_P1_SMAPCOEF5 , 0x77 }, - { R0900_P1_DMDCFG2 , 0x3b }, - { R0900_P1_MODCODLST0 , 0xff }, - { R0900_P1_MODCODLST1 , 0xff }, - { R0900_P1_MODCODLST2 , 0xff }, - { R0900_P1_MODCODLST3 , 0xff }, - { R0900_P1_MODCODLST4 , 0xff }, - { R0900_P1_MODCODLST5 , 0xff }, - { R0900_P1_MODCODLST6 , 0xff }, - { R0900_P1_MODCODLST7 , 0xcc }, - { R0900_P1_MODCODLST8 , 0xcc }, - { R0900_P1_MODCODLST9 , 0xcc }, - { R0900_P1_MODCODLSTA , 0xcc }, - { R0900_P1_MODCODLSTB , 0xcc }, - { R0900_P1_MODCODLSTC , 0xcc }, - { R0900_P1_MODCODLSTD , 0xcc }, - { R0900_P1_MODCODLSTE , 0xcc }, - { R0900_P1_MODCODLSTF , 0xcf }, - { R0900_GENCFG , 0x1d }, - { R0900_NBITER_NF4 , 0x37 }, - { R0900_NBITER_NF5 , 0x29 }, - { R0900_NBITER_NF6 , 0x37 }, - { R0900_NBITER_NF7 , 0x33 }, - { R0900_NBITER_NF8 , 0x31 }, - { R0900_NBITER_NF9 , 0x2f }, - { R0900_NBITER_NF10 , 0x39 }, - { R0900_NBITER_NF11 , 0x3a }, - { R0900_NBITER_NF12 , 0x29 }, - { R0900_NBITER_NF13 , 0x37 }, - { R0900_NBITER_NF14 , 0x33 }, - { R0900_NBITER_NF15 , 0x2f }, - { R0900_NBITER_NF16 , 0x39 }, - { R0900_NBITER_NF17 , 0x3a }, - { R0900_NBITERNOERR , 0x04 }, - { R0900_GAINLLR_NF4 , 0x0C }, - { R0900_GAINLLR_NF5 , 0x0F }, - { R0900_GAINLLR_NF6 , 0x11 }, - { R0900_GAINLLR_NF7 , 0x14 }, - { R0900_GAINLLR_NF8 , 0x17 }, - { R0900_GAINLLR_NF9 , 0x19 }, - { R0900_GAINLLR_NF10 , 0x20 }, - { R0900_GAINLLR_NF11 , 0x21 }, - { R0900_GAINLLR_NF12 , 0x0D }, - { R0900_GAINLLR_NF13 , 0x0F }, - { R0900_GAINLLR_NF14 , 0x13 }, - { R0900_GAINLLR_NF15 , 0x1A }, - { R0900_GAINLLR_NF16 , 0x1F }, - { R0900_GAINLLR_NF17 , 0x21 }, - { R0900_RCCFGH , 0x20 }, - { R0900_P1_FECM , 0x01 }, /*disable DSS modes*/ - { R0900_P2_FECM , 0x01 }, /*disable DSS modes*/ - { R0900_P1_PRVIT , 0x2F }, /*disable puncture rate 6/7*/ - { R0900_P2_PRVIT , 0x2F }, /*disable puncture rate 6/7*/ - { R0900_STROUT1CFG , 0x4c }, - { R0900_STROUT2CFG , 0x4c }, - { R0900_CLKOUT1CFG , 0x50 }, - { R0900_CLKOUT2CFG , 0x50 }, - { R0900_DPN1CFG , 0x4a }, - { R0900_DPN2CFG , 0x4a }, - { R0900_DATA71CFG , 0x52 }, - { 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 }, -}; - -static const u16 STV0900_Cut20_AddOnVal[32][2] = { - { R0900_P2_DMDCFG3 , 0xe8 }, - { R0900_P2_DMDCFG4 , 0x10 }, - { R0900_P2_CARFREQ , 0x38 }, - { R0900_P2_CARHDR , 0x20 }, - { R0900_P2_KREFTMG , 0x5a }, - { R0900_P2_SMAPCOEF7 , 0x06 }, - { R0900_P2_SMAPCOEF6 , 0x00 }, - { R0900_P2_SMAPCOEF5 , 0x04 }, - { R0900_P2_NOSCFG , 0x0c }, - { R0900_P1_DMDCFG3 , 0xe8 }, - { R0900_P1_DMDCFG4 , 0x10 }, - { R0900_P1_CARFREQ , 0x38 }, - { R0900_P1_CARHDR , 0x20 }, - { R0900_P1_KREFTMG , 0x5a }, - { R0900_P1_SMAPCOEF7 , 0x06 }, - { R0900_P1_SMAPCOEF6 , 0x00 }, - { R0900_P1_SMAPCOEF5 , 0x04 }, - { R0900_P1_NOSCFG , 0x0c }, - { R0900_GAINLLR_NF4 , 0x21 }, - { R0900_GAINLLR_NF5 , 0x21 }, - { R0900_GAINLLR_NF6 , 0x20 }, - { R0900_GAINLLR_NF7 , 0x1F }, - { R0900_GAINLLR_NF8 , 0x1E }, - { R0900_GAINLLR_NF9 , 0x1E }, - { R0900_GAINLLR_NF10 , 0x1D }, - { R0900_GAINLLR_NF11 , 0x1B }, - { R0900_GAINLLR_NF12 , 0x20 }, - { R0900_GAINLLR_NF13 , 0x20 }, - { R0900_GAINLLR_NF14 , 0x20 }, - { R0900_GAINLLR_NF15 , 0x20 }, - { R0900_GAINLLR_NF16 , 0x20 }, - { R0900_GAINLLR_NF17 , 0x21 } - -}; - -#endif diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h deleted file mode 100644 index 762d5af62d7..00000000000 --- a/drivers/media/dvb/frontends/stv0900_priv.h +++ /dev/null @@ -1,430 +0,0 @@ -/* - * stv0900_priv.h - * - * Driver for ST STV0900 satellite demodulator IC. - * - * Copyright (C) ST Microelectronics. - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> - * - * 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 <linux/i2c.h> - -#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)) - -static int stvdebug; - -#define dprintk(args...) \ - do { \ - if (stvdebug) \ - 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 diff --git a/drivers/media/dvb/frontends/stv0900_reg.h b/drivers/media/dvb/frontends/stv0900_reg.h deleted file mode 100644 index 264f9cf9a17..00000000000 --- a/drivers/media/dvb/frontends/stv0900_reg.h +++ /dev/null @@ -1,3787 +0,0 @@ -/* - * 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 <liplianin@netup.ru> - * - * 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 - diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c deleted file mode 100644 index a5a31536cbc..00000000000 --- a/drivers/media/dvb/frontends/stv0900_sw.c +++ /dev/null @@ -1,2847 +0,0 @@ -/* - * 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 <liplianin@netup.ru> - * - * 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; -} - diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c deleted file mode 100644 index 70efac869d2..00000000000 --- a/drivers/media/dvb/frontends/stv6110.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * stv6110.c - * - * Driver for ST STV6110 satellite tuner IC. - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> - * - * 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 <linux/module.h> -#include <linux/dvb/frontend.h> - -#include <linux/types.h> - -#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 deleted file mode 100644 index 1c0314d6aa5..00000000000 --- a/drivers/media/dvb/frontends/stv6110.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * stv6110.h - * - * Driver for ST STV6110 satellite tuner IC. - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> - * - * 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 <linux/i2c.h> -#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 diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c deleted file mode 100644 index f648fdb64bb..00000000000 --- a/drivers/media/dvb/frontends/tda10021.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - TDA10021 - Single Chip Cable Channel Receiver driver module - used on the Siemens DVB-C cards - - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> - Support for TDA10021 - - 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 <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "tda1002x.h" - - -struct tda10021_state { - struct i2c_adapter* i2c; - /* configuration settings */ - const struct tda1002x_config* config; - struct dvb_frontend frontend; - - u8 pwm; - u8 reg0; -}; - - -#if 0 -#define dprintk(x...) printk(x) -#else -#define dprintk(x...) -#endif - -static int verbose; - -#define XIN 57840000UL - -#define FIN (XIN >> 4) - -static int tda10021_inittab_size = 0x40; -static u8 tda10021_inittab[0x40]= -{ - 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a, - 0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40, - 0xb8, 0x3f, 0xa1, 0x00, 0xcd, 0x01, 0x00, 0xff, - 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58, - 0x00, 0x00, 0x80, 0x00, 0x80, 0xff, 0x00, 0x00, - 0x04, 0x2d, 0x2f, 0xff, 0x00, 0x00, 0x00, 0x00, -}; - -static int _tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - int ret; - - ret = i2c_transfer (state->i2c, &msg, 1); - if (ret != 1) - printk("DVB: TDA10021(%d): %s, writereg error " - "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", - state->frontend.dvb->num, __func__, reg, data, ret); - - msleep(10); - return (ret != 1) ? -EREMOTEIO : 0; -} - -static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) -{ - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - int ret; - - ret = i2c_transfer (state->i2c, msg, 2); - // Don't print an error message if the id is read. - if (ret != 2 && reg != 0x1a) - printk("DVB: TDA10021: %s: readreg error (ret == %i)\n", - __func__, ret); - return b1[0]; -} - -//get access to tuner -static int lock_tuner(struct tda10021_state* state) -{ - u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] | 0x80 }; - struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2}; - - if(i2c_transfer(state->i2c, &msg, 1) != 1) - { - printk("tda10021: lock tuner fails\n"); - return -EREMOTEIO; - } - return 0; -} - -//release access from tuner -static int unlock_tuner(struct tda10021_state* state) -{ - u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] & 0x7f }; - struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2}; - - if(i2c_transfer(state->i2c, &msg_post, 1) != 1) - { - printk("tda10021: unlock tuner fails\n"); - return -EREMOTEIO; - } - return 0; -} - -static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0, - fe_spectral_inversion_t inversion) -{ - reg0 |= state->reg0 & 0x63; - - if ((INVERSION_ON == inversion) ^ (state->config->invert == 0)) - reg0 &= ~0x20; - else - reg0 |= 0x20; - - _tda10021_writereg (state, 0x00, reg0 & 0xfe); - _tda10021_writereg (state, 0x00, reg0 | 0x01); - - state->reg0 = reg0; - return 0; -} - -static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate) -{ - s32 BDR; - s32 BDRI; - s16 SFIL=0; - u16 NDEC = 0; - u32 tmp, ratio; - - if (symbolrate > XIN/2) - symbolrate = XIN/2; - if (symbolrate < 500000) - symbolrate = 500000; - - if (symbolrate < XIN/16) NDEC = 1; - if (symbolrate < XIN/32) NDEC = 2; - if (symbolrate < XIN/64) NDEC = 3; - - if (symbolrate < (u32)(XIN/12.3)) SFIL = 1; - if (symbolrate < (u32)(XIN/16)) SFIL = 0; - if (symbolrate < (u32)(XIN/24.6)) SFIL = 1; - if (symbolrate < (u32)(XIN/32)) SFIL = 0; - if (symbolrate < (u32)(XIN/49.2)) SFIL = 1; - if (symbolrate < (u32)(XIN/64)) SFIL = 0; - if (symbolrate < (u32)(XIN/98.4)) SFIL = 1; - - symbolrate <<= NDEC; - ratio = (symbolrate << 4) / FIN; - tmp = ((symbolrate << 4) % FIN) << 8; - ratio = (ratio << 8) + tmp / FIN; - tmp = (tmp % FIN) << 8; - ratio = (ratio << 8) + (tmp + FIN/2) / FIN; - - BDR = ratio; - BDRI = (((XIN << 5) / symbolrate) + 1) / 2; - - if (BDRI > 0xFF) - BDRI = 0xFF; - - SFIL = (SFIL << 4) | tda10021_inittab[0x0E]; - - NDEC = (NDEC << 6) | tda10021_inittab[0x03]; - - _tda10021_writereg (state, 0x03, NDEC); - _tda10021_writereg (state, 0x0a, BDR&0xff); - _tda10021_writereg (state, 0x0b, (BDR>> 8)&0xff); - _tda10021_writereg (state, 0x0c, (BDR>>16)&0x3f); - - _tda10021_writereg (state, 0x0d, BDRI); - _tda10021_writereg (state, 0x0e, SFIL); - - return 0; -} - -static int tda10021_init (struct dvb_frontend *fe) -{ - struct tda10021_state* state = fe->demodulator_priv; - int i; - - dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num); - - //_tda10021_writereg (fe, 0, 0); - - for (i=0; i<tda10021_inittab_size; i++) - _tda10021_writereg (state, i, tda10021_inittab[i]); - - _tda10021_writereg (state, 0x34, state->pwm); - - //Comment by markus - //0x2A[3-0] == PDIV -> P multiplaying factor (P=PDIV+1)(default 0) - //0x2A[4] == BYPPLL -> Power down mode (default 1) - //0x2A[5] == LCK -> PLL Lock Flag - //0x2A[6] == POLAXIN -> Polarity of the input reference clock (default 0) - - //Activate PLL - _tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef); - return 0; -} - -static int tda10021_set_parameters (struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct tda10021_state* state = fe->demodulator_priv; - - //table for QAM4-QAM256 ready QAM4 QAM16 QAM32 QAM64 QAM128 QAM256 - //CONF - static const u8 reg0x00 [] = { 0x14, 0x00, 0x04, 0x08, 0x0c, 0x10 }; - //AGCREF value - static const u8 reg0x01 [] = { 0x78, 0x8c, 0x8c, 0x6a, 0x78, 0x5c }; - //LTHR value - static const u8 reg0x05 [] = { 0x78, 0x87, 0x64, 0x46, 0x36, 0x26 }; - //MSETH - static const u8 reg0x08 [] = { 0x8c, 0xa2, 0x74, 0x43, 0x34, 0x23 }; - //AREF - static const u8 reg0x09 [] = { 0x96, 0x91, 0x96, 0x6a, 0x7e, 0x6b }; - - int qam = p->u.qam.modulation; - - if (qam < 0 || qam > 5) - return -EINVAL; - - if (p->inversion != INVERSION_ON && p->inversion != INVERSION_OFF) - return -EINVAL; - - //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - tda10021_set_symbolrate (state, p->u.qam.symbol_rate); - _tda10021_writereg (state, 0x34, state->pwm); - - _tda10021_writereg (state, 0x01, reg0x01[qam]); - _tda10021_writereg (state, 0x05, reg0x05[qam]); - _tda10021_writereg (state, 0x08, reg0x08[qam]); - _tda10021_writereg (state, 0x09, reg0x09[qam]); - - tda10021_setup_reg0 (state, reg0x00[qam], p->inversion); - - return 0; -} - -static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct tda10021_state* state = fe->demodulator_priv; - int sync; - - *status = 0; - //0x11[0] == EQALGO -> Equalizer algorithms state - //0x11[1] == CARLOCK -> Carrier locked - //0x11[2] == FSYNC -> Frame synchronisation - //0x11[3] == FEL -> Front End locked - //0x11[6] == NODVB -> DVB Mode Information - sync = tda10021_readreg (state, 0x11); - - if (sync & 2) - *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER; - - if (sync & 4) - *status |= FE_HAS_SYNC|FE_HAS_VITERBI; - - if (sync & 8) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct tda10021_state* state = fe->demodulator_priv; - - u32 _ber = tda10021_readreg(state, 0x14) | - (tda10021_readreg(state, 0x15) << 8) | - ((tda10021_readreg(state, 0x16) & 0x0f) << 16); - _tda10021_writereg(state, 0x10, (tda10021_readreg(state, 0x10) & ~0xc0) - | (tda10021_inittab[0x10] & 0xc0)); - *ber = 10 * _ber; - - return 0; -} - -static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct tda10021_state* state = fe->demodulator_priv; - - u8 config = tda10021_readreg(state, 0x02); - u8 gain = tda10021_readreg(state, 0x17); - if (config & 0x02) - /* the agc value is inverted */ - gain = ~gain; - *strength = (gain << 8) | gain; - - return 0; -} - -static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct tda10021_state* state = fe->demodulator_priv; - - u8 quality = ~tda10021_readreg(state, 0x18); - *snr = (quality << 8) | quality; - - return 0; -} - -static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct tda10021_state* state = fe->demodulator_priv; - - *ucblocks = tda10021_readreg (state, 0x13) & 0x7f; - if (*ucblocks == 0x7f) - *ucblocks = 0xffffffff; - - /* reset uncorrected block counter */ - _tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf); - _tda10021_writereg (state, 0x10, tda10021_inittab[0x10]); - - return 0; -} - -static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct tda10021_state* state = fe->demodulator_priv; - int sync; - s8 afc = 0; - - sync = tda10021_readreg(state, 0x11); - afc = tda10021_readreg(state, 0x19); - if (verbose) { - /* AFC only valid when carrier has been recovered */ - printk(sync & 2 ? "DVB: TDA10021(%d): AFC (%d) %dHz\n" : - "DVB: TDA10021(%d): [AFC (%d) %dHz]\n", - state->frontend.dvb->num, afc, - -((s32)p->u.qam.symbol_rate * afc) >> 10); - } - - p->inversion = ((state->reg0 & 0x20) == 0x20) ^ (state->config->invert != 0) ? INVERSION_ON : INVERSION_OFF; - p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; - - p->u.qam.fec_inner = FEC_NONE; - p->frequency = ((p->frequency + 31250) / 62500) * 62500; - - if (sync & 2) - p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10; - - return 0; -} - -static int tda10021_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct tda10021_state* state = fe->demodulator_priv; - - if (enable) { - lock_tuner(state); - } else { - unlock_tuner(state); - } - return 0; -} - -static int tda10021_sleep(struct dvb_frontend* fe) -{ - struct tda10021_state* state = fe->demodulator_priv; - - _tda10021_writereg (state, 0x1b, 0x02); /* pdown ADC */ - _tda10021_writereg (state, 0x00, 0x80); /* standby */ - - return 0; -} - -static void tda10021_release(struct dvb_frontend* fe) -{ - struct tda10021_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops tda10021_ops; - -struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, - struct i2c_adapter* i2c, - u8 pwm) -{ - struct tda10021_state* state = NULL; - u8 id; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->pwm = pwm; - state->reg0 = tda10021_inittab[0]; - - /* check if the demod is there */ - id = tda10021_readreg(state, 0x1a); - if ((id & 0xf0) != 0x70) goto error; - - printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n", - state->config->demod_address, id); - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops tda10021_ops = { - - .info = { - .name = "Philips TDA10021 DVB-C", - .type = FE_QAM, - .frequency_stepsize = 62500, - .frequency_min = 47000000, - .frequency_max = 862000000, - .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ - .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ - #if 0 - .frequency_tolerance = ???, - .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ - #endif - .caps = 0x400 | //FE_CAN_QAM_4 - FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | - FE_CAN_QAM_128 | FE_CAN_QAM_256 | - FE_CAN_FEC_AUTO - }, - - .release = tda10021_release, - - .init = tda10021_init, - .sleep = tda10021_sleep, - .i2c_gate_ctrl = tda10021_i2c_gate_ctrl, - - .set_frontend = tda10021_set_parameters, - .get_frontend = tda10021_get_frontend, - - .read_status = tda10021_read_status, - .read_ber = tda10021_read_ber, - .read_signal_strength = tda10021_read_signal_strength, - .read_snr = tda10021_read_snr, - .read_ucblocks = tda10021_read_ucblocks, -}; - -module_param(verbose, int, 0644); -MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting"); - -MODULE_DESCRIPTION("Philips TDA10021 DVB-C demodulator driver"); -MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Markus Schulz"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(tda10021_attach); diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c deleted file mode 100644 index a3c34eecdee..00000000000 --- a/drivers/media/dvb/frontends/tda10023.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - TDA10023 - DVB-C decoder - (as used in Philips CU1216-3 NIM and the Reelbox DVB-C tuner card) - - Copyright (C) 2005 Georg Acher, BayCom GmbH (acher at baycom dot de) - Copyright (c) 2006 Hartmut Birr (e9hack at gmail dot com) - - Remotely based on tda10021.c - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> - Support for TDA10021 - - 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 <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "tda1002x.h" - -#define REG0_INIT_VAL 0x23 - -struct tda10023_state { - struct i2c_adapter* i2c; - /* configuration settings */ - const struct tda10023_config *config; - struct dvb_frontend frontend; - - u8 pwm; - u8 reg0; - - /* clock settings */ - u32 xtal; - u8 pll_m; - u8 pll_p; - u8 pll_n; - u32 sysclk; -}; - -#define dprintk(x...) - -static int verbose; - -static u8 tda10023_readreg (struct tda10023_state* state, u8 reg) -{ - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - int ret; - - ret = i2c_transfer (state->i2c, msg, 2); - if (ret != 2) { - int num = state->frontend.dvb ? state->frontend.dvb->num : -1; - printk(KERN_ERR "DVB: TDA10023(%d): %s: readreg error " - "(reg == 0x%02x, ret == %i)\n", - num, __func__, reg, ret); - } - return b1[0]; -} - -static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - int ret; - - ret = i2c_transfer (state->i2c, &msg, 1); - if (ret != 1) { - int num = state->frontend.dvb ? state->frontend.dvb->num : -1; - printk(KERN_ERR "DVB: TDA10023(%d): %s, writereg error " - "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", - num, __func__, reg, data, ret); - } - return (ret != 1) ? -EREMOTEIO : 0; -} - - -static int tda10023_writebit (struct tda10023_state* state, u8 reg, u8 mask,u8 data) -{ - if (mask==0xff) - return tda10023_writereg(state, reg, data); - else { - u8 val; - val=tda10023_readreg(state,reg); - val&=~mask; - val|=(data&mask); - return tda10023_writereg(state, reg, val); - } -} - -static void tda10023_writetab(struct tda10023_state* state, u8* tab) -{ - u8 r,m,v; - while (1) { - r=*tab++; - m=*tab++; - v=*tab++; - if (r==0xff) { - if (m==0xff) - break; - else - msleep(m); - } - else - tda10023_writebit(state,r,m,v); - } -} - -//get access to tuner -static int lock_tuner(struct tda10023_state* state) -{ - u8 buf[2] = { 0x0f, 0xc0 }; - struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2}; - - if(i2c_transfer(state->i2c, &msg, 1) != 1) - { - printk("tda10023: lock tuner fails\n"); - return -EREMOTEIO; - } - return 0; -} - -//release access from tuner -static int unlock_tuner(struct tda10023_state* state) -{ - u8 buf[2] = { 0x0f, 0x40 }; - struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2}; - - if(i2c_transfer(state->i2c, &msg_post, 1) != 1) - { - printk("tda10023: unlock tuner fails\n"); - return -EREMOTEIO; - } - return 0; -} - -static int tda10023_setup_reg0 (struct tda10023_state* state, u8 reg0) -{ - reg0 |= state->reg0 & 0x63; - - tda10023_writereg (state, 0x00, reg0 & 0xfe); - tda10023_writereg (state, 0x00, reg0 | 0x01); - - state->reg0 = reg0; - return 0; -} - -static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr) -{ - s32 BDR; - s32 BDRI; - s16 SFIL=0; - u16 NDEC = 0; - - /* avoid floating point operations multiplying syscloc and divider - by 10 */ - u32 sysclk_x_10 = state->sysclk * 10; - - if (sr < (u32)(sysclk_x_10/984)) { - NDEC=3; - SFIL=1; - } else if (sr < (u32)(sysclk_x_10/640)) { - NDEC=3; - SFIL=0; - } else if (sr < (u32)(sysclk_x_10/492)) { - NDEC=2; - SFIL=1; - } else if (sr < (u32)(sysclk_x_10/320)) { - NDEC=2; - SFIL=0; - } else if (sr < (u32)(sysclk_x_10/246)) { - NDEC=1; - SFIL=1; - } else if (sr < (u32)(sysclk_x_10/160)) { - NDEC=1; - SFIL=0; - } else if (sr < (u32)(sysclk_x_10/123)) { - NDEC=0; - SFIL=1; - } - - BDRI = (state->sysclk)*16; - BDRI>>=NDEC; - BDRI +=sr/2; - BDRI /=sr; - - if (BDRI>255) - BDRI=255; - - { - u64 BDRX; - - BDRX=1<<(24+NDEC); - BDRX*=sr; - do_div(BDRX, state->sysclk); /* BDRX/=SYSCLK; */ - - BDR=(s32)BDRX; - } - dprintk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n", - sr, BDR, BDRI, NDEC); - tda10023_writebit (state, 0x03, 0xc0, NDEC<<6); - tda10023_writereg (state, 0x0a, BDR&255); - tda10023_writereg (state, 0x0b, (BDR>>8)&255); - tda10023_writereg (state, 0x0c, (BDR>>16)&31); - tda10023_writereg (state, 0x0d, BDRI); - tda10023_writereg (state, 0x3d, (SFIL<<7)); - return 0; -} - -static int tda10023_init (struct dvb_frontend *fe) -{ - struct tda10023_state* state = fe->demodulator_priv; - u8 tda10023_inittab[] = { -/* reg mask val */ -/* 000 */ 0x2a, 0xff, 0x02, /* PLL3, Bypass, Power Down */ -/* 003 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ -/* 006 */ 0x2a, 0xff, 0x03, /* PLL3, Bypass, Power Down */ -/* 009 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ - /* PLL1 */ -/* 012 */ 0x28, 0xff, (state->pll_m-1), - /* PLL2 */ -/* 015 */ 0x29, 0xff, ((state->pll_p-1)<<6)|(state->pll_n-1), - /* GPR FSAMPLING=1 */ -/* 018 */ 0x00, 0xff, REG0_INIT_VAL, -/* 021 */ 0x2a, 0xff, 0x08, /* PLL3 PSACLK=1 */ -/* 024 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ -/* 027 */ 0x1f, 0xff, 0x00, /* RESET */ -/* 030 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ -/* 033 */ 0xe6, 0x0c, 0x04, /* RSCFG_IND */ -/* 036 */ 0x10, 0xc0, 0x80, /* DECDVBCFG1 PBER=1 */ - -/* 039 */ 0x0e, 0xff, 0x82, /* GAIN1 */ -/* 042 */ 0x03, 0x08, 0x08, /* CLKCONF DYN=1 */ -/* 045 */ 0x2e, 0xbf, 0x30, /* AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1 - PPWMTUN=0 PPWMIF=0 */ -/* 048 */ 0x01, 0xff, 0x30, /* AGCREF */ -/* 051 */ 0x1e, 0x84, 0x84, /* CONTROL SACLK_ON=1 */ -/* 054 */ 0x1b, 0xff, 0xc8, /* ADC TWOS=1 */ -/* 057 */ 0x3b, 0xff, 0xff, /* IFMAX */ -/* 060 */ 0x3c, 0xff, 0x00, /* IFMIN */ -/* 063 */ 0x34, 0xff, 0x00, /* PWMREF */ -/* 066 */ 0x35, 0xff, 0xff, /* TUNMAX */ -/* 069 */ 0x36, 0xff, 0x00, /* TUNMIN */ -/* 072 */ 0x06, 0xff, 0x7f, /* EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 */ -/* 075 */ 0x1c, 0x30, 0x30, /* EQCONF2 STEPALGO=SGNALGO=1 */ -/* 078 */ 0x37, 0xff, 0xf6, /* DELTAF_LSB */ -/* 081 */ 0x38, 0xff, 0xff, /* DELTAF_MSB */ -/* 084 */ 0x02, 0xff, 0x93, /* AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3 */ -/* 087 */ 0x2d, 0xff, 0xf6, /* SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 */ -/* 090 */ 0x04, 0x10, 0x00, /* SWRAMP=1 */ -/* 093 */ 0x12, 0xff, TDA10023_OUTPUT_MODE_PARALLEL_B, /* - INTP1 POCLKP=1 FEL=1 MFS=0 */ -/* 096 */ 0x2b, 0x01, 0xa1, /* INTS1 */ -/* 099 */ 0x20, 0xff, 0x04, /* INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? */ -/* 102 */ 0x2c, 0xff, 0x0d, /* INTP/S TRIP=0 TRIS=0 */ -/* 105 */ 0xc4, 0xff, 0x00, -/* 108 */ 0xc3, 0x30, 0x00, -/* 111 */ 0xb5, 0xff, 0x19, /* ERAGC_THD */ -/* 114 */ 0x00, 0x03, 0x01, /* GPR, CLBS soft reset */ -/* 117 */ 0x00, 0x03, 0x03, /* GPR, CLBS soft reset */ -/* 120 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ -/* 123 */ 0xff, 0xff, 0xff -}; - dprintk("DVB: TDA10023(%d): init chip\n", fe->dvb->num); - - /* override default values if set in config */ - if (state->config->deltaf) { - tda10023_inittab[80] = (state->config->deltaf & 0xff); - tda10023_inittab[83] = (state->config->deltaf >> 8); - } - - if (state->config->output_mode) - tda10023_inittab[95] = state->config->output_mode; - - tda10023_writetab(state, tda10023_inittab); - - return 0; -} - -static int tda10023_set_parameters (struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct tda10023_state* state = fe->demodulator_priv; - - static int qamvals[6][6] = { - // QAM LOCKTHR MSETH AREF AGCREFNYQ ERAGCNYQ_THD - { (5<<2), 0x78, 0x8c, 0x96, 0x78, 0x4c }, // 4 QAM - { (0<<2), 0x87, 0xa2, 0x91, 0x8c, 0x57 }, // 16 QAM - { (1<<2), 0x64, 0x74, 0x96, 0x8c, 0x57 }, // 32 QAM - { (2<<2), 0x46, 0x43, 0x6a, 0x6a, 0x44 }, // 64 QAM - { (3<<2), 0x36, 0x34, 0x7e, 0x78, 0x4c }, // 128 QAM - { (4<<2), 0x26, 0x23, 0x6c, 0x5c, 0x3c }, // 256 QAM - }; - - int qam = p->u.qam.modulation; - - if (qam < 0 || qam > 5) - return -EINVAL; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - tda10023_set_symbolrate (state, p->u.qam.symbol_rate); - tda10023_writereg (state, 0x05, qamvals[qam][1]); - tda10023_writereg (state, 0x08, qamvals[qam][2]); - tda10023_writereg (state, 0x09, qamvals[qam][3]); - tda10023_writereg (state, 0xb4, qamvals[qam][4]); - tda10023_writereg (state, 0xb6, qamvals[qam][5]); - -// tda10023_writereg (state, 0x04, (p->inversion?0x12:0x32)); -// tda10023_writebit (state, 0x04, 0x60, (p->inversion?0:0x20)); - tda10023_writebit (state, 0x04, 0x40, 0x40); - tda10023_setup_reg0 (state, qamvals[qam][0]); - - return 0; -} - -static int tda10023_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct tda10023_state* state = fe->demodulator_priv; - int sync; - - *status = 0; - - //0x11[1] == CARLOCK -> Carrier locked - //0x11[2] == FSYNC -> Frame synchronisation - //0x11[3] == FEL -> Front End locked - //0x11[6] == NODVB -> DVB Mode Information - sync = tda10023_readreg (state, 0x11); - - if (sync & 2) - *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER; - - if (sync & 4) - *status |= FE_HAS_SYNC|FE_HAS_VITERBI; - - if (sync & 8) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int tda10023_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct tda10023_state* state = fe->demodulator_priv; - u8 a,b,c; - a=tda10023_readreg(state, 0x14); - b=tda10023_readreg(state, 0x15); - c=tda10023_readreg(state, 0x16)&0xf; - tda10023_writebit (state, 0x10, 0xc0, 0x00); - - *ber = a | (b<<8)| (c<<16); - return 0; -} - -static int tda10023_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct tda10023_state* state = fe->demodulator_priv; - u8 ifgain=tda10023_readreg(state, 0x2f); - - u16 gain = ((255-tda10023_readreg(state, 0x17))) + (255-ifgain)/16; - // Max raw value is about 0xb0 -> Normalize to >0xf0 after 0x90 - if (gain>0x90) - gain=gain+2*(gain-0x90); - if (gain>255) - gain=255; - - *strength = (gain<<8)|gain; - return 0; -} - -static int tda10023_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct tda10023_state* state = fe->demodulator_priv; - - u8 quality = ~tda10023_readreg(state, 0x18); - *snr = (quality << 8) | quality; - return 0; -} - -static int tda10023_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct tda10023_state* state = fe->demodulator_priv; - u8 a,b,c,d; - a= tda10023_readreg (state, 0x74); - b= tda10023_readreg (state, 0x75); - c= tda10023_readreg (state, 0x76); - d= tda10023_readreg (state, 0x77); - *ucblocks = a | (b<<8)|(c<<16)|(d<<24); - - tda10023_writebit (state, 0x10, 0x20,0x00); - tda10023_writebit (state, 0x10, 0x20,0x20); - tda10023_writebit (state, 0x13, 0x01, 0x00); - - return 0; -} - -static int tda10023_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct tda10023_state* state = fe->demodulator_priv; - int sync,inv; - s8 afc = 0; - - sync = tda10023_readreg(state, 0x11); - afc = tda10023_readreg(state, 0x19); - inv = tda10023_readreg(state, 0x04); - - if (verbose) { - /* AFC only valid when carrier has been recovered */ - printk(sync & 2 ? "DVB: TDA10023(%d): AFC (%d) %dHz\n" : - "DVB: TDA10023(%d): [AFC (%d) %dHz]\n", - state->frontend.dvb->num, afc, - -((s32)p->u.qam.symbol_rate * afc) >> 10); - } - - p->inversion = (inv&0x20?0:1); - p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; - - p->u.qam.fec_inner = FEC_NONE; - p->frequency = ((p->frequency + 31250) / 62500) * 62500; - - if (sync & 2) - p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10; - - return 0; -} - -static int tda10023_sleep(struct dvb_frontend* fe) -{ - struct tda10023_state* state = fe->demodulator_priv; - - tda10023_writereg (state, 0x1b, 0x02); /* pdown ADC */ - tda10023_writereg (state, 0x00, 0x80); /* standby */ - - return 0; -} - -static int tda10023_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct tda10023_state* state = fe->demodulator_priv; - - if (enable) { - lock_tuner(state); - } else { - unlock_tuner(state); - } - return 0; -} - -static void tda10023_release(struct dvb_frontend* fe) -{ - struct tda10023_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops tda10023_ops; - -struct dvb_frontend *tda10023_attach(const struct tda10023_config *config, - struct i2c_adapter *i2c, - u8 pwm) -{ - struct tda10023_state* state = NULL; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* wakeup if in standby */ - tda10023_writereg (state, 0x00, 0x33); - /* check if the demod is there */ - if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops)); - state->pwm = pwm; - state->reg0 = REG0_INIT_VAL; - if (state->config->xtal) { - state->xtal = state->config->xtal; - state->pll_m = state->config->pll_m; - state->pll_p = state->config->pll_p; - state->pll_n = state->config->pll_n; - } else { - /* set default values if not defined in config */ - state->xtal = 28920000; - state->pll_m = 8; - state->pll_p = 4; - state->pll_n = 1; - } - - /* calc sysclk */ - state->sysclk = (state->xtal * state->pll_m / \ - (state->pll_n * state->pll_p)); - - state->frontend.ops.info.symbol_rate_min = (state->sysclk/2)/64; - state->frontend.ops.info.symbol_rate_max = (state->sysclk/2)/4; - - dprintk("DVB: TDA10023 %s: xtal:%d pll_m:%d pll_p:%d pll_n:%d\n", - __func__, state->xtal, state->pll_m, state->pll_p, - state->pll_n); - - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops tda10023_ops = { - - .info = { - .name = "Philips TDA10023 DVB-C", - .type = FE_QAM, - .frequency_stepsize = 62500, - .frequency_min = 47000000, - .frequency_max = 862000000, - .symbol_rate_min = 0, /* set in tda10023_attach */ - .symbol_rate_max = 0, /* set in tda10023_attach */ - .caps = 0x400 | //FE_CAN_QAM_4 - FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | - FE_CAN_QAM_128 | FE_CAN_QAM_256 | - FE_CAN_FEC_AUTO - }, - - .release = tda10023_release, - - .init = tda10023_init, - .sleep = tda10023_sleep, - .i2c_gate_ctrl = tda10023_i2c_gate_ctrl, - - .set_frontend = tda10023_set_parameters, - .get_frontend = tda10023_get_frontend, - - .read_status = tda10023_read_status, - .read_ber = tda10023_read_ber, - .read_signal_strength = tda10023_read_signal_strength, - .read_snr = tda10023_read_snr, - .read_ucblocks = tda10023_read_ucblocks, -}; - - -MODULE_DESCRIPTION("Philips TDA10023 DVB-C demodulator driver"); -MODULE_AUTHOR("Georg Acher, Hartmut Birr"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(tda10023_attach); diff --git a/drivers/media/dvb/frontends/tda1002x.h b/drivers/media/dvb/frontends/tda1002x.h deleted file mode 100644 index 04d19418bf2..00000000000 --- a/drivers/media/dvb/frontends/tda1002x.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - TDA10021/TDA10023 - Single Chip Cable Channel Receiver driver module - used on the the Siemens DVB-C cards - - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> - Support for TDA10021 - - 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 TDA1002x_H -#define TDA1002x_H - -#include <linux/dvb/frontend.h> - -struct tda1002x_config { - /* the demodulator's i2c address */ - u8 demod_address; - u8 invert; -}; - -enum tda10023_output_mode { - TDA10023_OUTPUT_MODE_PARALLEL_A = 0xe0, - TDA10023_OUTPUT_MODE_PARALLEL_B = 0xa1, - TDA10023_OUTPUT_MODE_PARALLEL_C = 0xa0, - TDA10023_OUTPUT_MODE_SERIAL, /* TODO: not implemented */ -}; - -struct tda10023_config { - /* the demodulator's i2c address */ - u8 demod_address; - u8 invert; - - /* clock settings */ - u32 xtal; /* defaults: 28920000 */ - u8 pll_m; /* defaults: 8 */ - u8 pll_p; /* defaults: 4 */ - u8 pll_n; /* defaults: 1 */ - - /* MPEG2 TS output mode */ - u8 output_mode; - - /* input freq offset + baseband conversion type */ - u16 deltaf; -}; - -#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) -extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, - struct i2c_adapter* i2c, u8 pwm); -#else -static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, - struct i2c_adapter* i2c, u8 pwm) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_TDA10021 - -#if defined(CONFIG_DVB_TDA10023) || \ - (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE)) -extern struct dvb_frontend *tda10023_attach( - const struct tda10023_config *config, - struct i2c_adapter *i2c, u8 pwm); -#else -static inline struct dvb_frontend *tda10023_attach( - const struct tda10023_config *config, - struct i2c_adapter *i2c, u8 pwm) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_TDA10023 - -#endif // TDA1002x_H diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c deleted file mode 100644 index 2a8bbcd44cd..00000000000 --- a/drivers/media/dvb/frontends/tda10048.c +++ /dev/null @@ -1,887 +0,0 @@ -/* - NXP TDA10048HN DVB OFDM demodulator driver - - Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> - - 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 <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "dvb_math.h" -#include "tda10048.h" - -#define TDA10048_DEFAULT_FIRMWARE "dvb-fe-tda10048-1.0.fw" -#define TDA10048_DEFAULT_FIRMWARE_SIZE 24878 - -/* Register name definitions */ -#define TDA10048_IDENTITY 0x00 -#define TDA10048_VERSION 0x01 -#define TDA10048_DSP_CODE_CPT 0x0C -#define TDA10048_DSP_CODE_IN 0x0E -#define TDA10048_IN_CONF1 0x10 -#define TDA10048_IN_CONF2 0x11 -#define TDA10048_IN_CONF3 0x12 -#define TDA10048_OUT_CONF1 0x14 -#define TDA10048_OUT_CONF2 0x15 -#define TDA10048_OUT_CONF3 0x16 -#define TDA10048_AUTO 0x18 -#define TDA10048_SYNC_STATUS 0x1A -#define TDA10048_CONF_C4_1 0x1E -#define TDA10048_CONF_C4_2 0x1F -#define TDA10048_CODE_IN_RAM 0x20 -#define TDA10048_CHANNEL_INFO_1_R 0x22 -#define TDA10048_CHANNEL_INFO_2_R 0x23 -#define TDA10048_CHANNEL_INFO1 0x24 -#define TDA10048_CHANNEL_INFO2 0x25 -#define TDA10048_TIME_ERROR_R 0x26 -#define TDA10048_TIME_ERROR 0x27 -#define TDA10048_FREQ_ERROR_LSB_R 0x28 -#define TDA10048_FREQ_ERROR_MSB_R 0x29 -#define TDA10048_FREQ_ERROR_LSB 0x2A -#define TDA10048_FREQ_ERROR_MSB 0x2B -#define TDA10048_IT_SEL 0x30 -#define TDA10048_IT_STAT 0x32 -#define TDA10048_DSP_AD_LSB 0x3C -#define TDA10048_DSP_AD_MSB 0x3D -#define TDA10048_DSP_REF_LSB 0x3E -#define TDA10048_DSP_REF_MSB 0x3F -#define TDA10048_CONF_TRISTATE1 0x44 -#define TDA10048_CONF_TRISTATE2 0x45 -#define TDA10048_CONF_POLARITY 0x46 -#define TDA10048_GPIO_SP_DS0 0x48 -#define TDA10048_GPIO_SP_DS1 0x49 -#define TDA10048_GPIO_SP_DS2 0x4A -#define TDA10048_GPIO_SP_DS3 0x4B -#define TDA10048_GPIO_OUT_SEL 0x4C -#define TDA10048_GPIO_SELECT 0x4D -#define TDA10048_IC_MODE 0x4E -#define TDA10048_CONF_XO 0x50 -#define TDA10048_CONF_PLL1 0x51 -#define TDA10048_CONF_PLL2 0x52 -#define TDA10048_CONF_PLL3 0x53 -#define TDA10048_CONF_ADC 0x54 -#define TDA10048_CONF_ADC_2 0x55 -#define TDA10048_CONF_C1_1 0x60 -#define TDA10048_CONF_C1_3 0x62 -#define TDA10048_AGC_CONF 0x70 -#define TDA10048_AGC_THRESHOLD_LSB 0x72 -#define TDA10048_AGC_THRESHOLD_MSB 0x73 -#define TDA10048_AGC_RENORM 0x74 -#define TDA10048_AGC_GAINS 0x76 -#define TDA10048_AGC_TUN_MIN 0x78 -#define TDA10048_AGC_TUN_MAX 0x79 -#define TDA10048_AGC_IF_MIN 0x7A -#define TDA10048_AGC_IF_MAX 0x7B -#define TDA10048_AGC_TUN_LEVEL 0x7E -#define TDA10048_AGC_IF_LEVEL 0x7F -#define TDA10048_DIG_AGC_LEVEL 0x81 -#define TDA10048_FREQ_PHY2_LSB 0x86 -#define TDA10048_FREQ_PHY2_MSB 0x87 -#define TDA10048_TIME_INVWREF_LSB 0x88 -#define TDA10048_TIME_INVWREF_MSB 0x89 -#define TDA10048_TIME_WREF_LSB 0x8A -#define TDA10048_TIME_WREF_MID1 0x8B -#define TDA10048_TIME_WREF_MID2 0x8C -#define TDA10048_TIME_WREF_MSB 0x8D -#define TDA10048_NP_OUT 0xA2 -#define TDA10048_CELL_ID_LSB 0xA4 -#define TDA10048_CELL_ID_MSB 0xA5 -#define TDA10048_EXTTPS_ODD 0xAA -#define TDA10048_EXTTPS_EVEN 0xAB -#define TDA10048_TPS_LENGTH 0xAC -#define TDA10048_FREE_REG_1 0xB2 -#define TDA10048_FREE_REG_2 0xB3 -#define TDA10048_CONF_C3_1 0xC0 -#define TDA10048_CYBER_CTRL 0xC2 -#define TDA10048_CBER_NMAX_LSB 0xC4 -#define TDA10048_CBER_NMAX_MSB 0xC5 -#define TDA10048_CBER_LSB 0xC6 -#define TDA10048_CBER_MSB 0xC7 -#define TDA10048_VBER_LSB 0xC8 -#define TDA10048_VBER_MID 0xC9 -#define TDA10048_VBER_MSB 0xCA -#define TDA10048_CYBER_LUT 0xCC -#define TDA10048_UNCOR_CTRL 0xCD -#define TDA10048_UNCOR_CPT_LSB 0xCE -#define TDA10048_UNCOR_CPT_MSB 0xCF -#define TDA10048_SOFT_IT_C3 0xD6 -#define TDA10048_CONF_TS2 0xE0 -#define TDA10048_CONF_TS1 0xE1 - -static unsigned int debug; - -#define dprintk(level, fmt, arg...)\ - do { if (debug >= level)\ - printk(KERN_DEBUG "tda10048: " fmt, ## arg);\ - } while (0) - -struct tda10048_state { - - struct i2c_adapter *i2c; - - /* configuration settings */ - const struct tda10048_config *config; - struct dvb_frontend frontend; - - int fwloaded; -}; - -static struct init_tab { - u8 reg; - u16 data; -} init_tab[] = { - { TDA10048_CONF_PLL1, 0x08 }, - { TDA10048_CONF_ADC_2, 0x00 }, - { TDA10048_CONF_C4_1, 0x00 }, - { TDA10048_CONF_PLL1, 0x0f }, - { TDA10048_CONF_PLL2, 0x0a }, - { TDA10048_CONF_PLL3, 0x43 }, - { TDA10048_FREQ_PHY2_LSB, 0x02 }, - { TDA10048_FREQ_PHY2_MSB, 0x0a }, - { TDA10048_TIME_WREF_LSB, 0xbd }, - { TDA10048_TIME_WREF_MID1, 0xe4 }, - { TDA10048_TIME_WREF_MID2, 0xa8 }, - { TDA10048_TIME_WREF_MSB, 0x02 }, - { TDA10048_TIME_INVWREF_LSB, 0x04 }, - { TDA10048_TIME_INVWREF_MSB, 0x06 }, - { TDA10048_CONF_C4_1, 0x00 }, - { TDA10048_CONF_C1_1, 0xa8 }, - { TDA10048_AGC_CONF, 0x16 }, - { TDA10048_CONF_C1_3, 0x0b }, - { TDA10048_AGC_TUN_MIN, 0x00 }, - { TDA10048_AGC_TUN_MAX, 0xff }, - { TDA10048_AGC_IF_MIN, 0x00 }, - { TDA10048_AGC_IF_MAX, 0xff }, - { TDA10048_AGC_THRESHOLD_MSB, 0x00 }, - { TDA10048_AGC_THRESHOLD_LSB, 0x70 }, - { TDA10048_CYBER_CTRL, 0x38 }, - { TDA10048_AGC_GAINS, 0x12 }, - { TDA10048_CONF_XO, 0x00 }, - { TDA10048_CONF_TS1, 0x07 }, - { TDA10048_IC_MODE, 0x00 }, - { TDA10048_CONF_TS2, 0xc0 }, - { TDA10048_CONF_TRISTATE1, 0x21 }, - { TDA10048_CONF_TRISTATE2, 0x00 }, - { TDA10048_CONF_POLARITY, 0x00 }, - { TDA10048_CONF_C4_2, 0x04 }, - { TDA10048_CONF_ADC, 0x60 }, - { TDA10048_CONF_ADC_2, 0x10 }, - { TDA10048_CONF_ADC, 0x60 }, - { TDA10048_CONF_ADC_2, 0x00 }, - { TDA10048_CONF_C1_1, 0xa8 }, - { TDA10048_UNCOR_CTRL, 0x00 }, - { TDA10048_CONF_C4_2, 0x04 }, -}; - -static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, .buf = buf, .len = 2 }; - - dprintk(2, "%s(reg = 0x%02x, data = 0x%02x)\n", __func__, reg, data); - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - printk("%s: writereg error (ret == %i)\n", __func__, ret); - - return (ret != 1) ? -1 : 0; -} - -static u8 tda10048_readreg(struct tda10048_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, - .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, - .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - dprintk(2, "%s(reg = 0x%02x)\n", __func__, reg); - - 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 tda10048_writeregbulk(struct tda10048_state *state, u8 reg, - const u8 *data, u16 len) -{ - int ret = -EREMOTEIO; - struct i2c_msg msg; - u8 *buf; - - dprintk(2, "%s(%d, ?, len = %d)\n", __func__, reg, len); - - buf = kmalloc(len + 1, GFP_KERNEL); - if (buf == NULL) { - ret = -ENOMEM; - goto error; - } - - *buf = reg; - memcpy(buf + 1, data, len); - - msg.addr = state->config->demod_address; - msg.flags = 0; - msg.buf = buf; - msg.len = len + 1; - - dprintk(2, "%s(): write len = %d\n", - __func__, msg.len); - - ret = i2c_transfer(state->i2c, &msg, 1); - if (ret != 1) { - printk(KERN_ERR "%s(): writereg error err %i\n", - __func__, ret); - ret = -EREMOTEIO; - } - -error: - kfree(buf); - - return ret; -} - -static int tda10048_firmware_upload(struct dvb_frontend *fe) -{ - struct tda10048_state *state = fe->demodulator_priv; - const struct firmware *fw; - int ret; - int pos = 0; - int cnt; - u8 wlen = state->config->fwbulkwritelen; - - if ((wlen != TDA10048_BULKWRITE_200) && (wlen != TDA10048_BULKWRITE_50)) - wlen = TDA10048_BULKWRITE_200; - - /* request the firmware, this will block and timeout */ - printk(KERN_INFO "%s: waiting for firmware upload (%s)...\n", - __func__, - TDA10048_DEFAULT_FIRMWARE); - - ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE, - &state->i2c->dev); - if (ret) { - printk(KERN_ERR "%s: Upload failed. (file not found?)\n", - __func__); - return -EIO; - } else { - printk(KERN_INFO "%s: firmware read %Zu bytes.\n", - __func__, - fw->size); - ret = 0; - } - - if (fw->size != TDA10048_DEFAULT_FIRMWARE_SIZE) { - printk(KERN_ERR "%s: firmware incorrect size\n", __func__); - ret = -EIO; - } else { - printk(KERN_INFO "%s: firmware uploading\n", __func__); - - /* Soft reset */ - tda10048_writereg(state, TDA10048_CONF_TRISTATE1, - tda10048_readreg(state, TDA10048_CONF_TRISTATE1) - & 0xfe); - tda10048_writereg(state, TDA10048_CONF_TRISTATE1, - tda10048_readreg(state, TDA10048_CONF_TRISTATE1) - | 0x01); - - /* Put the demod into host download mode */ - tda10048_writereg(state, TDA10048_CONF_C4_1, - tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xf9); - - /* Boot the DSP */ - tda10048_writereg(state, TDA10048_CONF_C4_1, - tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x08); - - /* Prepare for download */ - tda10048_writereg(state, TDA10048_DSP_CODE_CPT, 0); - - /* Download the firmware payload */ - while (pos < fw->size) { - - if ((fw->size - pos) > wlen) - cnt = wlen; - else - cnt = fw->size - pos; - - tda10048_writeregbulk(state, TDA10048_DSP_CODE_IN, - &fw->data[pos], cnt); - - pos += cnt; - } - - ret = -EIO; - /* Wait up to 250ms for the DSP to boot */ - for (cnt = 0; cnt < 250 ; cnt += 10) { - - msleep(10); - - if (tda10048_readreg(state, TDA10048_SYNC_STATUS) - & 0x40) { - ret = 0; - break; - } - } - } - - release_firmware(fw); - - if (ret == 0) { - printk(KERN_INFO "%s: firmware uploaded\n", __func__); - state->fwloaded = 1; - } else - printk(KERN_ERR "%s: firmware upload failed\n", __func__); - - return ret; -} - -static int tda10048_set_inversion(struct dvb_frontend *fe, int inversion) -{ - struct tda10048_state *state = fe->demodulator_priv; - - dprintk(1, "%s(%d)\n", __func__, inversion); - - if (inversion == TDA10048_INVERSION_ON) - tda10048_writereg(state, TDA10048_CONF_C1_1, - tda10048_readreg(state, TDA10048_CONF_C1_1) | 0x20); - else - tda10048_writereg(state, TDA10048_CONF_C1_1, - tda10048_readreg(state, TDA10048_CONF_C1_1) & 0xdf); - - return 0; -} - -/* Retrieve the demod settings */ -static int tda10048_get_tps(struct tda10048_state *state, - struct dvb_ofdm_parameters *p) -{ - u8 val; - - /* Make sure the TPS regs are valid */ - if (!(tda10048_readreg(state, TDA10048_AUTO) & 0x01)) - return -EAGAIN; - - val = tda10048_readreg(state, TDA10048_OUT_CONF2); - switch ((val & 0x60) >> 5) { - case 0: - p->constellation = QPSK; - break; - case 1: - p->constellation = QAM_16; - break; - case 2: - p->constellation = QAM_64; - break; - } - switch ((val & 0x18) >> 3) { - case 0: - p->hierarchy_information = HIERARCHY_NONE; - break; - case 1: - p->hierarchy_information = HIERARCHY_1; - break; - case 2: - p->hierarchy_information = HIERARCHY_2; - break; - case 3: - p->hierarchy_information = HIERARCHY_4; - break; - } - switch (val & 0x07) { - case 0: - p->code_rate_HP = FEC_1_2; - break; - case 1: - p->code_rate_HP = FEC_2_3; - break; - case 2: - p->code_rate_HP = FEC_3_4; - break; - case 3: - p->code_rate_HP = FEC_5_6; - break; - case 4: - p->code_rate_HP = FEC_7_8; - break; - } - - val = tda10048_readreg(state, TDA10048_OUT_CONF3); - switch (val & 0x07) { - case 0: - p->code_rate_LP = FEC_1_2; - break; - case 1: - p->code_rate_LP = FEC_2_3; - break; - case 2: - p->code_rate_LP = FEC_3_4; - break; - case 3: - p->code_rate_LP = FEC_5_6; - break; - case 4: - p->code_rate_LP = FEC_7_8; - break; - } - - val = tda10048_readreg(state, TDA10048_OUT_CONF1); - switch ((val & 0x0c) >> 2) { - case 0: - p->guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - p->guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - p->guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - p->guard_interval = GUARD_INTERVAL_1_4; - break; - } - switch (val & 0x02) { - case 0: - p->transmission_mode = TRANSMISSION_MODE_2K; - break; - case 1: - p->transmission_mode = TRANSMISSION_MODE_8K; - break; - } - - return 0; -} - -static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct tda10048_state *state = fe->demodulator_priv; - dprintk(1, "%s(%d)\n", __func__, enable); - - if (enable) - return tda10048_writereg(state, TDA10048_CONF_C4_1, - tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02); - else - return tda10048_writereg(state, TDA10048_CONF_C4_1, - tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xfd); -} - -static int tda10048_output_mode(struct dvb_frontend *fe, int serial) -{ - struct tda10048_state *state = fe->demodulator_priv; - dprintk(1, "%s(%d)\n", __func__, serial); - - /* Ensure pins are out of tri-state */ - tda10048_writereg(state, TDA10048_CONF_TRISTATE1, 0x21); - tda10048_writereg(state, TDA10048_CONF_TRISTATE2, 0x00); - - if (serial) { - tda10048_writereg(state, TDA10048_IC_MODE, 0x80 | 0x20); - tda10048_writereg(state, TDA10048_CONF_TS2, 0xc0); - } else { - tda10048_writereg(state, TDA10048_IC_MODE, 0x00); - tda10048_writereg(state, TDA10048_CONF_TS2, 0x01); - } - - return 0; -} - -/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -/* TODO: Support manual tuning with specific params */ -static int tda10048_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct tda10048_state *state = fe->demodulator_priv; - - dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency); - - if (fe->ops.tuner_ops.set_params) { - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - fe->ops.tuner_ops.set_params(fe, p); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* Enable demod TPS auto detection and begin acquisition */ - tda10048_writereg(state, TDA10048_AUTO, 0x57); - - return 0; -} - -/* Establish sane defaults and load firmware. */ -static int tda10048_init(struct dvb_frontend *fe) -{ - struct tda10048_state *state = fe->demodulator_priv; - int ret = 0, i; - - dprintk(1, "%s()\n", __func__); - - /* Apply register defaults */ - for (i = 0; i < ARRAY_SIZE(init_tab); i++) - tda10048_writereg(state, init_tab[i].reg, init_tab[i].data); - - if (state->fwloaded == 0) - ret = tda10048_firmware_upload(fe); - - /* Set either serial or parallel */ - tda10048_output_mode(fe, state->config->output_mode); - - /* set inversion */ - tda10048_set_inversion(fe, state->config->inversion); - - /* Ensure we leave the gate closed */ - tda10048_i2c_gate_ctrl(fe, 0); - - return ret; -} - -static int tda10048_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct tda10048_state *state = fe->demodulator_priv; - u8 reg; - - *status = 0; - - reg = tda10048_readreg(state, TDA10048_SYNC_STATUS); - - dprintk(1, "%s() status =0x%02x\n", __func__, reg); - - if (reg & 0x02) - *status |= FE_HAS_CARRIER; - - if (reg & 0x04) - *status |= FE_HAS_SIGNAL; - - if (reg & 0x08) { - *status |= FE_HAS_LOCK; - *status |= FE_HAS_VITERBI; - *status |= FE_HAS_SYNC; - } - - return 0; -} - -static int tda10048_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct tda10048_state *state = fe->demodulator_priv; - - dprintk(1, "%s()\n", __func__); - - /* TODO: A reset may be required here */ - *ber = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 | - tda10048_readreg(state, TDA10048_CBER_LSB); - - return 0; -} - -static int tda10048_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - struct tda10048_state *state = fe->demodulator_priv; - u8 v; - - dprintk(1, "%s()\n", __func__); - - *signal_strength = 65535; - - v = tda10048_readreg(state, TDA10048_NP_OUT); - if (v > 0) - *signal_strength -= (v << 8) | v; - - return 0; -} - -/* SNR lookup table */ -static struct snr_tab { - u8 val; - u8 data; -} snr_tab[] = { - { 0, 0 }, - { 1, 246 }, - { 2, 215 }, - { 3, 198 }, - { 4, 185 }, - { 5, 176 }, - { 6, 168 }, - { 7, 161 }, - { 8, 155 }, - { 9, 150 }, - { 10, 146 }, - { 11, 141 }, - { 12, 138 }, - { 13, 134 }, - { 14, 131 }, - { 15, 128 }, - { 16, 125 }, - { 17, 122 }, - { 18, 120 }, - { 19, 118 }, - { 20, 115 }, - { 21, 113 }, - { 22, 111 }, - { 23, 109 }, - { 24, 107 }, - { 25, 106 }, - { 26, 104 }, - { 27, 102 }, - { 28, 101 }, - { 29, 99 }, - { 30, 98 }, - { 31, 96 }, - { 32, 95 }, - { 33, 94 }, - { 34, 92 }, - { 35, 91 }, - { 36, 90 }, - { 37, 89 }, - { 38, 88 }, - { 39, 86 }, - { 40, 85 }, - { 41, 84 }, - { 42, 83 }, - { 43, 82 }, - { 44, 81 }, - { 45, 80 }, - { 46, 79 }, - { 47, 78 }, - { 48, 77 }, - { 49, 76 }, - { 50, 76 }, - { 51, 75 }, - { 52, 74 }, - { 53, 73 }, - { 54, 72 }, - { 56, 71 }, - { 57, 70 }, - { 58, 69 }, - { 60, 68 }, - { 61, 67 }, - { 63, 66 }, - { 64, 65 }, - { 66, 64 }, - { 67, 63 }, - { 68, 62 }, - { 69, 62 }, - { 70, 61 }, - { 72, 60 }, - { 74, 59 }, - { 75, 58 }, - { 77, 57 }, - { 79, 56 }, - { 81, 55 }, - { 83, 54 }, - { 85, 53 }, - { 87, 52 }, - { 89, 51 }, - { 91, 50 }, - { 93, 49 }, - { 95, 48 }, - { 97, 47 }, - { 100, 46 }, - { 102, 45 }, - { 104, 44 }, - { 107, 43 }, - { 109, 42 }, - { 112, 41 }, - { 114, 40 }, - { 117, 39 }, - { 120, 38 }, - { 123, 37 }, - { 125, 36 }, - { 128, 35 }, - { 131, 34 }, - { 134, 33 }, - { 138, 32 }, - { 141, 31 }, - { 144, 30 }, - { 147, 29 }, - { 151, 28 }, - { 154, 27 }, - { 158, 26 }, - { 162, 25 }, - { 165, 24 }, - { 169, 23 }, - { 173, 22 }, - { 177, 21 }, - { 181, 20 }, - { 186, 19 }, - { 190, 18 }, - { 194, 17 }, - { 199, 16 }, - { 204, 15 }, - { 208, 14 }, - { 213, 13 }, - { 218, 12 }, - { 223, 11 }, - { 229, 10 }, - { 234, 9 }, - { 239, 8 }, - { 245, 7 }, - { 251, 6 }, - { 255, 5 }, -}; - -static int tda10048_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct tda10048_state *state = fe->demodulator_priv; - u8 v; - int i, ret = -EINVAL; - - dprintk(1, "%s()\n", __func__); - - v = tda10048_readreg(state, TDA10048_NP_OUT); - for (i = 0; i < ARRAY_SIZE(snr_tab); i++) { - if (v <= snr_tab[i].val) { - *snr = snr_tab[i].data; - ret = 0; - break; - } - } - - return ret; -} - -static int tda10048_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct tda10048_state *state = fe->demodulator_priv; - - dprintk(1, "%s()\n", __func__); - - *ucblocks = tda10048_readreg(state, TDA10048_UNCOR_CPT_MSB) << 8 | - tda10048_readreg(state, TDA10048_UNCOR_CPT_LSB); - - return 0; -} - -static int tda10048_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct tda10048_state *state = fe->demodulator_priv; - - dprintk(1, "%s()\n", __func__); - - p->inversion = tda10048_readreg(state, TDA10048_CONF_C1_1) - & 0x20 ? INVERSION_ON : INVERSION_OFF; - - return tda10048_get_tps(state, &p->u.ofdm); -} - -static int tda10048_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void tda10048_release(struct dvb_frontend *fe) -{ - struct tda10048_state *state = fe->demodulator_priv; - dprintk(1, "%s()\n", __func__); - kfree(state); -} - -static struct dvb_frontend_ops tda10048_ops; - -struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, - struct i2c_adapter *i2c) -{ - struct tda10048_state *state = NULL; - - dprintk(1, "%s()\n", __func__); - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda10048_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->fwloaded = 0; - - /* check if the demod is present */ - if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10048_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - /* Leave the gate closed */ - tda10048_i2c_gate_ctrl(&state->frontend, 0); - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(tda10048_attach); - -static struct dvb_frontend_ops tda10048_ops = { - - .info = { - .name = "NXP TDA10048HN DVB-T", - .type = FE_OFDM, - .frequency_min = 177000000, - .frequency_max = 858000000, - .frequency_stepsize = 166666, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER - }, - - .release = tda10048_release, - .init = tda10048_init, - .i2c_gate_ctrl = tda10048_i2c_gate_ctrl, - .set_frontend = tda10048_set_frontend, - .get_frontend = tda10048_get_frontend, - .get_tune_settings = tda10048_get_tune_settings, - .read_status = tda10048_read_status, - .read_ber = tda10048_read_ber, - .read_signal_strength = tda10048_read_signal_strength, - .read_snr = tda10048_read_snr, - .read_ucblocks = tda10048_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - -MODULE_DESCRIPTION("NXP TDA10048HN DVB-T Demodulator driver"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb/frontends/tda10048.h deleted file mode 100644 index 0457b24601f..00000000000 --- a/drivers/media/dvb/frontends/tda10048.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - NXP TDA10048HN DVB OFDM demodulator driver - - Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> - - 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 TDA10048_H -#define TDA10048_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -struct tda10048_config { - - /* the demodulator's i2c address */ - u8 demod_address; - - /* serial/parallel output */ -#define TDA10048_PARALLEL_OUTPUT 0 -#define TDA10048_SERIAL_OUTPUT 1 - u8 output_mode; - -#define TDA10048_BULKWRITE_200 200 -#define TDA10048_BULKWRITE_50 50 - u8 fwbulkwritelen; - - /* Spectral Inversion */ -#define TDA10048_INVERSION_OFF 0 -#define TDA10048_INVERSION_ON 1 - u8 inversion; -}; - -#if defined(CONFIG_DVB_TDA10048) || \ - (defined(CONFIG_DVB_TDA10048_MODULE) && defined(MODULE)) -extern struct dvb_frontend *tda10048_attach( - const struct tda10048_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *tda10048_attach( - const struct tda10048_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_TDA10048 */ - -#endif /* TDA10048_H */ diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c deleted file mode 100644 index 4981cef8b44..00000000000 --- a/drivers/media/dvb/frontends/tda1004x.c +++ /dev/null @@ -1,1380 +0,0 @@ - /* - Driver for Philips tda1004xh OFDM Demodulator - - (c) 2003, 2004 Andrew de Quincey & Robert Schlabbach - - 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. - - */ -/* - * This driver needs external firmware. Please use the commands - * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", - * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to - * download/extract them, and then copy them to /usr/lib/hotplug/firmware - * or /lib/firmware (depending on configuration of firmware hotplug). - */ -#define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw" -#define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw" - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/jiffies.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "tda1004x.h" - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "tda1004x: " args); \ - } while (0) - -#define TDA1004X_CHIPID 0x00 -#define TDA1004X_AUTO 0x01 -#define TDA1004X_IN_CONF1 0x02 -#define TDA1004X_IN_CONF2 0x03 -#define TDA1004X_OUT_CONF1 0x04 -#define TDA1004X_OUT_CONF2 0x05 -#define TDA1004X_STATUS_CD 0x06 -#define TDA1004X_CONFC4 0x07 -#define TDA1004X_DSSPARE2 0x0C -#define TDA10045H_CODE_IN 0x0D -#define TDA10045H_FWPAGE 0x0E -#define TDA1004X_SCAN_CPT 0x10 -#define TDA1004X_DSP_CMD 0x11 -#define TDA1004X_DSP_ARG 0x12 -#define TDA1004X_DSP_DATA1 0x13 -#define TDA1004X_DSP_DATA2 0x14 -#define TDA1004X_CONFADC1 0x15 -#define TDA1004X_CONFC1 0x16 -#define TDA10045H_S_AGC 0x1a -#define TDA10046H_AGC_TUN_LEVEL 0x1a -#define TDA1004X_SNR 0x1c -#define TDA1004X_CONF_TS1 0x1e -#define TDA1004X_CONF_TS2 0x1f -#define TDA1004X_CBER_RESET 0x20 -#define TDA1004X_CBER_MSB 0x21 -#define TDA1004X_CBER_LSB 0x22 -#define TDA1004X_CVBER_LUT 0x23 -#define TDA1004X_VBER_MSB 0x24 -#define TDA1004X_VBER_MID 0x25 -#define TDA1004X_VBER_LSB 0x26 -#define TDA1004X_UNCOR 0x27 - -#define TDA10045H_CONFPLL_P 0x2D -#define TDA10045H_CONFPLL_M_MSB 0x2E -#define TDA10045H_CONFPLL_M_LSB 0x2F -#define TDA10045H_CONFPLL_N 0x30 - -#define TDA10046H_CONFPLL1 0x2D -#define TDA10046H_CONFPLL2 0x2F -#define TDA10046H_CONFPLL3 0x30 -#define TDA10046H_TIME_WREF1 0x31 -#define TDA10046H_TIME_WREF2 0x32 -#define TDA10046H_TIME_WREF3 0x33 -#define TDA10046H_TIME_WREF4 0x34 -#define TDA10046H_TIME_WREF5 0x35 - -#define TDA10045H_UNSURW_MSB 0x31 -#define TDA10045H_UNSURW_LSB 0x32 -#define TDA10045H_WREF_MSB 0x33 -#define TDA10045H_WREF_MID 0x34 -#define TDA10045H_WREF_LSB 0x35 -#define TDA10045H_MUXOUT 0x36 -#define TDA1004X_CONFADC2 0x37 - -#define TDA10045H_IOFFSET 0x38 - -#define TDA10046H_CONF_TRISTATE1 0x3B -#define TDA10046H_CONF_TRISTATE2 0x3C -#define TDA10046H_CONF_POLARITY 0x3D -#define TDA10046H_FREQ_OFFSET 0x3E -#define TDA10046H_GPIO_OUT_SEL 0x41 -#define TDA10046H_GPIO_SELECT 0x42 -#define TDA10046H_AGC_CONF 0x43 -#define TDA10046H_AGC_THR 0x44 -#define TDA10046H_AGC_RENORM 0x45 -#define TDA10046H_AGC_GAINS 0x46 -#define TDA10046H_AGC_TUN_MIN 0x47 -#define TDA10046H_AGC_TUN_MAX 0x48 -#define TDA10046H_AGC_IF_MIN 0x49 -#define TDA10046H_AGC_IF_MAX 0x4A - -#define TDA10046H_FREQ_PHY2_MSB 0x4D -#define TDA10046H_FREQ_PHY2_LSB 0x4E - -#define TDA10046H_CVBER_CTRL 0x4F -#define TDA10046H_AGC_IF_LEVEL 0x52 -#define TDA10046H_CODE_CPT 0x57 -#define TDA10046H_CODE_IN 0x58 - - -static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 }; - - dprintk("%s: reg=0x%x, data=0x%x\n", __func__, reg, data); - - msg.addr = state->config->demod_address; - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n", - __func__, reg, data, ret); - - dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__, - reg, data, ret); - return (ret != 1) ? -1 : 0; -} - -static int tda1004x_read_byte(struct tda1004x_state *state, int reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 }, - { .flags = I2C_M_RD, .buf = b1, .len = 1 }}; - - dprintk("%s: reg=0x%x\n", __func__, reg); - - msg[0].addr = state->config->demod_address; - msg[1].addr = state->config->demod_address; - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, - ret); - return -EINVAL; - } - - dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__, - reg, b1[0], ret); - return b1[0]; -} - -static int tda1004x_write_mask(struct tda1004x_state *state, int reg, int mask, int data) -{ - int val; - dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __func__, reg, - mask, data); - - // read a byte and check - val = tda1004x_read_byte(state, reg); - if (val < 0) - return val; - - // mask if off - val = val & ~mask; - val |= data & 0xff; - - // write it out again - return tda1004x_write_byteI(state, reg, val); -} - -static int tda1004x_write_buf(struct tda1004x_state *state, int reg, unsigned char *buf, int len) -{ - int i; - int result; - - dprintk("%s: reg=0x%x, len=0x%x\n", __func__, reg, len); - - result = 0; - for (i = 0; i < len; i++) { - result = tda1004x_write_byteI(state, reg + i, buf[i]); - if (result != 0) - break; - } - - return result; -} - -static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state) -{ - int result; - dprintk("%s\n", __func__); - - result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2); - msleep(20); - return result; -} - -static int tda1004x_disable_tuner_i2c(struct tda1004x_state *state) -{ - dprintk("%s\n", __func__); - - return tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 0); -} - -static int tda10045h_set_bandwidth(struct tda1004x_state *state, - fe_bandwidth_t bandwidth) -{ - static u8 bandwidth_6mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x60, 0x1e, 0xa7, 0x45, 0x4f }; - static u8 bandwidth_7mhz[] = { 0x02, 0x00, 0x37, 0x00, 0x4a, 0x2f, 0x6d, 0x76, 0xdb }; - static u8 bandwidth_8mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x48, 0x17, 0x89, 0xc7, 0x14 }; - - switch (bandwidth) { - case BANDWIDTH_6_MHZ: - tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz)); - break; - - case BANDWIDTH_7_MHZ: - tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz)); - break; - - case BANDWIDTH_8_MHZ: - tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz)); - break; - - default: - return -EINVAL; - } - - tda1004x_write_byteI(state, TDA10045H_IOFFSET, 0); - - return 0; -} - -static int tda10046h_set_bandwidth(struct tda1004x_state *state, - fe_bandwidth_t bandwidth) -{ - static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 }; - static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f }; - static u8 bandwidth_8mhz_53M[] = { 0x5c, 0x32, 0xc2, 0x96, 0x6d }; - - static u8 bandwidth_6mhz_48M[] = { 0x70, 0x02, 0x49, 0x24, 0x92 }; - static u8 bandwidth_7mhz_48M[] = { 0x60, 0x02, 0xaa, 0xaa, 0xab }; - static u8 bandwidth_8mhz_48M[] = { 0x54, 0x03, 0x0c, 0x30, 0xc3 }; - int tda10046_clk53m; - - if ((state->config->if_freq == TDA10046_FREQ_045) || - (state->config->if_freq == TDA10046_FREQ_052)) - tda10046_clk53m = 0; - else - tda10046_clk53m = 1; - switch (bandwidth) { - case BANDWIDTH_6_MHZ: - if (tda10046_clk53m) - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_53M, - sizeof(bandwidth_6mhz_53M)); - else - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_48M, - sizeof(bandwidth_6mhz_48M)); - if (state->config->if_freq == TDA10046_FREQ_045) { - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xab); - } - break; - - case BANDWIDTH_7_MHZ: - if (tda10046_clk53m) - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M, - sizeof(bandwidth_7mhz_53M)); - else - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_48M, - sizeof(bandwidth_7mhz_48M)); - if (state->config->if_freq == TDA10046_FREQ_045) { - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00); - } - break; - - case BANDWIDTH_8_MHZ: - if (tda10046_clk53m) - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M, - sizeof(bandwidth_8mhz_53M)); - else - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_48M, - sizeof(bandwidth_8mhz_48M)); - if (state->config->if_freq == TDA10046_FREQ_045) { - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x55); - } - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int tda1004x_do_upload(struct tda1004x_state *state, - const unsigned char *mem, unsigned int len, - u8 dspCodeCounterReg, u8 dspCodeInReg) -{ - u8 buf[65]; - struct i2c_msg fw_msg = { .flags = 0, .buf = buf, .len = 0 }; - int tx_size; - int pos = 0; - - /* clear code counter */ - tda1004x_write_byteI(state, dspCodeCounterReg, 0); - fw_msg.addr = state->config->demod_address; - - buf[0] = dspCodeInReg; - while (pos != len) { - // work out how much to send this time - tx_size = len - pos; - if (tx_size > 0x10) - tx_size = 0x10; - - // send the chunk - memcpy(buf + 1, mem + pos, tx_size); - fw_msg.len = tx_size + 1; - if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) { - printk(KERN_ERR "tda1004x: Error during firmware upload\n"); - return -EIO; - } - pos += tx_size; - - dprintk("%s: fw_pos=0x%x\n", __func__, pos); - } - // give the DSP a chance to settle 03/10/05 Hac - msleep(100); - - return 0; -} - -static int tda1004x_check_upload_ok(struct tda1004x_state *state) -{ - u8 data1, data2; - unsigned long timeout; - - if (state->demod_type == TDA1004X_DEMOD_TDA10046) { - timeout = jiffies + 2 * HZ; - while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) { - if (time_after(jiffies, timeout)) { - printk(KERN_ERR "tda1004x: timeout waiting for DSP ready\n"); - break; - } - msleep(1); - } - } else - msleep(100); - - // check upload was OK - tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP - tda1004x_write_byteI(state, TDA1004X_DSP_CMD, 0x67); - - data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1); - data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2); - if (data1 != 0x67 || data2 < 0x20 || data2 > 0x2e) { - printk(KERN_INFO "tda1004x: found firmware revision %x -- invalid\n", data2); - return -EIO; - } - printk(KERN_INFO "tda1004x: found firmware revision %x -- ok\n", data2); - return 0; -} - -static int tda10045_fwupload(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int ret; - const struct firmware *fw; - - /* don't re-upload unless necessary */ - if (tda1004x_check_upload_ok(state) == 0) - return 0; - - /* request the firmware, this will block until someone uploads it */ - printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE); - ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); - if (ret) { - printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); - return ret; - } - - /* reset chip */ - tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); - tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); - tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0); - msleep(10); - - /* set parameters */ - tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ); - - ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN); - release_firmware(fw); - if (ret) - return ret; - printk(KERN_INFO "tda1004x: firmware upload complete\n"); - - /* wait for DSP to initialise */ - /* DSPREADY doesn't seem to work on the TDA10045H */ - msleep(100); - - return tda1004x_check_upload_ok(state); -} - -static void tda10046_init_plls(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int tda10046_clk53m; - - if ((state->config->if_freq == TDA10046_FREQ_045) || - (state->config->if_freq == TDA10046_FREQ_052)) - tda10046_clk53m = 0; - else - tda10046_clk53m = 1; - - tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); - if(tda10046_clk53m) { - printk(KERN_INFO "tda1004x: setting up plls for 53MHz sampling clock\n"); - tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x08); // PLL M = 8 - } else { - printk(KERN_INFO "tda1004x: setting up plls for 48MHz sampling clock\n"); - tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3 - } - if (state->config->xtal_freq == TDA10046_XTAL_4M ) { - dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __func__); - tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 - } else { - dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __func__); - tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3 - } - if(tda10046_clk53m) - tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x67); - else - tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x72); - /* Note clock frequency is handled implicitly */ - switch (state->config->if_freq) { - case TDA10046_FREQ_045: - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00); - break; - case TDA10046_FREQ_052: - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xc7); - break; - case TDA10046_FREQ_3617: - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x59); - break; - case TDA10046_FREQ_3613: - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x3f); - break; - } - tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz - /* let the PLLs settle */ - msleep(120); -} - -static int tda10046_fwupload(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int ret, confc4; - const struct firmware *fw; - - /* reset + wake up chip */ - if (state->config->xtal_freq == TDA10046_XTAL_4M) { - confc4 = 0; - } else { - dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__); - 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) { - tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0x33); - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, state->config->gpio_config &0x0f); - } - /* let the clocks recover from sleep */ - msleep(10); - - /* The PLLs need to be reprogrammed after sleep */ - tda10046_init_plls(fe); - tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0); - - /* don't re-upload unless necessary */ - 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_byteI(state, TDA1004X_CONFC4, 4); - msleep(300); - 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"); - ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE); - if (ret) { - /* remain compatible to old bug: try to load with tda10045 image name */ - ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); - if (ret) { - printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); - return ret; - } else { - printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n", - TDA10046_DEFAULT_FIRMWARE); - } - } - } else { - printk(KERN_ERR "tda1004x: no request function defined, can't upload from file\n"); - return -EIO; - } - tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST - ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN); - release_firmware(fw); - return tda1004x_check_upload_ok(state); -} - -static int tda1004x_encode_fec(int fec) -{ - // convert known FEC values - switch (fec) { - case FEC_1_2: - return 0; - case FEC_2_3: - return 1; - case FEC_3_4: - return 2; - case FEC_5_6: - return 3; - case FEC_7_8: - return 4; - } - - // unsupported - return -EINVAL; -} - -static int tda1004x_decode_fec(int tdafec) -{ - // convert known FEC values - switch (tdafec) { - case 0: - return FEC_1_2; - case 1: - return FEC_2_3; - case 2: - return FEC_3_4; - case 3: - return FEC_5_6; - case 4: - return FEC_7_8; - } - - // unsupported - return -1; -} - -static int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len) -{ - struct tda1004x_state* state = fe->demodulator_priv; - - if (len != 2) - return -EINVAL; - - return tda1004x_write_byteI(state, buf[0], buf[1]); -} - -static int tda10045_init(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (tda10045_fwupload(fe)) { - printk("tda1004x: firmware upload failed\n"); - return -EIO; - } - - tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC - - // tda setup - tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer - tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream - tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0); // set polarity of VAGC signal - tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0x80); // enable pulse killer - tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10); // enable auto offset - tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0x0); // no frequency offset - tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 0); // setup MPEG2 TS interface - tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0); // setup MPEG2 TS interface - tda1004x_write_mask(state, TDA1004X_VBER_MSB, 0xe0, 0xa0); // 10^6 VBER measurement bits - tda1004x_write_mask(state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity - tda1004x_write_byteI(state, TDA1004X_CONFADC1, 0x2e); - - tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk); - - return 0; -} - -static int tda10046_init(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - dprintk("%s\n", __func__); - - if (tda10046_fwupload(fe)) { - printk("tda1004x: firmware upload failed\n"); - return -EIO; - } - - // tda setup - tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer - tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream - tda1004x_write_byteI(state, TDA1004X_CONFC1, 0x88); // enable pulse killer - - switch (state->config->agc_config) { - case TDA10046_AGC_DEFAULT: - tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities - break; - case TDA10046_AGC_IFO_AUTO_NEG: - tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities - break; - case TDA10046_AGC_IFO_AUTO_POS: - tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x00); // set AGC polarities - break; - case TDA10046_AGC_TDA827X: - tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup - tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold - tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities - break; - } - if (state->config->ts_mode == 0) { - tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x40); - tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); - } else { - tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x80); - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x10, - state->config->invert_oclk << 4); - } - tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); - tda1004x_write_mask (state, TDA10046H_CONF_TRISTATE1, 0x3e, 0x38); // Turn IF AGC output on - tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } - tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values - tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } - tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // } - tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x12); // IF gain 2, TUN gain 1 - tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits - tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config - tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config - // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes - - return 0; -} - -static int tda1004x_set_fe(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fe_params) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int tmp; - int inversion; - - dprintk("%s\n", __func__); - - if (state->demod_type == TDA1004X_DEMOD_TDA10046) { - // setup auto offset - tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x80, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0); - - // disable agc_conf[2] - tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 0); - } - - // set frequency - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fe_params); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - // Hardcoded to use auto as much as possible on the TDA10045 as it - // is very unreliable if AUTO mode is _not_ used. - if (state->demod_type == TDA1004X_DEMOD_TDA10045) { - fe_params->u.ofdm.code_rate_HP = FEC_AUTO; - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; - fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; - } - - // Set standard params.. or put them to auto - if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) || - (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) || - (fe_params->u.ofdm.constellation == QAM_AUTO) || - (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) { - tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits - tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x3f, 0); // turn off FEC bits - } else { - tda1004x_write_mask(state, TDA1004X_AUTO, 1, 0); // disable auto - - // set HP FEC - tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP); - if (tmp < 0) - return tmp; - tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp); - - // set LP FEC - tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP); - if (tmp < 0) - return tmp; - tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3); - - // set constellation - switch (fe_params->u.ofdm.constellation) { - case QPSK: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 0); - break; - - case QAM_16: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 1); - break; - - case QAM_64: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 2); - break; - - default: - return -EINVAL; - } - - // set hierarchy - switch (fe_params->u.ofdm.hierarchy_information) { - case HIERARCHY_NONE: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0 << 5); - break; - - case HIERARCHY_1: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 1 << 5); - break; - - case HIERARCHY_2: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 2 << 5); - break; - - case HIERARCHY_4: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 3 << 5); - break; - - default: - return -EINVAL; - } - } - - // set bandwidth - switch (state->demod_type) { - case TDA1004X_DEMOD_TDA10045: - tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth); - break; - - case TDA1004X_DEMOD_TDA10046: - tda10046h_set_bandwidth(state, fe_params->u.ofdm.bandwidth); - break; - } - - // set inversion - inversion = fe_params->inversion; - if (state->config->invert) - inversion = inversion ? INVERSION_OFF : INVERSION_ON; - switch (inversion) { - case INVERSION_OFF: - tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0); - break; - - case INVERSION_ON: - tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0x20); - break; - - default: - return -EINVAL; - } - - // set guard interval - switch (fe_params->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_32: - tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2); - break; - - case GUARD_INTERVAL_1_16: - tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 1 << 2); - break; - - case GUARD_INTERVAL_1_8: - tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 2 << 2); - break; - - case GUARD_INTERVAL_1_4: - tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 3 << 2); - break; - - case GUARD_INTERVAL_AUTO: - tda1004x_write_mask(state, TDA1004X_AUTO, 2, 2); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2); - break; - - default: - return -EINVAL; - } - - // set transmission mode - switch (fe_params->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: - tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0 << 4); - break; - - case TRANSMISSION_MODE_8K: - tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 1 << 4); - break; - - case TRANSMISSION_MODE_AUTO: - tda1004x_write_mask(state, TDA1004X_AUTO, 4, 4); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0); - break; - - default: - return -EINVAL; - } - - // start the lock - switch (state->demod_type) { - case TDA1004X_DEMOD_TDA10045: - tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); - tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0); - break; - - case TDA1004X_DEMOD_TDA10046: - tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); - msleep(1); - tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1); - break; - } - - msleep(10); - - return 0; -} - -static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) -{ - struct tda1004x_state* state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - // inversion status - fe_params->inversion = INVERSION_OFF; - if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) - fe_params->inversion = INVERSION_ON; - if (state->config->invert) - fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON; - - // bandwidth - switch (state->demod_type) { - case TDA1004X_DEMOD_TDA10045: - switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) { - case 0x14: - fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; - break; - case 0xdb: - fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; - break; - case 0x4f: - fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - break; - } - break; - case TDA1004X_DEMOD_TDA10046: - switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) { - case 0x5c: - case 0x54: - fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; - break; - case 0x6a: - case 0x60: - fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; - break; - case 0x7b: - case 0x70: - fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - break; - } - break; - } - - // FEC - fe_params->u.ofdm.code_rate_HP = - tda1004x_decode_fec(tda1004x_read_byte(state, TDA1004X_OUT_CONF2) & 7); - fe_params->u.ofdm.code_rate_LP = - tda1004x_decode_fec((tda1004x_read_byte(state, TDA1004X_OUT_CONF2) >> 3) & 7); - - // constellation - switch (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 3) { - case 0: - fe_params->u.ofdm.constellation = QPSK; - break; - case 1: - fe_params->u.ofdm.constellation = QAM_16; - break; - case 2: - fe_params->u.ofdm.constellation = QAM_64; - break; - } - - // transmission mode - fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; - if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) - fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - - // guard interval - switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) { - case 0: - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; - break; - } - - // hierarchy - switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x60) >> 5) { - case 0: - fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE; - break; - case 1: - fe_params->u.ofdm.hierarchy_information = HIERARCHY_1; - break; - case 2: - fe_params->u.ofdm.hierarchy_information = HIERARCHY_2; - break; - case 3: - fe_params->u.ofdm.hierarchy_information = HIERARCHY_4; - break; - } - - return 0; -} - -static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int status; - int cber; - int vber; - - dprintk("%s\n", __func__); - - // read status - status = tda1004x_read_byte(state, TDA1004X_STATUS_CD); - if (status == -1) - return -EIO; - - // decode - *fe_status = 0; - if (status & 4) - *fe_status |= FE_HAS_SIGNAL; - if (status & 2) - *fe_status |= FE_HAS_CARRIER; - if (status & 8) - *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - - // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi - // is getting anything valid - if (!(*fe_status & FE_HAS_VITERBI)) { - // read the CBER - cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB); - if (cber == -1) - return -EIO; - status = tda1004x_read_byte(state, TDA1004X_CBER_MSB); - if (status == -1) - return -EIO; - cber |= (status << 8); - // The address 0x20 should be read to cope with a TDA10046 bug - tda1004x_read_byte(state, TDA1004X_CBER_RESET); - - if (cber != 65535) - *fe_status |= FE_HAS_VITERBI; - } - - // if we DO have some valid VITERBI output, but don't already have SYNC - // bytes (i.e. not LOCKED), see if the RS decoder is getting anything valid. - if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) { - // read the VBER - vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB); - if (vber == -1) - return -EIO; - status = tda1004x_read_byte(state, TDA1004X_VBER_MID); - if (status == -1) - return -EIO; - vber |= (status << 8); - status = tda1004x_read_byte(state, TDA1004X_VBER_MSB); - if (status == -1) - return -EIO; - vber |= (status & 0x0f) << 16; - // The CVBER_LUT should be read to cope with TDA10046 hardware bug - tda1004x_read_byte(state, TDA1004X_CVBER_LUT); - - // if RS has passed some valid TS packets, then we must be - // getting some SYNC bytes - if (vber < 16632) - *fe_status |= FE_HAS_SYNC; - } - - // success - dprintk("%s: fe_status=0x%x\n", __func__, *fe_status); - return 0; -} - -static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int tmp; - int reg = 0; - - dprintk("%s\n", __func__); - - // determine the register to use - switch (state->demod_type) { - case TDA1004X_DEMOD_TDA10045: - reg = TDA10045H_S_AGC; - break; - - case TDA1004X_DEMOD_TDA10046: - reg = TDA10046H_AGC_IF_LEVEL; - break; - } - - // read it - tmp = tda1004x_read_byte(state, reg); - if (tmp < 0) - return -EIO; - - *signal = (tmp << 8) | tmp; - dprintk("%s: signal=0x%x\n", __func__, *signal); - return 0; -} - -static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int tmp; - - dprintk("%s\n", __func__); - - // read it - tmp = tda1004x_read_byte(state, TDA1004X_SNR); - if (tmp < 0) - return -EIO; - tmp = 255 - tmp; - - *snr = ((tmp << 8) | tmp); - dprintk("%s: snr=0x%x\n", __func__, *snr); - return 0; -} - -static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int tmp; - int tmp2; - int counter; - - dprintk("%s\n", __func__); - - // read the UCBLOCKS and reset - counter = 0; - tmp = tda1004x_read_byte(state, TDA1004X_UNCOR); - if (tmp < 0) - return -EIO; - tmp &= 0x7f; - while (counter++ < 5) { - tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0); - tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0); - tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0); - - tmp2 = tda1004x_read_byte(state, TDA1004X_UNCOR); - if (tmp2 < 0) - return -EIO; - tmp2 &= 0x7f; - if ((tmp2 < tmp) || (tmp2 == 0)) - break; - } - - if (tmp != 0x7f) - *ucblocks = tmp; - else - *ucblocks = 0xffffffff; - - dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks); - return 0; -} - -static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int tmp; - - dprintk("%s\n", __func__); - - // read it in - tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB); - if (tmp < 0) - return -EIO; - *ber = tmp << 1; - tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB); - if (tmp < 0) - return -EIO; - *ber |= (tmp << 9); - // The address 0x20 should be read to cope with a TDA10046 bug - tda1004x_read_byte(state, TDA1004X_CBER_RESET); - - dprintk("%s: ber=0x%x\n", __func__, *ber); - return 0; -} - -static int tda1004x_sleep(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int gpio_conf; - - switch (state->demod_type) { - case TDA1004X_DEMOD_TDA10045: - tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10); - break; - - case TDA1004X_DEMOD_TDA10046: - /* set outputs to tristate */ - tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); - /* invert GPIO 1 and 3 if desired*/ - gpio_conf = state->config->gpio_config; - if (gpio_conf >= TDA10046_GP00_I) - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, - (gpio_conf & 0x0f) ^ 0x0a); - - tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0xc0); - tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); - break; - } - - return 0; -} - -static int tda1004x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct tda1004x_state* state = fe->demodulator_priv; - - if (enable) { - return tda1004x_enable_tuner_i2c(state); - } else { - return tda1004x_disable_tuner_i2c(state); - } -} - -static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 800; - /* Drift compensation makes no sense for DVB-T */ - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static void tda1004x_release(struct dvb_frontend* fe) -{ - struct tda1004x_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops tda10045_ops = { - .info = { - .name = "Philips TDA10045H DVB-T", - .type = FE_OFDM, - .frequency_min = 51000000, - .frequency_max = 858000000, - .frequency_stepsize = 166667, - .caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO - }, - - .release = tda1004x_release, - - .init = tda10045_init, - .sleep = tda1004x_sleep, - .write = tda1004x_write, - .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, - - .set_frontend = tda1004x_set_fe, - .get_frontend = tda1004x_get_fe, - .get_tune_settings = tda1004x_get_tune_settings, - - .read_status = tda1004x_read_status, - .read_ber = tda1004x_read_ber, - .read_signal_strength = tda1004x_read_signal_strength, - .read_snr = tda1004x_read_snr, - .read_ucblocks = tda1004x_read_ucblocks, -}; - -struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, - struct i2c_adapter* i2c) -{ - struct tda1004x_state *state; - int id; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); - if (!state) { - printk(KERN_ERR "Can't alocate memory for tda10045 state\n"); - return NULL; - } - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->demod_type = TDA1004X_DEMOD_TDA10045; - - /* check if the demod is there */ - id = tda1004x_read_byte(state, TDA1004X_CHIPID); - if (id < 0) { - printk(KERN_ERR "tda10045: chip is not answering. Giving up.\n"); - kfree(state); - return NULL; - } - - if (id != 0x25) { - printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id); - kfree(state); - return NULL; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -static struct dvb_frontend_ops tda10046_ops = { - .info = { - .name = "Philips TDA10046H DVB-T", - .type = FE_OFDM, - .frequency_min = 51000000, - .frequency_max = 858000000, - .frequency_stepsize = 166667, - .caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO - }, - - .release = tda1004x_release, - - .init = tda10046_init, - .sleep = tda1004x_sleep, - .write = tda1004x_write, - .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, - - .set_frontend = tda1004x_set_fe, - .get_frontend = tda1004x_get_fe, - .get_tune_settings = tda1004x_get_tune_settings, - - .read_status = tda1004x_read_status, - .read_ber = tda1004x_read_ber, - .read_signal_strength = tda1004x_read_signal_strength, - .read_snr = tda1004x_read_snr, - .read_ucblocks = tda1004x_read_ucblocks, -}; - -struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, - struct i2c_adapter* i2c) -{ - struct tda1004x_state *state; - int id; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); - if (!state) { - printk(KERN_ERR "Can't alocate memory for tda10046 state\n"); - return NULL; - } - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->demod_type = TDA1004X_DEMOD_TDA10046; - - /* check if the demod is there */ - id = tda1004x_read_byte(state, TDA1004X_CHIPID); - if (id < 0) { - printk(KERN_ERR "tda10046: chip is not answering. Giving up.\n"); - kfree(state); - return NULL; - } - if (id != 0x46) { - printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id); - kfree(state); - return NULL; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Philips TDA10045H & TDA10046H DVB-T Demodulator"); -MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(tda10045_attach); -EXPORT_SYMBOL(tda10046_attach); diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h deleted file mode 100644 index 4e27ffb0f14..00000000000 --- a/drivers/media/dvb/frontends/tda1004x.h +++ /dev/null @@ -1,149 +0,0 @@ - /* - Driver for Philips tda1004xh OFDM Frontend - - (c) 2004 Andrew de Quincey - - 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 TDA1004X_H -#define TDA1004X_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -enum tda10046_xtal { - TDA10046_XTAL_4M, - TDA10046_XTAL_16M, -}; - -enum tda10046_agc { - TDA10046_AGC_DEFAULT, /* original configuration */ - TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */ - TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */ - TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */ -}; - -/* Many (hybrid) boards use GPIO 1 and 3 - GPIO1 analog - dvb switch - GPIO3 firmware eeprom address switch -*/ -enum tda10046_gpio { - TDA10046_GPTRI = 0x00, /* All GPIOs tristate */ - TDA10046_GP00 = 0x40, /* GPIO3=0, GPIO1=0 */ - TDA10046_GP01 = 0x42, /* GPIO3=0, GPIO1=1 */ - TDA10046_GP10 = 0x48, /* GPIO3=1, GPIO1=0 */ - TDA10046_GP11 = 0x4a, /* GPIO3=1, GPIO1=1 */ - TDA10046_GP00_I = 0x80, /* GPIO3=0, GPIO1=0, invert in sleep mode*/ - TDA10046_GP01_I = 0x82, /* GPIO3=0, GPIO1=1, invert in sleep mode */ - TDA10046_GP10_I = 0x88, /* GPIO3=1, GPIO1=0, invert in sleep mode */ - TDA10046_GP11_I = 0x8a, /* GPIO3=1, GPIO1=1, invert in sleep mode */ -}; - -enum tda10046_if { - TDA10046_FREQ_3617, /* original config, 36,166 MHZ */ - TDA10046_FREQ_3613, /* 36,13 MHZ */ - TDA10046_FREQ_045, /* low IF, 4.0, 4.5, or 5.0 MHZ */ - TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */ -}; - -enum tda10046_tsout { - TDA10046_TS_PARALLEL = 0x00, /* parallel transport stream, default */ - TDA10046_TS_SERIAL = 0x01, /* serial transport stream */ -}; - -struct tda1004x_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* does the "inversion" need inverted? */ - u8 invert; - - /* Does the OCLK signal need inverted? */ - u8 invert_oclk; - - /* parallel or serial transport stream */ - enum tda10046_tsout ts_mode; - - /* Xtal frequency, 4 or 16MHz*/ - enum tda10046_xtal xtal_freq; - - /* IF frequency */ - enum tda10046_if if_freq; - - /* AGC configuration */ - enum tda10046_agc agc_config; - - /* setting of GPIO1 and 3 */ - enum tda10046_gpio gpio_config; - - /* slave address and configuration of the tuner */ - u8 tuner_address; - u8 antenna_switch; - - /* if the board uses another I2c Bridge (tda8290), its address */ - u8 i2c_gate; - - /* request firmware for device */ - int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); -}; - -enum tda1004x_demod { - TDA1004X_DEMOD_TDA10045, - TDA1004X_DEMOD_TDA10046, -}; - -struct tda1004x_state { - struct i2c_adapter* i2c; - const struct tda1004x_config* config; - struct dvb_frontend frontend; - - /* private demod data */ - enum tda1004x_demod demod_type; -}; - -#if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE)) -extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, - struct i2c_adapter* i2c); - -extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -static inline struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_TDA1004X - -static inline int tda1004x_writereg(struct dvb_frontend *fe, u8 reg, u8 val) { - int r = 0; - u8 buf[] = {reg, val}; - if (fe->ops.write) - r = fe->ops.write(fe, buf, 2); - return r; -} - -#endif // TDA1004X_H diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c deleted file mode 100644 index a17ce3c4ad8..00000000000 --- a/drivers/media/dvb/frontends/tda10086.c +++ /dev/null @@ -1,775 +0,0 @@ - /* - Driver for Philips tda10086 DVBS Demodulator - - (c) 2006 Andrew de Quincey - - 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 <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/jiffies.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "tda10086.h" - -#define SACLK 96000000 - -struct tda10086_state { - struct i2c_adapter* i2c; - const struct tda10086_config* config; - struct dvb_frontend frontend; - - /* private demod data */ - u32 frequency; - u32 symbol_rate; - bool has_lock; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "tda10086: " args); \ - } while (0) - -static int tda10086_write_byte(struct tda10086_state *state, int reg, int data) -{ - int ret; - u8 b0[] = { reg, data }; - struct i2c_msg msg = { .flags = 0, .buf = b0, .len = 2 }; - - msg.addr = state->config->demod_address; - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n", - __func__, reg, data, ret); - - return (ret != 1) ? ret : 0; -} - -static int tda10086_read_byte(struct tda10086_state *state, int reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 }, - { .flags = I2C_M_RD, .buf = b1, .len = 1 }}; - - msg[0].addr = state->config->demod_address; - msg[1].addr = state->config->demod_address; - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, - ret); - return ret; - } - - return b1[0]; -} - -static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask, int data) -{ - int val; - - /* read a byte and check */ - val = tda10086_read_byte(state, reg); - if (val < 0) - return val; - - /* mask if off */ - val = val & ~mask; - val |= data & 0xff; - - /* write it out again */ - return tda10086_write_byte(state, reg, val); -} - -static int tda10086_init(struct dvb_frontend* fe) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 t22k_off = 0x80; - - dprintk ("%s\n", __func__); - - if (state->config->diseqc_tone) - t22k_off = 0; - /* reset */ - tda10086_write_byte(state, 0x00, 0x00); - msleep(10); - - /* misc setup */ - tda10086_write_byte(state, 0x01, 0x94); - tda10086_write_byte(state, 0x02, 0x35); /* NOTE: TT drivers appear to disable CSWP */ - tda10086_write_byte(state, 0x03, 0xe4); - tda10086_write_byte(state, 0x04, 0x43); - tda10086_write_byte(state, 0x0c, 0x0c); - tda10086_write_byte(state, 0x1b, 0xb0); /* noise threshold */ - tda10086_write_byte(state, 0x20, 0x89); /* misc */ - tda10086_write_byte(state, 0x30, 0x04); /* acquisition period length */ - tda10086_write_byte(state, 0x32, 0x00); /* irq off */ - tda10086_write_byte(state, 0x31, 0x56); /* setup AFC */ - - /* setup PLL (this assumes SACLK = 96MHz) */ - tda10086_write_byte(state, 0x55, 0x2c); /* misc PLL setup */ - if (state->config->xtal_freq == TDA10086_XTAL_16M) { - tda10086_write_byte(state, 0x3a, 0x0b); /* M=12 */ - tda10086_write_byte(state, 0x3b, 0x01); /* P=2 */ - } else { - tda10086_write_byte(state, 0x3a, 0x17); /* M=24 */ - tda10086_write_byte(state, 0x3b, 0x00); /* P=1 */ - } - tda10086_write_mask(state, 0x55, 0x20, 0x00); /* powerup PLL */ - - /* setup TS interface */ - tda10086_write_byte(state, 0x11, 0x81); - tda10086_write_byte(state, 0x12, 0x81); - tda10086_write_byte(state, 0x19, 0x40); /* parallel mode A + MSBFIRST */ - tda10086_write_byte(state, 0x56, 0x80); /* powerdown WPLL - unused in the mode we use */ - tda10086_write_byte(state, 0x57, 0x08); /* bypass WPLL - unused in the mode we use */ - tda10086_write_byte(state, 0x10, 0x2a); - - /* setup ADC */ - tda10086_write_byte(state, 0x58, 0x61); /* ADC setup */ - tda10086_write_mask(state, 0x58, 0x01, 0x00); /* powerup ADC */ - - /* setup AGC */ - tda10086_write_byte(state, 0x05, 0x0B); - tda10086_write_byte(state, 0x37, 0x63); - tda10086_write_byte(state, 0x3f, 0x0a); /* NOTE: flydvb varies it */ - tda10086_write_byte(state, 0x40, 0x64); - tda10086_write_byte(state, 0x41, 0x4f); - tda10086_write_byte(state, 0x42, 0x43); - - /* setup viterbi */ - tda10086_write_byte(state, 0x1a, 0x11); /* VBER 10^6, DVB, QPSK */ - - /* setup carrier recovery */ - tda10086_write_byte(state, 0x3d, 0x80); - - /* setup SEC */ - tda10086_write_byte(state, 0x36, t22k_off); /* all SEC off, 22k tone */ - tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); - tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); - - return 0; -} - -static void tda10086_diseqc_wait(struct tda10086_state *state) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(200); - while (!(tda10086_read_byte(state, 0x50) & 0x01)) { - if(time_after(jiffies, timeout)) { - printk("%s: diseqc queue not ready, command may be lost.\n", __func__); - break; - } - msleep(10); - } -} - -static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 t22k_off = 0x80; - - dprintk ("%s\n", __func__); - - if (state->config->diseqc_tone) - t22k_off = 0; - - switch (tone) { - case SEC_TONE_OFF: - tda10086_write_byte(state, 0x36, t22k_off); - break; - - case SEC_TONE_ON: - tda10086_write_byte(state, 0x36, 0x01 + t22k_off); - break; - } - - return 0; -} - -static int tda10086_send_master_cmd (struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd* cmd) -{ - struct tda10086_state* state = fe->demodulator_priv; - int i; - u8 oldval; - u8 t22k_off = 0x80; - - dprintk ("%s\n", __func__); - - if (state->config->diseqc_tone) - t22k_off = 0; - - if (cmd->msg_len > 6) - return -EINVAL; - oldval = tda10086_read_byte(state, 0x36); - - for(i=0; i< cmd->msg_len; i++) { - tda10086_write_byte(state, 0x48+i, cmd->msg[i]); - } - tda10086_write_byte(state, 0x36, (0x08 + t22k_off) - | ((cmd->msg_len - 1) << 4)); - - tda10086_diseqc_wait(state); - - tda10086_write_byte(state, 0x36, oldval); - - return 0; -} - -static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 oldval = tda10086_read_byte(state, 0x36); - u8 t22k_off = 0x80; - - dprintk ("%s\n", __func__); - - if (state->config->diseqc_tone) - t22k_off = 0; - - switch(minicmd) { - case SEC_MINI_A: - tda10086_write_byte(state, 0x36, 0x04 + t22k_off); - break; - - case SEC_MINI_B: - tda10086_write_byte(state, 0x36, 0x06 + t22k_off); - break; - } - - tda10086_diseqc_wait(state); - - tda10086_write_byte(state, 0x36, oldval); - - return 0; -} - -static int tda10086_set_inversion(struct tda10086_state *state, - struct dvb_frontend_parameters *fe_params) -{ - u8 invval = 0x80; - - dprintk ("%s %i %i\n", __func__, fe_params->inversion, state->config->invert); - - switch(fe_params->inversion) { - case INVERSION_OFF: - if (state->config->invert) - invval = 0x40; - break; - case INVERSION_ON: - if (!state->config->invert) - invval = 0x40; - break; - case INVERSION_AUTO: - invval = 0x00; - break; - } - tda10086_write_mask(state, 0x0c, 0xc0, invval); - - return 0; -} - -static int tda10086_set_symbol_rate(struct tda10086_state *state, - struct dvb_frontend_parameters *fe_params) -{ - u8 dfn = 0; - u8 afs = 0; - u8 byp = 0; - u8 reg37 = 0x43; - u8 reg42 = 0x43; - u64 big; - u32 tmp; - u32 bdr; - u32 bdri; - u32 symbol_rate = fe_params->u.qpsk.symbol_rate; - - dprintk ("%s %i\n", __func__, symbol_rate); - - /* setup the decimation and anti-aliasing filters.. */ - if (symbol_rate < (u32) (SACLK * 0.0137)) { - dfn=4; - afs=1; - } else if (symbol_rate < (u32) (SACLK * 0.0208)) { - dfn=4; - afs=0; - } else if (symbol_rate < (u32) (SACLK * 0.0270)) { - dfn=3; - afs=1; - } else if (symbol_rate < (u32) (SACLK * 0.0416)) { - dfn=3; - afs=0; - } else if (symbol_rate < (u32) (SACLK * 0.0550)) { - dfn=2; - afs=1; - } else if (symbol_rate < (u32) (SACLK * 0.0833)) { - dfn=2; - afs=0; - } else if (symbol_rate < (u32) (SACLK * 0.1100)) { - dfn=1; - afs=1; - } else if (symbol_rate < (u32) (SACLK * 0.1666)) { - dfn=1; - afs=0; - } else if (symbol_rate < (u32) (SACLK * 0.2200)) { - dfn=0; - afs=1; - } else if (symbol_rate < (u32) (SACLK * 0.3333)) { - dfn=0; - afs=0; - } else { - reg37 = 0x63; - reg42 = 0x4f; - byp=1; - } - - /* calculate BDR */ - big = (1ULL<<21) * ((u64) symbol_rate/1000ULL) * (1ULL<<dfn); - big += ((SACLK/1000ULL)-1ULL); - do_div(big, (SACLK/1000ULL)); - bdr = big & 0xfffff; - - /* calculate BDRI */ - tmp = (1<<dfn)*(symbol_rate/1000); - bdri = ((32 * (SACLK/1000)) + (tmp-1)) / tmp; - - tda10086_write_byte(state, 0x21, (afs << 7) | dfn); - tda10086_write_mask(state, 0x20, 0x08, byp << 3); - tda10086_write_byte(state, 0x06, bdr); - tda10086_write_byte(state, 0x07, bdr >> 8); - tda10086_write_byte(state, 0x08, bdr >> 16); - tda10086_write_byte(state, 0x09, bdri); - tda10086_write_byte(state, 0x37, reg37); - tda10086_write_byte(state, 0x42, reg42); - - return 0; -} - -static int tda10086_set_fec(struct tda10086_state *state, - struct dvb_frontend_parameters *fe_params) -{ - u8 fecval; - - dprintk ("%s %i\n", __func__, fe_params->u.qpsk.fec_inner); - - switch(fe_params->u.qpsk.fec_inner) { - case FEC_1_2: - fecval = 0x00; - break; - case FEC_2_3: - fecval = 0x01; - break; - case FEC_3_4: - fecval = 0x02; - break; - case FEC_4_5: - fecval = 0x03; - break; - case FEC_5_6: - fecval = 0x04; - break; - case FEC_6_7: - fecval = 0x05; - break; - case FEC_7_8: - fecval = 0x06; - break; - case FEC_8_9: - fecval = 0x07; - break; - case FEC_AUTO: - fecval = 0x08; - break; - default: - return -1; - } - tda10086_write_byte(state, 0x0d, fecval); - - return 0; -} - -static int tda10086_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fe_params) -{ - struct tda10086_state *state = fe->demodulator_priv; - int ret; - u32 freq = 0; - int freqoff; - - dprintk ("%s\n", __func__); - - /* modify parameters for tuning */ - tda10086_write_byte(state, 0x02, 0x35); - state->has_lock = false; - - /* set params */ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fe_params); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - if (fe->ops.tuner_ops.get_frequency) - fe->ops.tuner_ops.get_frequency(fe, &freq); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* calcluate the frequency offset (in *Hz* not kHz) */ - freqoff = fe_params->frequency - freq; - freqoff = ((1<<16) * freqoff) / (SACLK/1000); - tda10086_write_byte(state, 0x3d, 0x80 | ((freqoff >> 8) & 0x7f)); - tda10086_write_byte(state, 0x3e, freqoff); - - if ((ret = tda10086_set_inversion(state, fe_params)) < 0) - return ret; - if ((ret = tda10086_set_symbol_rate(state, fe_params)) < 0) - return ret; - if ((ret = tda10086_set_fec(state, fe_params)) < 0) - return ret; - - /* soft reset + disable TS output until lock */ - tda10086_write_mask(state, 0x10, 0x40, 0x40); - tda10086_write_mask(state, 0x00, 0x01, 0x00); - - state->symbol_rate = fe_params->u.qpsk.symbol_rate; - state->frequency = fe_params->frequency; - return 0; -} - -static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 val; - int tmp; - u64 tmp64; - - dprintk ("%s\n", __func__); - - /* check for invalid symbol rate */ - if (fe_params->u.qpsk.symbol_rate < 500000) - return -EINVAL; - - /* calculate the updated frequency (note: we convert from Hz->kHz) */ - tmp64 = tda10086_read_byte(state, 0x52); - tmp64 |= (tda10086_read_byte(state, 0x51) << 8); - if (tmp64 & 0x8000) - tmp64 |= 0xffffffffffff0000ULL; - tmp64 = (tmp64 * (SACLK/1000ULL)); - do_div(tmp64, (1ULL<<15) * (1ULL<<1)); - fe_params->frequency = (int) state->frequency + (int) tmp64; - - /* the inversion */ - val = tda10086_read_byte(state, 0x0c); - if (val & 0x80) { - switch(val & 0x40) { - case 0x00: - fe_params->inversion = INVERSION_OFF; - if (state->config->invert) - fe_params->inversion = INVERSION_ON; - break; - default: - fe_params->inversion = INVERSION_ON; - if (state->config->invert) - fe_params->inversion = INVERSION_OFF; - break; - } - } else { - tda10086_read_byte(state, 0x0f); - switch(val & 0x02) { - case 0x00: - fe_params->inversion = INVERSION_OFF; - if (state->config->invert) - fe_params->inversion = INVERSION_ON; - break; - default: - fe_params->inversion = INVERSION_ON; - if (state->config->invert) - fe_params->inversion = INVERSION_OFF; - break; - } - } - - /* calculate the updated symbol rate */ - tmp = tda10086_read_byte(state, 0x1d); - if (tmp & 0x80) - tmp |= 0xffffff00; - tmp = (tmp * 480 * (1<<1)) / 128; - tmp = ((state->symbol_rate/1000) * tmp) / (1000000/1000); - fe_params->u.qpsk.symbol_rate = state->symbol_rate + tmp; - - /* the FEC */ - val = (tda10086_read_byte(state, 0x0d) & 0x70) >> 4; - switch(val) { - case 0x00: - fe_params->u.qpsk.fec_inner = FEC_1_2; - break; - case 0x01: - fe_params->u.qpsk.fec_inner = FEC_2_3; - break; - case 0x02: - fe_params->u.qpsk.fec_inner = FEC_3_4; - break; - case 0x03: - fe_params->u.qpsk.fec_inner = FEC_4_5; - break; - case 0x04: - fe_params->u.qpsk.fec_inner = FEC_5_6; - break; - case 0x05: - fe_params->u.qpsk.fec_inner = FEC_6_7; - break; - case 0x06: - fe_params->u.qpsk.fec_inner = FEC_7_8; - break; - case 0x07: - fe_params->u.qpsk.fec_inner = FEC_8_9; - break; - } - - return 0; -} - -static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 val; - - dprintk ("%s\n", __func__); - - val = tda10086_read_byte(state, 0x0e); - *fe_status = 0; - if (val & 0x01) - *fe_status |= FE_HAS_SIGNAL; - if (val & 0x02) - *fe_status |= FE_HAS_CARRIER; - if (val & 0x04) - *fe_status |= FE_HAS_VITERBI; - if (val & 0x08) - *fe_status |= FE_HAS_SYNC; - if (val & 0x10) { - *fe_status |= FE_HAS_LOCK; - if (!state->has_lock) { - state->has_lock = true; - /* modify parameters for stable reception */ - tda10086_write_byte(state, 0x02, 0x00); - } - } - - return 0; -} - -static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 _str; - - dprintk ("%s\n", __func__); - - _str = 0xff - tda10086_read_byte(state, 0x43); - *signal = (_str << 8) | _str; - - return 0; -} - -static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 _snr; - - dprintk ("%s\n", __func__); - - _snr = 0xff - tda10086_read_byte(state, 0x1c); - *snr = (_snr << 8) | _snr; - - return 0; -} - -static int tda10086_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct tda10086_state* state = fe->demodulator_priv; - - dprintk ("%s\n", __func__); - - /* read it */ - *ucblocks = tda10086_read_byte(state, 0x18) & 0x7f; - - /* reset counter */ - tda10086_write_byte(state, 0x18, 0x00); - tda10086_write_byte(state, 0x18, 0x80); - - return 0; -} - -static int tda10086_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct tda10086_state* state = fe->demodulator_priv; - - dprintk ("%s\n", __func__); - - /* read it */ - *ber = 0; - *ber |= tda10086_read_byte(state, 0x15); - *ber |= tda10086_read_byte(state, 0x16) << 8; - *ber |= (tda10086_read_byte(state, 0x17) & 0xf) << 16; - - return 0; -} - -static int tda10086_sleep(struct dvb_frontend* fe) -{ - struct tda10086_state* state = fe->demodulator_priv; - - dprintk ("%s\n", __func__); - - tda10086_write_mask(state, 0x00, 0x08, 0x08); - - return 0; -} - -static int tda10086_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct tda10086_state* state = fe->demodulator_priv; - - dprintk ("%s\n", __func__); - - if (enable) { - tda10086_write_mask(state, 0x00, 0x10, 0x10); - } else { - tda10086_write_mask(state, 0x00, 0x10, 0x00); - } - - return 0; -} - -static int tda10086_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) { - fesettings->min_delay_ms = 50; - fesettings->step_size = 2000; - fesettings->max_drift = 8000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) { - fesettings->min_delay_ms = 100; - fesettings->step_size = 1500; - fesettings->max_drift = 9000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) { - fesettings->min_delay_ms = 100; - fesettings->step_size = 1000; - fesettings->max_drift = 8000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) { - fesettings->min_delay_ms = 100; - fesettings->step_size = 500; - fesettings->max_drift = 7000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) { - fesettings->min_delay_ms = 200; - fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); - fesettings->max_drift = 14 * fesettings->step_size; - } else { - fesettings->min_delay_ms = 200; - fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); - fesettings->max_drift = 18 * fesettings->step_size; - } - - return 0; -} - -static void tda10086_release(struct dvb_frontend* fe) -{ - struct tda10086_state *state = fe->demodulator_priv; - tda10086_sleep(fe); - kfree(state); -} - -static struct dvb_frontend_ops tda10086_ops = { - - .info = { - .name = "Philips TDA10086 DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK - }, - - .release = tda10086_release, - - .init = tda10086_init, - .sleep = tda10086_sleep, - .i2c_gate_ctrl = tda10086_i2c_gate_ctrl, - - .set_frontend = tda10086_set_frontend, - .get_frontend = tda10086_get_frontend, - .get_tune_settings = tda10086_get_tune_settings, - - .read_status = tda10086_read_status, - .read_ber = tda10086_read_ber, - .read_signal_strength = tda10086_read_signal_strength, - .read_snr = tda10086_read_snr, - .read_ucblocks = tda10086_read_ucblocks, - - .diseqc_send_master_cmd = tda10086_send_master_cmd, - .diseqc_send_burst = tda10086_send_burst, - .set_tone = tda10086_set_tone, -}; - -struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, - struct i2c_adapter* i2c) -{ - struct tda10086_state *state; - - dprintk ("%s\n", __func__); - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda10086_state), GFP_KERNEL); - if (!state) - return NULL; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* check if the demod is there */ - if (tda10086_read_byte(state, 0x1e) != 0xe1) { - kfree(state); - return NULL; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10086_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Philips TDA10086 DVB-S Demodulator"); -MODULE_AUTHOR("Andrew de Quincey"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(tda10086_attach); diff --git a/drivers/media/dvb/frontends/tda10086.h b/drivers/media/dvb/frontends/tda10086.h deleted file mode 100644 index 61148c558d8..00000000000 --- a/drivers/media/dvb/frontends/tda10086.h +++ /dev/null @@ -1,61 +0,0 @@ - /* - Driver for Philips tda10086 DVBS Frontend - - (c) 2006 Andrew de Quincey - - 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 TDA10086_H -#define TDA10086_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -enum tda10086_xtal { - TDA10086_XTAL_16M, - TDA10086_XTAL_4M -}; - -struct tda10086_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* does the "inversion" need inverted? */ - u8 invert; - - /* do we need the diseqc signal with carrier? */ - u8 diseqc_tone; - - /* frequency of the reference xtal */ - enum tda10086_xtal xtal_freq; -}; - -#if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE)) -extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_TDA10086 */ - -#endif /* TDA10086_H */ diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c deleted file mode 100644 index 5b843b2e67e..00000000000 --- a/drivers/media/dvb/frontends/tda8083.c +++ /dev/null @@ -1,486 +0,0 @@ -/* - Driver for Philips TDA8083 based QPSK Demodulator - - Copyright (C) 2001 Convergence Integrated Media GmbH - - written by Ralph Metzler <ralph@convergence.de> - - adoption to the new DVB frontend API and diagnostic ioctl's - by Holger Waechtler <holger@convergence.de> - - 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 <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/jiffies.h> -#include "dvb_frontend.h" -#include "tda8083.h" - - -struct tda8083_state { - struct i2c_adapter* i2c; - /* configuration settings */ - const struct tda8083_config* config; - struct dvb_frontend frontend; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "tda8083: " args); \ - } while (0) - - -static u8 tda8083_init_tab [] = { - 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea, - 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10, - 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8, - 0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00, - 0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - - -static int tda8083_writereg (struct tda8083_state* state, u8 reg, u8 data) -{ - int ret; - u8 buf [] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk ("%s: writereg error (reg %02x, ret == %i)\n", - __func__, reg, ret); - - return (ret != 1) ? -1 : 0; -} - -static int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len) -{ - int ret; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = ®1, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - dprintk ("%s: readreg error (reg %02x, ret == %i)\n", - __func__, reg1, ret); - - return ret == 2 ? 0 : -1; -} - -static inline u8 tda8083_readreg (struct tda8083_state* state, u8 reg) -{ - u8 val; - - tda8083_readregs (state, reg, &val, 1); - - return val; -} - -static int tda8083_set_inversion (struct tda8083_state* state, fe_spectral_inversion_t inversion) -{ - /* XXX FIXME: implement other modes than FEC_AUTO */ - if (inversion == INVERSION_AUTO) - return 0; - - return -EINVAL; -} - -static int tda8083_set_fec (struct tda8083_state* state, fe_code_rate_t fec) -{ - if (fec == FEC_AUTO) - return tda8083_writereg (state, 0x07, 0xff); - - if (fec >= FEC_1_2 && fec <= FEC_8_9) - return tda8083_writereg (state, 0x07, 1 << (FEC_8_9 - fec)); - - return -EINVAL; -} - -static fe_code_rate_t tda8083_get_fec (struct tda8083_state* state) -{ - u8 index; - static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4, - FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 }; - - index = tda8083_readreg(state, 0x0e) & 0x07; - - return fec_tab [index]; -} - -static int tda8083_set_symbolrate (struct tda8083_state* state, u32 srate) -{ - u32 ratio; - u32 tmp; - u8 filter; - - if (srate > 32000000) - srate = 32000000; - if (srate < 500000) - srate = 500000; - - filter = 0; - if (srate < 24000000) - filter = 2; - if (srate < 16000000) - filter = 3; - - tmp = 31250 << 16; - ratio = tmp / srate; - - tmp = (tmp % srate) << 8; - ratio = (ratio << 8) + tmp / srate; - - tmp = (tmp % srate) << 8; - ratio = (ratio << 8) + tmp / srate; - - dprintk("tda8083: ratio == %08x\n", (unsigned int) ratio); - - tda8083_writereg (state, 0x05, filter); - tda8083_writereg (state, 0x02, (ratio >> 16) & 0xff); - tda8083_writereg (state, 0x03, (ratio >> 8) & 0xff); - tda8083_writereg (state, 0x04, (ratio ) & 0xff); - - tda8083_writereg (state, 0x00, 0x3c); - tda8083_writereg (state, 0x00, 0x04); - - return 1; -} - -static void tda8083_wait_diseqc_fifo (struct tda8083_state* state, int timeout) -{ - unsigned long start = jiffies; - - while (jiffies - start < timeout && - !(tda8083_readreg(state, 0x02) & 0x80)) - { - msleep(50); - }; -} - -static int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t tone) -{ - tda8083_writereg (state, 0x26, 0xf1); - - switch (tone) { - case SEC_TONE_OFF: - return tda8083_writereg (state, 0x29, 0x00); - case SEC_TONE_ON: - return tda8083_writereg (state, 0x29, 0x80); - default: - return -EINVAL; - }; -} - -static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage) -{ - switch (voltage) { - case SEC_VOLTAGE_13: - return tda8083_writereg (state, 0x20, 0x00); - case SEC_VOLTAGE_18: - return tda8083_writereg (state, 0x20, 0x11); - default: - return -EINVAL; - }; -} - -static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst) -{ - switch (burst) { - case SEC_MINI_A: - tda8083_writereg (state, 0x29, (5 << 2)); /* send burst A */ - break; - case SEC_MINI_B: - tda8083_writereg (state, 0x29, (7 << 2)); /* send B */ - break; - default: - return -EINVAL; - }; - - tda8083_wait_diseqc_fifo (state, 100); - - return 0; -} - -static int tda8083_send_diseqc_msg (struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd *m) -{ - struct tda8083_state* state = fe->demodulator_priv; - int i; - - tda8083_writereg (state, 0x29, (m->msg_len - 3) | (1 << 2)); /* enable */ - - for (i=0; i<m->msg_len; i++) - tda8083_writereg (state, 0x23 + i, m->msg[i]); - - tda8083_writereg (state, 0x29, (m->msg_len - 3) | (3 << 2)); /* send!! */ - - tda8083_wait_diseqc_fifo (state, 100); - - return 0; -} - -static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct tda8083_state* state = fe->demodulator_priv; - - u8 signal = ~tda8083_readreg (state, 0x01); - u8 sync = tda8083_readreg (state, 0x02); - - *status = 0; - - if (signal > 10) - *status |= FE_HAS_SIGNAL; - - if (sync & 0x01) - *status |= FE_HAS_CARRIER; - - if (sync & 0x02) - *status |= FE_HAS_VITERBI; - - if (sync & 0x10) - *status |= FE_HAS_SYNC; - - if (sync & 0x20) /* frontend can not lock */ - *status |= FE_TIMEDOUT; - - if ((sync & 0x1f) == 0x1f) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int tda8083_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct tda8083_state* state = fe->demodulator_priv; - int ret; - u8 buf[3]; - - if ((ret = tda8083_readregs(state, 0x0b, buf, sizeof(buf)))) - return ret; - - *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2]; - - return 0; -} - -static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct tda8083_state* state = fe->demodulator_priv; - - u8 signal = ~tda8083_readreg (state, 0x01); - *strength = (signal << 8) | signal; - - return 0; -} - -static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct tda8083_state* state = fe->demodulator_priv; - - u8 _snr = tda8083_readreg (state, 0x08); - *snr = (_snr << 8) | _snr; - - return 0; -} - -static int tda8083_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct tda8083_state* state = fe->demodulator_priv; - - *ucblocks = tda8083_readreg(state, 0x0f); - if (*ucblocks == 0xff) - *ucblocks = 0xffffffff; - - return 0; -} - -static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct tda8083_state* state = fe->demodulator_priv; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - tda8083_set_inversion (state, p->inversion); - tda8083_set_fec (state, p->u.qpsk.fec_inner); - tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate); - - tda8083_writereg (state, 0x00, 0x3c); - tda8083_writereg (state, 0x00, 0x04); - - return 0; -} - -static int tda8083_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct tda8083_state* state = fe->demodulator_priv; - - /* FIXME: get symbolrate & frequency offset...*/ - /*p->frequency = ???;*/ - p->inversion = (tda8083_readreg (state, 0x0e) & 0x80) ? - INVERSION_ON : INVERSION_OFF; - p->u.qpsk.fec_inner = tda8083_get_fec (state); - /*p->u.qpsk.symbol_rate = tda8083_get_symbolrate (state);*/ - - return 0; -} - -static int tda8083_sleep(struct dvb_frontend* fe) -{ - struct tda8083_state* state = fe->demodulator_priv; - - tda8083_writereg (state, 0x00, 0x02); - return 0; -} - -static int tda8083_init(struct dvb_frontend* fe) -{ - struct tda8083_state* state = fe->demodulator_priv; - int i; - - for (i=0; i<44; i++) - tda8083_writereg (state, i, tda8083_init_tab[i]); - - tda8083_writereg (state, 0x00, 0x3c); - tda8083_writereg (state, 0x00, 0x04); - - return 0; -} - -static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) -{ - struct tda8083_state* state = fe->demodulator_priv; - - tda8083_send_diseqc_burst (state, burst); - tda8083_writereg (state, 0x00, 0x3c); - tda8083_writereg (state, 0x00, 0x04); - - return 0; -} - -static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct tda8083_state* state = fe->demodulator_priv; - - tda8083_set_tone (state, tone); - tda8083_writereg (state, 0x00, 0x3c); - tda8083_writereg (state, 0x00, 0x04); - - return 0; -} - -static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct tda8083_state* state = fe->demodulator_priv; - - tda8083_set_voltage (state, voltage); - tda8083_writereg (state, 0x00, 0x3c); - tda8083_writereg (state, 0x00, 0x04); - - return 0; -} - -static void tda8083_release(struct dvb_frontend* fe) -{ - struct tda8083_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops tda8083_ops; - -struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, - struct i2c_adapter* i2c) -{ - struct tda8083_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda8083_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* check if the demod is there */ - if ((tda8083_readreg(state, 0x00)) != 0x05) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda8083_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops tda8083_ops = { - - .info = { - .name = "Philips TDA8083 DVB-S", - .type = FE_QPSK, - .frequency_min = 920000, /* TDA8060 */ - .frequency_max = 2200000, /* TDA8060 */ - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - /* .frequency_tolerance = ???,*/ - .symbol_rate_min = 12000000, - .symbol_rate_max = 30000000, - /* .symbol_rate_tolerance = ???,*/ - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_MUTE_TS - }, - - .release = tda8083_release, - - .init = tda8083_init, - .sleep = tda8083_sleep, - - .set_frontend = tda8083_set_frontend, - .get_frontend = tda8083_get_frontend, - - .read_status = tda8083_read_status, - .read_signal_strength = tda8083_read_signal_strength, - .read_snr = tda8083_read_snr, - .read_ber = tda8083_read_ber, - .read_ucblocks = tda8083_read_ucblocks, - - .diseqc_send_master_cmd = tda8083_send_diseqc_msg, - .diseqc_send_burst = tda8083_diseqc_send_burst, - .set_tone = tda8083_diseqc_set_tone, - .set_voltage = tda8083_diseqc_set_voltage, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Philips TDA8083 DVB-S Demodulator"); -MODULE_AUTHOR("Ralph Metzler, Holger Waechtler"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(tda8083_attach); diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h deleted file mode 100644 index 5a03c14a10e..00000000000 --- a/drivers/media/dvb/frontends/tda8083.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Driver for Grundig 29504-491, a Philips TDA8083 based QPSK Frontend - - Copyright (C) 2001 Convergence Integrated Media GmbH - - written by Ralph Metzler <ralph@convergence.de> - - adoption to the new DVB frontend API and diagnostic ioctl's - by Holger Waechtler <holger@convergence.de> - - 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 TDA8083_H -#define TDA8083_H - -#include <linux/dvb/frontend.h> - -struct tda8083_config -{ - /* the demodulator's i2c address */ - u8 demod_address; -}; - -#if defined(CONFIG_DVB_TDA8083) || (defined(CONFIG_DVB_TDA8083_MODULE) && defined(MODULE)) -extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_TDA8083 - -#endif // TDA8083_H diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c deleted file mode 100644 index b6d17779910..00000000000 --- a/drivers/media/dvb/frontends/tda8261.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - TDA8261 8PSK/QPSK tuner driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - 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 <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> - -#include "dvb_frontend.h" -#include "tda8261.h" - -struct tda8261_state { - struct dvb_frontend *fe; - struct i2c_adapter *i2c; - const struct tda8261_config *config; - - /* state cache */ - u32 frequency; - u32 bandwidth; -}; - -static int tda8261_read(struct tda8261_state *state, u8 *buf) -{ - const struct tda8261_config *config = state->config; - int err = 0; - struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD,.buf = buf, .len = 2 }; - - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) - printk("%s: read error, err=%d\n", __func__, err); - - return err; -} - -static int tda8261_write(struct tda8261_state *state, u8 *buf) -{ - const struct tda8261_config *config = state->config; - int err = 0; - struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = 4 }; - - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) - printk("%s: write error, err=%d\n", __func__, err); - - return err; -} - -static int tda8261_get_status(struct dvb_frontend *fe, u32 *status) -{ - struct tda8261_state *state = fe->tuner_priv; - u8 result = 0; - int err = 0; - - *status = 0; - - if ((err = tda8261_read(state, &result)) < 0) { - printk("%s: I/O Error\n", __func__); - return err; - } - if ((result >> 6) & 0x01) { - printk("%s: Tuner Phase Locked\n", __func__); - *status = 1; - } - - return err; -} - -static const u32 div_tab[] = { 2000, 1000, 500, 250, 125 }; /* kHz */ -static const u8 ref_div[] = { 0x00, 0x01, 0x02, 0x05, 0x07 }; - -static int tda8261_get_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *tstate) -{ - struct tda8261_state *state = fe->tuner_priv; - int err = 0; - - switch (param) { - case DVBFE_TUNER_FREQUENCY: - tstate->frequency = state->frequency; - break; - case DVBFE_TUNER_BANDWIDTH: - tstate->bandwidth = 40000000; /* FIXME! need to calculate Bandwidth */ - break; - default: - printk("%s: Unknown parameter (param=%d)\n", __func__, param); - err = -EINVAL; - break; - } - - return err; -} - -static int tda8261_set_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *tstate) -{ - struct tda8261_state *state = fe->tuner_priv; - const struct tda8261_config *config = state->config; - u32 frequency, N, status = 0; - u8 buf[4]; - int err = 0; - - if (param & DVBFE_TUNER_FREQUENCY) { - /** - * N = Max VCO Frequency / Channel Spacing - * Max VCO Frequency = VCO frequency + (channel spacing - 1) - * (to account for half channel spacing on either side) - */ - frequency = tstate->frequency; - if ((frequency < 950000) || (frequency > 2150000)) { - printk("%s: Frequency beyond limits, frequency=%d\n", __func__, frequency); - return -EINVAL; - } - N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size]; - printk("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n", - __func__, config->step_size, div_tab[config->step_size], N, N); - - buf[0] = (N >> 8) & 0xff; - buf[1] = N & 0xff; - buf[2] = (0x01 << 7) | ((ref_div[config->step_size] & 0x07) << 1); - - if (frequency < 1450000) - buf[3] = 0x00; - if (frequency < 2000000) - buf[3] = 0x40; - if (frequency < 2150000) - buf[3] = 0x80; - - /* Set params */ - if ((err = tda8261_write(state, buf)) < 0) { - printk("%s: I/O Error\n", __func__); - return err; - } - /* sleep for some time */ - printk("%s: Waiting to Phase LOCK\n", __func__); - msleep(20); - /* check status */ - if ((err = tda8261_get_status(fe, &status)) < 0) { - printk("%s: I/O Error\n", __func__); - return err; - } - if (status == 1) { - printk("%s: Tuner Phase locked: status=%d\n", __func__, status); - state->frequency = frequency; /* cache successful state */ - } else { - printk("%s: No Phase lock: status=%d\n", __func__, status); - } - } else { - printk("%s: Unknown parameter (param=%d)\n", __func__, param); - return -EINVAL; - } - - return 0; -} - -static int tda8261_release(struct dvb_frontend *fe) -{ - struct tda8261_state *state = fe->tuner_priv; - - fe->tuner_priv = NULL; - kfree(state); - return 0; -} - -static struct dvb_tuner_ops tda8261_ops = { - - .info = { - .name = "TDA8261", -// .tuner_name = NULL, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 0 - }, - - .set_state = tda8261_set_state, - .get_state = tda8261_get_state, - .get_status = tda8261_get_status, - .release = tda8261_release -}; - -struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe, - const struct tda8261_config *config, - struct i2c_adapter *i2c) -{ - struct tda8261_state *state = NULL; - - if ((state = kzalloc(sizeof (struct tda8261_state), GFP_KERNEL)) == NULL) - goto exit; - - state->config = config; - state->i2c = i2c; - state->fe = fe; - fe->tuner_priv = state; - fe->ops.tuner_ops = tda8261_ops; - - fe->ops.tuner_ops.info.frequency_step = div_tab[config->step_size]; -// fe->ops.tuner_ops.tuner_name = &config->buf; - -// printk("%s: Attaching %s TDA8261 8PSK/QPSK tuner\n", -// __func__, fe->ops.tuner_ops.tuner_name); - printk("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__); - - return fe; - -exit: - kfree(state); - return NULL; -} - -EXPORT_SYMBOL(tda8261_attach); -MODULE_PARM_DESC(verbose, "Set verbosity level"); - -MODULE_AUTHOR("Manu Abraham"); -MODULE_DESCRIPTION("TDA8261 8PSK/QPSK Tuner"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/tda8261.h b/drivers/media/dvb/frontends/tda8261.h deleted file mode 100644 index 006e45351b9..00000000000 --- a/drivers/media/dvb/frontends/tda8261.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - TDA8261 8PSK/QPSK tuner driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - 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 __TDA8261_H -#define __TDA8261_H - -enum tda8261_step { - TDA8261_STEP_2000 = 0, /* 2000 kHz */ - TDA8261_STEP_1000, /* 1000 kHz */ - TDA8261_STEP_500, /* 500 kHz */ - TDA8261_STEP_250, /* 250 kHz */ - TDA8261_STEP_125 /* 125 kHz */ -}; - -struct tda8261_config { -// u8 buf[16]; - u8 addr; - enum tda8261_step step_size; -}; - -#if defined(CONFIG_DVB_TDA8261) || (defined(CONFIG_DVB_TDA8261_MODULE) && defined(MODULE)) - -extern struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe, - const struct tda8261_config *config, - struct i2c_adapter *i2c); - -#else - -static inline struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe, - const struct tda8261_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); - return NULL; -} - -#endif //CONFIG_DVB_TDA8261 - -#endif// __TDA8261_H diff --git a/drivers/media/dvb/frontends/tda8261_cfg.h b/drivers/media/dvb/frontends/tda8261_cfg.h deleted file mode 100644 index 1af1ee49b54..00000000000 --- a/drivers/media/dvb/frontends/tda8261_cfg.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - TDA8261 8PSK/QPSK tuner driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - 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. -*/ - -static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - struct tuner_state t_state; - int err = 0; - - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->get_state) { - if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - *frequency = t_state.frequency; - printk("%s: Frequency=%d\n", __func__, t_state.frequency); - } - return 0; -} - -static int tda8261_set_frequency(struct dvb_frontend *fe, u32 frequency) -{ - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - struct tuner_state t_state; - int err = 0; - - t_state.frequency = frequency; - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->set_state) { - if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - } - printk("%s: Frequency=%d\n", __func__, t_state.frequency); - return 0; -} - -static int tda8261_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -{ - struct dvb_frontend_ops *frontend_ops = &fe->ops; - struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; - int err = 0; - - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->get_state) { - if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - *bandwidth = t_state.bandwidth; - } - printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth); - return 0; -} diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c deleted file mode 100644 index a051554b5e2..00000000000 --- a/drivers/media/dvb/frontends/tda826x.c +++ /dev/null @@ -1,186 +0,0 @@ - /* - Driver for Philips tda8262/tda8263 DVBS Silicon tuners - - (c) 2006 Andrew de Quincey - - 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 <linux/module.h> -#include <linux/dvb/frontend.h> -#include <asm/types.h> - -#include "tda826x.h" - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "tda826x: " args); \ - } while (0) - -struct tda826x_priv { - /* i2c details */ - int i2c_address; - struct i2c_adapter *i2c; - u8 has_loopthrough:1; - u32 frequency; -}; - -static int tda826x_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static int tda826x_sleep(struct dvb_frontend *fe) -{ - struct tda826x_priv *priv = fe->tuner_priv; - int ret; - u8 buf [] = { 0x00, 0x8d }; - struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 2 }; - - dprintk("%s:\n", __func__); - - if (!priv->has_loopthrough) - buf[1] = 0xad; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) { - dprintk("%s: i2c error\n", __func__); - } - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return (ret == 1) ? 0 : ret; -} - -static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct tda826x_priv *priv = fe->tuner_priv; - int ret; - u32 div; - u32 ksyms; - u32 bandwidth; - u8 buf [11]; - struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 11 }; - - dprintk("%s:\n", __func__); - - div = (params->frequency + (1000-1)) / 1000; - - /* BW = ((1 + RO) * SR/2 + 5) * 1.3 [SR in MSPS, BW in MHz] */ - /* with R0 = 0.35 and some transformations: */ - ksyms = params->u.qpsk.symbol_rate / 1000; - bandwidth = (878 * ksyms + 6500000) / 1000000 + 1; - if (bandwidth < 5) - bandwidth = 5; - else if (bandwidth > 36) - bandwidth = 36; - - buf[0] = 0x00; // subaddress - buf[1] = 0x09; // powerdown RSSI + the magic value 1 - if (!priv->has_loopthrough) - buf[1] |= 0x20; // power down loopthrough if not needed - buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO - buf[3] = div >> 7; - buf[4] = div << 1; - buf[5] = ((bandwidth - 5) << 3) | 7; /* baseband cut-off */ - buf[6] = 0xfe; // baseband gain 9 db + no RF attenuation - buf[7] = 0x83; // charge pumps at high, tests off - buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports. - buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL - buf[10] = 0xd4; // recommended value 13 for BBIAS + unknown bit set on - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) { - dprintk("%s: i2c error\n", __func__); - } - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - priv->frequency = div * 1000; - - return (ret == 1) ? 0 : ret; -} - -static int tda826x_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct tda826x_priv *priv = fe->tuner_priv; - *frequency = priv->frequency; - return 0; -} - -static struct dvb_tuner_ops tda826x_tuner_ops = { - .info = { - .name = "Philips TDA826X", - .frequency_min = 950000, - .frequency_max = 2175000 - }, - .release = tda826x_release, - .sleep = tda826x_sleep, - .set_params = tda826x_set_params, - .get_frequency = tda826x_get_frequency, -}; - -struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough) -{ - struct tda826x_priv *priv = NULL; - u8 b1 [] = { 0, 0 }; - struct i2c_msg msg[2] = { - { .addr = addr, .flags = 0, .buf = NULL, .len = 0 }, - { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } - }; - int ret; - - dprintk("%s:\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - ret = i2c_transfer (i2c, msg, 2); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - if (ret != 2) - return NULL; - if (!(b1[1] & 0x80)) - return NULL; - - priv = kzalloc(sizeof(struct tda826x_priv), GFP_KERNEL); - if (priv == NULL) - return NULL; - - priv->i2c_address = addr; - priv->i2c = i2c; - priv->has_loopthrough = has_loopthrough; - - memcpy(&fe->ops.tuner_ops, &tda826x_tuner_ops, sizeof(struct dvb_tuner_ops)); - - fe->tuner_priv = priv; - - return fe; -} -EXPORT_SYMBOL(tda826x_attach); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("DVB TDA826x driver"); -MODULE_AUTHOR("Andrew de Quincey"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/tda826x.h b/drivers/media/dvb/frontends/tda826x.h deleted file mode 100644 index 89e97926ab2..00000000000 --- a/drivers/media/dvb/frontends/tda826x.h +++ /dev/null @@ -1,53 +0,0 @@ - /* - Driver for Philips tda8262/tda8263 DVBS Silicon tuners - - (c) 2006 Andrew de Quincey - - 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_TDA826X_H__ -#define __DVB_TDA826X_H__ - -#include <linux/i2c.h> -#include "dvb_frontend.h" - -/** - * Attach a tda826x tuner to the supplied frontend structure. - * - * @param fe Frontend to attach to. - * @param addr i2c address of the tuner. - * @param i2c i2c adapter to use. - * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector. - * @return FE pointer on success, NULL on failure. - */ -#if defined(CONFIG_DVB_TDA826X) || (defined(CONFIG_DVB_TDA826X_MODULE) && defined(MODULE)) -extern struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, int addr, - struct i2c_adapter *i2c, - int has_loopthrough); -#else -static inline struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, - int addr, - struct i2c_adapter *i2c, - int has_loopthrough) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_TDA826X - -#endif // __DVB_TDA826X_H__ diff --git a/drivers/media/dvb/frontends/tdhd1.h b/drivers/media/dvb/frontends/tdhd1.h deleted file mode 100644 index 51f17067865..00000000000 --- a/drivers/media/dvb/frontends/tdhd1.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * tdhd1.h - ALPS TDHD1-204A tuner support - * - * Copyright (C) 2008 Oliver Endriss <o.endriss@gmx.de> - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * The project's page is at http://www.linuxtv.org - */ - -#ifndef TDHD1_H -#define TDHD1_H - -#include "tda1004x.h" - -static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name); - -static struct tda1004x_config alps_tdhd1_204a_config = { - .demod_address = 0x8, - .invert = 1, - .invert_oclk = 0, - .xtal_freq = TDA10046_XTAL_4M, - .agc_config = TDA10046_AGC_DEFAULT, - .if_freq = TDA10046_FREQ_3617, - .request_firmware = alps_tdhd1_204_request_firmware -}; - -static int alps_tdhd1_204a_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct i2c_adapter *i2c = fe->tuner_priv; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - u32 div; - - div = (params->frequency + 36166666) / 166666; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x85; - - if (params->frequency >= 174000000 && params->frequency <= 230000000) - data[3] = 0x02; - else if (params->frequency >= 470000000 && params->frequency <= 823000000) - data[3] = 0x0C; - else if (params->frequency > 823000000 && params->frequency <= 862000000) - data[3] = 0x8C; - else - return -EINVAL; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(i2c, &msg, 1) != 1) - return -EIO; - - return 0; -} - -#endif /* TDHD1_H */ diff --git a/drivers/media/dvb/frontends/tua6100.c b/drivers/media/dvb/frontends/tua6100.c deleted file mode 100644 index 1790baee014..00000000000 --- a/drivers/media/dvb/frontends/tua6100.c +++ /dev/null @@ -1,204 +0,0 @@ -/** - * Driver for Infineon tua6100 pll. - * - * (c) 2006 Andrew de Quincey - * - * Based on code found in budget-av.c, which has the following: - * Compiled from various sources by Michael Hunold <michael@mihu.de> - * - * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> & - * Andrew de Quincey <adq_dvb@lidskialf.net> - * - * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * 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 <linux/module.h> -#include <linux/dvb/frontend.h> -#include <asm/types.h> - -#include "tua6100.h" - -struct tua6100_priv { - /* i2c details */ - int i2c_address; - struct i2c_adapter *i2c; - u32 frequency; -}; - -static int tua6100_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static int tua6100_sleep(struct dvb_frontend *fe) -{ - struct tua6100_priv *priv = fe->tuner_priv; - int ret; - u8 reg0[] = { 0x00, 0x00 }; - struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 }; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) { - printk("%s: i2c error\n", __func__); - } - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return (ret == 1) ? 0 : ret; -} - -static int tua6100_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct tua6100_priv *priv = fe->tuner_priv; - u32 div; - u32 prediv; - u8 reg0[] = { 0x00, 0x00 }; - u8 reg1[] = { 0x01, 0x00, 0x00, 0x00 }; - u8 reg2[] = { 0x02, 0x00, 0x00 }; - struct i2c_msg msg0 = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 }; - struct i2c_msg msg1 = { .addr = priv->i2c_address, .flags = 0, .buf = reg1, .len = 4 }; - struct i2c_msg msg2 = { .addr = priv->i2c_address, .flags = 0, .buf = reg2, .len = 3 }; - -#define _R 4 -#define _P 32 -#define _ri 4000000 - - // setup register 0 - if (params->frequency < 2000000) { - reg0[1] = 0x03; - } else { - reg0[1] = 0x07; - } - - // setup register 1 - if (params->frequency < 1630000) { - reg1[1] = 0x2c; - } else { - reg1[1] = 0x0c; - } - if (_P == 64) - reg1[1] |= 0x40; - if (params->frequency >= 1525000) - reg1[1] |= 0x80; - - // register 2 - reg2[1] = (_R >> 8) & 0x03; - reg2[2] = _R; - if (params->frequency < 1455000) { - reg2[1] |= 0x1c; - } else if (params->frequency < 1630000) { - reg2[1] |= 0x0c; - } else { - reg2[1] |= 0x1c; - } - - // The N divisor ratio (note: params->frequency is in kHz, but we need it in Hz) - prediv = (params->frequency * _R) / (_ri / 1000); - div = prediv / _P; - reg1[1] |= (div >> 9) & 0x03; - reg1[2] = div >> 1; - reg1[3] = (div << 7); - priv->frequency = ((div * _P) * (_ri / 1000)) / _R; - - // Finally, calculate and store the value for A - reg1[3] |= (prediv - (div*_P)) & 0x7f; - -#undef _R -#undef _P -#undef _ri - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(priv->i2c, &msg0, 1) != 1) - return -EIO; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(priv->i2c, &msg2, 1) != 1) - return -EIO; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(priv->i2c, &msg1, 1) != 1) - return -EIO; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return 0; -} - -static int tua6100_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct tua6100_priv *priv = fe->tuner_priv; - *frequency = priv->frequency; - return 0; -} - -static struct dvb_tuner_ops tua6100_tuner_ops = { - .info = { - .name = "Infineon TUA6100", - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 1000, - }, - .release = tua6100_release, - .sleep = tua6100_sleep, - .set_params = tua6100_set_params, - .get_frequency = tua6100_get_frequency, -}; - -struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c) -{ - struct tua6100_priv *priv = NULL; - u8 b1 [] = { 0x80 }; - u8 b2 [] = { 0x00 }; - struct i2c_msg msg [] = { { .addr = addr, .flags = 0, .buf = b1, .len = 1 }, - { .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 } }; - int ret; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - ret = i2c_transfer (i2c, msg, 2); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - if (ret != 2) - return NULL; - - priv = kzalloc(sizeof(struct tua6100_priv), GFP_KERNEL); - if (priv == NULL) - return NULL; - - priv->i2c_address = addr; - priv->i2c = i2c; - - memcpy(&fe->ops.tuner_ops, &tua6100_tuner_ops, sizeof(struct dvb_tuner_ops)); - fe->tuner_priv = priv; - return fe; -} -EXPORT_SYMBOL(tua6100_attach); - -MODULE_DESCRIPTION("DVB tua6100 driver"); -MODULE_AUTHOR("Andrew de Quincey"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/tua6100.h b/drivers/media/dvb/frontends/tua6100.h deleted file mode 100644 index f83dbd5e42a..00000000000 --- a/drivers/media/dvb/frontends/tua6100.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Driver for Infineon tua6100 PLL. - * - * (c) 2006 Andrew de Quincey - * - * Based on code found in budget-av.c, which has the following: - * Compiled from various sources by Michael Hunold <michael@mihu.de> - * - * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> & - * Andrew de Quincey <adq_dvb@lidskialf.net> - * - * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * 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_TUA6100_H__ -#define __DVB_TUA6100_H__ - -#include <linux/i2c.h> -#include "dvb_frontend.h" - -#if defined(CONFIG_DVB_TUA6100) || (defined(CONFIG_DVB_TUA6100_MODULE) && defined(MODULE)) -extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_TUA6100 - -#endif diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c deleted file mode 100644 index a184597f1d9..00000000000 --- a/drivers/media/dvb/frontends/ves1820.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - VES1820 - Single Chip Cable Channel Receiver driver module - - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - - 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 <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "ves1820.h" - - - -struct ves1820_state { - struct i2c_adapter* i2c; - /* configuration settings */ - const struct ves1820_config* config; - struct dvb_frontend frontend; - - /* private demodulator data */ - u8 reg0; - u8 pwm; -}; - - -static int verbose; - -static u8 ves1820_inittab[] = { - 0x69, 0x6A, 0x93, 0x1A, 0x12, 0x46, 0x26, 0x1A, - 0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x20, - 0xE0, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40 -}; - -static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data) -{ - u8 buf[] = { 0x00, reg, data }; - struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 3 }; - int ret; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - printk("ves1820: %s(): writereg error (reg == 0x%02x, " - "val == 0x%02x, ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static u8 ves1820_readreg(struct ves1820_state *state, u8 reg) -{ - u8 b0[] = { 0x00, reg }; - 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} - }; - int ret; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - printk("ves1820: %s(): readreg error (reg == 0x%02x, " - "ret == %i)\n", __func__, reg, ret); - - return b1[0]; -} - -static int ves1820_setup_reg0(struct ves1820_state *state, u8 reg0, fe_spectral_inversion_t inversion) -{ - reg0 |= state->reg0 & 0x62; - - if (INVERSION_ON == inversion) { - if (!state->config->invert) reg0 |= 0x20; - else reg0 &= ~0x20; - } else if (INVERSION_OFF == inversion) { - if (!state->config->invert) reg0 &= ~0x20; - else reg0 |= 0x20; - } - - ves1820_writereg(state, 0x00, reg0 & 0xfe); - ves1820_writereg(state, 0x00, reg0 | 0x01); - - state->reg0 = reg0; - - return 0; -} - -static int ves1820_set_symbolrate(struct ves1820_state *state, u32 symbolrate) -{ - s32 BDR; - s32 BDRI; - s16 SFIL = 0; - u16 NDEC = 0; - u32 ratio; - u32 fin; - u32 tmp; - u64 fptmp; - u64 fpxin; - - if (symbolrate > state->config->xin / 2) - symbolrate = state->config->xin / 2; - - if (symbolrate < 500000) - symbolrate = 500000; - - if (symbolrate < state->config->xin / 16) - NDEC = 1; - if (symbolrate < state->config->xin / 32) - NDEC = 2; - if (symbolrate < state->config->xin / 64) - NDEC = 3; - - /* yeuch! */ - fpxin = state->config->xin * 10; - fptmp = fpxin; do_div(fptmp, 123); - if (symbolrate < fptmp) - SFIL = 1; - fptmp = fpxin; do_div(fptmp, 160); - if (symbolrate < fptmp) - SFIL = 0; - fptmp = fpxin; do_div(fptmp, 246); - if (symbolrate < fptmp) - SFIL = 1; - fptmp = fpxin; do_div(fptmp, 320); - if (symbolrate < fptmp) - SFIL = 0; - fptmp = fpxin; do_div(fptmp, 492); - if (symbolrate < fptmp) - SFIL = 1; - fptmp = fpxin; do_div(fptmp, 640); - if (symbolrate < fptmp) - SFIL = 0; - fptmp = fpxin; do_div(fptmp, 984); - if (symbolrate < fptmp) - SFIL = 1; - - fin = state->config->xin >> 4; - symbolrate <<= NDEC; - ratio = (symbolrate << 4) / fin; - tmp = ((symbolrate << 4) % fin) << 8; - ratio = (ratio << 8) + tmp / fin; - tmp = (tmp % fin) << 8; - ratio = (ratio << 8) + (tmp + fin / 2) / fin; - - BDR = ratio; - BDRI = (((state->config->xin << 5) / symbolrate) + 1) / 2; - - if (BDRI > 0xFF) - BDRI = 0xFF; - - SFIL = (SFIL << 4) | ves1820_inittab[0x0E]; - - NDEC = (NDEC << 6) | ves1820_inittab[0x03]; - - ves1820_writereg(state, 0x03, NDEC); - ves1820_writereg(state, 0x0a, BDR & 0xff); - ves1820_writereg(state, 0x0b, (BDR >> 8) & 0xff); - ves1820_writereg(state, 0x0c, (BDR >> 16) & 0x3f); - - ves1820_writereg(state, 0x0d, BDRI); - ves1820_writereg(state, 0x0e, SFIL); - - return 0; -} - -static int ves1820_init(struct dvb_frontend* fe) -{ - struct ves1820_state* state = fe->demodulator_priv; - int i; - - ves1820_writereg(state, 0, 0); - - for (i = 0; i < sizeof(ves1820_inittab); i++) - ves1820_writereg(state, i, ves1820_inittab[i]); - if (state->config->selagc) - ves1820_writereg(state, 2, ves1820_inittab[2] | 0x08); - - ves1820_writereg(state, 0x34, state->pwm); - - return 0; -} - -static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct ves1820_state* state = fe->demodulator_priv; - static const u8 reg0x00[] = { 0x00, 0x04, 0x08, 0x0c, 0x10 }; - static const u8 reg0x01[] = { 140, 140, 106, 100, 92 }; - static const u8 reg0x05[] = { 135, 100, 70, 54, 38 }; - static const u8 reg0x08[] = { 162, 116, 67, 52, 35 }; - static const u8 reg0x09[] = { 145, 150, 106, 126, 107 }; - int real_qam = p->u.qam.modulation - QAM_16; - - if (real_qam < 0 || real_qam > 4) - return -EINVAL; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - ves1820_set_symbolrate(state, p->u.qam.symbol_rate); - ves1820_writereg(state, 0x34, state->pwm); - - ves1820_writereg(state, 0x01, reg0x01[real_qam]); - ves1820_writereg(state, 0x05, reg0x05[real_qam]); - ves1820_writereg(state, 0x08, reg0x08[real_qam]); - ves1820_writereg(state, 0x09, reg0x09[real_qam]); - - ves1820_setup_reg0(state, reg0x00[real_qam], p->inversion); - ves1820_writereg(state, 2, ves1820_inittab[2] | (state->config->selagc ? 0x08 : 0)); - return 0; -} - -static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct ves1820_state* state = fe->demodulator_priv; - int sync; - - *status = 0; - sync = ves1820_readreg(state, 0x11); - - if (sync & 1) - *status |= FE_HAS_SIGNAL; - - if (sync & 2) - *status |= FE_HAS_CARRIER; - - if (sync & 2) /* XXX FIXME! */ - *status |= FE_HAS_VITERBI; - - if (sync & 4) - *status |= FE_HAS_SYNC; - - if (sync & 8) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int ves1820_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct ves1820_state* state = fe->demodulator_priv; - - u32 _ber = ves1820_readreg(state, 0x14) | - (ves1820_readreg(state, 0x15) << 8) | - ((ves1820_readreg(state, 0x16) & 0x0f) << 16); - *ber = 10 * _ber; - - return 0; -} - -static int ves1820_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct ves1820_state* state = fe->demodulator_priv; - - u8 gain = ves1820_readreg(state, 0x17); - *strength = (gain << 8) | gain; - - return 0; -} - -static int ves1820_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct ves1820_state* state = fe->demodulator_priv; - - u8 quality = ~ves1820_readreg(state, 0x18); - *snr = (quality << 8) | quality; - - return 0; -} - -static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct ves1820_state* state = fe->demodulator_priv; - - *ucblocks = ves1820_readreg(state, 0x13) & 0x7f; - if (*ucblocks == 0x7f) - *ucblocks = 0xffffffff; - - /* reset uncorrected block counter */ - ves1820_writereg(state, 0x10, ves1820_inittab[0x10] & 0xdf); - ves1820_writereg(state, 0x10, ves1820_inittab[0x10]); - - return 0; -} - -static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct ves1820_state* state = fe->demodulator_priv; - int sync; - s8 afc = 0; - - sync = ves1820_readreg(state, 0x11); - afc = ves1820_readreg(state, 0x19); - if (verbose) { - /* AFC only valid when carrier has been recovered */ - printk(sync & 2 ? "ves1820: AFC (%d) %dHz\n" : - "ves1820: [AFC (%d) %dHz]\n", afc, -((s32) p->u.qam.symbol_rate * afc) >> 10); - } - - if (!state->config->invert) { - p->inversion = (state->reg0 & 0x20) ? INVERSION_ON : INVERSION_OFF; - } else { - p->inversion = (!(state->reg0 & 0x20)) ? INVERSION_ON : INVERSION_OFF; - } - - p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; - - p->u.qam.fec_inner = FEC_NONE; - - p->frequency = ((p->frequency + 31250) / 62500) * 62500; - if (sync & 2) - p->frequency -= ((s32) p->u.qam.symbol_rate * afc) >> 10; - - return 0; -} - -static int ves1820_sleep(struct dvb_frontend* fe) -{ - struct ves1820_state* state = fe->demodulator_priv; - - ves1820_writereg(state, 0x1b, 0x02); /* pdown ADC */ - ves1820_writereg(state, 0x00, 0x80); /* standby */ - - return 0; -} - -static int ves1820_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - - fesettings->min_delay_ms = 200; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static void ves1820_release(struct dvb_frontend* fe) -{ - struct ves1820_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops ves1820_ops; - -struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, - struct i2c_adapter* i2c, - u8 pwm) -{ - struct ves1820_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct ves1820_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->reg0 = ves1820_inittab[0]; - state->config = config; - state->i2c = i2c; - state->pwm = pwm; - - /* check if the demod is there */ - if ((ves1820_readreg(state, 0x1a) & 0xf0) != 0x70) - goto error; - - if (verbose) - printk("ves1820: pwm=0x%02x\n", state->pwm); - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &ves1820_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */ - state->frontend.ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */ - state->frontend.demodulator_priv = state; - - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops ves1820_ops = { - - .info = { - .name = "VLSI VES1820 DVB-C", - .type = FE_QAM, - .frequency_stepsize = 62500, - .frequency_min = 47000000, - .frequency_max = 862000000, - .caps = FE_CAN_QAM_16 | - FE_CAN_QAM_32 | - FE_CAN_QAM_64 | - FE_CAN_QAM_128 | - FE_CAN_QAM_256 | - FE_CAN_FEC_AUTO - }, - - .release = ves1820_release, - - .init = ves1820_init, - .sleep = ves1820_sleep, - - .set_frontend = ves1820_set_parameters, - .get_frontend = ves1820_get_frontend, - .get_tune_settings = ves1820_get_tune_settings, - - .read_status = ves1820_read_status, - .read_ber = ves1820_read_ber, - .read_signal_strength = ves1820_read_signal_strength, - .read_snr = ves1820_read_snr, - .read_ucblocks = ves1820_read_ucblocks, -}; - -module_param(verbose, int, 0644); -MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting"); - -MODULE_DESCRIPTION("VLSI VES1820 DVB-C Demodulator driver"); -MODULE_AUTHOR("Ralph Metzler, Holger Waechtler"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(ves1820_attach); diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h deleted file mode 100644 index e902ed634ec..00000000000 --- a/drivers/media/dvb/frontends/ves1820.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - VES1820 - Single Chip Cable Channel Receiver driver module - - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - - 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 VES1820_H -#define VES1820_H - -#include <linux/dvb/frontend.h> - -#define VES1820_SELAGC_PWM 0 -#define VES1820_SELAGC_SIGNAMPERR 1 - -struct ves1820_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* value of XIN to use */ - u32 xin; - - /* does inversion need inverted? */ - u8 invert:1; - - /* SELAGC control */ - u8 selagc:1; -}; - -#if defined(CONFIG_DVB_VES1820) || (defined(CONFIG_DVB_VES1820_MODULE) && defined(MODULE)) -extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, - struct i2c_adapter* i2c, u8 pwm); -#else -static inline struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, - struct i2c_adapter* i2c, u8 pwm) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_VES1820 - -#endif // VES1820_H diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c deleted file mode 100644 index bd558960bd8..00000000000 --- a/drivers/media/dvb/frontends/ves1x93.c +++ /dev/null @@ -1,550 +0,0 @@ -/* - Driver for VES1893 and VES1993 QPSK Demodulators - - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de> - Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de> - Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org> - - 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 <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> - -#include "dvb_frontend.h" -#include "ves1x93.h" - - -struct ves1x93_state { - struct i2c_adapter* i2c; - /* configuration settings */ - const struct ves1x93_config* config; - struct dvb_frontend frontend; - - /* previous uncorrected block counter */ - fe_spectral_inversion_t inversion; - u8 *init_1x93_tab; - u8 *init_1x93_wtab; - u8 tab_size; - u8 demod_type; -}; - -static int debug; -#define dprintk if (debug) printk - -#define DEMOD_VES1893 0 -#define DEMOD_VES1993 1 - -static u8 init_1893_tab [] = { - 0x01, 0xa4, 0x35, 0x80, 0x2a, 0x0b, 0x55, 0xc4, - 0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00, - 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x21, 0xb0, 0x14, 0x00, 0xdc, 0x00, - 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x55, 0x00, 0x00, 0x7f, 0x00 -}; - -static u8 init_1993_tab [] = { - 0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c, - 0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00, - 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10, - 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x0e, 0x80, 0x00 -}; - -static u8 init_1893_wtab[] = -{ - 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0, - 0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1, - 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0, - 1,1,1,0,1,1 -}; - -static u8 init_1993_wtab[] = -{ - 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0, - 0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1, - 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0, - 1,1,1,0,1,1,1,1, 1,1,1,1,1 -}; - -static int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data) -{ - u8 buf [] = { 0x00, reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 }; - int err; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data); - return -EREMOTEIO; - } - - return 0; -} - -static u8 ves1x93_readreg (struct ves1x93_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { 0x00, reg }; - 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) return ret; - - return b1[0]; -} - -static int ves1x93_clr_bit (struct ves1x93_state* state) -{ - msleep(10); - ves1x93_writereg (state, 0, state->init_1x93_tab[0] & 0xfe); - ves1x93_writereg (state, 0, state->init_1x93_tab[0]); - msleep(50); - return 0; -} - -static int ves1x93_set_inversion (struct ves1x93_state* state, fe_spectral_inversion_t inversion) -{ - u8 val; - - /* - * inversion on/off are interchanged because i and q seem to - * be swapped on the hardware - */ - - switch (inversion) { - case INVERSION_OFF: - val = 0xc0; - break; - case INVERSION_ON: - val = 0x80; - break; - case INVERSION_AUTO: - val = 0x00; - break; - default: - return -EINVAL; - } - - return ves1x93_writereg (state, 0x0c, (state->init_1x93_tab[0x0c] & 0x3f) | val); -} - -static int ves1x93_set_fec (struct ves1x93_state* state, fe_code_rate_t fec) -{ - if (fec == FEC_AUTO) - return ves1x93_writereg (state, 0x0d, 0x08); - else if (fec < FEC_1_2 || fec > FEC_8_9) - return -EINVAL; - else - return ves1x93_writereg (state, 0x0d, fec - FEC_1_2); -} - -static fe_code_rate_t ves1x93_get_fec (struct ves1x93_state* state) -{ - return FEC_1_2 + ((ves1x93_readreg (state, 0x0d) >> 4) & 0x7); -} - -static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate) -{ - u32 BDR; - u32 ratio; - u8 ADCONF, FCONF, FNR, AGCR; - u32 BDRI; - u32 tmp; - u32 FIN; - - dprintk("%s: srate == %d\n", __func__, (unsigned int) srate); - - if (srate > state->config->xin/2) - srate = state->config->xin/2; - - if (srate < 500000) - srate = 500000; - -#define MUL (1UL<<26) - - FIN = (state->config->xin + 6000) >> 4; - - tmp = srate << 6; - ratio = tmp / FIN; - - tmp = (tmp % FIN) << 8; - ratio = (ratio << 8) + tmp / FIN; - - tmp = (tmp % FIN) << 8; - ratio = (ratio << 8) + tmp / FIN; - - FNR = 0xff; - - if (ratio < MUL/3) FNR = 0; - if (ratio < (MUL*11)/50) FNR = 1; - if (ratio < MUL/6) FNR = 2; - if (ratio < MUL/9) FNR = 3; - if (ratio < MUL/12) FNR = 4; - if (ratio < (MUL*11)/200) FNR = 5; - if (ratio < MUL/24) FNR = 6; - if (ratio < (MUL*27)/1000) FNR = 7; - if (ratio < MUL/48) FNR = 8; - if (ratio < (MUL*137)/10000) FNR = 9; - - if (FNR == 0xff) { - ADCONF = 0x89; - FCONF = 0x80; - FNR = 0; - } else { - ADCONF = 0x81; - FCONF = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5); - /*FCONF = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/ - } - - BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1; - BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1; - - dprintk("FNR= %d\n", FNR); - dprintk("ratio= %08x\n", (unsigned int) ratio); - dprintk("BDR= %08x\n", (unsigned int) BDR); - dprintk("BDRI= %02x\n", (unsigned int) BDRI); - - if (BDRI > 0xff) - BDRI = 0xff; - - ves1x93_writereg (state, 0x06, 0xff & BDR); - ves1x93_writereg (state, 0x07, 0xff & (BDR >> 8)); - ves1x93_writereg (state, 0x08, 0x0f & (BDR >> 16)); - - ves1x93_writereg (state, 0x09, BDRI); - ves1x93_writereg (state, 0x20, ADCONF); - ves1x93_writereg (state, 0x21, FCONF); - - AGCR = state->init_1x93_tab[0x05]; - if (state->config->invert_pwm) - AGCR |= 0x20; - - if (srate < 6000000) - AGCR |= 0x80; - else - AGCR &= ~0x80; - - ves1x93_writereg (state, 0x05, AGCR); - - /* ves1993 hates this, will lose lock */ - if (state->demod_type != DEMOD_VES1993) - ves1x93_clr_bit (state); - - return 0; -} - -static int ves1x93_init (struct dvb_frontend* fe) -{ - struct ves1x93_state* state = fe->demodulator_priv; - int i; - int val; - - dprintk("%s: init chip\n", __func__); - - for (i = 0; i < state->tab_size; i++) { - if (state->init_1x93_wtab[i]) { - val = state->init_1x93_tab[i]; - - if (state->config->invert_pwm && (i == 0x05)) val |= 0x20; /* invert PWM */ - ves1x93_writereg (state, i, val); - } - } - - return 0; -} - -static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - switch (voltage) { - case SEC_VOLTAGE_13: - return ves1x93_writereg (state, 0x1f, 0x20); - case SEC_VOLTAGE_18: - return ves1x93_writereg (state, 0x1f, 0x30); - case SEC_VOLTAGE_OFF: - return ves1x93_writereg (state, 0x1f, 0x00); - default: - return -EINVAL; - } -} - -static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - u8 sync = ves1x93_readreg (state, 0x0e); - - /* - * The ves1893 sometimes returns sync values that make no sense, - * because, e.g., the SIGNAL bit is 0, while some of the higher - * bits are 1 (and how can there be a CARRIER w/o a SIGNAL?). - * Tests showed that the VITERBI and SYNC bits are returned - * reliably, while the SIGNAL and CARRIER bits ar sometimes wrong. - * If such a case occurs, we read the value again, until we get a - * valid value. - */ - int maxtry = 10; /* just for safety - let's not get stuck here */ - while ((sync & 0x03) != 0x03 && (sync & 0x0c) && maxtry--) { - msleep(10); - sync = ves1x93_readreg (state, 0x0e); - } - - *status = 0; - - if (sync & 1) - *status |= FE_HAS_SIGNAL; - - if (sync & 2) - *status |= FE_HAS_CARRIER; - - if (sync & 4) - *status |= FE_HAS_VITERBI; - - if (sync & 8) - *status |= FE_HAS_SYNC; - - if ((sync & 0x1f) == 0x1f) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - *ber = ves1x93_readreg (state, 0x15); - *ber |= (ves1x93_readreg (state, 0x16) << 8); - *ber |= ((ves1x93_readreg (state, 0x17) & 0x0F) << 16); - *ber *= 10; - - return 0; -} - -static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - u8 signal = ~ves1x93_readreg (state, 0x0b); - *strength = (signal << 8) | signal; - - return 0; -} - -static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - u8 _snr = ~ves1x93_readreg (state, 0x1c); - *snr = (_snr << 8) | _snr; - - return 0; -} - -static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f; - - if (*ucblocks == 0x7f) - *ucblocks = 0xffffffff; /* counter overflow... */ - - ves1x93_writereg (state, 0x18, 0x00); /* reset the counter */ - ves1x93_writereg (state, 0x18, 0x80); /* dto. */ - - return 0; -} - -static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - ves1x93_set_inversion (state, p->inversion); - ves1x93_set_fec (state, p->u.qpsk.fec_inner); - ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate); - state->inversion = p->inversion; - - return 0; -} - -static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct ves1x93_state* state = fe->demodulator_priv; - int afc; - - afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2; - afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16; - - p->frequency -= afc; - - /* - * inversion indicator is only valid - * if auto inversion was used - */ - if (state->inversion == INVERSION_AUTO) - p->inversion = (ves1x93_readreg (state, 0x0f) & 2) ? - INVERSION_OFF : INVERSION_ON; - p->u.qpsk.fec_inner = ves1x93_get_fec (state); - /* XXX FIXME: timing offset !! */ - - return 0; -} - -static int ves1x93_sleep(struct dvb_frontend* fe) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - return ves1x93_writereg (state, 0x00, 0x08); -} - -static void ves1x93_release(struct dvb_frontend* fe) -{ - struct ves1x93_state* state = fe->demodulator_priv; - kfree(state); -} - -static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - if (enable) { - return ves1x93_writereg(state, 0x00, 0x11); - } else { - return ves1x93_writereg(state, 0x00, 0x01); - } -} - -static struct dvb_frontend_ops ves1x93_ops; - -struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, - struct i2c_adapter* i2c) -{ - struct ves1x93_state* state = NULL; - u8 identity; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct ves1x93_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->inversion = INVERSION_OFF; - - /* check if the demod is there + identify it */ - identity = ves1x93_readreg(state, 0x1e); - switch (identity) { - case 0xdc: /* VES1893A rev1 */ - printk("ves1x93: Detected ves1893a rev1\n"); - state->demod_type = DEMOD_VES1893; - state->init_1x93_tab = init_1893_tab; - state->init_1x93_wtab = init_1893_wtab; - state->tab_size = sizeof(init_1893_tab); - break; - - case 0xdd: /* VES1893A rev2 */ - printk("ves1x93: Detected ves1893a rev2\n"); - state->demod_type = DEMOD_VES1893; - state->init_1x93_tab = init_1893_tab; - state->init_1x93_wtab = init_1893_wtab; - state->tab_size = sizeof(init_1893_tab); - break; - - case 0xde: /* VES1993 */ - printk("ves1x93: Detected ves1993\n"); - state->demod_type = DEMOD_VES1993; - state->init_1x93_tab = init_1993_tab; - state->init_1x93_wtab = init_1993_wtab; - state->tab_size = sizeof(init_1993_tab); - break; - - default: - goto error; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops ves1x93_ops = { - - .info = { - .name = "VLSI VES1x93 DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - .frequency_tolerance = 29500, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - /* .symbol_rate_tolerance = ???,*/ - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK - }, - - .release = ves1x93_release, - - .init = ves1x93_init, - .sleep = ves1x93_sleep, - .i2c_gate_ctrl = ves1x93_i2c_gate_ctrl, - - .set_frontend = ves1x93_set_frontend, - .get_frontend = ves1x93_get_frontend, - - .read_status = ves1x93_read_status, - .read_ber = ves1x93_read_ber, - .read_signal_strength = ves1x93_read_signal_strength, - .read_snr = ves1x93_read_snr, - .read_ucblocks = ves1x93_read_ucblocks, - - .set_voltage = ves1x93_set_voltage, -}; - -module_param(debug, int, 0644); - -MODULE_DESCRIPTION("VLSI VES1x93 DVB-S Demodulator driver"); -MODULE_AUTHOR("Ralph Metzler"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(ves1x93_attach); diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h deleted file mode 100644 index 8a5a49e808f..00000000000 --- a/drivers/media/dvb/frontends/ves1x93.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Driver for VES1893 and VES1993 QPSK Demodulators - - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de> - Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de> - Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org> - - 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 VES1X93_H -#define VES1X93_H - -#include <linux/dvb/frontend.h> - -struct ves1x93_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* value of XIN to use */ - u32 xin; - - /* should PWM be inverted? */ - u8 invert_pwm:1; -}; - -#if defined(CONFIG_DVB_VES1X93) || (defined(CONFIG_DVB_VES1X93_MODULE) && defined(MODULE)) -extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_VES1X93 - -#endif // VES1X93_H diff --git a/drivers/media/dvb/frontends/z0194a.h b/drivers/media/dvb/frontends/z0194a.h deleted file mode 100644 index 07f3fc0998f..00000000000 --- a/drivers/media/dvb/frontends/z0194a.h +++ /dev/null @@ -1,85 +0,0 @@ -/* z0194a.h Sharp z0194a tuner support -* -* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation, version 2. -* -* see Documentation/dvb/README.dvb-usb for more information -*/ - -#ifndef Z0194A -#define Z0194A - -static int sharp_z0194a_set_symbol_rate(struct dvb_frontend *fe, - u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - - if (srate < 1500000) { - aclk = 0xb7; bclk = 0x47; } - else if (srate < 3000000) { - aclk = 0xb7; bclk = 0x4b; } - else if (srate < 7000000) { - aclk = 0xb7; bclk = 0x4f; } - else if (srate < 14000000) { - aclk = 0xb7; bclk = 0x53; } - else if (srate < 30000000) { - aclk = 0xb6; bclk = 0x53; } - else if (srate < 45000000) { - aclk = 0xb4; bclk = 0x51; } - - stv0299_writereg(fe, 0x13, aclk); - stv0299_writereg(fe, 0x14, bclk); - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, (ratio) & 0xf0); - - return 0; -} - -static u8 sharp_z0194a_inittab[] = { - 0x01, 0x15, - 0x02, 0x00, - 0x03, 0x00, - 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x40, /* DAC not used, set to high impendance mode */ - 0x07, 0x00, /* DAC LSB */ - 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ - 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ - 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ - 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ - 0x10, 0x3f, /* AGC2 0x3d */ - 0x11, 0x84, - 0x12, 0xb9, - 0x15, 0xc9, /* lock detector threshold */ - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, /* out imp: normal out type: parallel FEC mode:0 */ - 0x29, 0x1e, /* 1/2 threshold */ - 0x2a, 0x14, /* 2/3 threshold */ - 0x2b, 0x0f, /* 3/4 threshold */ - 0x2c, 0x09, /* 5/6 threshold */ - 0x2d, 0x05, /* 7/8 threshold */ - 0x2e, 0x01, - 0x31, 0x1f, /* test all FECs */ - 0x32, 0x19, /* viterbi and synchro search */ - 0x33, 0xfc, /* rs control */ - 0x34, 0x93, /* error control */ - 0x0f, 0x52, - 0xff, 0xff -}; - -#endif diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c deleted file mode 100644 index e22a0b381dc..00000000000 --- a/drivers/media/dvb/frontends/zl10036.c +++ /dev/null @@ -1,519 +0,0 @@ -/** - * Driver for Zarlink zl10036 DVB-S silicon tuner - * - * Copyright (C) 2006 Tino Reichardt - * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de> - * - * 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 <linux/module.h> -#include <linux/dvb/frontend.h> -#include <asm/types.h> - -#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 deleted file mode 100644 index d84b8f8215e..00000000000 --- a/drivers/media/dvb/frontends/zl10036.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Driver for Zarlink ZL10036 DVB-S silicon tuner - * - * Copyright (C) 2006 Tino Reichardt - * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de> - * - * 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 <linux/i2c.h> -#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 */ diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c deleted file mode 100644 index 148b6f7f6cb..00000000000 --- a/drivers/media/dvb/frontends/zl10353.c +++ /dev/null @@ -1,693 +0,0 @@ -/* - * Driver for Zarlink DVB-T ZL10353 demodulator - * - * Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au> - * - * 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 <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "zl10353_priv.h" -#include "zl10353.h" - -struct zl10353_state { - struct i2c_adapter *i2c; - struct dvb_frontend frontend; - - struct zl10353_config config; - - enum fe_bandwidth bandwidth; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "zl10353: " args); \ - } while (0) - -static int debug_regs; - -static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val) -{ - struct zl10353_state *state = fe->demodulator_priv; - u8 buf[2] = { reg, val }; - struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0, - .buf = buf, .len = 2 }; - int err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - printk("zl10353: write to reg %x failed (err = %d)!\n", reg, err); - return err; - } - return 0; -} - -static int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen) -{ - int err, i; - for (i = 0; i < ilen - 1; i++) - if ((err = zl10353_single_write(fe, ibuf[0] + i, ibuf[i + 1]))) - return err; - - return 0; -} - -static int zl10353_read_register(struct zl10353_state *state, u8 reg) -{ - int ret; - u8 b0[1] = { reg }; - u8 b1[1] = { 0 }; - struct i2c_msg msg[2] = { { .addr = state->config.demod_address, - .flags = 0, - .buf = b0, .len = 1 }, - { .addr = state->config.demod_address, - .flags = I2C_M_RD, - .buf = b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - printk("%s: readreg error (reg=%d, ret==%i)\n", - __func__, reg, ret); - return ret; - } - - return b1[0]; -} - -static void zl10353_dump_regs(struct dvb_frontend *fe) -{ - struct zl10353_state *state = fe->demodulator_priv; - char buf[52], buf2[4]; - int ret; - u8 reg; - - /* Dump all registers. */ - for (reg = 0; ; reg++) { - if (reg % 16 == 0) { - if (reg) - printk(KERN_DEBUG "%s\n", buf); - sprintf(buf, "%02x: ", reg); - } - ret = zl10353_read_register(state, reg); - if (ret >= 0) - sprintf(buf2, "%02x ", (u8)ret); - else - strcpy(buf2, "-- "); - strcat(buf, buf2); - if (reg == 0xff) - break; - } - printk(KERN_DEBUG "%s\n", buf); -} - -static void zl10353_calc_nominal_rate(struct dvb_frontend *fe, - enum fe_bandwidth bandwidth, - u16 *nominal_rate) -{ - struct zl10353_state *state = fe->demodulator_priv; - u32 adc_clock = 450560; /* 45.056 MHz */ - u64 value; - u8 bw; - - if (state->config.adc_clock) - adc_clock = state->config.adc_clock; - - switch (bandwidth) { - case BANDWIDTH_6_MHZ: - bw = 6; - break; - case BANDWIDTH_7_MHZ: - bw = 7; - break; - case BANDWIDTH_8_MHZ: - default: - bw = 8; - break; - } - - value = (u64)10 * (1 << 23) / 7 * 125; - value = (bw * value) + adc_clock / 2; - do_div(value, adc_clock); - *nominal_rate = value; - - dprintk("%s: bw %d, adc_clock %d => 0x%x\n", - __func__, bw, adc_clock, *nominal_rate); -} - -static void zl10353_calc_input_freq(struct dvb_frontend *fe, - u16 *input_freq) -{ - struct zl10353_state *state = fe->demodulator_priv; - u32 adc_clock = 450560; /* 45.056 MHz */ - int if2 = 361667; /* 36.1667 MHz */ - int ife; - u64 value; - - if (state->config.adc_clock) - adc_clock = state->config.adc_clock; - if (state->config.if2) - if2 = state->config.if2; - - if (adc_clock >= if2 * 2) - ife = if2; - else { - ife = adc_clock - (if2 % adc_clock); - if (ife > adc_clock / 2) - ife = adc_clock - ife; - } - value = (u64)65536 * ife + adc_clock / 2; - do_div(value, adc_clock); - *input_freq = -value; - - dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n", - __func__, if2, ife, adc_clock, -(int)value, *input_freq); -} - -static int zl10353_sleep(struct dvb_frontend *fe) -{ - static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 }; - - zl10353_write(fe, zl10353_softdown, sizeof(zl10353_softdown)); - return 0; -} - -static int zl10353_set_parameters(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) -{ - struct zl10353_state *state = fe->demodulator_priv; - u16 nominal_rate, input_freq; - u8 pllbuf[6] = { 0x67 }, acq_ctl = 0; - u16 tps = 0; - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; - - zl10353_single_write(fe, RESET, 0x80); - udelay(200); - zl10353_single_write(fe, 0xEA, 0x01); - udelay(200); - zl10353_single_write(fe, 0xEA, 0x00); - - zl10353_single_write(fe, AGC_TARGET, 0x28); - - if (op->transmission_mode != TRANSMISSION_MODE_AUTO) - acq_ctl |= (1 << 0); - if (op->guard_interval != GUARD_INTERVAL_AUTO) - acq_ctl |= (1 << 1); - zl10353_single_write(fe, ACQ_CTL, acq_ctl); - - switch (op->bandwidth) { - case BANDWIDTH_6_MHZ: - /* These are extrapolated from the 7 and 8MHz values */ - zl10353_single_write(fe, MCLK_RATIO, 0x97); - zl10353_single_write(fe, 0x64, 0x34); - zl10353_single_write(fe, 0xcc, 0xdd); - break; - case BANDWIDTH_7_MHZ: - zl10353_single_write(fe, MCLK_RATIO, 0x86); - zl10353_single_write(fe, 0x64, 0x35); - zl10353_single_write(fe, 0xcc, 0x73); - break; - case BANDWIDTH_8_MHZ: - default: - zl10353_single_write(fe, MCLK_RATIO, 0x75); - zl10353_single_write(fe, 0x64, 0x36); - zl10353_single_write(fe, 0xcc, 0x73); - } - - zl10353_calc_nominal_rate(fe, op->bandwidth, &nominal_rate); - zl10353_single_write(fe, TRL_NOMINAL_RATE_1, msb(nominal_rate)); - zl10353_single_write(fe, TRL_NOMINAL_RATE_0, lsb(nominal_rate)); - state->bandwidth = op->bandwidth; - - zl10353_calc_input_freq(fe, &input_freq); - zl10353_single_write(fe, INPUT_FREQ_1, msb(input_freq)); - zl10353_single_write(fe, INPUT_FREQ_0, lsb(input_freq)); - - /* Hint at TPS settings */ - switch (op->code_rate_HP) { - case FEC_2_3: - tps |= (1 << 7); - break; - case FEC_3_4: - tps |= (2 << 7); - break; - case FEC_5_6: - tps |= (3 << 7); - break; - case FEC_7_8: - tps |= (4 << 7); - break; - case FEC_1_2: - case FEC_AUTO: - break; - default: - return -EINVAL; - } - - switch (op->code_rate_LP) { - case FEC_2_3: - tps |= (1 << 4); - break; - case FEC_3_4: - tps |= (2 << 4); - break; - case FEC_5_6: - tps |= (3 << 4); - break; - case FEC_7_8: - tps |= (4 << 4); - break; - case FEC_1_2: - case FEC_AUTO: - break; - case FEC_NONE: - if (op->hierarchy_information == HIERARCHY_AUTO || - op->hierarchy_information == HIERARCHY_NONE) - break; - default: - return -EINVAL; - } - - switch (op->constellation) { - case QPSK: - break; - case QAM_AUTO: - case QAM_16: - tps |= (1 << 13); - break; - case QAM_64: - tps |= (2 << 13); - break; - default: - return -EINVAL; - } - - switch (op->transmission_mode) { - case TRANSMISSION_MODE_2K: - case TRANSMISSION_MODE_AUTO: - break; - case TRANSMISSION_MODE_8K: - tps |= (1 << 0); - break; - default: - return -EINVAL; - } - - switch (op->guard_interval) { - case GUARD_INTERVAL_1_32: - case GUARD_INTERVAL_AUTO: - break; - case GUARD_INTERVAL_1_16: - tps |= (1 << 2); - break; - case GUARD_INTERVAL_1_8: - tps |= (2 << 2); - break; - case GUARD_INTERVAL_1_4: - tps |= (3 << 2); - break; - default: - return -EINVAL; - } - - switch (op->hierarchy_information) { - case HIERARCHY_AUTO: - case HIERARCHY_NONE: - break; - case HIERARCHY_1: - tps |= (1 << 10); - break; - case HIERARCHY_2: - tps |= (2 << 10); - break; - case HIERARCHY_4: - tps |= (3 << 10); - break; - default: - return -EINVAL; - } - - zl10353_single_write(fe, TPS_GIVEN_1, msb(tps)); - zl10353_single_write(fe, TPS_GIVEN_0, lsb(tps)); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - /* - * If there is no tuner attached to the secondary I2C bus, we call - * set_params to program a potential tuner attached somewhere else. - * Otherwise, we update the PLL registers via calc_regs. - */ - if (state->config.no_tuner) { - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - } else if (fe->ops.tuner_ops.calc_regs) { - fe->ops.tuner_ops.calc_regs(fe, param, pllbuf + 1, 5); - pllbuf[1] <<= 1; - zl10353_write(fe, pllbuf, sizeof(pllbuf)); - } - - zl10353_single_write(fe, 0x5F, 0x13); - - /* If no attached tuner or invalid PLL registers, just start the FSM. */ - if (state->config.no_tuner || fe->ops.tuner_ops.calc_regs == NULL) - zl10353_single_write(fe, FSM_GO, 0x01); - else - zl10353_single_write(fe, TUNER_GO, 0x01); - - return 0; -} - -static int zl10353_get_parameters(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) -{ - struct zl10353_state *state = fe->demodulator_priv; - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; - int s6, s9; - u16 tps; - static const u8 tps_fec_to_api[8] = { - FEC_1_2, - FEC_2_3, - FEC_3_4, - FEC_5_6, - FEC_7_8, - FEC_AUTO, - FEC_AUTO, - FEC_AUTO - }; - - s6 = zl10353_read_register(state, STATUS_6); - s9 = zl10353_read_register(state, STATUS_9); - if (s6 < 0 || s9 < 0) - return -EREMOTEIO; - if ((s6 & (1 << 5)) == 0 || (s9 & (1 << 4)) == 0) - return -EINVAL; /* no FE or TPS lock */ - - tps = zl10353_read_register(state, TPS_RECEIVED_1) << 8 | - zl10353_read_register(state, TPS_RECEIVED_0); - - op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7]; - op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7]; - - switch ((tps >> 13) & 3) { - case 0: - op->constellation = QPSK; - break; - case 1: - op->constellation = QAM_16; - break; - case 2: - op->constellation = QAM_64; - break; - default: - op->constellation = QAM_AUTO; - break; - } - - op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : - TRANSMISSION_MODE_2K; - - switch ((tps >> 2) & 3) { - case 0: - op->guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - op->guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - op->guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - op->guard_interval = GUARD_INTERVAL_1_4; - break; - default: - op->guard_interval = GUARD_INTERVAL_AUTO; - break; - } - - switch ((tps >> 10) & 7) { - case 0: - op->hierarchy_information = HIERARCHY_NONE; - break; - case 1: - op->hierarchy_information = HIERARCHY_1; - break; - case 2: - op->hierarchy_information = HIERARCHY_2; - break; - case 3: - op->hierarchy_information = HIERARCHY_4; - break; - default: - op->hierarchy_information = HIERARCHY_AUTO; - break; - } - - param->frequency = 0; - op->bandwidth = state->bandwidth; - param->inversion = INVERSION_AUTO; - - return 0; -} - -static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct zl10353_state *state = fe->demodulator_priv; - int s6, s7, s8; - - if ((s6 = zl10353_read_register(state, STATUS_6)) < 0) - return -EREMOTEIO; - if ((s7 = zl10353_read_register(state, STATUS_7)) < 0) - return -EREMOTEIO; - if ((s8 = zl10353_read_register(state, STATUS_8)) < 0) - return -EREMOTEIO; - - *status = 0; - if (s6 & (1 << 2)) - *status |= FE_HAS_CARRIER; - if (s6 & (1 << 1)) - *status |= FE_HAS_VITERBI; - if (s6 & (1 << 5)) - *status |= FE_HAS_LOCK; - if (s7 & (1 << 4)) - *status |= FE_HAS_SYNC; - if (s8 & (1 << 6)) - *status |= FE_HAS_SIGNAL; - - if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) != - (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) - *status &= ~FE_HAS_LOCK; - - return 0; -} - -static int zl10353_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct zl10353_state *state = fe->demodulator_priv; - - *ber = zl10353_read_register(state, RS_ERR_CNT_2) << 16 | - zl10353_read_register(state, RS_ERR_CNT_1) << 8 | - zl10353_read_register(state, RS_ERR_CNT_0); - - return 0; -} - -static int zl10353_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct zl10353_state *state = fe->demodulator_priv; - - u16 signal = zl10353_read_register(state, AGC_GAIN_1) << 10 | - zl10353_read_register(state, AGC_GAIN_0) << 2 | 3; - - *strength = ~signal; - - return 0; -} - -static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct zl10353_state *state = fe->demodulator_priv; - u8 _snr; - - if (debug_regs) - zl10353_dump_regs(fe); - - _snr = zl10353_read_register(state, SNR); - *snr = (_snr << 8) | _snr; - - return 0; -} - -static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct zl10353_state *state = fe->demodulator_priv; - - *ucblocks = zl10353_read_register(state, RS_UBC_1) << 8 | - zl10353_read_register(state, RS_UBC_0); - - return 0; -} - -static int zl10353_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings - *fe_tune_settings) -{ - fe_tune_settings->min_delay_ms = 1000; - fe_tune_settings->step_size = 0; - fe_tune_settings->max_drift = 0; - - return 0; -} - -static int zl10353_init(struct dvb_frontend *fe) -{ - struct zl10353_state *state = fe->demodulator_priv; - u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F }; - int rc = 0; - - if (debug_regs) - 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] || - zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) { - rc = zl10353_write(fe, zl10353_reset_attach, - sizeof(zl10353_reset_attach)); - if (debug_regs) - zl10353_dump_regs(fe); - } - - return 0; -} - -static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct zl10353_state *state = fe->demodulator_priv; - u8 val = 0x0a; - - if (state->config.disable_i2c_gate_ctrl) { - /* No tuner attached to the internal I2C bus */ - /* If set enable I2C bridge, the main I2C bus stopped hardly */ - return 0; - } - - if (enable) - val |= 0x10; - - return zl10353_single_write(fe, 0x62, val); -} - -static void zl10353_release(struct dvb_frontend *fe) -{ - struct zl10353_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops zl10353_ops; - -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); - if (state == NULL) - goto error; - - /* setup the state */ - state->i2c = i2c; - memcpy(&state->config, config, sizeof(struct zl10353_config)); - - /* check if the demod is there */ - id = zl10353_read_register(state, CHIP_ID); - if ((id != ID_ZL10353) && (id != ID_CE6230) && (id != ID_CE6231)) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &zl10353_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - return &state->frontend; -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops zl10353_ops = { - - .info = { - .name = "Zarlink ZL10353 DVB-T", - .type = FE_OFDM, - .frequency_min = 174000000, - .frequency_max = 862000000, - .frequency_stepsize = 166667, - .frequency_tolerance = 0, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | - FE_CAN_MUTE_TS - }, - - .release = zl10353_release, - - .init = zl10353_init, - .sleep = zl10353_sleep, - .i2c_gate_ctrl = zl10353_i2c_gate_ctrl, - .write = zl10353_write, - - .set_frontend = zl10353_set_parameters, - .get_frontend = zl10353_get_parameters, - .get_tune_settings = zl10353_get_tune_settings, - - .read_status = zl10353_read_status, - .read_ber = zl10353_read_ber, - .read_signal_strength = zl10353_read_signal_strength, - .read_snr = zl10353_read_snr, - .read_ucblocks = zl10353_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -module_param(debug_regs, int, 0644); -MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off)."); - -MODULE_DESCRIPTION("Zarlink ZL10353 DVB-T demodulator driver"); -MODULE_AUTHOR("Chris Pascoe"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(zl10353_attach); diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h deleted file mode 100644 index 6e3ca9eed04..00000000000 --- a/drivers/media/dvb/frontends/zl10353.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Driver for Zarlink DVB-T ZL10353 demodulator - * - * Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au> - * - * 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 ZL10353_H -#define ZL10353_H - -#include <linux/dvb/frontend.h> - -struct zl10353_config -{ - /* demodulator's I2C address */ - u8 demod_address; - - /* frequencies in units of 0.1kHz */ - int adc_clock; /* default: 450560 (45.056 MHz) */ - int if2; /* default: 361667 (36.1667 MHz) */ - - /* set if no pll is connected to the secondary i2c bus */ - int no_tuner; - - /* set if parallel ts output is required */ - int parallel_ts; - - /* 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)) -extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_ZL10353 */ - -#endif /* ZL10353_H */ diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h deleted file mode 100644 index e0dd1d3e09d..00000000000 --- a/drivers/media/dvb/frontends/zl10353_priv.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Driver for Zarlink DVB-T ZL10353 demodulator - * - * Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au> - * - * 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 _ZL10353_PRIV_ -#define _ZL10353_PRIV_ - -#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) - -enum zl10353_reg_addr { - INTERRUPT_0 = 0x00, - INTERRUPT_1 = 0x01, - INTERRUPT_2 = 0x02, - INTERRUPT_3 = 0x03, - INTERRUPT_4 = 0x04, - INTERRUPT_5 = 0x05, - STATUS_6 = 0x06, - STATUS_7 = 0x07, - STATUS_8 = 0x08, - STATUS_9 = 0x09, - AGC_GAIN_1 = 0x0A, - AGC_GAIN_0 = 0x0B, - SNR = 0x10, - RS_ERR_CNT_2 = 0x11, - RS_ERR_CNT_1 = 0x12, - RS_ERR_CNT_0 = 0x13, - RS_UBC_1 = 0x14, - RS_UBC_0 = 0x15, - TPS_RECEIVED_1 = 0x1D, - 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, - ACQ_CTL = 0x5E, - TRL_NOMINAL_RATE_1 = 0x65, - TRL_NOMINAL_RATE_0 = 0x66, - INPUT_FREQ_1 = 0x6C, - INPUT_FREQ_0 = 0x6D, - TPS_GIVEN_1 = 0x6E, - TPS_GIVEN_0 = 0x6F, - TUNER_GO = 0x70, - FSM_GO = 0x71, - CHIP_ID = 0x7F, - CHAN_STEP_1 = 0xE4, - CHAN_STEP_0 = 0xE5, - OFDM_LOCK_TIME = 0xE7, - FEC_LOCK_TIME = 0xE8, - ACQ_DELAY = 0xE9, -}; - -#endif /* _ZL10353_PRIV_ */ |
