diff options
Diffstat (limited to 'drivers/media/dvb/frontends')
74 files changed, 0 insertions, 23659 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig deleted file mode 100644 index db978555b1e..00000000000 --- a/drivers/media/dvb/frontends/Kconfig +++ /dev/null @@ -1,239 +0,0 @@ -menu "Customise DVB Frontends" - depends on DVB_CORE - -comment "DVB-S (satellite) frontends" - depends on DVB_CORE - -config DVB_STV0299 - tristate "ST STV0299 based" - depends on DVB_CORE && I2C - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_CX24110 - tristate "Conexant CX24110 based" - depends on DVB_CORE && I2C - 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 - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_TDA8083 - tristate "Philips TDA8083 based" - depends on DVB_CORE && I2C - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_MT312 - tristate "Zarlink VP310/MT312 based" - depends on DVB_CORE && I2C - 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 - 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 - 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 - select FW_LOADER - 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 - select FW_LOADER - 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 - 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 - help - A DVB-T tuner module. Say Y when you want to support this frontend. - -config DVB_L64781 - tristate "LSI L64781" - depends on DVB_CORE && I2C - 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 - select FW_LOADER - 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 - 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 - 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 - 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 - 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 - help - A DVB-T tuner module. Designed for mobile usage. 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 - 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 - 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 - 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 - select FW_LOADER - 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 - select FW_LOADER - 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 - select FW_LOADER - 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 - select FW_LOADER - 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 - help - An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want - to support this frontend. - - -comment "Miscellaneous devices" - depends on DVB_CORE - -config DVB_PLL - tristate - depends on DVB_CORE && I2C - -config DVB_LNBP21 - tristate "LNBP21 SEC controller" - depends on DVB_CORE && I2C - help - An SEC control chip. - -config DVB_ISL6421 - tristate "ISL6421 SEC controller" - depends on DVB_CORE && I2C - help - An SEC control chip. - -endmenu diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile deleted file mode 100644 index 0e4880b6db1..00000000000 --- a/drivers/media/dvb/frontends/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# -# Makefile for the kernel DVB frontend device drivers. -# - -EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ - -obj-$(CONFIG_DVB_PLL) += dvb-pll.o -obj-$(CONFIG_DVB_STV0299) += stv0299.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 dib3000-common.o -obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dib3000-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_ZL10353) += zl10353.o -obj-$(CONFIG_DVB_CX22702) += cx22702.o -obj-$(CONFIG_DVB_TDA10021) += tda10021.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_CX24123) += cx24123.o -obj-$(CONFIG_DVB_LNBP21) += lnbp21.o -obj-$(CONFIG_DVB_ISL6421) += isl6421.o diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c deleted file mode 100644 index baeb311de89..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/moduleparam.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", - __FUNCTION__, 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", - __FUNCTION__, 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, 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; - 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 80f5d0953d0..00000000000 --- a/drivers/media/dvb/frontends/bcm3510.h +++ /dev/null @@ -1,40 +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); -}; - -extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, - struct i2c_adapter* i2c); - -#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 d8f65738e5d..00000000000 --- a/drivers/media/dvb/frontends/bsbe1.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * bsbe1.h - ALPS BSBE1 tuner support (moved from av7110.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 BSBE1_H -#define BSBE1_H - -static u8 alps_bsbe1_inittab[] = { - 0x01, 0x15, - 0x02, 0x30, - 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, 0x92, - 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 + (125 - 1)) / 125; // round correctly - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; - data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; - - 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 e231cd84b3a..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 = STV0229_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 13ad1bfae66..00000000000 --- a/drivers/media/dvb/frontends/cx22700.c +++ /dev/null @@ -1,441 +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/moduleparam.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", __FUNCTION__); - - ret = i2c_transfer (state->i2c, &msg, 1); - - if (ret != 1) - printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", - __FUNCTION__, 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", __FUNCTION__); - - 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", __FUNCTION__); - - 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", __FUNCTION__); - - 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", __FUNCTION__); - - 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 dcd8979c1a1..00000000000 --- a/drivers/media/dvb/frontends/cx22700.h +++ /dev/null @@ -1,37 +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; -}; - -extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, - struct i2c_adapter* i2c); - -#endif // CX22700_H diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c deleted file mode 100644 index 4106d46c957..00000000000 --- a/drivers/media/dvb/frontends/cx22702.c +++ /dev/null @@ -1,534 +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@hauppauge.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 <linux/delay.h> -#include "dvb_frontend.h" -#include "dvb-pll.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 = 0; -#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("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", - __FUNCTION__, 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("%s: readreg error (ret == %i)\n", __FUNCTION__, 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", __FUNCTION__, 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",__FUNCTION__); - 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",__FUNCTION__); - 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",__FUNCTION__); - 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",__FUNCTION__); - 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",__FUNCTION__); - 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",__FUNCTION__); - 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",__FUNCTION__); - 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",__FUNCTION__); - 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<sizeof(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" - ,__FUNCTION__,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; - - *signal_strength = cx22702_readreg (state, 0x23); - - 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; -} - -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_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - -MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(cx22702_attach); diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h deleted file mode 100644 index 7f2f241e5d4..00000000000 --- a/drivers/media/dvb/frontends/cx22702.h +++ /dev/null @@ -1,47 +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@hauppauge.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 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; -}; - -extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, - struct i2c_adapter* i2c); - -#endif // CX22702_H diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c deleted file mode 100644 index ce3c7398bac..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/moduleparam.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", __FUNCTION__, 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",__FUNCTION__,srate); - if (srate>90999000UL/2) - srate=90999000UL/2; - if (srate<500000) - srate=500000; - - for(i=0;(i<sizeof(bands)/sizeof(bands[0]))&&(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; - -} - -int cx24110_pll_write (struct dvb_frontend* fe, u32 data) -{ - struct cx24110_state *state = fe->demodulator_priv; - -/* 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... */ - - dprintk("cx24110 debug: cx24108_write(%8.8x)\n",data); - - 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,(data>>24)&0xff); - - /* wait for the send to be completed */ - while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) - ; - - /* send another 8 bytes */ - cx24110_writereg(state,0x72,(data>>16)&0xff); - while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) - ; - - /* and the topmost 5 bits of this byte */ - cx24110_writereg(state,0x72,(data>>8)&0xff); - 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", __FUNCTION__); - - for(i=0;i<sizeof(cx24110_regdata)/sizeof(cx24110_regdata[0]);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, - .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); -EXPORT_SYMBOL(cx24110_pll_write); diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h deleted file mode 100644 index b354a64e0e7..00000000000 --- a/drivers/media/dvb/frontends/cx24110.h +++ /dev/null @@ -1,41 +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; -}; - -extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, - struct i2c_adapter* i2c); - -extern int cx24110_pll_write(struct dvb_frontend* fe, u32 data); - -#endif // CX24110_H diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c deleted file mode 100644 index 274a87b7a5d..00000000000 --- a/drivers/media/dvb/frontends/cx24123.c +++ /dev/null @@ -1,1023 +0,0 @@ -/* - Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver - - Copyright (C) 2005 Steven Toth <stoth@hauppauge.com> - - Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc> - - 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 "dvb_frontend.h" -#include "cx24123.h" - -#define XTAL 10111000 - -static int force_band; -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk (KERN_DEBUG "cx24123: " args); \ - } while (0) - -struct cx24123_state -{ - struct i2c_adapter* i2c; - const struct cx24123_config* config; - - struct dvb_frontend frontend; - - u32 lastber; - u16 snr; - - /* Some PLL specifics for tuning */ - u32 VCAarg; - u32 VGAarg; - u32 bandselectarg; - u32 pllarg; - u32 FILTune; - - /* 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 -{ - 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 -{ - 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, 0x02}, /* Frequency search range = Fsymbol / 4 (default) */ - {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, 0x41}, /* Various (default) */ - {0x57, 0xff}, /* Error Counter Window (default) */ - {0x67, 0x83}, /* Non-DCII symbol clock */ -}; - -static int cx24123_writereg(struct cx24123_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("cx24123: %s: write reg 0x%02x, value 0x%02x\n", - __FUNCTION__,reg, data); - - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk("%s: writereg error(err == %i, reg == 0x%02x," - " data == 0x%02x)\n", __FUNCTION__, err, reg, data); - return -EREMOTEIO; - } - - return 0; -} - -static int cx24123_readreg(struct cx24123_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: reg=0x%x (error=%d)\n", __FUNCTION__, reg, ret); - return ret; - } - - if (debug>1) - printk("cx24123: read reg 0x%02x, value 0x%02x\n",reg, ret); - - return b1[0]; -} - -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("%s: inversion off\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg & ~0x80); - cx24123_writereg(state, 0x10, auto_reg | 0x80); - break; - case INVERSION_ON: - dprintk("%s: inversion on\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x80); - cx24123_writereg(state, 0x10, auto_reg | 0x80); - break; - case INVERSION_AUTO: - dprintk("%s: inversion auto\n",__FUNCTION__); - 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("%s: read inversion off\n",__FUNCTION__); - *inversion = INVERSION_OFF; - } else { - dprintk("%s: read inversion on\n",__FUNCTION__); - *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; - - switch (fec) { - case FEC_1_2: - dprintk("%s: set FEC to 1/2\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x01); - cx24123_writereg(state, 0x0f, 0x02); - break; - case FEC_2_3: - dprintk("%s: set FEC to 2/3\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x02); - cx24123_writereg(state, 0x0f, 0x04); - break; - case FEC_3_4: - dprintk("%s: set FEC to 3/4\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x03); - cx24123_writereg(state, 0x0f, 0x08); - break; - case FEC_4_5: - dprintk("%s: set FEC to 4/5\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x04); - cx24123_writereg(state, 0x0f, 0x10); - break; - case FEC_5_6: - dprintk("%s: set FEC to 5/6\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x05); - cx24123_writereg(state, 0x0f, 0x20); - break; - case FEC_6_7: - dprintk("%s: set FEC to 6/7\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x06); - cx24123_writereg(state, 0x0f, 0x40); - break; - case FEC_7_8: - dprintk("%s: set FEC to 7/8\n",__FUNCTION__); - cx24123_writereg(state, 0x0e, nom_reg | 0x07); - cx24123_writereg(state, 0x0f, 0x80); - break; - case FEC_AUTO: - dprintk("%s: set FEC to auto\n",__FUNCTION__); - 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("%s: srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n", __FUNCTION__, 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 = sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); - - /* 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 < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++) - { - if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) && - (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { - state->VCAarg = cx24123_AGC_vals[i].VCAprogdata; - state->VGAarg = cx24123_AGC_vals[i].VGAprogdata; - state->FILTune = cx24123_AGC_vals[i].FILTune; - } - } - - /* determine the band to use */ - if(force_band < 1 || force_band > num_bands) - { - for (i = 0; i < num_bands; i++) - { - if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) && - (cx24123_bandselect_vals[i].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++; - - /* 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("%s: pll writereg called, data=0x%08x\n",__FUNCTION__,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)) { - printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); - 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)) { - printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); - 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)) { - printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); - 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) { - printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__); - 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("%s: pll tune VCA=%d, band=%d, pll=%d\n",__FUNCTION__,state->VCAarg, - state->bandselectarg,state->pllarg); - - return 0; -} - -static int cx24123_initfe(struct dvb_frontend* fe) -{ - struct cx24123_state *state = fe->demodulator_priv; - int i; - - dprintk("%s: init frontend\n",__FUNCTION__); - - /* Configure the demod to a good set of defaults */ - for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) - cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); - - 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("%s: setting voltage 13V\n", __FUNCTION__); - return cx24123_writereg(state, 0x29, val & 0x7f); - case SEC_VOLTAGE_18: - dprintk("%s: setting voltage 18V\n", __FUNCTION__); - return cx24123_writereg(state, 0x29, val | 0x80); - 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)) { - printk("%s: diseqc queue not ready, command may be lost.\n", __FUNCTION__); - 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("%s:\n",__FUNCTION__); - - /* 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("%s:\n", __FUNCTION__); - - /* 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); - int lock = cx24123_readreg(state, 0x20); - - *status = 0; - if (lock & 0x01) - *status |= FE_HAS_SIGNAL; - if (sync & 0x02) - *status |= FE_HAS_CARRIER; - if (sync & 0x04) - *status |= FE_HAS_VITERBI; - if (sync & 0x08) - *status |= FE_HAS_SYNC; - if (sync & 0x80) - *status |= FE_HAS_LOCK; - - 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; - - state->lastber = - ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) | - (cx24123_readreg(state, 0x1d) << 8 | - cx24123_readreg(state, 0x1e)); - - /* Do the signal quality processing here, it's derived from the BER. */ - /* Scale the BER from a 24bit to a SNR 16 bit where higher = better */ - if (state->lastber < 5000) - state->snr = 655*100; - else if ( (state->lastber >= 5000) && (state->lastber < 55000) ) - state->snr = 655*90; - else if ( (state->lastber >= 55000) && (state->lastber < 150000) ) - state->snr = 655*80; - else if ( (state->lastber >= 150000) && (state->lastber < 250000) ) - state->snr = 655*70; - else if ( (state->lastber >= 250000) && (state->lastber < 450000) ) - state->snr = 655*65; - else - state->snr = 0; - - dprintk("%s: BER = %d, S/N index = %d\n",__FUNCTION__,state->lastber, state->snr); - - *ber = state->lastber; - - return 0; -} - -static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) -{ - struct cx24123_state *state = fe->demodulator_priv; - *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */ - - dprintk("%s: Signal strength = %d\n",__FUNCTION__,*signal_strength); - - return 0; -} - -static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct cx24123_state *state = fe->demodulator_priv; - *snr = state->snr; - - dprintk("%s: read S/N index = %d\n",__FUNCTION__,*snr); - - return 0; -} - -static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct cx24123_state *state = fe->demodulator_priv; - *ucblocks = state->lastber; - - dprintk("%s: ucblocks (ber) = %d\n",__FUNCTION__,*ucblocks); - - return 0; -} - -static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - - dprintk("%s: set_frontend\n",__FUNCTION__); - - 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); - cx24123_pll_tune(fe, p); - - /* 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); - - return 0; -} - -static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - - dprintk("%s: get_frontend\n",__FUNCTION__); - - if (cx24123_get_inversion(state, &p->inversion) != 0) { - printk("%s: Failed to get inversion status\n",__FUNCTION__); - return -EREMOTEIO; - } - if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) { - printk("%s: Failed to get fec status\n",__FUNCTION__); - 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("%s: setting tone on\n", __FUNCTION__); - return cx24123_writereg(state, 0x29, val | 0x10); - case SEC_TONE_OFF: - dprintk("%s: setting tone off\n",__FUNCTION__); - return cx24123_writereg(state, 0x29, val & 0xef); - default: - printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); - return -EINVAL; - } - - return 0; -} - -static void cx24123_release(struct dvb_frontend* fe) -{ - struct cx24123_state* state = fe->demodulator_priv; - dprintk("%s\n",__FUNCTION__); - kfree(state); -} - -static struct dvb_frontend_ops cx24123_ops; - -struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, - struct i2c_adapter* i2c) -{ - struct cx24123_state* state = NULL; - int ret; - - dprintk("%s\n",__FUNCTION__); - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct cx24123_state), GFP_KERNEL); - if (state == NULL) { - printk("Unable to kmalloc\n"); - goto error; - } - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->lastber = 0; - state->snr = 0; - state->VCAarg = 0; - state->VGAarg = 0; - state->bandselectarg = 0; - state->pllarg = 0; - state->currentfreq = 0; - state->currentsymbolrate = 0; - - /* check if the demod is there */ - ret = cx24123_readreg(state, 0x00); - if ((ret != 0xd1) && (ret != 0xe1)) { - printk("Version != d1 or e1\n"); - goto error; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - - return NULL; -} - -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, - .read_ucblocks = cx24123_read_ucblocks, - .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, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); - -module_param(force_band, int, 0644); -MODULE_PARM_DESC(force_band, "Force a specific band select (1-9, default:off)."); - -MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(cx24123_attach); diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h deleted file mode 100644 index 9606f825935..00000000000 --- a/drivers/media/dvb/frontends/cx24123.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver - - Copyright (C) 2005 Steven Toth <stoth@hauppauge.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 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); -}; - -extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, - struct i2c_adapter* i2c); - -#endif /* CX24123_H */ diff --git a/drivers/media/dvb/frontends/dib3000-common.c b/drivers/media/dvb/frontends/dib3000-common.c deleted file mode 100644 index 1a4f1f7c228..00000000000 --- a/drivers/media/dvb/frontends/dib3000-common.c +++ /dev/null @@ -1,83 +0,0 @@ -#include "dib3000-common.h" - -#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 -#define deb_info(args...) dprintk(0x01,args) -#define deb_i2c(args...) dprintk(0x02,args) -#define deb_srch(args...) dprintk(0x04,args) - - -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]; -} - -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; -} - -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 */ -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 } */ - } - }; - -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de"); -MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb frontend drivers"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(dib3000_seq); - -EXPORT_SYMBOL(dib3000_read_reg); -EXPORT_SYMBOL(dib3000_write_reg); -EXPORT_SYMBOL(dib3000_search_status); diff --git a/drivers/media/dvb/frontends/dib3000-common.h b/drivers/media/dvb/frontends/dib3000-common.h deleted file mode 100644 index be1c0d3e138..00000000000 --- a/drivers/media/dvb/frontends/dib3000-common.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * .h-files for the common use of the frontend drivers made by DiBcom - * DiBcom 3000M-B/C, 3000P - * - * 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 - * - */ - -#ifndef DIB3000_COMMON_H -#define DIB3000_COMMON_H - -#include "dvb_frontend.h" -#include "dib3000.h" - -/* 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) - -/* 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; -}; - -/* commonly used methods by the dib3000mb/mc/p frontend */ -extern int dib3000_read_reg(struct dib3000_state *state, u16 reg); -extern int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val); - -extern int dib3000_search_status(u16 irq,u16 lock); - -/* 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))) - -/* for auto search */ -extern u16 dib3000_seq[2][2][2]; - -#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) - -#endif // DIB3000_COMMON_H diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h deleted file mode 100644 index ec927628d27..00000000000 --- a/drivers/media/dvb/frontends/dib3000.h +++ /dev/null @@ -1,49 +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); -}; - -extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, - struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); - -extern struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, - struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); -#endif // DIB3000_H diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c deleted file mode 100644 index 5302e11883a..00000000000 --- a/drivers/media/dvb/frontends/dib3000mb.c +++ /dev/null @@ -1,770 +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/moduleparam.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dib3000-common.h" -#include "dib3000mb_priv.h" -#include "dib3000.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_xfer(args...) dprintk(0x02,args) -#define deb_setf(args...) dprintk(0x04,args) -#define deb_getf(args...) dprintk(0x08,args) - -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("hierachy: "); - 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 999b1904781..00000000000 --- a/drivers/media/dvb/frontends/dib3000mb_priv.h +++ /dev/null @@ -1,467 +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__ - -/* 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 98673474a14..00000000000 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ /dev/null @@ -1,913 +0,0 @@ -/* - * Frontend driver for mobile DVB-T demodulator DiBcom 3000P/M-C - * 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/moduleparam.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dib3000-common.h" -#include "dib3000mc_priv.h" -#include "dib3000.h" - -/* Version information */ -#define DRIVER_VERSION "0.1" -#define DRIVER_DESC "DiBcom 3000M-C 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,16=stat (|-able))."); -#endif -#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) -#define deb_stat(args...) dprintk(0x10,args) - -static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode, - fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth) -{ - switch (transmission_mode) { - case TRANSMISSION_MODE_2K: - wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[0]); - break; - case TRANSMISSION_MODE_8K: - wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[1]); - break; - default: - break; - } - - switch (bandwidth) { -/* case BANDWIDTH_5_MHZ: - wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[0]); - break; */ - case BANDWIDTH_6_MHZ: - wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[1]); - break; - case BANDWIDTH_7_MHZ: - wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[2]); - break; - case BANDWIDTH_8_MHZ: - wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[3]); - break; - default: - break; - } - - switch (mode) { - case 0: /* no impulse */ /* fall through */ - wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[0]); - break; - case 1: /* new algo */ - wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[1]); - set_or(DIB3000MC_REG_IMP_NOISE_55,DIB3000MC_IMP_NEW_ALGO(0)); /* gives 1<<10 */ - break; - default: /* old algo */ - wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[3]); - break; - } - return 0; -} - -static int dib3000mc_set_timing(struct dib3000_state *state, int upd_offset, - fe_transmit_mode_t fft, fe_bandwidth_t bw) -{ - u16 timf_msb,timf_lsb; - s32 tim_offset,tim_sgn; - u64 comp1,comp2,comp=0; - - switch (bw) { - case BANDWIDTH_8_MHZ: comp = DIB3000MC_CLOCK_REF*8; break; - case BANDWIDTH_7_MHZ: comp = DIB3000MC_CLOCK_REF*7; break; - case BANDWIDTH_6_MHZ: comp = DIB3000MC_CLOCK_REF*6; break; - default: err("unknown bandwidth (%d)",bw); break; - } - timf_msb = (comp >> 16) & 0xff; - timf_lsb = (comp & 0xffff); - - // Update the timing offset ; - if (upd_offset > 0) { - if (!state->timing_offset_comp_done) { - msleep(200); - state->timing_offset_comp_done = 1; - } - tim_offset = rd(DIB3000MC_REG_TIMING_OFFS_MSB); - if ((tim_offset & 0x2000) == 0x2000) - tim_offset |= 0xC000; - if (fft == TRANSMISSION_MODE_2K) - tim_offset <<= 2; - state->timing_offset += tim_offset; - } - - tim_offset = state->timing_offset; - if (tim_offset < 0) { - tim_sgn = 1; - tim_offset = -tim_offset; - } else - tim_sgn = 0; - - comp1 = (u32)tim_offset * (u32)timf_lsb ; - comp2 = (u32)tim_offset * (u32)timf_msb ; - comp = ((comp1 >> 16) + comp2) >> 7; - - if (tim_sgn == 0) - comp = (u32)(timf_msb << 16) + (u32) timf_lsb + comp; - else - comp = (u32)(timf_msb << 16) + (u32) timf_lsb - comp ; - - timf_msb = (comp >> 16) & 0xff; - timf_lsb = comp & 0xffff; - - wr(DIB3000MC_REG_TIMING_FREQ_MSB,timf_msb); - wr(DIB3000MC_REG_TIMING_FREQ_LSB,timf_lsb); - return 0; -} - -static int dib3000mc_init_auto_scan(struct dib3000_state *state, fe_bandwidth_t bw, int boost) -{ - if (boost) { - wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_ON); - } else { - wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_OFF); - } - switch (bw) { - case BANDWIDTH_8_MHZ: - wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz); - break; - case BANDWIDTH_7_MHZ: - wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_7mhz); - break; - case BANDWIDTH_6_MHZ: - wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_6mhz); - break; -/* case BANDWIDTH_5_MHZ: - wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_5mhz); - break;*/ - case BANDWIDTH_AUTO: - return -EOPNOTSUPP; - default: - err("unknown bandwidth value (%d).",bw); - return -EINVAL; - } - if (boost) { - u32 timeout = (rd(DIB3000MC_REG_BW_TIMOUT_MSB) << 16) + - rd(DIB3000MC_REG_BW_TIMOUT_LSB); - timeout *= 85; timeout >>= 7; - wr(DIB3000MC_REG_BW_TIMOUT_MSB,(timeout >> 16) & 0xffff); - wr(DIB3000MC_REG_BW_TIMOUT_LSB,timeout & 0xffff); - } - return 0; -} - -static int dib3000mc_set_adp_cfg(struct dib3000_state *state, fe_modulation_t con) -{ - switch (con) { - case QAM_64: - wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[2]); - break; - case QAM_16: - wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]); - break; - case QPSK: - wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[0]); - break; - case QAM_AUTO: - break; - default: - warn("unkown constellation."); - break; - } - return 0; -} - -static int dib3000mc_set_general_cfg(struct dib3000_state *state, struct dvb_frontend_parameters *fep, int *auto_val) -{ - struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; - fe_code_rate_t fe_cr = FEC_NONE; - u8 fft=0, guard=0, qam=0, alpha=0, sel_hp=0, cr=0, hrch=0; - int seq; - - switch (ofdm->transmission_mode) { - case TRANSMISSION_MODE_2K: fft = DIB3000_TRANSMISSION_MODE_2K; break; - case TRANSMISSION_MODE_8K: fft = DIB3000_TRANSMISSION_MODE_8K; break; - case TRANSMISSION_MODE_AUTO: break; - default: return -EINVAL; - } - switch (ofdm->guard_interval) { - case GUARD_INTERVAL_1_32: guard = DIB3000_GUARD_TIME_1_32; break; - case GUARD_INTERVAL_1_16: guard = DIB3000_GUARD_TIME_1_16; break; - case GUARD_INTERVAL_1_8: guard = DIB3000_GUARD_TIME_1_8; break; - case GUARD_INTERVAL_1_4: guard = DIB3000_GUARD_TIME_1_4; break; - case GUARD_INTERVAL_AUTO: break; - default: return -EINVAL; - } - switch (ofdm->constellation) { - case QPSK: qam = DIB3000_CONSTELLATION_QPSK; break; - case QAM_16: qam = DIB3000_CONSTELLATION_16QAM; break; - case QAM_64: qam = DIB3000_CONSTELLATION_64QAM; break; - case QAM_AUTO: break; - default: return -EINVAL; - } - switch (ofdm->hierarchy_information) { - case HIERARCHY_NONE: /* fall through */ - case HIERARCHY_1: alpha = DIB3000_ALPHA_1; break; - case HIERARCHY_2: alpha = DIB3000_ALPHA_2; break; - case HIERARCHY_4: alpha = DIB3000_ALPHA_4; break; - case HIERARCHY_AUTO: break; - default: return -EINVAL; - } - if (ofdm->hierarchy_information == HIERARCHY_NONE) { - hrch = DIB3000_HRCH_OFF; - sel_hp = DIB3000_SELECT_HP; - fe_cr = ofdm->code_rate_HP; - } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) { - hrch = DIB3000_HRCH_ON; - sel_hp = DIB3000_SELECT_LP; - fe_cr = ofdm->code_rate_LP; - } - switch (fe_cr) { - case FEC_1_2: cr = DIB3000_FEC_1_2; break; - case FEC_2_3: cr = DIB3000_FEC_2_3; break; - case FEC_3_4: cr = DIB3000_FEC_3_4; break; - case FEC_5_6: cr = DIB3000_FEC_5_6; break; - case FEC_7_8: cr = DIB3000_FEC_7_8; break; - case FEC_NONE: break; - case FEC_AUTO: break; - default: return -EINVAL; - } - - wr(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_PARM(alpha,qam,guard,fft)); - wr(DIB3000MC_REG_HRCH_PARM,DIB3000MC_HRCH_PARM(sel_hp,cr,hrch)); - - switch (fep->inversion) { - case INVERSION_OFF: - wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF); - break; - case INVERSION_AUTO: /* fall through */ - case INVERSION_ON: - wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_ON); - 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(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS(seq,1)); - *auto_val = ofdm->constellation == QAM_AUTO || - ofdm->hierarchy_information == HIERARCHY_AUTO || - ofdm->guard_interval == GUARD_INTERVAL_AUTO || - ofdm->transmission_mode == TRANSMISSION_MODE_AUTO || - fe_cr == FEC_AUTO || - fep->inversion == INVERSION_AUTO; - return 0; -} - -static int dib3000mc_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,cr_val; - int inv_test1,inv_test2; - u32 dds_val, threshold = 0x1000000; - - if (!(rd(DIB3000MC_REG_LOCK_507) & DIB3000MC_LOCK_507)) - return 0; - - dds_val = (rd(DIB3000MC_REG_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_DDS_FREQ_LSB); - deb_getf("DDS_FREQ: %6x\n",dds_val); - if (dds_val < threshold) - inv_test1 = 0; - else if (dds_val == threshold) - inv_test1 = 1; - else - inv_test1 = 2; - - dds_val = (rd(DIB3000MC_REG_SET_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_SET_DDS_FREQ_LSB); - deb_getf("DDS_SET_FREQ: %6x\n",dds_val); - 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); - - fep->frequency = state->last_tuned_freq; - fep->u.ofdm.bandwidth= state->last_tuned_bw; - - tps_val = rd(DIB3000MC_REG_TUNING_PARM); - - switch (DIB3000MC_TP_QAM(tps_val)) { - 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; - } - - if (DIB3000MC_TP_HRCH(tps_val)) { - deb_getf("HRCH ON "); - cr = &ofdm->code_rate_LP; - ofdm->code_rate_HP = FEC_NONE; - switch (DIB3000MC_TP_ALPHA(tps_val)) { - 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; - } - cr_val = DIB3000MC_TP_FEC_CR_LP(tps_val); - } else { - deb_getf("HRCH OFF "); - cr = &ofdm->code_rate_HP; - ofdm->code_rate_LP = FEC_NONE; - ofdm->hierarchy_information = HIERARCHY_NONE; - cr_val = DIB3000MC_TP_FEC_CR_HP(tps_val); - } - - switch (cr_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; - } - - switch (DIB3000MC_TP_GUARD(tps_val)) { - 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; - } - - switch (DIB3000MC_TP_FFT(tps_val)) { - 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("\n"); - - return 0; -} - -static int dib3000mc_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; - int search_state,auto_val; - u16 val; - - if (tuner && fe->ops.tuner_ops.set_params) { /* initial call from dvb */ - fe->ops.tuner_ops.set_params(fe, fep); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - - state->last_tuned_freq = fep->frequency; - // if (!scanboost) { - dib3000mc_set_timing(state,0,ofdm->transmission_mode,ofdm->bandwidth); - dib3000mc_init_auto_scan(state, ofdm->bandwidth, 0); - state->last_tuned_bw = ofdm->bandwidth; - - wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth); - wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_AGC); - wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF); - - /* Default cfg isi offset adp */ - wr_foreach(dib3000mc_reg_offset,dib3000mc_offset[0]); - - wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT | DIB3000MC_ISI_INHIBIT); - dib3000mc_set_adp_cfg(state,ofdm->constellation); - wr(DIB3000MC_REG_UNK_133,DIB3000MC_UNK_133); - - wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general); - /* power smoothing */ - if (ofdm->bandwidth != BANDWIDTH_8_MHZ) { - wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[0]); - } else { - wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]); - } - auto_val = 0; - dib3000mc_set_general_cfg(state,fep,&auto_val); - dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth); - - val = rd(DIB3000MC_REG_DEMOD_PARM); - wr(DIB3000MC_REG_DEMOD_PARM,val|DIB3000MC_DEMOD_RST_DEMOD_ON); - wr(DIB3000MC_REG_DEMOD_PARM,val); - // } - msleep(70); - - /* something has to be auto searched */ - if (auto_val) { - int as_count=0; - - deb_setf("autosearch enabled.\n"); - - val = rd(DIB3000MC_REG_DEMOD_PARM); - wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON); - wr(DIB3000MC_REG_DEMOD_PARM,val); - - while ((search_state = dib3000_search_status( - rd(DIB3000MC_REG_AS_IRQ),1)) < 0 && as_count++ < 100) - msleep(10); - - deb_info("search_state after autosearch %d after %d checks\n",search_state,as_count); - - if (search_state == 1) { - struct dvb_frontend_parameters feps; - if (dib3000mc_get_frontend(fe, &feps) == 0) { - deb_setf("reading tuning data from frontend succeeded.\n"); - return dib3000mc_set_frontend(fe, &feps, 0); - } - } - } else { - dib3000mc_set_impulse_noise(state,0,ofdm->transmission_mode,ofdm->bandwidth); - wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE); - dib3000mc_set_adp_cfg(state,ofdm->constellation); - - /* set_offset_cfg */ - wr_foreach(dib3000mc_reg_offset, - dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]); - } - } else { /* second call, after autosearch (fka: set_WithKnownParams) */ -// dib3000mc_set_timing(state,1,ofdm->transmission_mode,ofdm->bandwidth); - - auto_val = 0; - dib3000mc_set_general_cfg(state,fep,&auto_val); - if (auto_val) - deb_info("auto_val is true, even though an auto search was already performed.\n"); - - dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth); - - val = rd(DIB3000MC_REG_DEMOD_PARM); - wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON); - wr(DIB3000MC_REG_DEMOD_PARM,val); - - msleep(30); - - wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE); - dib3000mc_set_adp_cfg(state,ofdm->constellation); - wr_foreach(dib3000mc_reg_offset, - dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]); - } - return 0; -} - -static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) -{ - struct dib3000_state *state = fe->demodulator_priv; - deb_info("init start\n"); - - state->timing_offset = 0; - state->timing_offset_comp_done = 0; - - wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_CONFIG); - wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF); - wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_UP); - wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_PUP_MOBILE); - wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_UP); - wr(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_INIT); - - wr(DIB3000MC_REG_RST_UNC,DIB3000MC_RST_UNC_OFF); - wr(DIB3000MC_REG_UNK_19,DIB3000MC_UNK_19); - - wr(33,5); - wr(36,81); - wr(DIB3000MC_REG_UNK_88,DIB3000MC_UNK_88); - - wr(DIB3000MC_REG_UNK_99,DIB3000MC_UNK_99); - wr(DIB3000MC_REG_UNK_111,DIB3000MC_UNK_111_PH_N_MODE_0); /* phase noise algo off */ - - /* mobile mode - portable reception */ - wr_foreach(dib3000mc_reg_mobile_mode,dib3000mc_mobile_mode[1]); - -/* TUNER_PANASONIC_ENV57H12D5: */ - wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth); - wr_foreach(dib3000mc_reg_agc_bandwidth_general,dib3000mc_agc_bandwidth_general); - wr_foreach(dib3000mc_reg_agc,dib3000mc_agc_tuner[1]); - - wr(DIB3000MC_REG_UNK_110,DIB3000MC_UNK_110); - wr(26,0x6680); - wr(DIB3000MC_REG_UNK_1,DIB3000MC_UNK_1); - wr(DIB3000MC_REG_UNK_2,DIB3000MC_UNK_2); - wr(DIB3000MC_REG_UNK_3,DIB3000MC_UNK_3); - wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS_DEFAULT); - - wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz); - wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general); - - wr(DIB3000MC_REG_UNK_4,DIB3000MC_UNK_4); - - wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF); - wr(DIB3000MC_REG_SET_DDS_FREQ_LSB,DIB3000MC_DDS_FREQ_LSB); - - dib3000mc_set_timing(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ); -// wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[3]); - - wr(DIB3000MC_REG_UNK_120,DIB3000MC_UNK_120); - wr(DIB3000MC_REG_UNK_134,DIB3000MC_UNK_134); - wr(DIB3000MC_REG_FEC_CFG,DIB3000MC_FEC_CFG); - - wr(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF); - - dib3000mc_set_impulse_noise(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ); - -/* output mode control, just the MPEG2_SLAVE */ -// set_or(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE); - wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE); - wr(DIB3000MC_REG_SMO_MODE,DIB3000MC_SMO_MODE_SLAVE); - wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_SLAVE); - wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_SLAVE); - -/* MPEG2_PARALLEL_CONTINUOUS_CLOCK - wr(DIB3000MC_REG_OUTMODE, - DIB3000MC_SET_OUTMODE(DIB3000MC_OM_PAR_CONT_CLK, - rd(DIB3000MC_REG_OUTMODE))); - - wr(DIB3000MC_REG_SMO_MODE, - DIB3000MC_SMO_MODE_DEFAULT | - DIB3000MC_SMO_MODE_188); - - wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_DEFAULT); - wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON); -*/ - -/* diversity */ - wr(DIB3000MC_REG_DIVERSITY1,DIB3000MC_DIVERSITY1_DEFAULT); - wr(DIB3000MC_REG_DIVERSITY2,DIB3000MC_DIVERSITY2_DEFAULT); - - set_and(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF); - - set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); - - deb_info("init end\n"); - return 0; -} -static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat) -{ - struct dib3000_state* state = fe->demodulator_priv; - u16 lock = rd(DIB3000MC_REG_LOCKING); - - *stat = 0; - if (DIB3000MC_AGC_LOCK(lock)) - *stat |= FE_HAS_SIGNAL; - if (DIB3000MC_CARRIER_LOCK(lock)) - *stat |= FE_HAS_CARRIER; - if (DIB3000MC_TPS_LOCK(lock)) - *stat |= FE_HAS_VITERBI; - if (DIB3000MC_MPEG_SYNC_LOCK(lock)) - *stat |= (FE_HAS_SYNC | FE_HAS_LOCK); - - deb_stat("actual status is %2x fifo_level: %x,244: %x, 206: %x, 207: %x, 1040: %x\n",*stat,rd(510),rd(244),rd(206),rd(207),rd(1040)); - - return 0; -} - -static int dib3000mc_read_ber(struct dvb_frontend* fe, u32 *ber) -{ - struct dib3000_state* state = fe->demodulator_priv; - *ber = ((rd(DIB3000MC_REG_BER_MSB) << 16) | rd(DIB3000MC_REG_BER_LSB)); - return 0; -} - -static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) -{ - struct dib3000_state* state = fe->demodulator_priv; - - *unc = rd(DIB3000MC_REG_PACKET_ERRORS); - return 0; -} - -/* see dib3000mb.c for calculation comments */ -static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength) -{ - struct dib3000_state* state = fe->demodulator_priv; - u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB); - *strength = (((val >> 6) & 0xff) << 8) + (val & 0x3f); - - deb_stat("signal: mantisse = %d, exponent = %d\n",(*strength >> 8) & 0xff, *strength & 0xff); - return 0; -} - -/* see dib3000mb.c for calculation comments */ -static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - struct dib3000_state* state = fe->demodulator_priv; - u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB), - val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB); - u16 sig,noise; - - sig = (((val >> 6) & 0xff) << 8) + (val & 0x3f); - noise = (((val >> 4) & 0xff) << 8) + ((val & 0xf) << 2) + ((val2 >> 14) & 0x3); - if (noise == 0) - *snr = 0xffff; - else - *snr = (u16) sig/noise; - - deb_stat("signal: mantisse = %d, exponent = %d\n",(sig >> 8) & 0xff, sig & 0xff); - deb_stat("noise: mantisse = %d, exponent = %d\n",(noise >> 8) & 0xff, noise & 0xff); - deb_stat("snr: %d\n",*snr); - return 0; -} - -static int dib3000mc_sleep(struct dvb_frontend* fe) -{ - struct dib3000_state* state = fe->demodulator_priv; - - set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_PWR_DOWN); - wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_DOWN); - wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_POWER_DOWN); - wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_DOWN); - 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 int dib3000mc_fe_init_nonmobile(struct dvb_frontend* fe) -{ - return dib3000mc_fe_init(fe, 0); -} - -static int dib3000mc_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) -{ - return dib3000mc_set_frontend(fe, fep, 1); -} - -static void dib3000mc_release(struct dvb_frontend* fe) -{ - struct dib3000_state *state = fe->demodulator_priv; - kfree(state); -} - -/* pid filter and transfer stuff */ -static int dib3000mc_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+DIB3000MC_REG_FIRST_PID,pid); - return 0; -} - -static int dib3000mc_fifo_control(struct dvb_frontend *fe, int onoff) -{ - struct dib3000_state *state = fe->demodulator_priv; - u16 tmp = rd(DIB3000MC_REG_SMO_MODE); - - deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling"); - - if (onoff) { - deb_xfer("%d %x\n",tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH); - wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH); - } else { - deb_xfer("%d %x\n",tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH); - wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH); - } - return 0; -} - -static int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff) -{ - struct dib3000_state *state = fe->demodulator_priv; - u16 tmp = rd(DIB3000MC_REG_SMO_MODE); - - deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling"); - - if (onoff) { - wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_PID_PARSE); - } else { - wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE); - } - return 0; -} - -static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr) -{ - struct dib3000_state *state = fe->demodulator_priv; - if (onoff) { - wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr)); - } else { - wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr)); - } - return 0; -} - -static int dib3000mc_demod_init(struct dib3000_state *state) -{ - u16 default_addr = 0x0a; - /* first init */ - if (state->config.demod_address != default_addr) { - deb_info("initializing the demod the first time. Setting demod addr to 0x%x\n",default_addr); - wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON); - wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_PAR_CONT_CLK); - - wr(DIB3000MC_REG_RST_I2C_ADDR, - DIB3000MC_DEMOD_ADDR(default_addr) | - DIB3000MC_DEMOD_ADDR_ON); - - state->config.demod_address = default_addr; - - wr(DIB3000MC_REG_RST_I2C_ADDR, - DIB3000MC_DEMOD_ADDR(default_addr)); - } else - deb_info("demod is already initialized. Demod addr: 0x%x\n",state->config.demod_address); - return 0; -} - - -static struct dvb_frontend_ops dib3000mc_ops; - -struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, - struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops) -{ - struct dib3000_state* state = NULL; - u16 devid; - - /* 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; - - devid = rd(DIB3000_REG_DEVICE_ID); - if (devid != DIB3000MC_DEVICE_ID && devid != DIB3000P_DEVICE_ID) - goto error; - - switch (devid) { - case DIB3000MC_DEVICE_ID: - info("Found a DiBcom 3000M-C, interesting..."); - break; - case DIB3000P_DEVICE_ID: - info("Found a DiBcom 3000P."); - break; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - /* set the xfer operations */ - xfer_ops->pid_parse = dib3000mc_pid_parse; - xfer_ops->fifo_ctrl = dib3000mc_fifo_control; - xfer_ops->pid_ctrl = dib3000mc_pid_control; - xfer_ops->tuner_pass_ctrl = dib3000mc_tuner_pass_ctrl; - - dib3000mc_demod_init(state); - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(dib3000mc_attach); - -static struct dvb_frontend_ops dib3000mc_ops = { - - .info = { - .name = "DiBcom 3000P/M-C 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 = dib3000mc_release, - - .init = dib3000mc_fe_init_nonmobile, - .sleep = dib3000mc_sleep, - - .set_frontend = dib3000mc_set_frontend_and_tuner, - .get_frontend = dib3000mc_get_frontend, - .get_tune_settings = dib3000mc_fe_get_tune_settings, - - .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(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dib3000mc_priv.h b/drivers/media/dvb/frontends/dib3000mc_priv.h deleted file mode 100644 index 2930aac7591..00000000000 --- a/drivers/media/dvb/frontends/dib3000mc_priv.h +++ /dev/null @@ -1,428 +0,0 @@ -/* - * dib3000mc_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 dib3000mc.c . - */ - -#ifndef __DIB3000MC_PRIV_H__ -#define __DIB3000MC_PRIV_H__ - -/* - * Demodulator parameters - * reg: 0 1 1 1 11 11 111 - * | | | | | | - * | | | | | +-- alpha (000=0, 001=1, 010=2, 100=4) - * | | | | +----- constellation (00=QPSK, 01=16QAM, 10=64QAM) - * | | | +-------- guard (00=1/32, 01=1/16, 10=1/8, 11=1/4) - * | | +----------- transmission mode (0=2k, 1=8k) - * | | - * | +-------------- restart autosearch for parameters - * +---------------- restart the demodulator - * reg: 181 1 111 1 - * | | | - * | | +- FEC applies for HP or LP (0=LP, 1=HP) - * | +---- FEC rate (001=1/2, 010=2/3, 011=3/4, 101=5/6, 111=7/8) - * +------- hierarchy on (0=no, 1=yes) - */ - -/* demodulator tuning parameter and restart options */ -#define DIB3000MC_REG_DEMOD_PARM ( 0) -#define DIB3000MC_DEMOD_PARM(a,c,g,t) ( \ - (0x7 & a) | \ - ((0x3 & c) << 3) | \ - ((0x3 & g) << 5) | \ - ((0x1 & t) << 7) ) -#define DIB3000MC_DEMOD_RST_AUTO_SRCH_ON (1 << 8) -#define DIB3000MC_DEMOD_RST_AUTO_SRCH_OFF (0 << 8) -#define DIB3000MC_DEMOD_RST_DEMOD_ON (1 << 9) -#define DIB3000MC_DEMOD_RST_DEMOD_OFF (0 << 9) - -/* register for hierarchy parameters */ -#define DIB3000MC_REG_HRCH_PARM ( 181) -#define DIB3000MC_HRCH_PARM(s,f,h) ( \ - (0x1 & s) | \ - ((0x7 & f) << 1) | \ - ((0x1 & h) << 4) ) - -/* timeout ??? */ -#define DIB3000MC_REG_UNK_1 ( 1) -#define DIB3000MC_UNK_1 ( 0x04) - -/* timeout ??? */ -#define DIB3000MC_REG_UNK_2 ( 2) -#define DIB3000MC_UNK_2 ( 0x04) - -/* timeout ??? */ -#define DIB3000MC_REG_UNK_3 ( 3) -#define DIB3000MC_UNK_3 (0x1000) - -#define DIB3000MC_REG_UNK_4 ( 4) -#define DIB3000MC_UNK_4 (0x0814) - -/* timeout ??? */ -#define DIB3000MC_REG_SEQ_TPS ( 5) -#define DIB3000MC_SEQ_TPS_DEFAULT ( 1) -#define DIB3000MC_SEQ_TPS(s,t) ( \ - ((s & 0x0f) << 4) | \ - ((t & 0x01) << 8) ) -#define DIB3000MC_IS_TPS(v) ((v << 8) & 0x1) -#define DIB3000MC_IS_AS(v) ((v >> 4) & 0xf) - -/* parameters for the bandwidth */ -#define DIB3000MC_REG_BW_TIMOUT_MSB ( 6) -#define DIB3000MC_REG_BW_TIMOUT_LSB ( 7) - -static u16 dib3000mc_reg_bandwidth[] = { 6,7,8,9,10,11,16,17 }; - -/*static u16 dib3000mc_bandwidth_5mhz[] = - { 0x28, 0x9380, 0x87, 0x4100, 0x2a4, 0x4500, 0x1, 0xb0d0 };*/ - -static u16 dib3000mc_bandwidth_6mhz[] = - { 0x21, 0xd040, 0x70, 0xb62b, 0x233, 0x8ed5, 0x1, 0xb0d0 }; - -static u16 dib3000mc_bandwidth_7mhz[] = - { 0x1c, 0xfba5, 0x60, 0x9c25, 0x1e3, 0x0cb7, 0x1, 0xb0d0 }; - -static u16 dib3000mc_bandwidth_8mhz[] = - { 0x19, 0x5c30, 0x54, 0x88a0, 0x1a6, 0xab20, 0x1, 0xb0d0 }; - -static u16 dib3000mc_reg_bandwidth_general[] = { 12,13,14,15 }; -static u16 dib3000mc_bandwidth_general[] = { 0x0000, 0x03e8, 0x0000, 0x03f2 }; - -/* lock mask */ -#define DIB3000MC_REG_LOCK_MASK ( 15) -#define DIB3000MC_ACTIVATE_LOCK_MASK (0x0800) - -/* reset the uncorrected packet count (??? do it 5 times) */ -#define DIB3000MC_REG_RST_UNC ( 18) -#define DIB3000MC_RST_UNC_ON ( 1) -#define DIB3000MC_RST_UNC_OFF ( 0) - -#define DIB3000MC_REG_UNK_19 ( 19) -#define DIB3000MC_UNK_19 ( 0) - -/* DDS frequency value (IF position) and inversion bit */ -#define DIB3000MC_REG_INVERSION ( 21) -#define DIB3000MC_REG_SET_DDS_FREQ_MSB ( 21) -#define DIB3000MC_DDS_FREQ_MSB_INV_OFF (0x0164) -#define DIB3000MC_DDS_FREQ_MSB_INV_ON (0x0364) - -#define DIB3000MC_REG_SET_DDS_FREQ_LSB ( 22) -#define DIB3000MC_DDS_FREQ_LSB (0x463d) - -/* timing frequencies setting */ -#define DIB3000MC_REG_TIMING_FREQ_MSB ( 23) -#define DIB3000MC_REG_TIMING_FREQ_LSB ( 24) -#define DIB3000MC_CLOCK_REF (0x151fd1) - -//static u16 dib3000mc_reg_timing_freq[] = { 23,24 }; - -//static u16 dib3000mc_timing_freq[][2] = { -// { 0x69, 0x9f18 }, /* 5 MHz */ -// { 0x7e ,0xbee9 }, /* 6 MHz */ -// { 0x93 ,0xdebb }, /* 7 MHz */ -// { 0xa8 ,0xfe8c }, /* 8 MHz */ -//}; - -/* timeout ??? */ -static u16 dib3000mc_reg_offset[] = { 26,33 }; - -static u16 dib3000mc_offset[][2] = { - { 26240, 5 }, /* default */ - { 30336, 6 }, /* 8K */ - { 38528, 8 }, /* 2K */ -}; - -#define DIB3000MC_REG_ISI ( 29) -#define DIB3000MC_ISI_DEFAULT (0x1073) -#define DIB3000MC_ISI_ACTIVATE (0x0000) -#define DIB3000MC_ISI_INHIBIT (0x0200) - -/* impulse noise control */ -static u16 dib3000mc_reg_imp_noise_ctl[] = { 34,35 }; - -static u16 dib3000mc_imp_noise_ctl[][2] = { - { 0x1294, 0x1ff8 }, /* mode 0 */ - { 0x1294, 0x1ff8 }, /* mode 1 */ - { 0x1294, 0x1ff8 }, /* mode 2 */ - { 0x1294, 0x1ff8 }, /* mode 3 */ - { 0x1294, 0x1ff8 }, /* mode 4 */ -}; - -/* AGC registers */ -static u16 dib3000mc_reg_agc[] = { - 36,37,38,39,42,43,44,45,46,47,48,49 -}; - -static u16 dib3000mc_agc_tuner[][12] = { - { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xcf5c, 0x6666, - 0xbae1, 0xa148, 0x3b5e, 0x3c1c, 0x001a, 0x2019 - }, /* TUNER_PANASONIC_ENV77H04D5, */ - - { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xdc29, 0x570a, - 0xbae1, 0x8ccd, 0x3b6d, 0x551d, 0x000a, 0x951e - }, /* TUNER_PANASONIC_ENV57H13D5, TUNER_PANASONIC_ENV57H12D5 */ - - { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xffff, 0xffff, - 0xffff, 0x0000, 0xfdfd, 0x4040, 0x00fd, 0x4040 - }, /* TUNER_SAMSUNG_DTOS333IH102, TUNER_RFAGCIN_UNKNOWN */ - - { 0x0196, 0x301d, 0x0000, 0x1cc7, 0xbd71, 0x5c29, - 0xb5c3, 0x6148, 0x6569, 0x5127, 0x0033, 0x3537 - }, /* TUNER_PROVIDER_X */ - /* TODO TUNER_PANASONIC_ENV57H10D8, TUNER_PANASONIC_ENV57H11D8 */ -}; - -/* AGC loop bandwidth */ -static u16 dib3000mc_reg_agc_bandwidth[] = { 40,41 }; -static u16 dib3000mc_agc_bandwidth[] = { 0x119,0x330 }; - -static u16 dib3000mc_reg_agc_bandwidth_general[] = { 50,51,52,53,54 }; -static u16 dib3000mc_agc_bandwidth_general[] = - { 0x8000, 0x91ca, 0x01ba, 0x0087, 0x0087 }; - -#define DIB3000MC_REG_IMP_NOISE_55 ( 55) -#define DIB3000MC_IMP_NEW_ALGO(w) (w | (1<<10)) - -/* Impulse noise params */ -static u16 dib3000mc_reg_impulse_noise[] = { 55,56,57 }; -static u16 dib3000mc_impluse_noise[][3] = { - { 0x489, 0x89, 0x72 }, /* 5 MHz */ - { 0x4a5, 0xa5, 0x89 }, /* 6 MHz */ - { 0x4c0, 0xc0, 0xa0 }, /* 7 MHz */ - { 0x4db, 0xdb, 0xb7 }, /* 8 Mhz */ -}; - -static u16 dib3000mc_reg_fft[] = { - 58,59,60,61,62,63,64,65,66,67,68,69, - 70,71,72,73,74,75,76,77,78,79,80,81, - 82,83,84,85,86 -}; - -static u16 dib3000mc_fft_modes[][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, 0x0, 0xd - }, /* fft mode 0 */ - { 0x3b, 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, 0x0, 0x8200, 0xd - }, /* fft mode 1 */ -}; - -#define DIB3000MC_REG_UNK_88 ( 88) -#define DIB3000MC_UNK_88 (0x0410) - -static u16 dib3000mc_reg_bw[] = { 93,94,95,96,97,98 }; -static u16 dib3000mc_bw[][6] = { - { 0,0,0,0,0,0 }, /* 5 MHz */ - { 0,0,0,0,0,0 }, /* 6 MHz */ - { 0,0,0,0,0,0 }, /* 7 MHz */ - { 0x20, 0x21, 0x20, 0x23, 0x20, 0x27 }, /* 8 MHz */ -}; - - -/* phase noise control */ -#define DIB3000MC_REG_UNK_99 ( 99) -#define DIB3000MC_UNK_99 (0x0220) - -#define DIB3000MC_REG_SCAN_BOOST ( 100) -#define DIB3000MC_SCAN_BOOST_ON ((11 << 6) + 6) -#define DIB3000MC_SCAN_BOOST_OFF ((16 << 6) + 9) - -/* timeout ??? */ -#define DIB3000MC_REG_UNK_110 ( 110) -#define DIB3000MC_UNK_110 ( 3277) - -#define DIB3000MC_REG_UNK_111 ( 111) -#define DIB3000MC_UNK_111_PH_N_MODE_0 ( 0) -#define DIB3000MC_UNK_111_PH_N_MODE_1 (1 << 1) - -/* superious rm config */ -#define DIB3000MC_REG_UNK_120 ( 120) -#define DIB3000MC_UNK_120 ( 8207) - -#define DIB3000MC_REG_UNK_133 ( 133) -#define DIB3000MC_UNK_133 ( 15564) - -#define DIB3000MC_REG_UNK_134 ( 134) -#define DIB3000MC_UNK_134 ( 0) - -/* adapter config for constellation */ -static u16 dib3000mc_reg_adp_cfg[] = { 129, 130, 131, 132 }; - -static u16 dib3000mc_adp_cfg[][4] = { - { 0x99a, 0x7fae, 0x333, 0x7ff0 }, /* QPSK */ - { 0x23d, 0x7fdf, 0x0a4, 0x7ff0 }, /* 16-QAM */ - { 0x148, 0x7ff0, 0x0a4, 0x7ff8 }, /* 64-QAM */ -}; - -static u16 dib3000mc_reg_mobile_mode[] = { 139, 140, 141, 175, 1032 }; - -static u16 dib3000mc_mobile_mode[][5] = { - { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* fixed */ - { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* portable */ - { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* mobile */ - { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* auto */ -}; - -#define DIB3000MC_REG_DIVERSITY1 ( 177) -#define DIB3000MC_DIVERSITY1_DEFAULT ( 1) - -#define DIB3000MC_REG_DIVERSITY2 ( 178) -#define DIB3000MC_DIVERSITY2_DEFAULT ( 1) - -#define DIB3000MC_REG_DIVERSITY3 ( 180) -#define DIB3000MC_DIVERSITY3_IN_OFF (0xfff0) -#define DIB3000MC_DIVERSITY3_IN_ON (0xfff6) - -#define DIB3000MC_REG_FEC_CFG ( 195) -#define DIB3000MC_FEC_CFG ( 0x10) - -/* - * reg 206, output mode - * 1111 1111 - * |||| |||| - * |||| |||+- unk - * |||| ||+-- unk - * |||| |+--- unk (on by default) - * |||| +---- fifo_ctrl (1 = inhibit (flushed), 0 = active (unflushed)) - * |||+------ pid_parse (1 = enabled, 0 = disabled) - * ||+------- outp_188 (1 = TS packet size 188, 0 = packet size 204) - * |+-------- unk - * +--------- unk - */ - -#define DIB3000MC_REG_SMO_MODE ( 206) -#define DIB3000MC_SMO_MODE_DEFAULT (1 << 2) -#define DIB3000MC_SMO_MODE_FIFO_FLUSH (1 << 3) -#define DIB3000MC_SMO_MODE_FIFO_UNFLUSH (0xfff7) -#define DIB3000MC_SMO_MODE_PID_PARSE (1 << 4) -#define DIB3000MC_SMO_MODE_NO_PID_PARSE (0xffef) -#define DIB3000MC_SMO_MODE_188 (1 << 5) -#define DIB3000MC_SMO_MODE_SLAVE (DIB3000MC_SMO_MODE_DEFAULT | \ - DIB3000MC_SMO_MODE_188 | DIB3000MC_SMO_MODE_PID_PARSE | (1<<1)) - -#define DIB3000MC_REG_FIFO_THRESHOLD ( 207) -#define DIB3000MC_FIFO_THRESHOLD_DEFAULT ( 1792) -#define DIB3000MC_FIFO_THRESHOLD_SLAVE ( 512) -/* - * pidfilter - * it is not a hardware pidfilter but a filter which drops all pids - * except the ones set. When connected to USB1.1 bandwidth this is important. - * DiB3000P/M-C can filter up to 32 PIDs - */ -#define DIB3000MC_REG_FIRST_PID ( 212) -#define DIB3000MC_NUM_PIDS ( 32) - -#define DIB3000MC_REG_OUTMODE ( 244) -#define DIB3000MC_OM_PARALLEL_GATED_CLK ( 0) -#define DIB3000MC_OM_PAR_CONT_CLK (1 << 11) -#define DIB3000MC_OM_SERIAL (2 << 11) -#define DIB3000MC_OM_DIVOUT_ON (4 << 11) -#define DIB3000MC_OM_SLAVE (DIB3000MC_OM_DIVOUT_ON | DIB3000MC_OM_PAR_CONT_CLK) - -#define DIB3000MC_REG_RF_POWER ( 392) - -#define DIB3000MC_REG_FFT_POSITION ( 407) - -#define DIB3000MC_REG_DDS_FREQ_MSB ( 414) -#define DIB3000MC_REG_DDS_FREQ_LSB ( 415) - -#define DIB3000MC_REG_TIMING_OFFS_MSB ( 416) -#define DIB3000MC_REG_TIMING_OFFS_LSB ( 417) - -#define DIB3000MC_REG_TUNING_PARM ( 458) -#define DIB3000MC_TP_QAM(v) ((v >> 13) & 0x03) -#define DIB3000MC_TP_HRCH(v) ((v >> 12) & 0x01) -#define DIB3000MC_TP_ALPHA(v) ((v >> 9) & 0x07) -#define DIB3000MC_TP_FFT(v) ((v >> 8) & 0x01) -#define DIB3000MC_TP_FEC_CR_HP(v) ((v >> 5) & 0x07) -#define DIB3000MC_TP_FEC_CR_LP(v) ((v >> 2) & 0x07) -#define DIB3000MC_TP_GUARD(v) (v & 0x03) - -#define DIB3000MC_REG_SIGNAL_NOISE_MSB ( 483) -#define DIB3000MC_REG_SIGNAL_NOISE_LSB ( 484) - -#define DIB3000MC_REG_MER ( 485) - -#define DIB3000MC_REG_BER_MSB ( 500) -#define DIB3000MC_REG_BER_LSB ( 501) - -#define DIB3000MC_REG_PACKET_ERRORS ( 503) - -#define DIB3000MC_REG_PACKET_ERROR_COUNT ( 506) - -#define DIB3000MC_REG_LOCK_507 ( 507) -#define DIB3000MC_LOCK_507 (0x0002) // ? name correct ? - -#define DIB3000MC_REG_LOCKING ( 509) -#define DIB3000MC_AGC_LOCK(v) (v & 0x8000) -#define DIB3000MC_CARRIER_LOCK(v) (v & 0x2000) -#define DIB3000MC_MPEG_SYNC_LOCK(v) (v & 0x0080) -#define DIB3000MC_MPEG_DATA_LOCK(v) (v & 0x0040) -#define DIB3000MC_TPS_LOCK(v) (v & 0x0004) - -#define DIB3000MC_REG_AS_IRQ ( 511) -#define DIB3000MC_AS_IRQ_SUCCESS (1 << 1) -#define DIB3000MC_AS_IRQ_FAIL ( 1) - -#define DIB3000MC_REG_TUNER ( 769) - -#define DIB3000MC_REG_RST_I2C_ADDR ( 1024) -#define DIB3000MC_DEMOD_ADDR_ON ( 1) -#define DIB3000MC_DEMOD_ADDR(a) ((a << 4) & 0x03F0) - -#define DIB3000MC_REG_RESTART ( 1027) -#define DIB3000MC_RESTART_OFF (0x0000) -#define DIB3000MC_RESTART_AGC (0x0800) -#define DIB3000MC_RESTART_CONFIG (0x8000) - -#define DIB3000MC_REG_RESTART_VIT ( 1028) -#define DIB3000MC_RESTART_VIT_OFF ( 0) -#define DIB3000MC_RESTART_VIT_ON ( 1) - -#define DIB3000MC_REG_CLK_CFG_1 ( 1031) -#define DIB3000MC_CLK_CFG_1_POWER_UP ( 0) -#define DIB3000MC_CLK_CFG_1_POWER_DOWN (0xffff) - -#define DIB3000MC_REG_CLK_CFG_2 ( 1032) -#define DIB3000MC_CLK_CFG_2_PUP_FIXED (0x012c) -#define DIB3000MC_CLK_CFG_2_PUP_PORT (0x0104) -#define DIB3000MC_CLK_CFG_2_PUP_MOBILE (0x0000) -#define DIB3000MC_CLK_CFG_2_POWER_DOWN (0xffff) - -#define DIB3000MC_REG_CLK_CFG_3 ( 1033) -#define DIB3000MC_CLK_CFG_3_POWER_UP ( 0) -#define DIB3000MC_CLK_CFG_3_POWER_DOWN (0xfff5) - -#define DIB3000MC_REG_CLK_CFG_7 ( 1037) -#define DIB3000MC_CLK_CFG_7_INIT ( 12592) -#define DIB3000MC_CLK_CFG_7_POWER_UP (~0x0003) -#define DIB3000MC_CLK_CFG_7_PWR_DOWN (0x0003) -#define DIB3000MC_CLK_CFG_7_DIV_IN_OFF (1 << 8) - -/* was commented out ??? */ -#define DIB3000MC_REG_CLK_CFG_8 ( 1038) -#define DIB3000MC_CLK_CFG_8_POWER_UP (0x160c) - -#define DIB3000MC_REG_CLK_CFG_9 ( 1039) -#define DIB3000MC_CLK_CFG_9_POWER_UP ( 0) - -/* also clock ??? */ -#define DIB3000MC_REG_ELEC_OUT ( 1040) -#define DIB3000MC_ELEC_OUT_HIGH_Z ( 0) -#define DIB3000MC_ELEC_OUT_DIV_OUT_ON ( 1) -#define DIB3000MC_ELEC_OUT_SLAVE ( 3) - -#endif diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c deleted file mode 100644 index 2be33f27c69..00000000000 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ /dev/null @@ -1,652 +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" - -/* ----------------------------------------------------------- */ -/* descriptions */ - -struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { - .name = "Thomson dtt7579", - .min = 177000000, - .max = 858000000, - .count = 5, - .entries = { - { 0, 36166667, 166666, 0xb4, 0x03 }, /* go sleep */ - { 443250000, 36166667, 166666, 0xb4, 0x02 }, - { 542000000, 36166667, 166666, 0xb4, 0x08 }, - { 771000000, 36166667, 166666, 0xbc, 0x08 }, - { 999999999, 36166667, 166666, 0xf4, 0x08 }, - }, -}; -EXPORT_SYMBOL(dvb_pll_thomson_dtt7579); - -struct dvb_pll_desc dvb_pll_thomson_dtt7610 = { - .name = "Thomson dtt7610", - .min = 44000000, - .max = 958000000, - .count = 3, - .entries = { - { 157250000, 44000000, 62500, 0x8e, 0x39 }, - { 454000000, 44000000, 62500, 0x8e, 0x3a }, - { 999999999, 44000000, 62500, 0x8e, 0x3c }, - }, -}; -EXPORT_SYMBOL(dvb_pll_thomson_dtt7610); - -static void thomson_dtt759x_bw(u8 *buf, u32 freq, int bandwidth) -{ - if (BANDWIDTH_7_MHZ == bandwidth) - buf[3] |= 0x10; -} - -struct dvb_pll_desc dvb_pll_thomson_dtt759x = { - .name = "Thomson dtt759x", - .min = 177000000, - .max = 896000000, - .setbw = thomson_dtt759x_bw, - .count = 6, - .entries = { - { 0, 36166667, 166666, 0x84, 0x03 }, - { 264000000, 36166667, 166666, 0xb4, 0x02 }, - { 470000000, 36166667, 166666, 0xbc, 0x02 }, - { 735000000, 36166667, 166666, 0xbc, 0x08 }, - { 835000000, 36166667, 166666, 0xf4, 0x08 }, - { 999999999, 36166667, 166666, 0xfc, 0x08 }, - }, -}; -EXPORT_SYMBOL(dvb_pll_thomson_dtt759x); - -struct dvb_pll_desc dvb_pll_lg_z201 = { - .name = "LG z201", - .min = 174000000, - .max = 862000000, - .count = 6, - .entries = { - { 0, 36166667, 166666, 0xbc, 0x03 }, - { 157500000, 36166667, 166666, 0xbc, 0x01 }, - { 443250000, 36166667, 166666, 0xbc, 0x02 }, - { 542000000, 36166667, 166666, 0xbc, 0x04 }, - { 830000000, 36166667, 166666, 0xf4, 0x04 }, - { 999999999, 36166667, 166666, 0xfc, 0x04 }, - }, -}; -EXPORT_SYMBOL(dvb_pll_lg_z201); - -struct dvb_pll_desc dvb_pll_microtune_4042 = { - .name = "Microtune 4042 FI5", - .min = 57000000, - .max = 858000000, - .count = 3, - .entries = { - { 162000000, 44000000, 62500, 0x8e, 0xa1 }, - { 457000000, 44000000, 62500, 0x8e, 0x91 }, - { 999999999, 44000000, 62500, 0x8e, 0x31 }, - }, -}; -EXPORT_SYMBOL(dvb_pll_microtune_4042); - -struct dvb_pll_desc dvb_pll_thomson_dtt761x = { - /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ - .name = "Thomson dtt761x", - .min = 57000000, - .max = 863000000, - .count = 3, - .entries = { - { 147000000, 44000000, 62500, 0x8e, 0x39 }, - { 417000000, 44000000, 62500, 0x8e, 0x3a }, - { 999999999, 44000000, 62500, 0x8e, 0x3c }, - }, -}; -EXPORT_SYMBOL(dvb_pll_thomson_dtt761x); - -struct dvb_pll_desc dvb_pll_unknown_1 = { - .name = "unknown 1", /* used by dntv live dvb-t */ - .min = 174000000, - .max = 862000000, - .count = 9, - .entries = { - { 150000000, 36166667, 166666, 0xb4, 0x01 }, - { 173000000, 36166667, 166666, 0xbc, 0x01 }, - { 250000000, 36166667, 166666, 0xb4, 0x02 }, - { 400000000, 36166667, 166666, 0xbc, 0x02 }, - { 420000000, 36166667, 166666, 0xf4, 0x02 }, - { 470000000, 36166667, 166666, 0xfc, 0x02 }, - { 600000000, 36166667, 166666, 0xbc, 0x08 }, - { 730000000, 36166667, 166666, 0xf4, 0x08 }, - { 999999999, 36166667, 166666, 0xfc, 0x08 }, - }, -}; -EXPORT_SYMBOL(dvb_pll_unknown_1); - -/* Infineon TUA6010XS - * used in Thomson Cable Tuner - */ -struct dvb_pll_desc dvb_pll_tua6010xs = { - .name = "Infineon TUA6010XS", - .min = 44250000, - .max = 858000000, - .count = 3, - .entries = { - { 115750000, 36125000, 62500, 0x8e, 0x03 }, - { 403250000, 36125000, 62500, 0x8e, 0x06 }, - { 999999999, 36125000, 62500, 0x8e, 0x85 }, - }, -}; -EXPORT_SYMBOL(dvb_pll_tua6010xs); - -/* Panasonic env57h1xd5 (some Philips PLL ?) */ -struct dvb_pll_desc dvb_pll_env57h1xd5 = { - .name = "Panasonic ENV57H1XD5", - .min = 44250000, - .max = 858000000, - .count = 4, - .entries = { - { 153000000, 36291666, 166666, 0xc2, 0x41 }, - { 470000000, 36291666, 166666, 0xc2, 0x42 }, - { 526000000, 36291666, 166666, 0xc2, 0x84 }, - { 999999999, 36291666, 166666, 0xc2, 0xa4 }, - }, -}; -EXPORT_SYMBOL(dvb_pll_env57h1xd5); - -/* Philips TDA6650/TDA6651 - * used in Panasonic ENV77H11D5 - */ -static void tda665x_bw(u8 *buf, u32 freq, int bandwidth) -{ - if (bandwidth == BANDWIDTH_8_MHZ) - buf[3] |= 0x08; -} - -struct dvb_pll_desc dvb_pll_tda665x = { - .name = "Philips TDA6650/TDA6651", - .min = 44250000, - .max = 858000000, - .setbw = tda665x_bw, - .count = 12, - .entries = { - { 93834000, 36249333, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ }, - { 123834000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, - { 161000000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, - { 163834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, - { 253834000, 36249333, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ }, - { 383834000, 36249333, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ }, - { 443834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, - { 444000000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, - { 583834000, 36249333, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ }, - { 793834000, 36249333, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ }, - { 444834000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, - { 861000000, 36249333, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ }, - } -}; -EXPORT_SYMBOL(dvb_pll_tda665x); - -/* Infineon TUA6034 - * used in LG TDTP E102P - */ -static void tua6034_bw(u8 *buf, u32 freq, int bandwidth) -{ - if (BANDWIDTH_7_MHZ != bandwidth) - buf[3] |= 0x08; -} - -struct dvb_pll_desc dvb_pll_tua6034 = { - .name = "Infineon TUA6034", - .min = 44250000, - .max = 858000000, - .count = 3, - .setbw = tua6034_bw, - .entries = { - { 174500000, 36166667, 62500, 0xce, 0x01 }, - { 230000000, 36166667, 62500, 0xce, 0x02 }, - { 999999999, 36166667, 62500, 0xce, 0x04 }, - }, -}; -EXPORT_SYMBOL(dvb_pll_tua6034); - -/* Infineon TUA6034 - * used in LG TDVS-H061F, LG TDVS-H062F and LG TDVS-H064F - */ -struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = { - .name = "LG TDVS-H06xF", - .min = 54000000, - .max = 863000000, - .count = 3, - .entries = { - { 165000000, 44000000, 62500, 0xce, 0x01 }, - { 450000000, 44000000, 62500, 0xce, 0x02 }, - { 999999999, 44000000, 62500, 0xce, 0x04 }, - }, -}; -EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf); - -/* Philips FMD1216ME - * used in Medion Hybrid PCMCIA card and USB Box - */ -static void fmd1216me_bw(u8 *buf, u32 freq, int bandwidth) -{ - if (bandwidth == BANDWIDTH_8_MHZ && freq >= 158870000) - buf[3] |= 0x08; -} - -struct dvb_pll_desc dvb_pll_fmd1216me = { - .name = "Philips FMD1216ME", - .min = 50870000, - .max = 858000000, - .setbw = fmd1216me_bw, - .count = 7, - .entries = { - { 143870000, 36213333, 166667, 0xbc, 0x41 }, - { 158870000, 36213333, 166667, 0xf4, 0x41 }, - { 329870000, 36213333, 166667, 0xbc, 0x42 }, - { 441870000, 36213333, 166667, 0xf4, 0x42 }, - { 625870000, 36213333, 166667, 0xbc, 0x44 }, - { 803870000, 36213333, 166667, 0xf4, 0x44 }, - { 999999999, 36213333, 166667, 0xfc, 0x44 }, - } -}; -EXPORT_SYMBOL(dvb_pll_fmd1216me); - -/* ALPS TDED4 - * used in Nebula-Cards and USB boxes - */ -static void tded4_bw(u8 *buf, u32 freq, int bandwidth) -{ - if (bandwidth == BANDWIDTH_8_MHZ) - buf[3] |= 0x04; -} - -struct dvb_pll_desc dvb_pll_tded4 = { - .name = "ALPS TDED4", - .min = 47000000, - .max = 863000000, - .setbw = tded4_bw, - .count = 4, - .entries = { - { 153000000, 36166667, 166667, 0x85, 0x01 }, - { 470000000, 36166667, 166667, 0x85, 0x02 }, - { 823000000, 36166667, 166667, 0x85, 0x08 }, - { 999999999, 36166667, 166667, 0x85, 0x88 }, - } -}; -EXPORT_SYMBOL(dvb_pll_tded4); - -/* ALPS TDHU2 - * used in AverTVHD MCE A180 - */ -struct dvb_pll_desc dvb_pll_tdhu2 = { - .name = "ALPS TDHU2", - .min = 54000000, - .max = 864000000, - .count = 4, - .entries = { - { 162000000, 44000000, 62500, 0x85, 0x01 }, - { 426000000, 44000000, 62500, 0x85, 0x02 }, - { 782000000, 44000000, 62500, 0x85, 0x08 }, - { 999999999, 44000000, 62500, 0x85, 0x88 }, - } -}; -EXPORT_SYMBOL(dvb_pll_tdhu2); - -/* Philips TUV1236D - * used in ATI HDTV Wonder - */ -struct dvb_pll_desc dvb_pll_tuv1236d = { - .name = "Philips TUV1236D", - .min = 54000000, - .max = 864000000, - .count = 3, - .entries = { - { 157250000, 44000000, 62500, 0xc6, 0x41 }, - { 454000000, 44000000, 62500, 0xc6, 0x42 }, - { 999999999, 44000000, 62500, 0xc6, 0x44 }, - }, -}; -EXPORT_SYMBOL(dvb_pll_tuv1236d); - -/* Samsung TBMV30111IN / TBMV30712IN1 - * used in Air2PC ATSC - 2nd generation (nxt2002) - */ -struct dvb_pll_desc dvb_pll_samsung_tbmv = { - .name = "Samsung TBMV30111IN / TBMV30712IN1", - .min = 54000000, - .max = 860000000, - .count = 6, - .entries = { - { 172000000, 44000000, 166666, 0xb4, 0x01 }, - { 214000000, 44000000, 166666, 0xb4, 0x02 }, - { 467000000, 44000000, 166666, 0xbc, 0x02 }, - { 721000000, 44000000, 166666, 0xbc, 0x08 }, - { 841000000, 44000000, 166666, 0xf4, 0x08 }, - { 999999999, 44000000, 166666, 0xfc, 0x02 }, - } -}; -EXPORT_SYMBOL(dvb_pll_samsung_tbmv); - -/* - * Philips SD1878 Tuner. - */ -struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = { - .name = "Philips SD1878", - .min = 950000, - .max = 2150000, - .count = 4, - .entries = { - { 1250000, 499, 500, 0xc4, 0x00}, - { 1550000, 499, 500, 0xc4, 0x40}, - { 2050000, 499, 500, 0xc4, 0x80}, - { 2150000, 499, 500, 0xc4, 0xc0}, - }, -}; -EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261); - -/* - * Philips TD1316 Tuner. - */ -static void td1316_bw(u8 *buf, u32 freq, int bandwidth) -{ - u8 band; - - /* determine band */ - if (freq < 161000000) - band = 1; - else if (freq < 444000000) - band = 2; - else - band = 4; - - buf[3] |= band; - - /* setup PLL filter */ - if (bandwidth == BANDWIDTH_8_MHZ) - buf[3] |= 1 << 3; -} - -struct dvb_pll_desc dvb_pll_philips_td1316 = { - .name = "Philips TD1316", - .min = 87000000, - .max = 895000000, - .setbw = td1316_bw, - .count = 9, - .entries = { - { 93834000, 36166000, 166666, 0xca, 0x60}, - { 123834000, 36166000, 166666, 0xca, 0xa0}, - { 163834000, 36166000, 166666, 0xca, 0xc0}, - { 253834000, 36166000, 166666, 0xca, 0x60}, - { 383834000, 36166000, 166666, 0xca, 0xa0}, - { 443834000, 36166000, 166666, 0xca, 0xc0}, - { 583834000, 36166000, 166666, 0xca, 0x60}, - { 793834000, 36166000, 166666, 0xca, 0xa0}, - { 858834000, 36166000, 166666, 0xca, 0xe0}, - }, -}; -EXPORT_SYMBOL(dvb_pll_philips_td1316); - -/* FE6600 used on DViCO Hybrid */ -struct dvb_pll_desc dvb_pll_thomson_fe6600 = { - .name = "Thomson FE6600", - .min = 44250000, - .max = 858000000, - .count = 4, - .entries = { - { 250000000, 36213333, 166667, 0xb4, 0x12 }, - { 455000000, 36213333, 166667, 0xfe, 0x11 }, - { 775500000, 36213333, 166667, 0xbc, 0x18 }, - { 999999999, 36213333, 166667, 0xf4, 0x18 }, - } -}; -EXPORT_SYMBOL(dvb_pll_thomson_fe6600); - -struct dvb_pll_priv { - /* 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; -}; - -/* ----------------------------------------------------------- */ -/* code */ - -static int debug = 0; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "enable verbose debug messages"); - -int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, - u32 freq, int bandwidth) -{ - u32 div; - int i; - - if (freq != 0 && (freq < desc->min || freq > desc->max)) - return -EINVAL; - - for (i = 0; i < desc->count; i++) { - if (freq > desc->entries[i].limit) - continue; - break; - } - if (debug) - printk("pll: %s: freq=%d bw=%d | i=%d/%d\n", - desc->name, freq, bandwidth, i, desc->count); - if (i == desc->count) - return -EINVAL; - - div = (freq + desc->entries[i].offset) / 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->setbw) - desc->setbw(buf, freq, bandwidth); - - 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]); - - return 0; -} -EXPORT_SYMBOL(dvb_pll_configure); - -static int dvb_pll_release(struct dvb_frontend *fe) -{ - if (fe->tuner_priv) - 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; - u8 buf[4]; - struct i2c_msg msg = - { .addr = priv->pll_i2c_address, .flags = 0, .buf = buf, .len = sizeof(buf) }; - int i; - int result; - - for (i = 0; i < priv->pll_desc->count; i++) { - if (priv->pll_desc->entries[i].limit == 0) - break; - } - if (i == priv->pll_desc->count) - return 0; - - buf[0] = 0; - buf[1] = 0; - buf[2] = priv->pll_desc->entries[i].config; - buf[3] = priv->pll_desc->entries[i].cb; - - 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; -} - -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 div; - int i; - u32 bandwidth = 0; - - if (priv->i2c == NULL) - return -EINVAL; - - // DVBT bandwidth only just now - if (fe->ops.info.type == FE_OFDM) { - bandwidth = params->u.ofdm.bandwidth; - } - - if ((result = dvb_pll_configure(priv->pll_desc, buf, params->frequency, bandwidth)) != 0) - return 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; - } - - // calculate the frequency we set it to - for (i = 0; i < priv->pll_desc->count; i++) { - if (params->frequency > priv->pll_desc->entries[i].limit) - continue; - break; - } - div = (params->frequency + priv->pll_desc->entries[i].offset) / priv->pll_desc->entries[i].stepsize; - priv->frequency = (div * priv->pll_desc->entries[i].stepsize) - priv->pll_desc->entries[i].offset; - priv->bandwidth = bandwidth; - - 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 div; - int i; - u32 bandwidth = 0; - - if (buf_len < 5) - return -EINVAL; - - // DVBT bandwidth only just now - if (fe->ops.info.type == FE_OFDM) { - bandwidth = params->u.ofdm.bandwidth; - } - - if ((result = dvb_pll_configure(priv->pll_desc, buf+1, params->frequency, bandwidth)) != 0) - return result; - buf[0] = priv->pll_i2c_address; - - // calculate the frequency we set it to - for (i = 0; i < priv->pll_desc->count; i++) { - if (params->frequency > priv->pll_desc->entries[i].limit) - continue; - break; - } - div = (params->frequency + priv->pll_desc->entries[i].offset) / priv->pll_desc->entries[i].stepsize; - priv->frequency = (div * priv->pll_desc->entries[i].stepsize) - priv->pll_desc->entries[i].offset; - priv->bandwidth = bandwidth; - - 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 struct dvb_tuner_ops dvb_pll_tuner_ops = { - .release = dvb_pll_release, - .sleep = dvb_pll_sleep, - .set_params = dvb_pll_set_params, - .calc_regs = dvb_pll_calc_regs, - .get_frequency = dvb_pll_get_frequency, - .get_bandwidth = dvb_pll_get_bandwidth, -}; - -int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc) -{ - 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; - - 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 -1; - 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 -ENOMEM; - - priv->pll_i2c_address = pll_addr; - priv->i2c = i2c; - priv->pll_desc = desc; - - memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, sizeof(struct dvb_tuner_ops)); - strncpy(fe->ops.tuner_ops.info.name, desc->name, 128); - fe->ops.tuner_ops.info.frequency_min = desc->min; - fe->ops.tuner_ops.info.frequency_min = desc->max; - - fe->tuner_priv = priv; - return 0; -} -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 66361cd1880..00000000000 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ /dev/null @@ -1,64 +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" - -struct dvb_pll_desc { - char *name; - u32 min; - u32 max; - void (*setbw)(u8 *buf, u32 freq, int bandwidth); - int count; - struct { - u32 limit; - u32 offset; - u32 stepsize; - u8 config; - u8 cb; - } entries[12]; -}; - -extern struct dvb_pll_desc dvb_pll_thomson_dtt7579; -extern struct dvb_pll_desc dvb_pll_thomson_dtt759x; -extern struct dvb_pll_desc dvb_pll_thomson_dtt7610; -extern struct dvb_pll_desc dvb_pll_lg_z201; -extern struct dvb_pll_desc dvb_pll_microtune_4042; -extern struct dvb_pll_desc dvb_pll_thomson_dtt761x; -extern struct dvb_pll_desc dvb_pll_unknown_1; - -extern struct dvb_pll_desc dvb_pll_tua6010xs; -extern struct dvb_pll_desc dvb_pll_env57h1xd5; -extern struct dvb_pll_desc dvb_pll_tua6034; -extern struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf; -extern struct dvb_pll_desc dvb_pll_tda665x; -extern struct dvb_pll_desc dvb_pll_fmd1216me; -extern struct dvb_pll_desc dvb_pll_tded4; - -extern struct dvb_pll_desc dvb_pll_tuv1236d; -extern struct dvb_pll_desc dvb_pll_tdhu2; -extern struct dvb_pll_desc dvb_pll_samsung_tbmv; -extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; -extern struct dvb_pll_desc dvb_pll_philips_td1316; - -extern struct dvb_pll_desc dvb_pll_thomson_fe6600; - -extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, - u32 freq, int bandwidth); - -/** - * 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 desc dvb_pll_desc to use. - * @return 0 on success, nonzero on failure. - */ -extern int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc); - -#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 6271b1e7f6a..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/moduleparam.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() -{ - 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() -{ - 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 8210f19d56c..00000000000 --- a/drivers/media/dvb/frontends/dvb_dummy_fe.h +++ /dev/null @@ -1,32 +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" - -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); - -#endif // DVB_DUMMY_FE_H diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c deleted file mode 100644 index 58c34db3107..00000000000 --- a/drivers/media/dvb/frontends/isl6421.c +++ /dev/null @@ -1,149 +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/moduleparam.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; - void (*release_chain)(struct dvb_frontend* fe); -}; - -static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_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->misc_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) -{ - struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv; - - /* power off */ - isl6421_set_voltage(fe, SEC_VOLTAGE_OFF); - - /* free data & call next release routine */ - fe->ops.release = isl6421->release_chain; - kfree(fe->misc_priv); - fe->misc_priv = NULL; - if (fe->ops.release) - fe->ops.release(fe); -} - -int 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 -ENOMEM; - - /* default configuration */ - isl6421->config = ISL6421_ISEL1; - isl6421->i2c = i2c; - isl6421->i2c_addr = i2c_addr; - fe->misc_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->misc_priv = NULL; - return -EIO; - } - - /* install release callback */ - isl6421->release_chain = fe->ops.release; - fe->ops.release = isl6421_release; - - /* override frontend ops */ - fe->ops.set_voltage = isl6421_set_voltage; - fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage; - - return 0; -} -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 675f80a19b9..00000000000 --- a/drivers/media/dvb/frontends/isl6421.h +++ /dev/null @@ -1,46 +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 - -/* override_set and override_clear control which system register bits (above) to always set & clear */ -extern int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, - u8 override_set, u8 override_clear); - -#endif diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c deleted file mode 100644 index f3bc82e44a2..00000000000 --- a/drivers/media/dvb/frontends/l64781.c +++ /dev/null @@ -1,603 +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/moduleparam.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 */ - 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", - __FUNCTION__, 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 83b8bc21027..00000000000 --- a/drivers/media/dvb/frontends/l64781.h +++ /dev/null @@ -1,38 +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; -}; - - -extern struct dvb_frontend* l64781_attach(const struct l64781_config* config, - struct i2c_adapter* i2c); - -#endif // L64781_H diff --git a/drivers/media/dvb/frontends/lg_h06xf.h b/drivers/media/dvb/frontends/lg_h06xf.h deleted file mode 100644 index 754d51d1112..00000000000 --- a/drivers/media/dvb/frontends/lg_h06xf.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * lg_h06xf.h - ATSC Tuner support for LG TDVS-H06xF - * - * 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 _LG_H06XF_H_ -#define _LG_H06XF_H_ -#include "dvb-pll.h" - -static int lg_h06xf_pll_set(struct dvb_frontend* fe, struct i2c_adapter* i2c_adap, - struct dvb_frontend_parameters* params) -{ - u8 buf[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, - .buf = buf, .len = sizeof(buf) }; - int err; - - dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf, params->frequency, 0); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) { - printk(KERN_WARNING "lg_h06xf: %s error " - "(addr %02x <- %02x, err = %i)\n", - __FUNCTION__, buf[0], buf[1], err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - - /* Set the Auxiliary Byte. */ - buf[0] = buf[2]; - buf[0] &= ~0x20; - buf[0] |= 0x18; - buf[1] = 0x50; - msg.len = 2; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) { - printk(KERN_WARNING "lg_h06xf: %s error " - "(addr %02x <- %02x, err = %i)\n", - __FUNCTION__, buf[0], buf[1], err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - - return 0; -} -#endif diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c deleted file mode 100644 index 9a354708bd2..00000000000 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ /dev/null @@ -1,812 +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 - * - * TODO: - * signal strength always returns 0. - * - */ - -#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 <asm/byteorder.h> - -#include "dvb_frontend.h" -#include "lgdt330x_priv.h" -#include "lgdt330x.h" - -static int debug = 0; -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; - - /* 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", __FUNCTION__, 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", __FUNCTION__, 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_lgdt3303_init_data[] = { - 0x4c, 0x14, - 0x87, 0xf3 - }; - - 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"; - if (state->config->clock_polarity_flip) { - err = i2c_write_demod_bytes(state, flip_lgdt3303_init_data, - sizeof(flip_lgdt3303_init_data)); - } else { - 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", __FUNCTION__, 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", __FUNCTION__); - - /* 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", __FUNCTION__); - - /* 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", __FUNCTION__); - - /* 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", __FUNCTION__, 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", __FUNCTION__, buf[0]); - if ((buf[0] & 0x0c) == 0x8){ - /* Test signal does not exist flag */ - /* as well as the AGC lock flag. */ - *status |= FE_HAS_SIGNAL; - } else { - /* Without a signal all other status bits are meaningless */ - return 0; - } - - /* - * 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", __FUNCTION__, 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", __FUNCTION__, 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", __FUNCTION__); - } - - 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", __FUNCTION__, 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; - } else { - /* Without a signal all other status bits are meaningless */ - return 0; - } - - /* Carrier Recovery Lock Status Register */ - i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1); - dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, 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", __FUNCTION__); - } - return 0; -} - -static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - /* not directly available. */ - *strength = 0; - return 0; -} - -static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr) -{ -#ifdef SNR_IN_DB - /* - * Spec sheet shows formula for SNR_EQ = 10 log10(25 * 24**2 / noise) - * and SNR_PH = 10 log10(25 * 32**2 / noise) for equalizer and phase tracker - * respectively. The following tables are built on these formulas. - * The usual definition is SNR = 20 log10(signal/noise) - * If the specification is wrong the value retuned is 1/2 the actual SNR in db. - * - * This table is a an ordered list of noise values computed by the - * formula from the spec sheet such that the index into the table - * starting at 43 or 45 is the SNR value in db. There are duplicate noise - * value entries at the beginning because the SNR varies more than - * 1 db for a change of 1 digit in noise at very small values of noise. - * - * Examples from SNR_EQ table: - * noise SNR - * 0 43 - * 1 42 - * 2 39 - * 3 37 - * 4 36 - * 5 35 - * 6 34 - * 7 33 - * 8 33 - * 9 32 - * 10 32 - * 11 31 - * 12 31 - * 13 30 - */ - - static const u32 SNR_EQ[] = - { 1, 2, 2, 2, 3, 3, 4, 4, 5, 7, - 9, 11, 13, 17, 21, 26, 33, 41, 52, 65, - 81, 102, 129, 162, 204, 257, 323, 406, 511, 644, - 810, 1020, 1284, 1616, 2035, 2561, 3224, 4059, 5110, 6433, - 8098, 10195, 12835, 16158, 20341, 25608, 32238, 40585, 51094, 64323, - 80978, 101945, 128341, 161571, 203406, 256073, 0x40000 - }; - - static const u32 SNR_PH[] = - { 1, 2, 2, 2, 3, 3, 4, 5, 6, 8, - 10, 12, 15, 19, 23, 29, 37, 46, 58, 73, - 91, 115, 144, 182, 229, 288, 362, 456, 574, 722, - 909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216, - 9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151, - 90833, 114351, 143960, 181235, 228161, 0x080000 - }; - - static u8 buf[5];/* read data buffer */ - static u32 noise; /* noise value */ - static u32 snr_db; /* index into SNR_EQ[] */ - struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; - - /* read both equalizer and phase tracker noise data */ - i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf)); - - if (state->current_modulation == VSB_8) { - /* Equalizer Mean-Square Error Register for VSB */ - noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2]; - - /* - * Look up noise value in table. - * A better search algorithm could be used... - * watch out there are duplicate entries. - */ - for (snr_db = 0; snr_db < sizeof(SNR_EQ); snr_db++) { - if (noise < SNR_EQ[snr_db]) { - *snr = 43 - snr_db; - break; - } - } - } else { - /* Phase Tracker Mean-Square Error Register for QAM */ - noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4]; - - /* Look up noise value in table. */ - for (snr_db = 0; snr_db < sizeof(SNR_PH); snr_db++) { - if (noise < SNR_PH[snr_db]) { - *snr = 45 - snr_db; - break; - } - } - } -#else - /* Return the raw noise value */ - static u8 buf[5];/* read data buffer */ - static u32 noise; /* noise value */ - struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; - - /* read both equalizer and pase tracker noise data */ - i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf)); - - if (state->current_modulation == VSB_8) { - /* Phase Tracker Mean-Square Error Register for VSB */ - noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4]; - } else { - - /* Carrier Recovery Mean-Square Error for QAM */ - i2c_read_demod_bytes(state, 0x1a, buf, 2); - noise = ((buf[0] & 3) << 8) | buf[1]; - } - - /* Small values for noise mean signal is better so invert noise */ - *snr = ~noise; -#endif - - dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr); - - return 0; -} - -static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr) -{ - /* Return the raw noise value */ - static u8 buf[5];/* read data buffer */ - static u32 noise; /* noise value */ - struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; - - if (state->current_modulation == VSB_8) { - - i2c_read_demod_bytes(state, 0x6e, buf, 5); - /* Phase Tracker Mean-Square Error Register for VSB */ - noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4]; - } else { - - /* Carrier Recovery Mean-Square Error for QAM */ - i2c_read_demod_bytes(state, 0x1a, buf, 2); - noise = (buf[0] << 8) | buf[1]; - } - - /* Small values for noise mean signal is better so invert noise */ - *snr = ~noise; - - dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr); - - 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",__FUNCTION__); - 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 bad903c6f0f..00000000000 --- a/drivers/media/dvb/frontends/lgdt330x.h +++ /dev/null @@ -1,64 +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; -}; - -extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, - struct i2c_adapter* i2c); - -#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 59b7c5b9012..00000000000 --- a/drivers/media/dvb/frontends/lgdt330x_priv.h +++ /dev/null @@ -1,72 +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, - EQPH_ERR0= 0x47, - EQ_ERR1= 0x48, - EQ_ERR2= 0x49, - PH_ERR1= 0x4a, - PH_ERR2= 0x4b, - DEMUX_CONTROL= 0x66, - LGDT3302_PACKET_ERR_COUNTER1= 0x6a, - LGDT3302_PACKET_ERR_COUNTER2= 0x6b, - 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/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c deleted file mode 100644 index e933edc8dd2..00000000000 --- a/drivers/media/dvb/frontends/lnbp21.c +++ /dev/null @@ -1,145 +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 - */ -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "lnbp21.h" - -struct lnbp21 { - u8 config; - u8 override_or; - u8 override_and; - struct i2c_adapter *i2c; - void (*release_chain)(struct dvb_frontend* fe); -}; - -static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; - struct i2c_msg msg = { .addr = 0x08, .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->misc_priv; - struct i2c_msg msg = { .addr = 0x08, .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) -{ - struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; - - /* LNBP power off */ - lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); - - /* free data & call next release routine */ - fe->ops.release = lnbp21->release_chain; - kfree(fe->misc_priv); - fe->misc_priv = NULL; - if (fe->ops.release) - fe->ops.release(fe); -} - -int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) -{ - struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); - if (!lnbp21) - return -ENOMEM; - - /* default configuration */ - lnbp21->config = LNBP21_ISEL; - lnbp21->i2c = i2c; - fe->misc_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); - fe->misc_priv = NULL; - return -EIO; - } - - /* install release callback */ - lnbp21->release_chain = fe->ops.release; - fe->ops.release = lnbp21_release; - - /* override frontend ops */ - fe->ops.set_voltage = lnbp21_set_voltage; - fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; - - return 0; -} -EXPORT_SYMBOL(lnbp21_attach); - -MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21"); -MODULE_AUTHOR("Oliver Endriss"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h deleted file mode 100644 index 047a4ab68c0..00000000000 --- a/drivers/media/dvb/frontends/lnbp21.h +++ /dev/null @@ -1,45 +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 */ -#define LNBP21_OLF 0x01 -#define LNBP21_OTF 0x02 -#define LNBP21_EN 0x04 -#define LNBP21_VSEL 0x08 -#define LNBP21_LLC 0x10 -#define LNBP21_TEN 0x20 -#define LNBP21_ISEL 0x40 -#define LNBP21_PCL 0x80 - -#include <linux/dvb/frontend.h> - -/* override_set and override_clear control which system register bits (above) to always set & clear */ -extern int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear); - -#endif diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c deleted file mode 100644 index 1ef82182564..00000000000 --- a/drivers/media/dvb/frontends/mt312.c +++ /dev/null @@ -1,709 +0,0 @@ -/* - Driver for Zarlink VP310/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 -*/ - -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.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; - u8 frequency; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "mt312: " args); \ - } while (0) - -#define MT312_SYS_CLK 90000000UL /* 90 MHz */ -#define MT312_LPOWER_SYS_CLK 60000000UL /* 60 MHz */ -#define MT312_PLL_CLK 10000000UL /* 10 MHz */ - -static int mt312_read(struct mt312_state* state, const enum mt312_reg_addr reg, - void *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", __FUNCTION__, ret); - return -EREMOTEIO; - } - - if(debug) { - int i; - dprintk("R(%d):", reg & 0x7f); - for (i = 0; i < count; i++) - printk(" %02x", ((const u8 *) buf)[i]); - printk("\n"); - } - - return 0; -} - -static int mt312_write(struct mt312_state* state, const enum mt312_reg_addr reg, - const void *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", ((const u8 *) 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", __FUNCTION__, 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; - - if ((ret = mt312_readreg(state, VIT_MODE, &vit_mode)) < 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]; - - if ((ret = mt312_readreg(state, SYM_RATE_H, &sym_rate_h)) < 0) - return ret; - - if (sym_rate_h & 0x80) { /* symbol rate search was used */ - if ((ret = mt312_writereg(state, MON_CTRL, 0x03)) < 0) - return ret; - - if ((ret = mt312_read(state, MONITOR_H, buf, sizeof(buf))) < 0) - return ret; - - monitor = (buf[0] << 8) | buf[1]; - - dprintk(KERN_DEBUG "sr(auto) = %u\n", - mt312_div(monitor * 15625, 4)); - } else { - if ((ret = mt312_writereg(state, MON_CTRL, 0x05)) < 0) - return ret; - - if ((ret = mt312_read(state, MONITOR_H, buf, sizeof(buf))) < 0) - return ret; - - dec_ratio = ((buf[0] >> 5) & 0x07) * 32; - - if ((ret = mt312_read(state, SYM_RAT_OP_H, buf, sizeof(buf))) < 0) - return ret; - - sym_rat_op = (buf[0] << 8) | buf[1]; - - dprintk(KERN_DEBUG "sym_rat_op=%d dec_ratio=%d\n", - sym_rat_op, dec_ratio); - dprintk(KERN_DEBUG "*sr(manual) = %lu\n", - (((MT312_PLL_CLK * 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; - - if ((ret = mt312_readreg(state, FEC_STATUS, &fec_status)) < 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 */ - if ((ret = mt312_writereg(state, CONFIG, (state->frequency == 60 ? 0x88 : 0x8c))) < 0) - return ret; - - /* wait at least 150 usec */ - udelay(150); - - /* full reset */ - if ((ret = mt312_reset(state, 1)) < 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}; - - if ((ret = mt312_write(state, VIT_SETUP, buf_def, sizeof(buf_def))) < 0) - return ret; - } - - /* SYS_CLK */ - buf[0] = mt312_div((state->frequency == 60 ? MT312_LPOWER_SYS_CLK : MT312_SYS_CLK) * 2, 1000000); - - /* DISEQC_RATIO */ - buf[1] = mt312_div(MT312_PLL_CLK, 15000 * 4); - - if ((ret = mt312_write(state, SYS_CLK, buf, sizeof(buf))) < 0) - return ret; - - if ((ret = mt312_writereg(state, SNR_THS_HIGH, 0x32)) < 0) - return ret; - - if ((ret = mt312_writereg(state, OP_CTRL, 0x53)) < 0) - return ret; - - /* TS_SW_LIM */ - buf[0] = 0x8c; - buf[1] = 0x98; - - if ((ret = mt312_write(state, TS_SW_LIM_L, buf, sizeof(buf))) < 0) - return ret; - - if ((ret = mt312_writereg(state, CS_SW_LIM, 0x69)) < 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; - - if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0) - return ret; - - if ((ret = - mt312_write(state, (0x80 | DISEQC_INSTR), c->msg, c->msg_len)) < 0) - return ret; - - if ((ret = - mt312_writereg(state, DISEQC_MODE, - (diseqc_mode & 0x40) | ((c->msg_len - 1) << 3) - | 0x04)) < 0) - return ret; - - /* set DISEQC_MODE[2:0] to zero if a return message is expected */ - if (c->msg[0] & 0x02) - if ((ret = - mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40))) < 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; - - if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0) - return ret; - - if ((ret = - mt312_writereg(state, DISEQC_MODE, - (diseqc_mode & 0x40) | mini_tab[c])) < 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; - - if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0) - return ret; - - if ((ret = - mt312_writereg(state, DISEQC_MODE, - (diseqc_mode & 0x40) | tone_tab[t])) < 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 }; - - if (v > SEC_VOLTAGE_OFF) - return -EINVAL; - - return mt312_writereg(state, DISEQC_MODE, volt_tab[v]); -} - -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; - - if ((ret = mt312_read(state, QPSK_STAT_H, status, sizeof(status))) < 0) - return ret; - - dprintk(KERN_DEBUG "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]; - - if ((ret = mt312_read(state, RS_BERCNT_H, buf, 3)) < 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; - - if ((ret = mt312_read(state, AGC_H, buf, sizeof(buf))) < 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(KERN_DEBUG "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]; - - if ((ret = mt312_read(state, M_SNR_H, &buf, sizeof(buf))) < 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]; - - if ((ret = mt312_read(state, RS_UBC_H, &buf, sizeof(buf))) < 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", __FUNCTION__, 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 tunning 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 ((config_val & 0x0c) == 0x08) { //We are running 60MHz - state->frequency = 90; - if ((ret = mt312_initfe(fe)) < 0) - return ret; - } - } - else - { - if ((config_val & 0x0c) == 0x0C) { //We are running 90MHz - state->frequency = 60; - if ((ret = mt312_initfe(fe)) < 0) - return ret; - } - } - break; - - case ID_MT312: - 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; - - if ((ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf))) < 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; - - if ((ret = mt312_get_inversion(state, &p->inversion)) < 0) - return ret; - - if ((ret = mt312_get_symbol_rate(state, &p->u.qpsk.symbol_rate)) < 0) - return ret; - - if ((ret = mt312_get_code_rate(state, &p->u.qpsk.fec_inner)) < 0) - return ret; - - return 0; -} - -static int mt312_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct mt312_state* state = fe->demodulator_priv; - - if (enable) { - return mt312_writereg(state, GPP_CTRL, 0x40); - } else { - return mt312_writereg(state, GPP_CTRL, 0x00); - } -} - -static int mt312_sleep(struct dvb_frontend* fe) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 config; - - /* reset all registers to defaults */ - if ((ret = mt312_reset(state, 1)) < 0) - return ret; - - if ((ret = mt312_readreg(state, CONFIG, &config)) < 0) - return ret; - - /* enter standby */ - if ((ret = mt312_writereg(state, CONFIG, config & 0x7f)) < 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); -} - -static struct dvb_frontend_ops vp310_mt312_ops = { - - .info = { - .name = "Zarlink ???? DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128, - .symbol_rate_min = MT312_SYS_CLK / 128, - .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* vp310_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, &vp310_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->frequency = 90; - break; - case ID_MT312: - strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S"); - state->frequency = 60; - break; - default: - printk (KERN_WARNING "Only Zarlink VP310/MT312 are supported chips.\n"); - goto error; - } - - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Zarlink VP310/MT312 DVB-S Demodulator driver"); -MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(vp310_mt312_attach); diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h deleted file mode 100644 index 666a1bd1c24..00000000000 --- a/drivers/media/dvb/frontends/mt312.h +++ /dev/null @@ -1,41 +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; -}; - -struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, - struct i2c_adapter* i2c); - - -#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 5e0b95b5337..00000000000 --- a/drivers/media/dvb/frontends/mt312_priv.h +++ /dev/null @@ -1,162 +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, - 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 -}; - -#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 5de7376c94c..00000000000 --- a/drivers/media/dvb/frontends/mt352.c +++ /dev/null @@ -1,608 +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/moduleparam.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; -} - -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", - __FUNCTION__, 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", - __FUNCTION__, 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; - - ife = (2*adc_clock - if2); - value = -16374 * ife / adc_clock; - dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n", - __FUNCTION__, 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",__FUNCTION__); - - 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, - - .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); -EXPORT_SYMBOL(mt352_write); diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h deleted file mode 100644 index 9e7ff4b8fe5..00000000000 --- a/drivers/media/dvb/frontends/mt352.h +++ /dev/null @@ -1,59 +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); -}; - -extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, - struct i2c_adapter* i2c); - -extern int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen); - -#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 87c286ee6a0..00000000000 --- a/drivers/media/dvb/frontends/nxt200x.c +++ /dev/null @@ -1,1248 +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/moduleparam.h> -#include <linux/slab.h> -#include <linux/string.h> - -#include "dvb_frontend.h" -#include "dvb-pll.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", - __FUNCTION__, addr, err); - return -EREMOTEIO; - } - return 0; -} - -static u8 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", - __FUNCTION__, addr, err); - return -EREMOTEIO; - } - return 0; -} - -static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, 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", - __FUNCTION__, state->config->demod_address, err); - return -EREMOTEIO; - } - return 0; -} - -static u8 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", - __FUNCTION__, 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", __FUNCTION__); - - /* 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", __FUNCTION__); - - /* 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", __FUNCTION__); - - /* 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", __FUNCTION__); - - 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", __FUNCTION__); - - 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", __FUNCTION__); - - 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", __FUNCTION__); - - 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", __FUNCTION__); - 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", __FUNCTION__); - 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); - } - - /* get tuning information */ - if (fe->ops.tuner_ops.calc_regs) { - fe->ops.tuner_ops.calc_regs(fe, p, buf, 5); - } - - /* 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); - - /* set input */ - if (state->config->set_pll_input) - state->config->set_pll_input(buf, 1); - break; - case VSB_8: - /* Set non-punctured clock for VSB */ - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - - /* set input */ - if (state->config->set_pll_input) - state->config->set_pll_input(buf, 0); - break; - default: - return -EINVAL; - break; - } - - /* 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 34d61735845..00000000000 --- a/drivers/media/dvb/frontends/nxt200x.h +++ /dev/null @@ -1,57 +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; - - /* used to set pll input */ - int (*set_pll_input)(u8* buf, int input); - - /* need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); -}; - -extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, - struct i2c_adapter* i2c); - -#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 d313d7dcf38..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 = 0; -#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 117031d1170..00000000000 --- a/drivers/media/dvb/frontends/nxt6000.h +++ /dev/null @@ -1,39 +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; -}; - -extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, - struct i2c_adapter* i2c); - -#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 d20ab30c1e8..00000000000 --- a/drivers/media/dvb/frontends/or51132.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM - * - * 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/moduleparam.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-pll.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; - - /* Tuner private data */ - u32 current_frequency; -}; - -static int i2c_writebytes (struct or51132_state* state, u8 reg, u8 *buf, int len) -{ - int err; - struct i2c_msg msg; - msg.addr = reg; - msg.flags = 0; - msg.len = len; - msg.buf = buf; - - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk(KERN_WARNING "or51132: i2c_writebytes error (addr %02x, err == %i)\n", reg, err); - return -EREMOTEIO; - } - - return 0; -} - -static u8 i2c_readbytes (struct or51132_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 "or51132: i2c_readbytes error (addr %02x, err == %i)\n", reg, err); - return -EREMOTEIO; - } - - return 0; -} - -static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) -{ - struct or51132_state* state = fe->demodulator_priv; - static u8 run_buf[] = {0x7F,0x01}; - u8 rec_buf[8]; - u8 cmd_buf[3]; - 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(*((u32*)fw->data)); - dprintk("FirmwareA is %i bytes\n",firmwareAsize); - firmwareBsize = le32_to_cpu(*((u32*)(fw->data+4))); - dprintk("FirmwareB is %i bytes\n",firmwareBsize); - - /* Upload firmware */ - if ((ret = i2c_writebytes(state,state->config->demod_address, - &fw->data[8],firmwareAsize))) { - printk(KERN_WARNING "or51132: load_firmware error 1\n"); - return ret; - } - msleep(1); /* 1ms */ - if ((ret = i2c_writebytes(state,state->config->demod_address, - &fw->data[8+firmwareAsize],firmwareBsize))) { - printk(KERN_WARNING "or51132: load_firmware error 2\n"); - return ret; - } - msleep(1); /* 1ms */ - - if ((ret = i2c_writebytes(state,state->config->demod_address, - run_buf,2))) { - printk(KERN_WARNING "or51132: load_firmware error 3\n"); - return ret; - } - - /* Wait at least 5 msec */ - msleep(20); /* 10ms */ - - if ((ret = i2c_writebytes(state,state->config->demod_address, - 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 */ - cmd_buf[0] = 0x10; - cmd_buf[1] = 0x10; - cmd_buf[2] = 0x00; - msleep(20); /* 20ms */ - if ((ret = i2c_writebytes(state,state->config->demod_address, - cmd_buf,3))) { - printk(KERN_WARNING "or51132: load_firmware error a\n"); - return ret; - } - - cmd_buf[0] = 0x04; - cmd_buf[1] = 0x17; - msleep(20); /* 20ms */ - if ((ret = i2c_writebytes(state,state->config->demod_address, - cmd_buf,2))) { - printk(KERN_WARNING "or51132: load_firmware error b\n"); - return ret; - } - - cmd_buf[0] = 0x00; - cmd_buf[1] = 0x00; - msleep(20); /* 20ms */ - if ((ret = i2c_writebytes(state,state->config->demod_address, - cmd_buf,2))) { - printk(KERN_WARNING "or51132: load_firmware error c\n"); - return ret; - } - - for(i=0;i<4;i++) { - msleep(20); /* 20ms */ - /* 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 = i2c_readbytes(state,state->config->demod_address, - &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); - - cmd_buf[0] = 0x10; - cmd_buf[1] = 0x00; - cmd_buf[2] = 0x00; - msleep(20); /* 20ms */ - if ((ret = i2c_writebytes(state,state->config->demod_address, - cmd_buf,3))) { - 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; - unsigned char cmd_buf[3]; - - dprintk("setmode %d\n",(int)state->current_modulation); - /* set operation mode in Receiver 1 register; */ - cmd_buf[0] = 0x04; - cmd_buf[1] = 0x01; - switch (state->current_modulation) { - case QAM_256: - case QAM_64: - case QAM_AUTO: - /* Auto-deinterleave; MPEG ser, MPEG2tr, phase noise-high*/ - cmd_buf[2] = 0x5F; - break; - case VSB_8: - /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high*/ - cmd_buf[2] = 0x50; - break; - default: - printk("setmode:Modulation set to unsupported value\n"); - }; - if (i2c_writebytes(state,state->config->demod_address, - cmd_buf,3)) { - printk(KERN_WARNING "or51132: set_mode error 1\n"); - return -1; - } - dprintk("or51132: set #1 to %02x\n", cmd_buf[2]); - - /* Set operation mode in Receiver 6 register */ - cmd_buf[0] = 0x1C; - switch (state->current_modulation) { - case QAM_AUTO: - /* REC MODE Normal Carrier Lock */ - cmd_buf[1] = 0x00; - /* Channel MODE Auto QAM64/256 */ - cmd_buf[2] = 0x4f; - break; - case QAM_256: - /* REC MODE Normal Carrier Lock */ - cmd_buf[1] = 0x00; - /* Channel MODE QAM256 */ - cmd_buf[2] = 0x45; - break; - case QAM_64: - /* REC MODE Normal Carrier Lock */ - cmd_buf[1] = 0x00; - /* Channel MODE QAM64 */ - cmd_buf[2] = 0x43; - break; - case VSB_8: - /* REC MODE inv IF spectrum, Normal */ - cmd_buf[1] = 0x03; - /* Channel MODE ATSC/VSB8 */ - cmd_buf[2] = 0x06; - break; - default: - printk("setmode: Modulation set to unsupported value\n"); - }; - msleep(20); /* 20ms */ - if (i2c_writebytes(state,state->config->demod_address, - cmd_buf,3)) { - printk(KERN_WARNING "or51132: set_mode error 2\n"); - return -1; - } - dprintk("or51132: set #6 to 0x%02x%02x\n", cmd_buf[1], cmd_buf[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; - u8 buf[2]; - - /* Receiver Status */ - buf[0]=0x04; - buf[1]=0x00; - msleep(30); /* 30ms */ - if (i2c_writebytes(state,state->config->demod_address,buf,2)) { - printk(KERN_WARNING "or51132: get_parameters write error\n"); - return -EREMOTEIO; - } - msleep(30); /* 30ms */ - if (i2c_readbytes(state,state->config->demod_address,buf,2)) { - printk(KERN_WARNING "or51132: get_parameters read error\n"); - return -EREMOTEIO; - } - switch(buf[0]) { - 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: - printk(KERN_WARNING "or51132: unknown status 0x%02x\n", - buf[0]); - 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; - unsigned char rec_buf[2]; - unsigned char snd_buf[2]; - *status = 0; - - /* Receiver Status */ - snd_buf[0]=0x04; - snd_buf[1]=0x00; - msleep(30); /* 30ms */ - if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) { - printk(KERN_WARNING "or51132: read_status write error\n"); - return -1; - } - msleep(30); /* 30ms */ - 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[1] & 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; -} - -/* log10-1 table at .5 increments from 1 to 100.5 */ -static unsigned int i100x20log10[] = { - 0, 352, 602, 795, 954, 1088, 1204, 1306, 1397, 1480, - 1556, 1625, 1690, 1750, 1806, 1858, 1908, 1955, 2000, 2042, - 2082, 2121, 2158, 2193, 2227, 2260, 2292, 2322, 2352, 2380, - 2408, 2434, 2460, 2486, 2510, 2534, 2557, 2580, 2602, 2623, - 2644, 2664, 2684, 2704, 2723, 2742, 2760, 2778, 2795, 2813, - 2829, 2846, 2862, 2878, 2894, 2909, 2924, 2939, 2954, 2968, - 2982, 2996, 3010, 3023, 3037, 3050, 3062, 3075, 3088, 3100, - 3112, 3124, 3136, 3148, 3159, 3170, 3182, 3193, 3204, 3214, - 3225, 3236, 3246, 3256, 3266, 3276, 3286, 3296, 3306, 3316, - 3325, 3334, 3344, 3353, 3362, 3371, 3380, 3389, 3397, 3406, - 3415, 3423, 3432, 3440, 3448, 3456, 3464, 3472, 3480, 3488, - 3496, 3504, 3511, 3519, 3526, 3534, 3541, 3549, 3556, 3563, - 3570, 3577, 3584, 3591, 3598, 3605, 3612, 3619, 3625, 3632, - 3639, 3645, 3652, 3658, 3665, 3671, 3677, 3683, 3690, 3696, - 3702, 3708, 3714, 3720, 3726, 3732, 3738, 3744, 3750, 3755, - 3761, 3767, 3772, 3778, 3784, 3789, 3795, 3800, 3806, 3811, - 3816, 3822, 3827, 3832, 3838, 3843, 3848, 3853, 3858, 3863, - 3868, 3874, 3879, 3884, 3888, 3893, 3898, 3903, 3908, 3913, - 3918, 3922, 3927, 3932, 3936, 3941, 3946, 3950, 3955, 3960, - 3964, 3969, 3973, 3978, 3982, 3986, 3991, 3995, 4000, 4004, -}; - -static unsigned int denom[] = {1,1,100,1000,10000,100000,1000000,10000000,100000000}; - -static unsigned int i20Log10(unsigned short val) -{ - unsigned int rntval = 100; - unsigned int tmp = val; - unsigned int exp = 1; - - while(tmp > 100) {tmp /= 100; exp++;} - - val = (2 * val)/denom[exp]; - if (exp > 1) rntval = 2000*exp; - - rntval += i100x20log10[val]; - return rntval; -} - -static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct or51132_state* state = fe->demodulator_priv; - unsigned char rec_buf[2]; - unsigned char snd_buf[2]; - u8 rcvr_stat; - u16 snr_equ; - u32 signal_strength; - int usK; - - snd_buf[0]=0x04; - snd_buf[1]=0x02; /* SNR after Equalizer */ - msleep(30); /* 30ms */ - if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) { - printk(KERN_WARNING "or51132: read_status write error\n"); - return -1; - } - msleep(30); /* 30ms */ - if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { - printk(KERN_WARNING "or51132: read_status read error\n"); - return -1; - } - snr_equ = rec_buf[0] | (rec_buf[1] << 8); - dprintk("read_signal_strength snr_equ %x %x (%i)\n",rec_buf[0],rec_buf[1],snr_equ); - - /* Receiver Status */ - snd_buf[0]=0x04; - snd_buf[1]=0x00; - msleep(30); /* 30ms */ - if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) { - printk(KERN_WARNING "or51132: read_signal_strength read_status write error\n"); - return -1; - } - msleep(30); /* 30ms */ - if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { - printk(KERN_WARNING "or51132: read_signal_strength read_status read error\n"); - return -1; - } - dprintk("read_signal_strength read_status %x %x\n",rec_buf[0],rec_buf[1]); - rcvr_stat = rec_buf[1]; - usK = (rcvr_stat & 0x10) ? 3 : 0; - - /* The value reported back from the frontend will be FFFF=100% 0000=0% */ - signal_strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000; - if (signal_strength > 0xffff) - *strength = 0xffff; - else - *strength = signal_strength; - dprintk("read_signal_strength %i\n",*strength); - - return 0; -} - -static int or51132_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct or51132_state* state = fe->demodulator_priv; - unsigned char rec_buf[2]; - unsigned char snd_buf[2]; - u16 snr_equ; - - snd_buf[0]=0x04; - snd_buf[1]=0x02; /* SNR after Equalizer */ - msleep(30); /* 30ms */ - if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) { - printk(KERN_WARNING "or51132: read_snr write error\n"); - return -1; - } - msleep(30); /* 30ms */ - if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { - printk(KERN_WARNING "or51132: read_snr dvr read error\n"); - return -1; - } - snr_equ = rec_buf[0] | (rec_buf[1] << 8); - dprintk("read_snr snr_equ %x %x (%i)\n",rec_buf[0],rec_buf[1],snr_equ); - - *snr = 0xFFFF - snr_equ; - dprintk("read_snr %i\n",*snr); - - 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) - goto error; - - /* 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; - -error: - kfree(state); - return NULL; -} - -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_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 89658883abf..00000000000 --- a/drivers/media/dvb/frontends/or51132.h +++ /dev/null @@ -1,46 +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); -}; - -extern struct dvb_frontend* or51132_attach(const struct or51132_config* config, - struct i2c_adapter* i2c); - -#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 2bf124b5368..00000000000 --- a/drivers/media/dvb/frontends/or51211.c +++ /dev/null @@ -1,636 +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/moduleparam.h> -#include <linux/device.h> -#include <linux/firmware.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <asm/byteorder.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; - - /* Tuner private data */ - u32 current_frequency; -}; - -static int i2c_writebytes (struct or51211_state* state, u8 reg, u8 *buf, - int len) -{ - int err; - struct i2c_msg msg; - msg.addr = reg; - msg.flags = 0; - msg.len = len; - msg.buf = 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 u8 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; - u32 freq = 0; - u16 tunerfreq = 0; - u8 buf[4]; - - /* Change only if we are actually changing the channel */ - if (state->current_frequency != param->frequency) { - freq = 44000 + (param->frequency/1000); - tunerfreq = freq * 16/1000; - - dprintk("set_parameters frequency = %d (tunerfreq = %d)\n", - param->frequency,tunerfreq); - - buf[0] = (tunerfreq >> 8) & 0x7F; - buf[1] = (tunerfreq & 0xFF); - buf[2] = 0x8E; - - if (param->frequency < 157250000) { - buf[3] = 0xA0; - dprintk("set_parameters VHF low range\n"); - } else if (param->frequency < 454000000) { - buf[3] = 0x90; - dprintk("set_parameters VHF high range\n"); - } else { - buf[3] = 0x30; - dprintk("set_parameters UHF range\n"); - } - dprintk("set_parameters tuner bytes: 0x%02x 0x%02x " - "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]); - - if (i2c_writebytes(state,0xC2>>1,buf,4)) - printk(KERN_WARNING "or51211:set_parameters error " - "writing to tuner\n"); - - /* 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; -} - -/* log10-1 table at .5 increments from 1 to 100.5 */ -static unsigned int i100x20log10[] = { - 0, 352, 602, 795, 954, 1088, 1204, 1306, 1397, 1480, - 1556, 1625, 1690, 1750, 1806, 1858, 1908, 1955, 2000, 2042, - 2082, 2121, 2158, 2193, 2227, 2260, 2292, 2322, 2352, 2380, - 2408, 2434, 2460, 2486, 2510, 2534, 2557, 2580, 2602, 2623, - 2644, 2664, 2684, 2704, 2723, 2742, 2760, 2778, 2795, 2813, - 2829, 2846, 2862, 2878, 2894, 2909, 2924, 2939, 2954, 2968, - 2982, 2996, 3010, 3023, 3037, 3050, 3062, 3075, 3088, 3100, - 3112, 3124, 3136, 3148, 3159, 3170, 3182, 3193, 3204, 3214, - 3225, 3236, 3246, 3256, 3266, 3276, 3286, 3296, 3306, 3316, - 3325, 3334, 3344, 3353, 3362, 3371, 3380, 3389, 3397, 3406, - 3415, 3423, 3432, 3440, 3448, 3456, 3464, 3472, 3480, 3488, - 3496, 3504, 3511, 3519, 3526, 3534, 3541, 3549, 3556, 3563, - 3570, 3577, 3584, 3591, 3598, 3605, 3612, 3619, 3625, 3632, - 3639, 3645, 3652, 3658, 3665, 3671, 3677, 3683, 3690, 3696, - 3702, 3708, 3714, 3720, 3726, 3732, 3738, 3744, 3750, 3755, - 3761, 3767, 3772, 3778, 3784, 3789, 3795, 3800, 3806, 3811, - 3816, 3822, 3827, 3832, 3838, 3843, 3848, 3853, 3858, 3863, - 3868, 3874, 3879, 3884, 3888, 3893, 3898, 3903, 3908, 3913, - 3918, 3922, 3927, 3932, 3936, 3941, 3946, 3950, 3955, 3960, - 3964, 3969, 3973, 3978, 3982, 3986, 3991, 3995, 4000, 4004, -}; - -static unsigned int denom[] = {1,1,100,1000,10000,100000,1000000,10000000,100000000}; - -static unsigned int i20Log10(unsigned short val) -{ - unsigned int rntval = 100; - unsigned int tmp = val; - unsigned int exp = 1; - - while(tmp > 100) {tmp /= 100; exp++;} - - val = (2 * val)/denom[exp]; - if (exp > 1) rntval = 2000*exp; - - rntval += i100x20log10[val]; - return rntval; -} - -static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct or51211_state* state = fe->demodulator_priv; - u8 rec_buf[2]; - u8 snd_buf[4]; - u8 snr_equ; - u32 signal_strength; - - /* SNR after Equalizer */ - snd_buf[0] = 0x04; - snd_buf[1] = 0x00; - snd_buf[2] = 0x04; - snd_buf[3] = 0x00; - - if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) { - printk(KERN_WARNING "or51211: read_status write error\n"); - return -1; - } - msleep(3); - if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { - printk(KERN_WARNING "or51211: read_status read error\n"); - return -1; - } - snr_equ = rec_buf[0] & 0xff; - - /* The value reported back from the frontend will be FFFF=100% 0000=0% */ - signal_strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000; - if (signal_strength > 0xffff) - *strength = 0xffff; - else - *strength = signal_strength; - dprintk("read_signal_strength %i\n",*strength); - - return 0; -} - -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[4]; - - /* SNR after Equalizer */ - snd_buf[0] = 0x04; - snd_buf[1] = 0x00; - snd_buf[2] = 0x04; - snd_buf[3] = 0x00; - - if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) { - printk(KERN_WARNING "or51211: read_status write error\n"); - return -1; - } - msleep(3); - if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { - printk(KERN_WARNING "or51211: read_status read error\n"); - return -1; - } - *snr = rec_buf[0] & 0xff; - - dprintk("read_snr %i\n",*snr); - - 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) - goto error; - - /* 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; - -error: - kfree(state); - return NULL; -} - -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 13a5a3afbf8..00000000000 --- a/drivers/media/dvb/frontends/or51211.h +++ /dev/null @@ -1,44 +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); -}; - -extern struct dvb_frontend* or51211_attach(const struct or51211_config* config, - struct i2c_adapter* i2c); - -#endif // OR51211_H - diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c deleted file mode 100644 index 2c2c344c4c6..00000000000 --- a/drivers/media/dvb/frontends/s5h1420.c +++ /dev/null @@ -1,835 +0,0 @@ -/* -Driver for Samsung S5H1420 QPSK Demodulator - -Copyright (C) 2005 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/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 "dvb_frontend.h" -#include "s5h1420.h" - - - -#define TONE_FREQ 22000 - -struct s5h1420_state { - struct i2c_adapter* i2c; - const struct s5h1420_config* config; - struct dvb_frontend frontend; - - u8 postlocked:1; - u32 fclk; - u32 tunedfreq; - fe_code_rate_t fec_inner; - u32 symbol_rate; -}; - -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 = 0; -#define dprintk if (debug) printk - -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; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data); - return -EREMOTEIO; - } - - return 0; -} - -static u8 s5h1420_readreg (struct s5h1420_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg1 = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }; - struct i2c_msg msg2 = { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 }; - - if ((ret = i2c_transfer (state->i2c, &msg1, 1)) != 1) - return ret; - - if ((ret = i2c_transfer (state->i2c, &msg2, 1)) != 1) - return ret; - - return b1[0]; -} - -static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - 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; - } - - return 0; -} - -static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - 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; - } - - 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; - - 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); - 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; - - 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, 0x32); - if ((val & 0x07) == 0x03) { - if (val & 0x08) - s5h1420_writereg(state, 0x31, 0x13); - else - s5h1420_writereg(state, 0x31, 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, 0x32) & 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("s5h1420: avoided division by 0\n"); - tmp = 1; - } - tmp = state->fclk / tmp; - - /* set the MPEG_CLK_INTL for the calculated data rate */ - if (tmp < 4) - val = 0x00; - else if (tmp < 8) - val = 0x01; - else if (tmp < 12) - val = 0x02; - else if (tmp < 16) - val = 0x03; - else if (tmp < 24) - val = 0x04; - else if (tmp < 32) - val = 0x05; - else - val = 0x06; - s5h1420_writereg(state, 0x22, val); - - /* DC freeze */ - s5h1420_writereg(state, 0x1f, s5h1420_readreg(state, 0x1f) | 0x01); - - /* kicker disable + remove DC offset */ - s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) & 0x6f); - - /* post-lock processing has been done! */ - state->postlocked = 1; - } - - 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) -{ - 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) -{ - u64 val; - - val = ((u64) p->u.qpsk.symbol_rate / 1000ULL) * (1ULL<<24); - if (p->u.qpsk.symbol_rate <= 21000000) { - val *= 2; - } - do_div(val, (state->fclk / 1000)); - - s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0x7f); - s5h1420_writereg(state, 0x11, val >> 16); - s5h1420_writereg(state, 0x12, val >> 8); - s5h1420_writereg(state, 0x13, val & 0xff); - s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x80); -} - -static u32 s5h1420_getsymbolrate(struct s5h1420_state* state) -{ - u64 val = 0; - int sampling = 2; - - if (s5h1420_readreg(state, 0x05) & 0x2) - sampling = 1; - - s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08); - val = s5h1420_readreg(state, 0x11) << 16; - val |= s5h1420_readreg(state, 0x12) << 8; - val |= s5h1420_readreg(state, 0x13); - s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7); - - val *= (state->fclk / 1000ULL); - do_div(val, ((1<<24) * sampling)); - - return (u32) (val * 1000ULL); -} - -static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset) -{ - int val; - - /* 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)); - - s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0xbf); - s5h1420_writereg(state, 0x0e, val >> 16); - s5h1420_writereg(state, 0x0f, val >> 8); - s5h1420_writereg(state, 0x10, val & 0xff); - s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x40); -} - -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; - - 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)) { - s5h1420_writereg(state, 0x30, 0x3f); - s5h1420_writereg(state, 0x31, 0x00 | inversion); - } else { - switch(p->u.qpsk.fec_inner) { - case FEC_1_2: - s5h1420_writereg(state, 0x30, 0x01); - s5h1420_writereg(state, 0x31, 0x10 | inversion); - break; - - case FEC_2_3: - s5h1420_writereg(state, 0x30, 0x02); - s5h1420_writereg(state, 0x31, 0x11 | inversion); - break; - - case FEC_3_4: - s5h1420_writereg(state, 0x30, 0x04); - s5h1420_writereg(state, 0x31, 0x12 | inversion); - break; - - case FEC_5_6: - s5h1420_writereg(state, 0x30, 0x08); - s5h1420_writereg(state, 0x31, 0x13 | inversion); - break; - - case FEC_6_7: - s5h1420_writereg(state, 0x30, 0x10); - s5h1420_writereg(state, 0x31, 0x14 | inversion); - break; - - case FEC_7_8: - s5h1420_writereg(state, 0x30, 0x20); - s5h1420_writereg(state, 0x31, 0x15 | inversion); - break; - - default: - return; - } - } -} - -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; - - /* 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); - } - return 0; - } - - /* first of all, software reset */ - s5h1420_reset(state); - - /* set s5h1420 fclk PLL according to desired symbol rate */ - if (p->u.qpsk.symbol_rate > 28000000) { - state->fclk = 88000000; - s5h1420_writereg(state, 0x03, 0x50); - s5h1420_writereg(state, 0x04, 0x40); - s5h1420_writereg(state, 0x05, 0xae); - } else if (p->u.qpsk.symbol_rate > 21000000) { - state->fclk = 59000000; - s5h1420_writereg(state, 0x03, 0x33); - s5h1420_writereg(state, 0x04, 0x40); - s5h1420_writereg(state, 0x05, 0xae); - } else { - state->fclk = 88000000; - s5h1420_writereg(state, 0x03, 0x50); - s5h1420_writereg(state, 0x04, 0x40); - s5h1420_writereg(state, 0x05, 0xac); - } - - /* set misc registers */ - s5h1420_writereg(state, 0x02, 0x00); - s5h1420_writereg(state, 0x06, 0x00); - s5h1420_writereg(state, 0x07, 0xb0); - s5h1420_writereg(state, 0x0a, 0xe7); - s5h1420_writereg(state, 0x0b, 0x78); - s5h1420_writereg(state, 0x0c, 0x48); - s5h1420_writereg(state, 0x0d, 0x6b); - s5h1420_writereg(state, 0x2e, 0x8e); - s5h1420_writereg(state, 0x35, 0x33); - s5h1420_writereg(state, 0x38, 0x01); - s5h1420_writereg(state, 0x39, 0x7d); - s5h1420_writereg(state, 0x3a, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32)); - s5h1420_writereg(state, 0x3c, 0x00); - s5h1420_writereg(state, 0x45, 0x61); - s5h1420_writereg(state, 0x46, 0x1d); - - /* start QPSK */ - s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1); - - /* 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); - - state->fec_inner = p->u.qpsk.fec_inner; - state->symbol_rate = p->u.qpsk.symbol_rate; - state->postlocked = 0; - state->tunedfreq = p->frequency; - 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, s5h1420_readreg(state,0x02) | 1); - } else { - return s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe); - } -} - -static int s5h1420_init (struct dvb_frontend* fe) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - /* disable power down and do reset */ - s5h1420_writereg(state, 0x02, 0x10); - msleep(10); - s5h1420_reset(state); - - return 0; -} - -static int s5h1420_sleep(struct dvb_frontend* fe) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - return s5h1420_writereg(state, 0x02, 0x12); -} - -static void s5h1420_release(struct dvb_frontend* fe) -{ - struct s5h1420_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops s5h1420_ops; - -struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, - struct i2c_adapter* i2c) -{ - struct s5h1420_state* state = NULL; - u8 identity; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct s5h1420_state), GFP_KERNEL); - 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 */ - identity = s5h1420_readreg(state, 0x00); - if (identity != 0x03) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops s5h1420_ops = { - - .info = { - .name = "Samsung S5H1420 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_param(debug, int, 0644); - -MODULE_DESCRIPTION("Samsung S5H1420 DVB-S Demodulator driver"); -MODULE_AUTHOR("Andrew de Quincey"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(s5h1420_attach); diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h deleted file mode 100644 index 4e39015fa67..00000000000 --- a/drivers/media/dvb/frontends/s5h1420.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Driver for S5H1420 QPSK Demodulators - - Copyright (C) 2005 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 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; -}; - -extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, - struct i2c_adapter* i2c); - -#endif // S5H1420_H diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c deleted file mode 100644 index d98fd5c2e13..00000000000 --- a/drivers/media/dvb/frontends/sp8870.c +++ /dev/null @@ -1,620 +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/moduleparam.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", __FUNCTION__, 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", __FUNCTION__, 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; - char *fw_buf = fw->data; - int fw_pos; - u8 tx_buf[255]; - int tx_len; - int err = 0; - - dprintk ("%s: ...\n", __FUNCTION__); - - 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", __FUNCTION__); - printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err); - return err; - } - fw_pos += tx_len; - } - - dprintk ("%s: done!\n", __FUNCTION__); - 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", __FUNCTION__); - - - /* 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 = 0; -// only for debugging: counter for channel switches -static int switches = 0; - -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", __FUNCTION__, 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", - __FUNCTION__, check_count * 10); - break; - } - udelay(10); - } - if (valid) - break; - } - - if (!valid) { - printk("%s: firmware crash!!!!!!\n", __FUNCTION__); - return -EIO; - } - - if (debug) { - if (valid) { - if (trials > 1) { - printk("%s: firmware lockup!!!\n", __FUNCTION__); - printk("%s: recovered after %i trial(s))\n", __FUNCTION__, trials - 1); - lockups++; - } - } - switches++; - printk("%s: switches = %i lockups = %i\n", __FUNCTION__, 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 93afbb969d6..00000000000 --- a/drivers/media/dvb/frontends/sp8870.h +++ /dev/null @@ -1,41 +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); -}; - -extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, - struct i2c_adapter* i2c); - -#endif // SP8870_H diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c deleted file mode 100644 index 5c2f8f4e0ae..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/moduleparam.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", - __FUNCTION__, 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", - __FUNCTION__, 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", __FUNCTION__, ret); - return -1; - } - - return (((b1[0] << 8) | b1[1]) & 0xfff); -} - -static void sp887x_microcontroller_stop (struct sp887x_state* state) -{ - dprintk("%s\n", __FUNCTION__); - 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", __FUNCTION__); - 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", __FUNCTION__); - 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; - unsigned char *mem = fw->data; - - dprintk("%s\n", __FUNCTION__); - - /* 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... ", __FUNCTION__); - - /* 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", __FUNCTION__, 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; - int actual_freq, 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 c44b0ebdf1e..00000000000 --- a/drivers/media/dvb/frontends/sp887x.h +++ /dev/null @@ -1,23 +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); -}; - -extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, - struct i2c_adapter* i2c); - -#endif // SP887X_H diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c deleted file mode 100644 index 1ca64249010..00000000000 --- a/drivers/media/dvb/frontends/stv0297.c +++ /dev/null @@ -1,700 +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 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", __FUNCTION__, 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", __FUNCTION__, reg, ret); - return -1; - } - if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); - return -1; - } - } else { - if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, 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", __FUNCTION__, reg1, ret); - return -1; - } - if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); - return -1; - } - } else { - if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, 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); - - 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_writereg(state, 0xA0, 0x80); // Start Counting bit errors for 4096 Bytes - mdelay(25); // Hopefully got 4096 Bytes - stv0297_readregs(state, 0xA0, BER, 3); - mdelay(25); - *ber = (BER[2] << 8 | BER[1]) / (8 * 4096); - - return 0; -} - - -static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength) -{ - struct stv0297_state *state = fe->demodulator_priv; - u8 STRENGTH[2]; - - stv0297_readregs(state, 0x41, STRENGTH, 2); - *strength = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0]; - - 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; - - *ucblocks = (stv0297_readreg(state, 0xD5) << 8) - | stv0297_readreg(state, 0xD4); - - 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->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 = 64000000, - .frequency_max = 1300000000, - .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 1da5384fb98..00000000000 --- a/drivers/media/dvb/frontends/stv0297.h +++ /dev/null @@ -1,48 +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; -}; - -extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, - struct i2c_adapter* i2c); - -#endif // STV0297_H diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c deleted file mode 100644 index 96648a75440..00000000000 --- a/drivers/media/dvb/frontends/stv0299.c +++ /dev/null @@ -1,728 +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/moduleparam.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; -}; - -#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", __FUNCTION__, reg, data, ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data) -{ - struct stv0299_state* state = fe->demodulator_priv; - - return stv0299_writeregI(state, reg, data); -} - -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", - __FUNCTION__, 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", __FUNCTION__, ret); - - return ret == 2 ? 0 : ret; -} - -static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) -{ - dprintk ("%s\n", __FUNCTION__); - - 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", __FUNCTION__); - - 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", __FUNCTION__); - - while (stv0299_readreg(state, 0x0a) & 1) { - if (jiffies - start > timeout) { - dprintk ("%s: timeout!!\n", __FUNCTION__); - 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", __FUNCTION__); - - while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) { - if (jiffies - start > timeout) { - dprintk ("%s: timeout!!\n", __FUNCTION__); - 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", __FUNCTION__); - - stv0299_readregs (state, 0x1f, sfr, 3); - stv0299_readregs (state, 0x1a, &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", __FUNCTION__, srate); - dprintk ("%s : ofset = %i\n", __FUNCTION__, 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", __FUNCTION__); - - 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", __FUNCTION__); - - 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", __FUNCTION__, - 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; - - if (voltage == SEC_VOLTAGE_OFF) { - stv0299_writeregI (state, 0x0c, 0x00); /* LNB power off! */ - return stv0299_writeregI (state, 0x08, 0x00); /* LNB power off! */ - } - - stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6)); - - switch (voltage) { - case SEC_VOLTAGE_13: - if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0) reg0x0c |= 0x10; - else reg0x0c |= 0x40; - - return stv0299_writeregI(state, 0x0c, reg0x0c); - - case SEC_VOLTAGE_18: - return stv0299_writeregI(state, 0x0c, reg0x0c | 0x50); - default: - return -EINVAL; - }; -} - -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",__FUNCTION__, 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", - __FUNCTION__, 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; - - dprintk("stv0299: init chip\n"); - - for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2) - stv0299_writeregI(state, state->config->inittab[i], state->config->inittab[i+1]); - - 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", __FUNCTION__, 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 0; - *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); - - 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", __FUNCTION__, - 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) *ucblocks = 0; - else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); - - 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", __FUNCTION__); - - // 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, - .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_writereg); -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 1504828e423..00000000000 --- a/drivers/media/dvb/frontends/stv0299.h +++ /dev/null @@ -1,97 +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 STV0229_LOCKOUTPUT_0 0 -#define STV0229_LOCKOUTPUT_1 1 -#define STV0229_LOCKOUTPUT_CF 2 -#define STV0229_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; - - /* minimum delay before retuning */ - int min_delay_ms; - - /* Set the symbol rate */ - int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); -}; - -extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); - -extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, - struct i2c_adapter* i2c); - -#endif // STV0299_H diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c deleted file mode 100644 index 9cbd164aa28..00000000000 --- a/drivers/media/dvb/frontends/tda10021.c +++ /dev/null @@ -1,481 +0,0 @@ -/* - TDA10021 - 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. -*/ - -#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 "tda10021.h" - - -struct tda10021_state { - struct i2c_adapter* i2c; - /* configuration settings */ - const struct tda10021_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 DISABLE_INVERSION(reg0) do { reg0 |= 0x20; } while (0) -#define ENABLE_INVERSION(reg0) do { reg0 &= ~0x20; } while (0) -#define HAS_INVERSION(reg0) (!(reg0 & 0x20)) - -#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, 0xa0, 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, __FUNCTION__, reg, data, ret); - - msleep(10); - return (ret != 1) ? -EREMOTEIO : 0; -} - -int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data) -{ - struct tda10021_state* state = fe->demodulator_priv; - - return tda10021_writereg(state, reg, data); -} -EXPORT_SYMBOL(tda10021_write_byte); - -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); - if (ret != 2) - printk("DVB: TDA10021: %s: readreg error (ret == %i)\n", - __FUNCTION__, 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) - ENABLE_INVERSION(reg0); - else if (INVERSION_OFF == inversion) - DISABLE_INVERSION(reg0); - - 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; - - //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); - *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 gain = tda10021_readreg(state, 0x17); - *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 = HAS_INVERSION(state->reg0) ? 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 tda10021_config* config, - struct i2c_adapter* i2c, - u8 pwm) -{ - struct tda10021_state* state = NULL; - - /* 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 */ - if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; - - /* 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 = 51000000, - .frequency_max = 858000000, - .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/tda10021.h b/drivers/media/dvb/frontends/tda10021.h deleted file mode 100644 index b1df4259bee..00000000000 --- a/drivers/media/dvb/frontends/tda10021.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - TDA10021 - 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 TDA10021_H -#define TDA10021_H - -#include <linux/dvb/frontend.h> - -struct tda10021_config -{ - /* the demodulator's i2c address */ - u8 demod_address; -}; - -extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, - struct i2c_adapter* i2c, u8 pwm); - -extern int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data); - -#endif // TDA10021_H diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c deleted file mode 100644 index 59a2ed614fc..00000000000 --- a/drivers/media/dvb/frontends/tda1004x.c +++ /dev/null @@ -1,1326 +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/moduleparam.h> -#include <linux/device.h> -#include <linux/jiffies.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "tda1004x.h" - -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; -}; - -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", __FUNCTION__, 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", - __FUNCTION__, reg, data, ret); - - dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__, - 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", __FUNCTION__, 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", __FUNCTION__, reg, - ret); - return -1; - } - - dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__, - 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", __FUNCTION__, 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", __FUNCTION__, 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", __FUNCTION__); - - 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", __FUNCTION__); - - 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, - 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", __FUNCTION__, 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", __FUNCTION__); - tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 - } else { - dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__); - 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; - const struct firmware *fw; - - /* reset + wake up chip */ - if (state->config->xtal_freq == TDA10046_XTAL_4M) { - tda1004x_write_byteI(state, TDA1004X_CONFC4, 0); - } else { - dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __FUNCTION__); - tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); - } - tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); - /* let the clocks recover from sleep */ - msleep(5); - - /* The PLLs need to be reprogrammed after sleep */ - tda10046_init_plls(fe); - - /* don't re-upload unless necessary */ - if (tda1004x_check_upload_ok(state) == 0) - return 0; - - 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) { - printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); - return ret; - } - 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); - if (ret) - return ret; - } else { - /* boot from firmware eeprom */ - printk(KERN_INFO "tda1004x: booting from eeprom\n"); - tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); - msleep(300); - } - 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; -} - -int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data) -{ - struct tda1004x_state* state = fe->demodulator_priv; - - return tda1004x_write_byteI(state, reg, data); -} - -static int tda10045_init(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - - dprintk("%s\n", __FUNCTION__); - - 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", __FUNCTION__); - - 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_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities - break; - case TDA10046_AGC_IFO_AUTO_NEG: - tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup - tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities - break; - case TDA10046_AGC_IFO_AUTO_POS: - tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup - tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 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_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities - break; - case TDA10046_AGC_TDA827X_GPL: - 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_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities - break; - } - tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); - tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs 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 - tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); - - 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", __FUNCTION__); - - 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", __FUNCTION__); - - // 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", __FUNCTION__); - - // 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", __FUNCTION__, *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", __FUNCTION__); - - // 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", __FUNCTION__, *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", __FUNCTION__); - - // 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", __FUNCTION__, *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", __FUNCTION__); - - // 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", __FUNCTION__, *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", __FUNCTION__); - - // 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", __FUNCTION__, *ber); - return 0; -} - -static int tda1004x_sleep(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - - 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); - 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, - .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; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); - if (!state) - return NULL; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->demod_type = TDA1004X_DEMOD_TDA10045; - - /* check if the demod is there */ - if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) { - 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, - .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; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); - if (!state) - return NULL; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->demod_type = TDA1004X_DEMOD_TDA10046; - - /* check if the demod is there */ - if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) { - 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); -EXPORT_SYMBOL(tda1004x_write_byte); diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h deleted file mode 100644 index b877b23ed73..00000000000 --- a/drivers/media/dvb/frontends/tda1004x.h +++ /dev/null @@ -1,82 +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 */ - TDA10046_AGC_TDA827X_GPL, /* same as above, but GPIOs 0 */ -}; - -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 */ -}; - -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; - - /* Xtal frequency, 4 or 16MHz*/ - enum tda10046_xtal xtal_freq; - - /* IF frequency */ - enum tda10046_if if_freq; - - /* AGC configuration */ - enum tda10046_agc agc_config; - - /* request firmware for device */ - /* set this to NULL if the card has a firmware EEPROM */ - int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); -}; - -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); - -extern int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data); - -#endif // TDA1004X_H diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c deleted file mode 100644 index 3aa45ebbac3..00000000000 --- a/drivers/media/dvb/frontends/tda8083.c +++ /dev/null @@ -1,457 +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/moduleparam.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", - __FUNCTION__, 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", - __FUNCTION__, 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 & 0x1f) == 0x1f) - *status |= FE_HAS_LOCK; - - 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_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 = 950000, /* FIXME: guessed! */ - .frequency_max = 1400000, /* FIXME: guessed! */ - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - /* .frequency_tolerance = ???,*/ - .symbol_rate_min = 1000000, /* FIXME: guessed! */ - .symbol_rate_max = 45000000, /* FIXME: guessed! */ - /* .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, - - .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 e7a48f61ea2..00000000000 --- a/drivers/media/dvb/frontends/tda8083.h +++ /dev/null @@ -1,41 +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; -}; - -extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, - struct i2c_adapter* i2c); - -#endif // TDA8083_H diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c deleted file mode 100644 index 9b57576bfeb..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, 0x12, 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", __FUNCTION__, 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", __FUNCTION__, 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 = 51000000, - .frequency_max = 858000000, - .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 520f09522fb..00000000000 --- a/drivers/media/dvb/frontends/ves1820.h +++ /dev/null @@ -1,47 +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; -}; - -extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, - struct i2c_adapter* i2c, u8 pwm); - -#endif // VES1820_H diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c deleted file mode 100644 index 54d7b07571b..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 = 0; -#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", __FUNCTION__, 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", __FUNCTION__, (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", __FUNCTION__); - - 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 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 ba88ae0855c..00000000000 --- a/drivers/media/dvb/frontends/ves1x93.h +++ /dev/null @@ -1,46 +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; -}; - -extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, - struct i2c_adapter* i2c); - -#endif // VES1X93_H diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c deleted file mode 100644 index 2b95e8b6cd3..00000000000 --- a/drivers/media/dvb/frontends/zl10353.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Driver for Zarlink DVB-T ZL10353 demodulator - * - * Copyright (C) 2006 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/moduleparam.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.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; -}; - -static int debug_regs = 0; - -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; -} - -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", - __FUNCTION__, 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 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; - - u8 pllbuf[6] = { 0x67 }; - - /* These settings set "auto-everything" and start the FSM. */ - zl10353_single_write(fe, 0x55, 0x80); - udelay(200); - zl10353_single_write(fe, 0xEA, 0x01); - udelay(200); - zl10353_single_write(fe, 0xEA, 0x00); - - zl10353_single_write(fe, 0x56, 0x28); - zl10353_single_write(fe, 0x89, 0x20); - zl10353_single_write(fe, 0x5E, 0x00); - zl10353_single_write(fe, 0x65, 0x5A); - zl10353_single_write(fe, 0x66, 0xE9); - zl10353_single_write(fe, 0x62, 0x0A); - - // if there is no attached secondary tuner, we call set_params to program - // a potential tuner attached somewhere else - 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); - } - } - - // if pllbuf is defined, retrieve the settings - if (fe->ops.tuner_ops.calc_regs) { - fe->ops.tuner_ops.calc_regs(fe, param, pllbuf+1, 5); - pllbuf[1] <<= 1; - } else { - // fake pllbuf settings - pllbuf[1] = 0x61 << 1; - pllbuf[2] = 0; - pllbuf[3] = 0; - pllbuf[3] = 0; - pllbuf[4] = 0; - } - - // there is no call to _just_ start decoding, so we send the pllbuf anyway - // even if there isn't a PLL attached to the secondary bus - zl10353_write(fe, pllbuf, sizeof(pllbuf)); - - zl10353_single_write(fe, 0x70, 0x01); - udelay(250); - zl10353_single_write(fe, 0xE4, 0x00); - zl10353_single_write(fe, 0xE5, 0x2A); - zl10353_single_write(fe, 0xE9, 0x02); - zl10353_single_write(fe, 0xE7, 0x40); - zl10353_single_write(fe, 0xE8, 0x10); - - 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_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_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); - - /* Do a "hard" reset if not already done */ - if (zl10353_read_register(state, 0x50) != 0x03) { - rc = zl10353_write(fe, zl10353_reset_attach, - sizeof(zl10353_reset_attach)); - if (debug_regs) - zl10353_dump_regs(fe); - } - - return 0; -} - -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; - - /* 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 */ - if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353) - 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, - - .set_frontend = zl10353_set_parameters, - .get_tune_settings = zl10353_get_tune_settings, - - .read_status = zl10353_read_status, - .read_snr = zl10353_read_snr, -}; - -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); -EXPORT_SYMBOL(zl10353_write); diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h deleted file mode 100644 index 9770cb840cf..00000000000 --- a/drivers/media/dvb/frontends/zl10353.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Driver for Zarlink DVB-T ZL10353 demodulator - * - * Copyright (C) 2006 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; - - /* set if no pll is connected to the secondary i2c bus */ - int no_tuner; -}; - -extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, - struct i2c_adapter *i2c); - -extern int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen); - -#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 b72224bd7dd..00000000000 --- a/drivers/media/dvb/frontends/zl10353_priv.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Driver for Zarlink DVB-T ZL10353 demodulator - * - * Copyright (C) 2006 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 - -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, - SNR = 0x10, - CHIP_ID = 0x7F, -}; - -#endif /* _ZL10353_PRIV_ */ |
