From 930f7c234a59cde31e520dc99f89314ba37f4d33 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 29 Mar 2008 21:15:19 +0100 Subject: Remove obsolete STV0297 module for CableStar2 From: Patrick Boettcher The support for the CableStar2 has been merge to the main stv0297-module - so this is obsolete. Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/b2c2/Makefile | 4 - linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 15 - linux/drivers/media/dvb/b2c2/stv0297_cs2.c | 774 ------------------------ linux/drivers/media/dvb/b2c2/stv0297_cs2.h | 51 -- linux/drivers/media/dvb/b2c2/stv0297_priv.h | 154 ----- 5 files changed, 998 deletions(-) delete mode 100644 linux/drivers/media/dvb/b2c2/stv0297_cs2.c delete mode 100644 linux/drivers/media/dvb/b2c2/stv0297_cs2.h delete mode 100644 linux/drivers/media/dvb/b2c2/stv0297_priv.h (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/b2c2/Makefile b/linux/drivers/media/dvb/b2c2/Makefile index d845f88e8..870e2848c 100644 --- a/linux/drivers/media/dvb/b2c2/Makefile +++ b/linux/drivers/media/dvb/b2c2/Makefile @@ -2,10 +2,6 @@ b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \ flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o -ifdef STV0297_CS2 -obj-$(CONFIG_DVB_B2C2_FLEXCOP) += stv0297_cs2.o - -endif ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),) b2c2-flexcop-objs += flexcop-dma.o diff --git a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 2a7cb6eb2..441ffdf0d 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -13,11 +13,7 @@ #include "mt352.h" #include "nxt200x.h" #include "bcm3510.h" -#ifdef STV0297_CS2 -#include "stv0297_cs2.h" -#else #include "stv0297.h" -#endif #include "mt312.h" #include "lgdt330x.h" #include "dvb-pll.h" @@ -399,7 +395,6 @@ static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, return 0; } -#ifndef STV0297_CS2 static u8 alps_tdee4_stv0297_inittab[] = { 0x80, 0x01, 0x80, 0x00, @@ -472,18 +467,12 @@ static u8 alps_tdee4_stv0297_inittab[] = { 0xdf, 0x01, 0xff, 0xff, }; -#endif static struct stv0297_config alps_tdee4_stv0297_config = { .demod_address = 0x1c, -#ifdef STV0297_CS2 - .fclk = STV0297_PAL_FCLK, - .demodfreq = STV0297_PAL_IF - STV0297_PAL_FCLK, -#else .inittab = alps_tdee4_stv0297_inittab, // .invert = 1, // .pll_set = alps_tdee4_stv0297_pll_set, -#endif }; /* try to figure out the frontend, each card/box can have on of the following list */ @@ -530,11 +519,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address); } else /* try the cable dvb (stv0297) */ -#ifdef STV0297_CS2 - if ((fc->fe = dvb_attach(stv0297_cs2_attach, &alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) { -#else if ((fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) { -#endif fc->dev_type = FC_CABLE; fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address); diff --git a/linux/drivers/media/dvb/b2c2/stv0297_cs2.c b/linux/drivers/media/dvb/b2c2/stv0297_cs2.c deleted file mode 100644 index 826231164..000000000 --- a/linux/drivers/media/dvb/b2c2/stv0297_cs2.c +++ /dev/null @@ -1,774 +0,0 @@ -/* - * Driver for the DVB-C STV0297 demodulator - * - * a special, temporary version for the CableStar2 which can hopefully be - * rewritten to be used with the other stv0297-based cards - * - * Copyright (C) 2005 Patrick Boettcher - * - * Copyright (C) 2004 Andrew de Quincey - * - * Copyright (C) 2003-2004 Dennis Noermann - * - * This program is free software; 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. - * - * Changelog 2005-03-24 - revamp in order to get the CableStar2 working - * (thanks to John Jurrius, BBTI Inc.) - */ - -#include -#include -#include -#include - -#include "dvb_frontend.h" - -#include "stv0297_cs2.h" - -#include "stv0297_priv.h" - -struct stv0297_state { - struct i2c_adapter *i2c; - const struct stv0297_config *config; - struct dvb_frontend frontend; - - int invert; - u32 lastber; - unsigned long base_freq; -}; - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=calc (|-able))."); - -#define dprintk(level,x...) if (level & debug) printk(x) -#define dbufout(b,l) if (debug & 0x02) {\ - int i; \ - for (i = 0; i < l; i++) \ - deb_i2c("%02x ",b[i]); \ -} -#define deb_info(args...) dprintk(0x01,args) -#define deb_i2c(args...) dprintk(0x02,args) -#define deb_calc(args...) dprintk(0x04,args) - -#define abs64(x) (x) < 0 ? -(x) : (x); -static s64 div64(s64 dividend,s64 divisor) -{ - s64 rdiv,remainder,result=0,i; - s64 divbits,valbits; - s64 neg = 0; - - if (divisor == 0) - return 0; - - if (dividend < 0) - neg = !neg; - if (divisor < 0) - neg = !neg; - - dividend = abs64(dividend); - divisor = abs64(divisor); - - deb_calc("%Ld / %Ld\n",dividend,divisor); - - for (i = 1,divbits = 0; i < divisor; i *= 2, divbits++); - for (i = 1,valbits = 0; i < dividend; i *= 2, valbits++); - - rdiv = divisor << (valbits-divbits); - for (i = valbits; i >= divbits; i--) { - result <<= 1; - if (dividend >= rdiv) { - result |= 1; - dividend -= rdiv; - } - rdiv >>= 1; - } - remainder = dividend; - if (neg) - return -result; - else - return result; -} - -static int stv0297_writeregsI(struct stv0297_state *state, u8 reg1, u8 *b, u8 len) -{ - int ret; - u8 buf[len+1]; - struct i2c_msg msg = { - .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = len+1 - }; - - deb_i2c("wr: %02x ",reg1); - dbufout(b,len); - deb_i2c("\n"); - - buf[0] = reg1; - memcpy(&buf[1],b,len); - - if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) - deb_info("%s: writereg error (reg == 0x%02x, datalen == %d, " - "ret == %i)\n", __FUNCTION__, reg1, len, ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static int stv0297_writeregI(struct stv0297_state *state, u8 reg, u8 data) -{ - return stv0297_writeregsI(state,reg,&data,1); -} - -static int stv0297_readregsI(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} - }; - - /* the Nexus-CA needs a STOP between the register and data, but this breaks - * the common i2c-routine, where you have 2 i2c-message in a package - * when doing a read operation TODO - */ - - if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - deb_info("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); - return -EREMOTEIO; - } - - deb_i2c("rd: %02x ",reg1); - dbufout(b,len); - deb_i2c("\n"); - - /* - if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { - deb_info("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); - return -1; - }*/ - - return 0; -} - - -static int stv0297_readregI(struct stv0297_state *state, u8 reg) -{ - int ret; - u8 b[] = { 0 }; - - if ((ret = stv0297_readregsI(state,reg,b,1)) < 0) - return ret; - - return b[0]; -} - -static int stv0297_writereg_maskI(struct stv0297_state *state, u8 reg, u8 mask, u8 data) -{ - int val; - - if ((val = stv0297_readregI(state, reg)) < 0) - return val; - val &= ~mask; - val |= (data & mask); - return stv0297_writeregI(state, reg, val); -} - - -static void stv0297_set_symbolrate(struct stv0297_state *state, u32 srate) -{ - u64 tmp = div64(((u64) srate) << 32,state->config->fclk); - deb_info("symbolrate: %u, regval: %016Lx\n",srate,tmp ); - - stv0297_writeregI(state, ST_LOOP5, tmp & 0xFF); - stv0297_writeregI(state, ST_LOOP6, tmp >> 8); - stv0297_writeregI(state, ST_LOOP7, tmp >> 16); - stv0297_writeregI(state, ST_LOOP8, tmp >> 24); -} - -static u32 stv0297_get_symbolrate(struct stv0297_state *state) -{ - u64 tmp; - tmp = stv0297_readregI(state, ST_LOOP5); - tmp |= stv0297_readregI(state, ST_LOOP6) << 8; - tmp |= stv0297_readregI(state, ST_LOOP7) << 16; - tmp |= stv0297_readregI(state, ST_LOOP8) << 24; - - tmp *= state->config->fclk; - tmp >>= 32; - return (u32) tmp; -} - - -static void stv0297_set_crl(struct stv0297_state *state, struct dvb_frontend_parameters *p, s32 car_offset) -{ - u8 crlbuf[10] = { 0 }; - u32 sweeprate,iphase; - u64 tmp; - u16 sweepvalue; - - if (p->u.qam.symbol_rate < 2000000UL) sweeprate = 80000UL; - else if (p->u.qam.symbol_rate < 3500000UL) sweeprate = 200000UL; - else if (p->u.qam.symbol_rate < 4500000UL) sweeprate = 800000UL; - else sweeprate = 1000000UL; - - tmp = div64(((u64) sweeprate) << 29, p->u.qam.symbol_rate); - sweepvalue = div64(tmp,1000000UL); - if (sweepvalue & 1) - sweepvalue += 2; /* round up, adjust */ - sweepvalue >>=1; - - deb_calc("symbol_rate: %u, sweeprate: %u, sweepvalue: %u (%x)\n",p->u.qam.symbol_rate,sweeprate,sweepvalue,sweepvalue); - - crlbuf[0] = sweepvalue & 0xff; - crlbuf[9] = (sweepvalue >> 4) & 0xf0; - - if (p->u.qam.modulation == QAM_256) - crlbuf[1] = 0x58; - else - crlbuf[1] = 0x49; - - crlbuf[2] = 0x0a; - crlbuf[3] = crlbuf[4] = crlbuf[5] = 0x00; - - /* carrier offset */ - if (p->u.qam.modulation == QAM_16) - iphase = 0; - else - iphase = div64(((u64) car_offset) << 28, p->u.qam.symbol_rate); - - deb_calc("symbol_rate: %u, car_offset %d, iphase: %u (%x)\n",p->u.qam.symbol_rate,car_offset,iphase,iphase); - crlbuf[6] = iphase & 0xff; - crlbuf[7] = (iphase >> 8) & 0xff; - crlbuf[8] = (iphase >> 16) & 0xff; - crlbuf[9] |= (iphase >> 24) & 0x0f; - - stv0297_writeregsI(state,CRL_0,crlbuf,sizeof(crlbuf)); -} - -/* -static long stv0297_get_carrieroffset(struct stv0297_state *state) -{ - s64 tmp; - - stv0297_writeregI(state, CRL_11, 0x00); - - tmp = stv0297_readregI(state, CRL_6); - tmp |= (stv0297_readregI(state, CRL_7) << 8); - tmp |= (stv0297_readregI(state, CRL_8) << 16); - tmp |= (stv0297_readregI(state, CRL_9) & 0x0F) << 24; - - tmp *= stv0297_get_symbolrate(state); - tmp >>= 28; - - return (s32) tmp; -} -*/ - -static int stv0297_set_modulation(struct stv0297_state *state, fe_modulation_t modulation) -{ - int val = stv0297_readregI(state,EQU_0) & STV0297_CLEARQAM; - switch (modulation) { - case QAM_16: val = STV0297_QAM16; break; - case QAM_32: val = STV0297_QAM32; break; - case QAM_64: val = STV0297_QAM64; break; - case QAM_128: val = STV0297_QAM128; break; - case QAM_256: val = STV0297_QAM256; break; - default: return -EINVAL; - } - stv0297_writeregI(state, EQU_0, val); - 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_maskI(state, CTRL_3, 0x08, val << 3); - return 0; -} - -int stv0297_cs2_enable_plli2c(struct dvb_frontend *fe) -{ - struct stv0297_state *state = fe->demodulator_priv; - - stv0297_writeregI(state, CTRL_7, 0x78); - stv0297_writeregI(state, CTRL_6, 0xc8); - - return 0; -} - -static int stv0297_init(struct dvb_frontend *fe) -{ - struct stv0297_state *state = fe->demodulator_priv; - - state->invert = 0; - return 0; -} - -static int stv0297_reset(struct dvb_frontend *fe) -{ - struct stv0297_state *state = fe->demodulator_priv; - - /* soft reset */ - stv0297_writeregI(state, CTRL_0, 0x01); - stv0297_writeregI(state, CTRL_0, 0x00); - - /* reset deinterleaver */ - stv0297_writeregI(state, CTRL_1, 0x01); - stv0297_writeregI(state, CTRL_1, 0x00); - - /* device specific initialization here */ -/* state->config_struct->demod_init(fe); */ - - /* this is the initialization for the CableStar, maybe it works for other too */ - { - u8 equ0[] = { 0x48, 0x58 }; /* QAM64, for QAM256: { 0x3a, 0x8a } */ - u8 equ3[] = { 0x00, 0x00 }; - u8 equ7[] = { 0x00, 0x00 }; - u8 delagc[] = { 0xff, /* gold, original: 0x6b or 0x54 */ - 0x9d, 0xff, /* ALPS, MT203x: 0x54 (Gold) 0xb5 */ - 0x00, /* gold, original: 0x44 or 0xff, 0xb0, 0x8b */ - 0x29, /* original, or 0x00, 0x07, 0xb3 */ - 0x55, /* gold */ - 0x80, /* original */ - 0x6e, 0x9c }; - u8 wbagc0[] = { 0x1a, 0xfe, 0x33, 0x00 /* original */, 0xff, 0x00, 0x00 }; - u8 wbagc9[] = { 0x04, 0x51, 0xf8 }; -#define GAIN_PATH0 0x01 -#define GAIN_PATH1 0x04 -#define INTEGRAL_GAIN_HI 0X0 -#define INTEGRAL_GAIN_LO 0X06 -#define DIRECT_GAIN_HI 0x0 -#define DIRECT_GAIN_LO 0x06 -#define STLOOP_ALGORITHM 0x00 - u8 st_loop2[] = { (GAIN_PATH0 << 5) | (GAIN_PATH1 << 2) | INTEGRAL_GAIN_HI, DIRECT_GAIN_LO }; - u8 st_loop9[] = { DIRECT_GAIN_HI | INTEGRAL_GAIN_LO, 0x5e /* original */, 0x04 | (STLOOP_ALGORITHM << 4) }; - u8 pmfagc0[] = { 0xff, 0x04, 0x00, 0x00, 0x0c }; - u8 ctrl[] = { 0x20, 0x00, 0x30, - stv0297_readregI(state,CTRL_3) & SPECTRAL_INVERSION_TOGGLE, /* Clear, except the Spectral Inversion Bit. */ - 0x04,0x22,0x08,0x1b,0x00 /* Gold */,0x00 }; - u8 deint_sync[] = { 0x00, 0x04 }; - u8 bert[] = { 0x86, 0x00, 0x00 }; /* bit4 of byte0 toggles byte-wise-counting */ - u8 deint[] = { 0x91, 0x0b }; - u8 outformat[] = { 0x5b, 0x10, 0x12 }; - u8 rs_desc0[] = { 0x02, 0x00, 0x00, 0x00, 0x02, 0x00 }; - u8 rs_desc14[] = { 0x00, 0x01 }; - - stv0297_writeregsI(state,EQU_0,equ0,sizeof(equ0)); - stv0297_writeregsI(state,EQU_3,equ3,sizeof(equ3)); - stv0297_writeregsI(state,EQU_7,equ7,sizeof(equ7)); - stv0297_writeregsI(state,DELAGC_0,delagc,sizeof(delagc)); - stv0297_writeregsI(state,WBAGC_0,wbagc0,sizeof(wbagc0)); - stv0297_writeregsI(state,WBAGC_9,wbagc9,sizeof(wbagc9)); - stv0297_writeregsI(state,ST_LOOP2,st_loop2,sizeof(st_loop2)); - stv0297_writeregsI(state,ST_LOOP9,st_loop9,sizeof(st_loop9)); - stv0297_writeregsI(state,PMFAGC_0,pmfagc0,sizeof(pmfagc0)); - stv0297_writeregsI(state,CTRL_0,ctrl,sizeof(ctrl)); - stv0297_writeregsI(state,DEINT_SYNC_0,deint_sync,sizeof(deint_sync)); - stv0297_writeregsI(state,BERT_0,bert,sizeof(bert)); - stv0297_writeregsI(state,DEINT_0,deint,sizeof(deint)); - stv0297_writeregsI(state,OUTFORMAT_0,outformat,sizeof(outformat)); - stv0297_writeregsI(state,RS_DESC_0,rs_desc0,sizeof(rs_desc0)); - stv0297_writeregsI(state,RS_DESC_14,rs_desc14,sizeof(rs_desc14)); - } - - state->lastber = 0; - - if (state->config->pll_init) - state->config->pll_init(fe); - - return 0; -} - - -static void stv0297_set_initdemod(struct stv0297_state *state, s32 offset) -{ - u16 initdemod = div64( (s64) (state->config->demodfreq - offset) << 16 , state->config->fclk); - u8 initdem[6]; - - deb_calc("demodfreq: %d, offset: %d, fclk: %d, initdemod: %d (%x)\n", - state->config->demodfreq, offset, state->config->fclk, initdemod, initdemod); - - initdem[0] = initdemod & 0xff; - initdem[1] = (initdemod >> 8) & 0xff; - initdem[2] = 0x00; - initdem[3] = 0x00; - initdem[4] = 0x40; - initdem[5] = 0x88; - - stv0297_writeregsI(state,INITDEM_0, initdem,6); -} - -#define try(expr,num,sleep) \ - for (i = 0; i < (num) && !(expr); i++) msleep(sleep); - -static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct stv0297_state *state = fe->demodulator_priv; - int i; - u8 equ_save[2]; - fe_spectral_inversion_t inversion; - - switch (p->inversion) { - case INVERSION_AUTO: /* fall through wanted */ - case INVERSION_OFF: - inversion = state->invert ? INVERSION_ON : INVERSION_OFF; - break; - case INVERSION_ON: - inversion = state->invert ? INVERSION_OFF : INVERSION_ON; - break; - default: - return -EINVAL; - } - deb_info("spectrum inversion: %s\n",inversion == INVERSION_ON ? "on" : "off"); - - stv0297_reset(fe); - state->config->pll_set(fe, p); -/* clear software interrupts */ - stv0297_writeregI(state, CTRL_2, 0x00); - -/* set initial demodulation frequency */ - stv0297_set_initdemod(state, 0); -/* setup AGC */ - stv0297_writeregI(state, WBAGC_3, 0x00); -/* Wide Band AGC agc2sd initialisation: mid-range */ - stv0297_writeregI(state, WBAGC_1, 0x00); -// stv0297_writereg_maskI(state, WBAGC_2, 0x03, 0x01); -/* Wide Band AGC1&AGC2 nofreeze */ - stv0297_writereg_maskI(state, DELAGC_6, 0x7f, 0x00); -/* PMF AGC accumulator reset */ - stv0297_writereg_maskI(state, PMFAGC_1, 0x80, 0x80); - stv0297_writeregI(state, PMFAGC_2, 0x00); - stv0297_writeregI(state, PMFAGC_3, 0x00); - stv0297_writereg_maskI(state, PMFAGC_4, 0x7f, 0x00); -/* Force AGC ACQ low */ - stv0297_writereg_maskI(state, WBAGC_3, 0x08, 0x00); -/* Disable unlock forcing. */ - stv0297_writereg_maskI(state, PMFAGC_1, 0x80, 0x00); -/* setup STL - * Phase clear */ - stv0297_writereg_maskI(state, ST_LOOP10, 0x20, 0x20); -/* STL integral path clear */ - stv0297_writereg_maskI(state, ST_LOOP11, 0x02, 0x02); -/* STL integral path clear release */ - stv0297_writereg_maskI(state, ST_LOOP11, 0x02, 0x00); -/* integral path enabled only */ - stv0297_writereg_maskI(state, ST_LOOP11, 0x01, 0x00); -/* direct path immediatly enabled */ - stv0297_writereg_maskI(state, ST_LOOP10, 0x40, 0x40); -/* disable frequency sweep */ - stv0297_writereg_maskI(state, CRL_10, 0x01, 0x00); -/* reset deinterleaver */ - stv0297_writereg_maskI(state, CTRL_1, 0x01, 0x01); - stv0297_writereg_maskI(state, CTRL_1, 0x01, 0x00); -/* ??? */ - stv0297_writereg_maskI(state, CTRL_3, 0x20, 0x20); - stv0297_writereg_maskI(state, CTRL_3, 0x20, 0x00); -/* Reed-Salomon clear */ - stv0297_writereg_maskI(state, CTRL_3, 0x10, 0x10); - stv0297_writereg_maskI(state, CTRL_3, 0x10, 0x00); -/* Equalizer values capture */ - stv0297_readregsI(state, EQU_0, equ_save, 2); -/* reset equalizer */ - stv0297_writereg_maskI(state, CTRL_4, 0x01, 0x01); - stv0297_writereg_maskI(state, CTRL_4, 0x01, 0x00); -/* Equalizer values restore */ - stv0297_writeregsI(state, EQU_0, equ_save, 2); -/* data comes from internal A/D */ - stv0297_writereg_maskI(state, CTRL_7, 0x80, 0x00); - -/* set parameters */ - stv0297_set_modulation(state, p->u.qam.modulation); - stv0297_set_symbolrate(state, p->u.qam.symbol_rate); - stv0297_set_crl(state, p, -130000); - stv0297_set_inversion(state, inversion); - - stv0297_writereg_maskI(state, EQU_0, 0x0f, 0x09); - stv0297_writeregI(state, EQU_1, 0x69); - -/* only disable corner detection for QAM256 and QAM128, otherwise, enable it */ - if (p->u.qam.modulation == QAM_256 || - p->u.qam.modulation == QAM_128) - stv0297_writereg_maskI(state, CTRL_8, 0x08, 0x00); - else - stv0297_writereg_maskI(state, CTRL_8, 0x08, 0x08); - -/* Phase clear release */ - stv0297_writereg_maskI(state, ST_LOOP10, 0x20, 0x00); - -/* Sweep Enable */ - stv0297_writereg_maskI(state, CRL_10, 0x01, 0x01); - msleep(10); -/* Clear wide band AGC */ - stv0297_writereg_maskI(state, WBAGC_3, 0x40, 0x40); - -/* enable wide band AGC */ - stv0297_writereg_maskI(state, WBAGC_3, 0x10, WAGC_EN); - - deb_info("initialized - waiting for the locks now\n"); - - /* wait for WBAGC lock */ - deb_info("waiting for WBAGC lock\n"); - try(stv0297_readregI(state, WBAGC_3) & 0x08, 200, 10); - if (i == 200) - goto timeout; - deb_info("WBAGC has lock\n"); - msleep(20); - - /* wait for equalizer 1 lock */ - deb_info("waiting for equalizer 1 lock\n"); - try(stv0297_readregI(state, CTRL_2) & 0x04, 400, 10); - if (i == 400) - goto timeout; - deb_info("equalizer 1 has lock\n"); - - /* wait for equalizer 2 lock and if it's stable */ - deb_info("waiting for equalizer 2 lock\n"); - try(stv0297_readregI(state, CTRL_2) & 0x08, 200, 10); - if (i == 200) - goto timeout; - - deb_info("equalizer 2 has lock\n"); - msleep(20); - if (!(stv0297_readregI(state, CTRL_2) & 0x08)) - goto timeout; - deb_info("equalizer 2 is stable\n"); - - /* we have modulation, do we have data */ - deb_info("waiting for data lock\n"); - try(stv0297_readregI(state,RS_DESC_15) & 0x80,5,10); - if (i == 5) { /* try to invert the inversion during the next run */ - deb_info("no data lock achieved, trying to invert the spectrum in the next run.\n"); - state->invert = !state->invert; - goto timeout; - } - deb_info("we have data lock\n"); - -/* Turn off corner detection */ - stv0297_writereg_maskI(state, CTRL_8,0x08, 0x00); - /* success!! */ - state->base_freq = p->frequency; - return 0; - -timeout: - deb_info("timed out\n"); - stv0297_writereg_maskI(state, CRL_10, 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_readregI(state, EQU_0); - reg_83 = stv0297_readregI(state, CTRL_3); - - p->frequency = state->base_freq; - - if (reg_83 & 0x08) - p->inversion = INVERSION_ON; - else - p->inversion = INVERSION_OFF; - - p->u.qam.symbol_rate = stv0297_get_symbolrate(state); - p->u.qam.fec_inner = FEC_NONE; - - switch (reg_00 & 0x70) { - case STV0297_QAM16: - p->u.qam.modulation = QAM_16; - break; - case STV0297_QAM32: - p->u.qam.modulation = QAM_32; - break; - case STV0297_QAM128: - p->u.qam.modulation = QAM_128; - break; - case STV0297_QAM256: - p->u.qam.modulation = QAM_256; - break; - case STV0297_QAM64: - p->u.qam.modulation = QAM_64; - break; - } - - return 0; -} - -static int stv0297_sleep(struct dvb_frontend *fe) -{ - struct stv0297_state *state = fe->demodulator_priv; - deb_info("stv0297 is going to bed.\n"); - - stv0297_writereg_maskI(state, CTRL_0, 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 ctrl_2 = stv0297_readregI(state, CTRL_2); - *status = 0; - -/* The following status assignments are only guesses, but we wanted to have a - * kind of grade here */ - - if (stv0297_readregI(state, WBAGC_3) & 0x08) - *status |= FE_HAS_SIGNAL; - - if (ctrl_2 & 0x04) - *status |= FE_HAS_CARRIER; - - if (ctrl_2 & 0x08) - *status |= FE_HAS_VITERBI; - - if (stv0297_readregI(state, RS_DESC_15) & 0x80) - *status |= FE_HAS_SYNC | FE_HAS_LOCK; - - return 0; -} - -static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength) -{ - struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; - u8 STRENGTH[2]; - - stv0297_readregsI(state, WBAGC_1, 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 = (struct stv0297_state *) fe->demodulator_priv; - u8 SNR[2]; - - stv0297_readregsI(state, EQU_7, SNR, 2); - *snr = SNR[1] << 8 | SNR[0]; - - return 0; -} - -static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber) -{ - struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; - u8 BER[3]; - *ber = 0; - - stv0297_readregsI(state, BERT_0, BER, 3); - if (!(BER[0] & 0x80)) { - state->lastber = (BER[0] & 0x07 << 16) | (BER[2] << 8) | BER[1]; - /* reset the BER counter */ - BER[0] |= 0x80; - BER[1] = BER[2] = 0x00; - stv0297_writeregsI(state, BERT_0, BER, 3); - } - *ber = state->lastber; - - return 0; -} - -static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) -{ - struct stv0297_state *state = fe->demodulator_priv; - u8 block_count[6]; - - stv0297_writeregI(state,RS_DESC_15,0x03); /* freeze the counters */ - stv0297_readregsI(state,RS_DESC_0,block_count,6); - stv0297_writeregI(state,RS_DESC_15,0x02); /* clear the counters */ - stv0297_writeregI(state,RS_DESC_15,0x01); /* re-enable the counters */ - -/* LastBlockCount = (block_count[1] << 8) | block_count[0]; */ -/* LastCorrectedBlockCount = (block_count[3] << 8) | block_count[2]; */ - *ucblocks = (block_count[5] << 8) | block_count[4]; - 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_cs2_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_readregI(state, CTRL_0) & 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, - - .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, Andrew de Quincey and Patrick Boettcher"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("1.0"); - -EXPORT_SYMBOL(stv0297_cs2_attach); -EXPORT_SYMBOL(stv0297_cs2_enable_plli2c); diff --git a/linux/drivers/media/dvb/b2c2/stv0297_cs2.h b/linux/drivers/media/dvb/b2c2/stv0297_cs2.h deleted file mode 100644 index d2b2fa5c8..000000000 --- a/linux/drivers/media/dvb/b2c2/stv0297_cs2.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Driver for STV0297 demodulator - - Copyright (C) 2003-2004 Dennis Noermann - - This program is free software; 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 -#include "dvb_frontend.h" - -#define STV0297_NTSC_FCLK 33868800UL -#define STV0297_NTSC_IF 43750000UL - -#define STV0297_PAL_FCLK 28900000UL -#define STV0297_PAL_IF 36125000UL - -struct stv0297_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* clocks in Hz */ - u32 fclk; - u32 demodfreq; - - /* PLL maintenance */ - int (*pll_init)(struct dvb_frontend* fe); - int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); -}; - -extern struct dvb_frontend* stv0297_cs2_attach(const struct stv0297_config* config, - struct i2c_adapter* i2c); -extern int stv0297_cs2_enable_plli2c(struct dvb_frontend* fe); - -#endif // STV0297_H diff --git a/linux/drivers/media/dvb/b2c2/stv0297_priv.h b/linux/drivers/media/dvb/b2c2/stv0297_priv.h deleted file mode 100644 index a3c1bbe4a..000000000 --- a/linux/drivers/media/dvb/b2c2/stv0297_priv.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Driver for the DVB-C STV0297 demodulator - chip stuff - * - * Copyright (C) 2005 Patrick Boettcher - * - * This program is free software; 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_PRIV_INCLUDED__ -#define __STV0297_PRIV_INCLUDED__ - -enum stv0297_registers { - EQU_0 = 0x00, - EQU_1, - EQU_2, - EQU_3, - EQU_4, - EQU_5, - EQU_6, - EQU_7, - EQU_8, - INITDEM_0 = 0x20, - INITDEM_1, - INITDEM_2, - INITDEM_3, - INITDEM_4, - INITDEM_5, - DELAGC_0 = 0x30, - DELAGC_1, - DELAGC_2, - DELAGC_3, - DELAGC_4, - DELAGC_5, - DELAGC_6, - DELAGC_7, - DELAGC_8, - DELAGC_BLK_LEN = 1+DELAGC_8-DELAGC_0, - WBAGC_0 = 0x40, - WBAGC_1, - WBAGC_2, - WBAGC_3, - WBAGC_4, - WBAGC_5, - WBAGC_6, - WBAGC_7, - WBAGC_8, - WBAGC_9, - WBAGC_10, - WBAGC_11, - WBAGC_BLK_LEN = 1+WBAGC_11-WBAGC_0, - ST_LOOP2 = 0x52, - ST_LOOP3, - ST_LOOP4, // Not used. - ST_LOOP5, - ST_LOOP6, - ST_LOOP7, - ST_LOOP8, - ST_LOOP9, - ST_LOOP10, - ST_LOOP11, - CRL_0 = 0x60, - CRL_1, - CRL_2, - CRL_3, - CRL_4, - CRL_5, - CRL_6, - CRL_7, - CRL_8, - CRL_9, - CRL_10, - CRL_11, - PMFAGC_0 = 0x70, - PMFAGC_1, - PMFAGC_2, - PMFAGC_3, - PMFAGC_4, - CTRL_0 = 0x80, - CTRL_1, - CTRL_2, - CTRL_3, - CTRL_4, - CTRL_5, - CTRL_6, - CTRL_7, - CTRL_8, - CTRL_9, - DEINT_SYNC_0 = 0x90, - DEINT_SYNC_1, - BERT_0 = 0xA0, - BERT_1, - BERT_2, - DEINT_0 = 0xB0, - DEINT_1, - DEINT_2, - DEINT_3, - OUTFORMAT_0 = 0xC0, - OUTFORMAT_1, - OUTFORMAT_2, - RS_DESC_0 = 0xD0, - RS_DESC_1, - RS_DESC_2, - RS_DESC_3, - RS_DESC_4, - RS_DESC_5, - RS_DESC_14 =0xDE, - RS_DESC_15 -}; - -enum { - WAGC_EN = 0x10, - STV0297_QAM16 = 0x00, - STV0297_QAM32 = 0x10, - STV0297_QAM64 = 0x40, - STV0297_QAM128 = 0x20, - STV0297_QAM256 = 0x30, - STV0297_CLEARQAM = ~0x70 -}; - -#define AGC2MAX DELAGC_0 -#define AGC2MIN DELAGC_1 -#define AGC1MAX DELAGC_2 -#define AGC1MIN DELAGC_3 -#define AGC2_THRESH DELAGC_5 - -#define NO_AGC_FREEZE 0x80 -#define SOFT_AGC_FREEZE 0x28 - -#define SPECTRAL_INVERSION_TOGGLE 0x08 - -#define MINIMUM_SYMBOL_RATE_IN_BAUD 1000000UL -#define MAXIMUM_SYMBOL_RATE_IN_BAUD 7000000UL -#define MAXIMUM_NTSC_SYMBOL_RATE 5300000UL - -#define MINIMUM_FREQUENCY_IN_KHz 48000000UL -#define MAXIMUM_FREQUENCY_IN_KHz 860000000UL - -/* Set to an invalid, non-zero figure. */ -#define INITIAL_SYMBOL_RATE MAXIMUM_SYMBOL_RATE_IN_BAUD+1 - -#define TOGGLE_MASK 0x03 - -#endif -- cgit v1.2.3 From 1be90df9422b4ee4d6343477eda998c5d3e3e488 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 29 Mar 2008 21:49:57 +0100 Subject: Preparation for supporting new devices, cleanup and saneness From: Patrick Boettcher To prepare the support for new device to the flexcop-family some preparation and cleanups was done + some saneness: - created an i2c-adapter for each i2c-port available. Easier usage for devices with several device on different i2c-busses - initialize i2c before doing the eeprom read - changed the way to attach the different frontends, easier to read now - enabled support for i2c-devices having no register address (1-byte access) Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/b2c2/flexcop-common.h | 17 ++- linux/drivers/media/dvb/b2c2/flexcop-eeprom.c | 9 +- linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 111 ++++++++------- linux/drivers/media/dvb/b2c2/flexcop-i2c.c | 180 ++++++++++++++++-------- linux/drivers/media/dvb/b2c2/flexcop-usb.c | 17 ++- linux/drivers/media/dvb/b2c2/flexcop.c | 10 +- 6 files changed, 221 insertions(+), 123 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/b2c2/flexcop-common.h b/linux/drivers/media/dvb/b2c2/flexcop-common.h index 49852ba16..22fc0490d 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-common.h +++ b/linux/drivers/media/dvb/b2c2/flexcop-common.h @@ -47,6 +47,14 @@ struct flexcop_dma { u32 size; /* size of each address in bytes */ }; +struct flexcop_i2c_adapter { + struct flexcop_device *fc; + struct i2c_adapter i2c_adap; + + u8 no_base_addr; + flexcop_i2c_port_t port; +}; + /* Control structure for data definitions that are common to * the B2C2-based PCI and USB devices. */ @@ -75,7 +83,7 @@ struct flexcop_device { struct dmx_frontend mem_frontend; int (*fe_sleep) (struct dvb_frontend *); - struct i2c_adapter i2c_adap; + struct flexcop_i2c_adapter fc_i2c_adap[3]; #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) struct mutex i2c_mutex; #else @@ -94,7 +102,8 @@ struct flexcop_device { int (*write_ibi_reg) (struct flexcop_device *, flexcop_ibi_register, flexcop_ibi_value); - int (*i2c_request) (struct flexcop_device*, flexcop_access_op_t, flexcop_i2c_port_t, u8 chipaddr, u8 addr, u8 *buf, u16 len); + int (*i2c_request) (struct flexcop_i2c_adapter*, + flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len); int (*stream_control) (struct flexcop_device*, int); int (*get_mac_addr) (struct flexcop_device *fc, int extended); @@ -135,8 +144,8 @@ int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended); * one. We have it in flexcop-i2c.c, because it is going via the actual * I2C-channel of the flexcop. */ -int flexcop_i2c_request(struct flexcop_device*, flexcop_access_op_t, - flexcop_i2c_port_t, u8 chipaddr, u8 addr, u8 *buf, u16 len); +int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t, + u8 chipaddr, u8 addr, u8 *buf, u16 len); /* from flexcop-sram.c */ int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target); diff --git a/linux/drivers/media/dvb/b2c2/flexcop-eeprom.c b/linux/drivers/media/dvb/b2c2/flexcop-eeprom.c index 16015fedb..5d563fbc7 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-eeprom.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-eeprom.c @@ -114,15 +114,18 @@ static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t { int i,ret = 0; u8 chipaddr = 0x50 | ((addr >> 8) & 3); - for (i = 0; i < retries; i++) - if ((ret = fc->i2c_request(fc,op,FC_I2C_PORT_EEPROM,chipaddr,addr & 0xff,buf,len)) == 0) + for (i = 0; i < retries; i++) { + ret = fc->i2c_request(&fc->fc_i2c_adap[1], op, chipaddr, + addr & 0xff, buf, len); + if (ret == 0) break; + } return ret; } static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len, int retries) { - int ret = flexcop_eeprom_request(fc,FC_READ,addr,buf,len,retries); + int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries); if (ret == 0) if (calc_lrc(buf, len - 1) != buf[len - 1]) ret = -EINVAL; diff --git a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 441ffdf0d..46d6f5d8c 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -183,13 +183,13 @@ static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dv buf[2] = 0x84; /* 0xC4 */ buf[3] = 0x08; - if (params->frequency < 1500000) buf[3] |= 0x10; + if (params->frequency < 1500000) + buf[3] |= 0x10; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) { + if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1) return -EIO; - } return 0; } @@ -340,7 +340,7 @@ static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) + if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1) return -EIO; return 0; } @@ -389,10 +389,11 @@ static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]); - ret = fc->i2c_request(fc, FC_WRITE, FC_I2C_PORT_TUNER, 0x61, buf[0], &buf[1], 3); + ret = fc->i2c_request(&fc->fc_i2c_adap[2], + FC_WRITE, 0x61, buf[0], &buf[1], 3); deb_tuner("tuner write returned: %d\n",ret); - return 0; + return ret; } static u8 alps_tdee4_stv0297_inittab[] = { @@ -479,53 +480,67 @@ static struct stv0297_config alps_tdee4_stv0297_config = { int flexcop_frontend_init(struct flexcop_device *fc) { struct dvb_frontend_ops *ops; + struct i2c_adapter *i2c = &fc->fc_i2c_adap[0].i2c_adap; /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ - if ((fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { + fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c); + if (fc->fe != NULL) { ops = &fc->fe->ops; ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params; ops->set_voltage = flexcop_set_voltage; - fc->fe_sleep = ops->sleep; - ops->sleep = flexcop_sleep; + fc->fe_sleep = ops->sleep; + ops->sleep = flexcop_sleep; + + fc->dev_type = FC_SKY; + goto fe_found; + } - fc->dev_type = FC_SKY; - info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address); - } else /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */ - if ((fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) { - fc->dev_type = FC_AIR_DVB; + fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c); + if (fc->fe != NULL) { + fc->dev_type = FC_AIR_DVB; fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; - info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); - } else + goto fe_found; + } + /* try the air atsc 2nd generation (nxt2002) */ - if ((fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, &fc->i2c_adap)) != NULL) { - fc->dev_type = FC_AIR_ATSC2; + fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c); + if (fc->fe != NULL) { + fc->dev_type = FC_AIR_ATSC2; dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, DVB_PLL_SAMSUNG_TBMV); - info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); - } else - /* try the air atsc 3nd generation (lgdt3303) */ - if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { - fc->dev_type = FC_AIR_ATSC3; - dvb_attach(simple_tuner_attach, fc->fe, - &fc->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF); - info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); - } else + goto fe_found; + } + + fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c); + if (fc->fe != NULL) { + fc->dev_type = FC_AIR_ATSC3; + dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, + TUNER_LG_TDVS_H06XF); + goto fe_found; + } + /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ - if ((fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) { - fc->dev_type = FC_AIR_ATSC1; - info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address); - } else + fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c); + if (fc->fe != NULL) { + fc->dev_type = FC_AIR_ATSC1; + goto fe_found; + } + /* try the cable dvb (stv0297) */ - if ((fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) { - fc->dev_type = FC_CABLE; + fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c); + if (fc->fe != NULL) { + fc->dev_type = FC_CABLE; fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; - info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address); - } else + goto fe_found; + } + /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ - if ((fc->fe = dvb_attach(vp310_mt312_attach, &skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { + fc->fe = dvb_attach(vp310_mt312_attach, + &skystar23_samsung_tbdu18132_config, i2c); + if (fc->fe != NULL) { ops = &fc->fe->ops; ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params; @@ -539,19 +554,21 @@ int flexcop_frontend_init(struct flexcop_device *fc) ops->sleep = flexcop_sleep; fc->dev_type = FC_SKY_OLD; - info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address); + goto fe_found; } - if (fc->fe == NULL) { - err("no frontend driver found for this B2C2/FlexCop adapter"); - return -ENODEV; - } else { - if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { - err("frontend registration failed!"); - dvb_frontend_detach(fc->fe); - fc->fe = NULL; - return -EINVAL; - } + err("no frontend driver found for this B2C2/FlexCop adapter"); + return -ENODEV; + +fe_found: + info("found '%s' .", fc->fe->ops.info.name); + if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { + err("frontend registration failed!"); + ops = &fc->fe->ops; + if (ops->release != NULL) + ops->release(fc->fe); + fc->fe = NULL; + return -EINVAL; } fc->init_state |= FC_STATE_FE_INIT; return 0; diff --git a/linux/drivers/media/dvb/b2c2/flexcop-i2c.c b/linux/drivers/media/dvb/b2c2/flexcop-i2c.c index 6bf858a43..55973eaf3 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -9,6 +9,8 @@ #define FC_MAX_I2C_RETRIES 100000 +/* #define DUMP_I2C_MESSAGES */ + static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r100) { int i; @@ -38,30 +40,25 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r return -EREMOTEIO; } -static int flexcop_i2c_read4(struct flexcop_device *fc, flexcop_ibi_value r100, u8 *buf) +static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c, + flexcop_ibi_value r100, u8 *buf) { flexcop_ibi_value r104; int len = r100.tw_sm_c_100.total_bytes, /* remember total_bytes is buflen-1 */ ret; - if ((ret = flexcop_i2c_operation(fc,&r100)) != 0) { - /* The Cablestar needs a different kind of i2c-transfer (does not - * support "Repeat Start"): - * wait for the ACK failure, - * and do a subsequent read with the Bit 30 enabled - */ - r100.tw_sm_c_100.no_base_addr_ack_error = 1; - if ((ret = flexcop_i2c_operation(fc,&r100)) != 0) { - deb_i2c("no_base_addr read failed. %d\n",ret); - return ret; - } + r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr; + ret = flexcop_i2c_operation(i2c->fc, &r100); + if (ret != 0) { + deb_i2c("read failed. %d\n", ret); + return ret; } buf[0] = r100.tw_sm_c_100.data1_reg; if (len > 0) { - r104 = fc->read_ibi_reg(fc,tw_sm_c_104); - deb_i2c("read: r100: %08x, r104: %08x\n",r100.raw,r104.raw); + r104 = i2c->fc->read_ibi_reg(i2c->fc, tw_sm_c_104); + deb_i2c("read: r100: %08x, r104: %08x\n", r100.raw, r104.raw); /* there is at least one more byte, otherwise we wouldn't be here */ buf[1] = r104.tw_sm_c_104.data2_reg; @@ -85,17 +82,22 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100, r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0; r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0; - deb_i2c("write: r100: %08x, r104: %08x\n",r100.raw,r104.raw); + deb_i2c("write: r100: %08x, r104: %08x\n", r100.raw, r104.raw); /* write the additional i2c data before doing the actual i2c operation */ - fc->write_ibi_reg(fc,tw_sm_c_104,r104); - return flexcop_i2c_operation(fc,&r100); + fc->write_ibi_reg(fc, tw_sm_c_104, r104); + return flexcop_i2c_operation(fc, &r100); } -int flexcop_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op, - flexcop_i2c_port_t port, u8 chipaddr, u8 addr, u8 *buf, u16 len) +int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c, + flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len) { int ret; + +#ifdef DUMP_I2C_MESSAGES + int i; +#endif + u16 bytes_to_transfer; flexcop_ibi_value r100; @@ -103,7 +105,25 @@ int flexcop_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op, r100.raw = 0; r100.tw_sm_c_100.chipaddr = chipaddr; r100.tw_sm_c_100.twoWS_rw = op; - r100.tw_sm_c_100.twoWS_port_reg = port; + r100.tw_sm_c_100.twoWS_port_reg = i2c->port; + +#ifdef DUMP_I2C_MESSAGES + printk(KERN_DEBUG "%d ", i2c->port); + if (op == FC_READ) + printk("rd("); + else + printk("wr("); + + printk("%02x): %02x ", chipaddr, addr); +#endif + + /* in that case addr is the only value -> + * we write it twice as baseaddr and val0 + * BBTI is doing it like that for ISL6421 at least */ + if (i2c->no_base_addr && len == 0 && op == FC_WRITE) { + buf = &addr; + len = 1; + } while (len != 0) { bytes_to_transfer = len > 4 ? 4 : len; @@ -112,9 +132,14 @@ int flexcop_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op, r100.tw_sm_c_100.baseaddr = addr; if (op == FC_READ) - ret = flexcop_i2c_read4(fc, r100, buf); + ret = flexcop_i2c_read4(i2c, r100, buf); else - ret = flexcop_i2c_write4(fc,r100, buf); + ret = flexcop_i2c_write4(i2c->fc, r100, buf); + +#ifdef DUMP_I2C_MESSAGES + for (i = 0; i < bytes_to_transfer; i++) + printk("%02x ", buf[i]); +#endif if (ret < 0) return ret; @@ -122,7 +147,11 @@ int flexcop_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op, buf += bytes_to_transfer; addr += bytes_to_transfer; len -= bytes_to_transfer; - }; + } + +#ifdef DUMP_I2C_MESSAGES + printk("\n"); +#endif return 0; } @@ -132,7 +161,7 @@ EXPORT_SYMBOL(flexcop_i2c_request); /* master xfer callback for demodulator */ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) { - struct flexcop_device *fc = i2c_get_adapdata(i2c_adap); + struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap); int i, ret = 0; /* Some drivers use 1 byte or 0 byte reads as probes, which this @@ -142,34 +171,29 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs if (num == 1 && msgs[0].flags == I2C_M_RD && msgs[0].len <= 1) return 1; - if (mutex_lock_interruptible(&fc->i2c_mutex)) + if (mutex_lock_interruptible(&i2c->fc->i2c_mutex)) return -ERESTARTSYS; - /* reading */ - if (num == 2 && - msgs[0].flags == 0 && - msgs[1].flags == I2C_M_RD && - msgs[0].buf != NULL && - msgs[1].buf != NULL) { - - ret = fc->i2c_request(fc, FC_READ, FC_I2C_PORT_DEMOD, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len); - - } else for (i = 0; i < num; i++) { /* writing command */ - if (msgs[i].flags != 0 || msgs[i].buf == NULL || msgs[i].len < 2) { - ret = -EINVAL; + for (i = 0; i < num; i++) { + /* reading */ + if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) { + ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr, + msgs[i].buf[0], msgs[i+1].buf, msgs[i+1].len); + i++; /* skip the following message */ + } else /* writing */ + ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr, + msgs[i].buf[0], &msgs[i].buf[1], + msgs[i].len - 1); + if (ret < 0) { + err("i2c master_xfer failed"); break; } - - ret = fc->i2c_request(fc, FC_WRITE, FC_I2C_PORT_DEMOD, msgs[i].addr, msgs[i].buf[0], &msgs[i].buf[1], msgs[i].len - 1); } - if (ret < 0) - err("i2c master_xfer failed"); - else - ret = num; - - mutex_unlock(&fc->i2c_mutex); + mutex_unlock(&i2c->fc->i2c_mutex); + if (ret == 0) + ret = num; return ret; } @@ -189,28 +213,68 @@ int flexcop_i2c_init(struct flexcop_device *fc) mutex_init(&fc->i2c_mutex); - memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter)); - strncpy(fc->i2c_adap.name, "B2C2 FlexCop device", - sizeof(fc->i2c_adap.name)); - - i2c_set_adapdata(&fc->i2c_adap,fc); + fc->fc_i2c_adap[0].fc = fc; + fc->fc_i2c_adap[1].fc = fc; + fc->fc_i2c_adap[2].fc = fc; + + fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD; + fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM; + fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER; + + strncpy(fc->fc_i2c_adap[0].i2c_adap.name, + "B2C2 FlexCop I2C to demod", I2C_NAME_SIZE); + strncpy(fc->fc_i2c_adap[1].i2c_adap.name, + "B2C2 FlexCop I2C to eeprom", I2C_NAME_SIZE); + strncpy(fc->fc_i2c_adap[2].i2c_adap.name, + "B2C2 FlexCop I2C to tuner", I2C_NAME_SIZE); + + i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]); + i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]); + i2c_set_adapdata(&fc->fc_i2c_adap[2].i2c_adap, &fc->fc_i2c_adap[2]); + + fc->fc_i2c_adap[0].i2c_adap.class = + fc->fc_i2c_adap[1].i2c_adap.class = + fc->fc_i2c_adap[2].i2c_adap.class = I2C_CLASS_TV_DIGITAL; + fc->fc_i2c_adap[0].i2c_adap.algo = + fc->fc_i2c_adap[1].i2c_adap.algo = + fc->fc_i2c_adap[2].i2c_adap.algo = &flexcop_algo; + fc->fc_i2c_adap[0].i2c_adap.algo_data = + fc->fc_i2c_adap[1].i2c_adap.algo_data = + fc->fc_i2c_adap[2].i2c_adap.algo_data = NULL; + fc->fc_i2c_adap[0].i2c_adap.dev.parent = + fc->fc_i2c_adap[1].i2c_adap.dev.parent = + fc->fc_i2c_adap[2].i2c_adap.dev.parent = fc->dev; + + ret = i2c_add_adapter(&fc->fc_i2c_adap[0].i2c_adap); + if (ret < 0) + return ret; - fc->i2c_adap.class = I2C_CLASS_TV_DIGITAL; - fc->i2c_adap.algo = &flexcop_algo; - fc->i2c_adap.algo_data = NULL; - fc->i2c_adap.dev.parent = fc->dev; + ret = i2c_add_adapter(&fc->fc_i2c_adap[1].i2c_adap); + if (ret < 0) + goto adap_1_failed; - if ((ret = i2c_add_adapter(&fc->i2c_adap)) < 0) - return ret; + ret = i2c_add_adapter(&fc->fc_i2c_adap[2].i2c_adap); + if (ret < 0) + goto adap_2_failed; fc->init_state |= FC_STATE_I2C_INIT; return 0; + +adap_2_failed: + i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap); +adap_1_failed: + i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap); + + return ret; } void flexcop_i2c_exit(struct flexcop_device *fc) { - if (fc->init_state & FC_STATE_I2C_INIT) - i2c_del_adapter(&fc->i2c_adap); + if (fc->init_state & FC_STATE_I2C_INIT) { + i2c_del_adapter(&fc->fc_i2c_adap[2].i2c_adap); + i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap); + i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap); + } fc->init_state &= ~FC_STATE_I2C_INIT; } diff --git a/linux/drivers/media/dvb/b2c2/flexcop-usb.c b/linux/drivers/media/dvb/b2c2/flexcop-usb.c index 397d0d6a7..683217b0f 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-usb.c @@ -211,10 +211,11 @@ static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set, #endif /* usb i2c stuff */ -static int flexcop_usb_i2c_req(struct flexcop_usb *fc_usb, +static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c, flexcop_usb_request_t req, flexcop_usb_i2c_function_t func, - flexcop_i2c_port_t port, u8 chipaddr, u8 addr, u8 *buf, u8 buflen) + u8 chipaddr, u8 addr, u8 *buf, u8 buflen) { + struct flexcop_usb *fc_usb = i2c->fc->bus_specific; u16 wValue, wIndex; int nWaitTime,pipe,len; // u8 dwRequestType; @@ -242,7 +243,7 @@ static int flexcop_usb_i2c_req(struct flexcop_usb *fc_usb, deb_info("unsupported function for i2c_req %x\n",func); return -EINVAL; } - wValue = (func << 8 ) | (port << 4); + wValue = (func << 8) | (i2c->port << 4); wIndex = (chipaddr << 8 ) | addr; deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req, @@ -274,13 +275,15 @@ static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_regi return flexcop_usb_readwrite_dw(fc,reg, &val.raw, 0); } -static int flexcop_usb_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op, - flexcop_i2c_port_t port, u8 chipaddr, u8 addr, u8 *buf, u16 len) +static int flexcop_usb_i2c_request(struct flexcop_i2c_adapter *i2c, + flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len) { if (op == FC_READ) - return flexcop_usb_i2c_req(fc->bus_specific,B2C2_USB_I2C_REQUEST,USB_FUNC_I2C_READ,port,chipaddr,addr,buf,len); + return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST, + USB_FUNC_I2C_READ, chipaddr, addr, buf, len); else - return flexcop_usb_i2c_req(fc->bus_specific,B2C2_USB_I2C_REQUEST,USB_FUNC_I2C_WRITE,port,chipaddr,addr,buf,len); + return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST, + USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len); } static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length) diff --git a/linux/drivers/media/dvb/b2c2/flexcop.c b/linux/drivers/media/dvb/b2c2/flexcop.c index 2ddafd071..205146c24 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop.c +++ b/linux/drivers/media/dvb/b2c2/flexcop.c @@ -257,6 +257,12 @@ int flexcop_device_initialize(struct flexcop_device *fc) if ((ret = flexcop_dvb_init(fc))) goto error; + /* i2c has to be done before doing EEProm stuff - + * because the EEProm is accessed via i2c */ + ret = flexcop_i2c_init(fc); + if (ret) + goto error; + /* do the MAC address reading after initializing the dvb_adapter */ if (fc->get_mac_addr(fc, 0) == 0) { u8 *b = fc->dvb_adapter.proposed_mac; @@ -266,10 +272,6 @@ int flexcop_device_initialize(struct flexcop_device *fc) } else warn("reading of MAC address failed.\n"); - - if ((ret = flexcop_i2c_init(fc))) - goto error; - if ((ret = flexcop_frontend_init(fc))) goto error; -- cgit v1.2.3 From d8580b741f3e97d4ab9882286ca68143258df6a6 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 29 Mar 2008 22:01:12 +0100 Subject: CX24123: preparing support for CX24113 tuner From: Patrick Boettcher To support a new device based on CX24123 (using the CX24113-tuner) the following was done: - added two parameters to de-select the internal PLL-driver (for CX24108) and a AGC-function callback. - added a virtual i2c-adapter which allow simple access behind the i2c-gate - cleanup up some code Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/frontends/cx24123.c | 304 +++++++++++++++++++--------- linux/drivers/media/dvb/frontends/cx24123.h | 21 +- 2 files changed, 220 insertions(+), 105 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/frontends/cx24123.c b/linux/drivers/media/dvb/frontends/cx24123.c index 023b36f01..83b6793de 100644 --- a/linux/drivers/media/dvb/frontends/cx24123.c +++ b/linux/drivers/media/dvb/frontends/cx24123.c @@ -1,24 +1,26 @@ /* - Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver - - Copyright (C) 2005 Steven Toth - - Support for KWorld DVB-S 100 by Vadim Catana - - This program is free software; 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. -*/ + * Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver + * + * Copyright (C) 2005 Steven Toth + * + * Support for KWorld DVB-S 100 by Vadim Catana + * + * Support for CX24123/CX24113-NIM by Patrick Boettcher + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ #include #include @@ -32,9 +34,16 @@ static int force_band; static int debug; + +#define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0) +#define err(args...) do { printk(KERN_ERR "CX24123: " args); } while (0) + #define dprintk(args...) \ do { \ - if (debug) printk (KERN_DEBUG "cx24123: " args); \ + if (debug) { \ + printk(KERN_DEBUG "CX24123: %s: ", __func__); \ + printk(args); \ + } \ } while (0) struct cx24123_state @@ -51,6 +60,10 @@ struct cx24123_state u32 pllarg; u32 FILTune; + struct i2c_adapter tuner_i2c_adapter; + + u8 demod_rev; + /* The Demod/Tuner can't easily provide these, we cache them */ u32 currentfreq; u32 currentsymbolrate; @@ -236,48 +249,52 @@ static struct { {0x67, 0x83}, /* Non-DCII symbol clock */ }; -static int cx24123_writereg(struct cx24123_state* state, int reg, int data) +static int cx24123_i2c_writereg(struct cx24123_state *state, + u8 i2c_addr, int reg, int data) { u8 buf[] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; + struct i2c_msg msg = { + .addr = i2c_addr, .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); + /* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, 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; + " data == 0x%02x)\n", __func__, err, reg, data); + return err; } return 0; } -static int cx24123_readreg(struct cx24123_state* state, u8 reg) +static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg) { int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; + u8 b = 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 } + { .addr = i2c_addr, .flags = 0, .buf = ®, .len = 1 }, + { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &b, .len = 1 } }; ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) { - printk("%s: reg=0x%x (error=%d)\n", __FUNCTION__, reg, ret); + err("%s: reg=0x%x (error=%d)\n", __func__, reg, ret); return ret; } - if (debug>1) - printk("cx24123: read reg 0x%02x, value 0x%02x\n",reg, ret); + /* printk(KERN_DEBUG "rd(%02x): %02x %02x\n", i2c_addr, reg, b); */ - return b1[0]; + return b; } +#define cx24123_readreg(state, reg) \ + cx24123_i2c_readreg(state, state->config->demod_address, reg) +#define cx24123_writereg(state, reg, val) \ + cx24123_i2c_writereg(state, state->config->demod_address, reg, val) + static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) { u8 nom_reg = cx24123_readreg(state, 0x0e); @@ -285,17 +302,17 @@ static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_invers switch (inversion) { case INVERSION_OFF: - dprintk("%s: inversion off\n",__FUNCTION__); + dprintk("inversion off\n"); cx24123_writereg(state, 0x0e, nom_reg & ~0x80); cx24123_writereg(state, 0x10, auto_reg | 0x80); break; case INVERSION_ON: - dprintk("%s: inversion on\n",__FUNCTION__); + dprintk("inversion on\n"); cx24123_writereg(state, 0x0e, nom_reg | 0x80); cx24123_writereg(state, 0x10, auto_reg | 0x80); break; case INVERSION_AUTO: - dprintk("%s: inversion auto\n",__FUNCTION__); + dprintk("inversion auto\n"); cx24123_writereg(state, 0x10, auto_reg & ~0x80); break; default: @@ -312,10 +329,10 @@ static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_invers val = cx24123_readreg(state, 0x1b) >> 7; if (val == 0) { - dprintk("%s: read inversion off\n",__FUNCTION__); + dprintk("read inversion off\n"); *inversion = INVERSION_OFF; } else { - dprintk("%s: read inversion on\n",__FUNCTION__); + dprintk("read inversion on\n"); *inversion = INVERSION_ON; } @@ -337,42 +354,42 @@ static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec) switch (fec) { case FEC_1_2: - dprintk("%s: set FEC to 1/2\n",__FUNCTION__); + dprintk("set FEC to 1/2\n"); cx24123_writereg(state, 0x0e, nom_reg | 0x01); cx24123_writereg(state, 0x0f, 0x02); break; case FEC_2_3: - dprintk("%s: set FEC to 2/3\n",__FUNCTION__); + dprintk("set FEC to 2/3\n"); cx24123_writereg(state, 0x0e, nom_reg | 0x02); cx24123_writereg(state, 0x0f, 0x04); break; case FEC_3_4: - dprintk("%s: set FEC to 3/4\n",__FUNCTION__); + dprintk("set FEC to 3/4\n"); cx24123_writereg(state, 0x0e, nom_reg | 0x03); cx24123_writereg(state, 0x0f, 0x08); break; case FEC_4_5: - dprintk("%s: set FEC to 4/5\n",__FUNCTION__); + dprintk("set FEC to 4/5\n"); cx24123_writereg(state, 0x0e, nom_reg | 0x04); cx24123_writereg(state, 0x0f, 0x10); break; case FEC_5_6: - dprintk("%s: set FEC to 5/6\n",__FUNCTION__); + dprintk("set FEC to 5/6\n"); cx24123_writereg(state, 0x0e, nom_reg | 0x05); cx24123_writereg(state, 0x0f, 0x20); break; case FEC_6_7: - dprintk("%s: set FEC to 6/7\n",__FUNCTION__); + dprintk("set FEC to 6/7\n"); cx24123_writereg(state, 0x0e, nom_reg | 0x06); cx24123_writereg(state, 0x0f, 0x40); break; case FEC_7_8: - dprintk("%s: set FEC to 7/8\n",__FUNCTION__); + dprintk("set FEC to 7/8\n"); cx24123_writereg(state, 0x0e, nom_reg | 0x07); cx24123_writereg(state, 0x0f, 0x80); break; case FEC_AUTO: - dprintk("%s: set FEC to auto\n",__FUNCTION__); + dprintk("set FEC to auto\n"); cx24123_writereg(state, 0x0f, 0xfe); break; default: @@ -501,7 +518,8 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 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); + dprintk("srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n", + srate, ratio, sample_rate, sample_gain); return 0; } @@ -581,7 +599,7 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par struct cx24123_state *state = fe->demodulator_priv; unsigned long timeout; - dprintk("%s: pll writereg called, data=0x%08x\n",__FUNCTION__,data); + dprintk("pll writereg called, data=0x%08x\n", data); /* align the 21 bytes into to bit23 boundary */ data = data << 3; @@ -594,7 +612,8 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par 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__); + err("%s: demodulator is not responding, "\ + "possibly hung, aborting.\n", __func__); return -EREMOTEIO; } msleep(10); @@ -605,7 +624,8 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par 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__); + err("%s: demodulator is not responding, "\ + "possibly hung, aborting.\n", __func__); return -EREMOTEIO; } msleep(10); @@ -616,7 +636,8 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par 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__); + err("%s: demodulator is not responding," \ + "possibly hung, aborting.\n", __func__); return -EREMOTEIO; } msleep(10); @@ -637,7 +658,7 @@ static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_paramet dprintk("frequency=%i\n", p->frequency); if (cx24123_pll_calculate(fe, p) != 0) { - printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__); + err("%s: cx24123_pll_calcutate failed\n", __func__); return -EINVAL; } @@ -654,18 +675,38 @@ static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_paramet 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); + dprintk("pll tune VCA=%d, band=%d, pll=%d\n", state->VCAarg, + state->bandselectarg, state->pllarg); return 0; } + +/* + * 0x23: + * [7:7] = BTI enabled + * [6:6] = I2C repeater enabled + * [5:5] = I2C repeater start + * [0:0] = BTI start + */ + +/* mode == 1 -> i2c-repeater, 0 -> bti */ +static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start) +{ + u8 r = cx24123_readreg(state, 0x23) & 0x1e; + if (mode) + r |= (1 << 6) | (start << 5); + else + r |= (1 << 7) | (start); + return cx24123_writereg(state, 0x23, r); +} + static int cx24123_initfe(struct dvb_frontend* fe) { struct cx24123_state *state = fe->demodulator_priv; int i; - dprintk("%s: init frontend\n",__FUNCTION__); + dprintk("init frontend\n"); /* Configure the demod to a good set of defaults */ for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++) @@ -675,6 +716,9 @@ static int cx24123_initfe(struct dvb_frontend* fe) if(state->config->lnb_polarity) cx24123_writereg(state, 0x32, cx24123_readreg(state, 0x32) | 0x02); + if (state->config->dont_use_pll) + cx24123_repeater_mode(state, 1, 0); + return 0; } @@ -687,10 +731,10 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage switch (voltage) { case SEC_VOLTAGE_13: - dprintk("%s: setting voltage 13V\n", __FUNCTION__); + dprintk("setting voltage 13V\n"); return cx24123_writereg(state, 0x29, val & 0x7f); case SEC_VOLTAGE_18: - dprintk("%s: setting voltage 18V\n", __FUNCTION__); + dprintk("setting voltage 18V\n"); return cx24123_writereg(state, 0x29, val | 0x80); case SEC_VOLTAGE_OFF: /* already handled in cx88-dvb */ @@ -708,7 +752,8 @@ 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__); + err("%s: diseqc queue not ready, " \ + "command may be lost.\n", __func__); break; } msleep(10); @@ -720,7 +765,7 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma struct cx24123_state *state = fe->demodulator_priv; int i, val, tone; - dprintk("%s:\n",__FUNCTION__); + dprintk("\n"); /* stop continuous tone if enabled */ tone = cx24123_readreg(state, 0x29); @@ -755,7 +800,7 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t struct cx24123_state *state = fe->demodulator_priv; int val, tone; - dprintk("%s:\n", __FUNCTION__); + dprintk("\n"); /* stop continuous tone if enabled */ tone = cx24123_readreg(state, 0x29); @@ -789,13 +834,21 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t 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 (state->config->dont_use_pll) { + u32 tun_status = 0; + if (fe->ops.tuner_ops.get_status) + fe->ops.tuner_ops.get_status(fe, &tun_status); + if (tun_status & TUNER_STATUS_LOCKED) + *status |= FE_HAS_SIGNAL; + } else { + int lock = cx24123_readreg(state, 0x20); + if (lock & 0x01) + *status |= FE_HAS_SIGNAL; + } + if (sync & 0x02) *status |= FE_HAS_CARRIER; /* Phase locked */ if (sync & 0x04) @@ -814,7 +867,7 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) * 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) +static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber) { struct cx24123_state *state = fe->demodulator_priv; @@ -824,23 +877,24 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber) (cx24123_readreg(state, 0x1d) << 8 | cx24123_readreg(state, 0x1e)); - dprintk("%s: BER = %d\n",__FUNCTION__,*ber); + dprintk("BER = %d\n", *ber); return 0; } -static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) +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); + dprintk("Signal strength = %d\n", *signal_strength); return 0; } -static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr) +static int cx24123_read_snr(struct dvb_frontend *fe, u16 *snr) { struct cx24123_state *state = fe->demodulator_priv; @@ -849,16 +903,17 @@ static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr) *snr = 65535 - (((u16)cx24123_readreg(state, 0x18) << 8) | (u16)cx24123_readreg(state, 0x19)); - dprintk("%s: read S/N index = %d\n",__FUNCTION__,*snr); + dprintk("read S/N index = %d\n", *snr); return 0; } -static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +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__); + dprintk("\n"); if (state->config->set_ts_params) state->config->set_ts_params(fe, 0); @@ -869,13 +924,22 @@ static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par 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); + + if (!state->config->dont_use_pll) + cx24123_pll_tune(fe, p); + else if (fe->ops.tuner_ops.set_params) + fe->ops.tuner_ops.set_params(fe, p); + else + err("it seems I don't have a tuner..."); /* Enable automatic aquisition and reset cycle */ cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07)); cx24123_writereg(state, 0x00, 0x10); cx24123_writereg(state, 0x00, 0); + if (state->config->agc_callback) + state->config->agc_callback(fe); + return 0; } @@ -883,14 +947,14 @@ static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par { struct cx24123_state *state = fe->demodulator_priv; - dprintk("%s: get_frontend\n",__FUNCTION__); + dprintk("\n"); if (cx24123_get_inversion(state, &p->inversion) != 0) { - printk("%s: Failed to get inversion status\n",__FUNCTION__); + err("%s: Failed to get inversion status\n", __func__); return -EREMOTEIO; } if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) { - printk("%s: Failed to get fec status\n",__FUNCTION__); + err("%s: Failed to get fec status\n", __func__); return -EREMOTEIO; } p->frequency = state->currentfreq; @@ -911,13 +975,13 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) switch (tone) { case SEC_TONE_ON: - dprintk("%s: setting tone on\n", __FUNCTION__); + dprintk("setting tone on\n"); return cx24123_writereg(state, 0x29, val | 0x10); case SEC_TONE_OFF: - dprintk("%s: setting tone off\n",__FUNCTION__); + dprintk("setting tone off\n"); return cx24123_writereg(state, 0x29, val & 0xef); default: - printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); + err("CASE reached default with tone=%d\n", tone); return -EINVAL; } @@ -950,47 +1014,86 @@ static int cx24123_get_algo(struct dvb_frontend *fe) static void cx24123_release(struct dvb_frontend* fe) { struct cx24123_state* state = fe->demodulator_priv; - dprintk("%s\n",__FUNCTION__); + dprintk("\n"); + i2c_del_adapter(&state->tuner_i2c_adapter); kfree(state); } +static int cx24123_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg msg[], int num) +{ + struct cx24123_state *state = i2c_get_adapdata(i2c_adap); + /* this repeater closes after the first stop */ + cx24123_repeater_mode(state, 1, 1); + return i2c_transfer(state->i2c, msg, num); +} + +static u32 cx24123_tuner_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm cx24123_tuner_i2c_algo = { + .master_xfer = cx24123_tuner_i2c_tuner_xfer, + .functionality = cx24123_tuner_i2c_func, +}; + +struct i2c_adapter * + cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe) +{ + struct cx24123_state *state = fe->demodulator_priv; + return &state->tuner_i2c_adapter; +} +EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter); + static struct dvb_frontend_ops cx24123_ops; struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, struct i2c_adapter* i2c) { - struct cx24123_state* state = NULL; - int ret; - - dprintk("%s\n",__FUNCTION__); + struct cx24123_state *state = + kzalloc(sizeof(struct cx24123_state), GFP_KERNEL); + dprintk("\n"); /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct cx24123_state), GFP_KERNEL); if (state == NULL) { - printk("Unable to kmalloc\n"); + err("Unable to kmalloc\n"); goto error; } /* setup the state */ state->config = config; state->i2c = i2c; - 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"); + state->demod_rev = cx24123_readreg(state, 0x00); + switch (state->demod_rev) { + case 0xe1: info("detected CX24123C\n"); break; + case 0xd1: info("detected CX24123\n"); break; + default: + err("wrong demod revision: %x\n", state->demod_rev); goto error; } /* create dvb_frontend */ memcpy(&state->frontend.ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; + + /* create tuner i2c adapter */ + if (config->dont_use_pll) + cx24123_repeater_mode(state, 1, 0); + + strncpy(state->tuner_i2c_adapter.name, + "CX24123 tuner I2C bus", I2C_NAME_SIZE); + state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, + state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo; + state->tuner_i2c_adapter.algo_data = NULL; + i2c_set_adapdata(&state->tuner_i2c_adapter, state); + if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) { + err("tuner i2c bus could not be initialized\n"); + goto error; + } + return &state->frontend; error: @@ -1040,7 +1143,8 @@ 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_DESCRIPTION("DVB Frontend module for Conexant " \ + "CX24123/CX24109/CX24113 hardware"); MODULE_AUTHOR("Steven Toth"); MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/frontends/cx24123.h b/linux/drivers/media/dvb/frontends/cx24123.h index 84f9e4f5c..81ebc3d2f 100644 --- a/linux/drivers/media/dvb/frontends/cx24123.h +++ b/linux/drivers/media/dvb/frontends/cx24123.h @@ -33,16 +33,27 @@ struct cx24123_config /* 0 = LNB voltage normal, 1 = LNB voltage inverted */ int lnb_polarity; + + /* this device has another tuner */ + u8 dont_use_pll; + void (*agc_callback) (struct dvb_frontend *); }; #if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) && defined(MODULE)) -extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, - struct i2c_adapter* i2c); +extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, + struct i2c_adapter *i2c); +extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *); #else -static inline struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, - struct i2c_adapter* i2c) +static inline struct dvb_frontend *cx24123_attach( + const struct cx24123_config *config, struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +static struct i2c_adapter * + cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_CX24123 -- cgit v1.2.3 From 2108d7236c7fc286fe808bf6d74ecbb3626ecd28 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 29 Mar 2008 22:28:07 +0100 Subject: SkyStar2: preparing support for the rev2.8 From: Patrick Boettcher Support is prepared, but the CX24113-driver .c-file is missing. After sorting out the NDA problems, the file will be there immediatly. Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/b2c2/Kconfig | 2 + linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 48 +++++++++++++++++++++ linux/drivers/media/dvb/b2c2/flexcop-misc.c | 2 + linux/drivers/media/dvb/b2c2/flexcop-reg.h | 2 + linux/drivers/media/dvb/frontends/cx24113.h | 55 +++++++++++++++++++++++++ 5 files changed, 109 insertions(+) create mode 100644 linux/drivers/media/dvb/frontends/cx24113.h (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/b2c2/Kconfig b/linux/drivers/media/dvb/b2c2/Kconfig index ffcbc7610..8193d88d1 100644 --- a/linux/drivers/media/dvb/b2c2/Kconfig +++ b/linux/drivers/media/dvb/b2c2/Kconfig @@ -10,6 +10,8 @@ config DVB_B2C2_FLEXCOP select DVB_BCM3510 if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE select TUNER_SIMPLE if !DVB_FE_CUSTOMISE + select DVB_ISL6421 if !DVB_FE_CUSTOMISE + select DVB_CX24123 if !DVB_FE_CUSTOMISE help Support for the digital TV receiver chip made by B2C2 Inc. included in Technisats PCI cards and USB boxes. diff --git a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 46d6f5d8c..6759c3ad2 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -19,6 +19,11 @@ #include "dvb-pll.h" #include "tuner-simple.h" +#include "cx24123.h" +#include "cx24113.h" + +#include "isl6421.h" + /* lnb control */ static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) @@ -476,11 +481,54 @@ static struct stv0297_config alps_tdee4_stv0297_config = { // .pll_set = alps_tdee4_stv0297_pll_set, }; + +static struct cx24123_config skystar2_rev2_8_cx24123_config = { + .demod_address = 0x55, + .dont_use_pll = 1, + .agc_callback = cx24113_agc_callback, +}; + +static const struct cx24113_config skystar2_rev2_8_cx24113_config = { + .i2c_addr = 0x54, + .xtal_khz = 10111, +}; + /* try to figure out the frontend, each card/box can have on of the following list */ int flexcop_frontend_init(struct flexcop_device *fc) { struct dvb_frontend_ops *ops; struct i2c_adapter *i2c = &fc->fc_i2c_adap[0].i2c_adap; + struct i2c_adapter *i2c_tuner; + + /* try the sky v2.8 (cx24123, isl6421) */ + fc->fe = dvb_attach(cx24123_attach, + &skystar2_rev2_8_cx24123_config, i2c); + if (fc->fe != NULL) { + i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe); + if (i2c_tuner != NULL) { + if (dvb_attach(cx24113_attach, fc->fe, + &skystar2_rev2_8_cx24113_config, + i2c_tuner) == NULL) + err("CX24113 could NOT be attached"); + else + info("CX24113 successfully attached"); + } + + fc->dev_type = FC_SKY_REV28; + + fc->fc_i2c_adap[2].no_base_addr = 1; + if (dvb_attach(isl6421_attach, fc->fe, + &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0) == NULL) + err("ISL6421 could NOT be attached"); + else + info("ISL6421 successfully attached"); + + /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an + * IR-receiver (PIC16F818) - but the card has no input for + * that ??? */ + + goto fe_found; + } /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c); diff --git a/linux/drivers/media/dvb/b2c2/flexcop-misc.c b/linux/drivers/media/dvb/b2c2/flexcop-misc.c index 167583bf0..93d20e56f 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-misc.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-misc.c @@ -52,6 +52,8 @@ static const char *flexcop_device_names[] = { "Sky2PC/SkyStar 2 DVB-S (old version)", "Cable2PC/CableStar 2 DVB-C", "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", + "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u", + "Sky2PC/SkyStar 2 DVB-S rev 2.8", }; static const char *flexcop_bus_names[] = { diff --git a/linux/drivers/media/dvb/b2c2/flexcop-reg.h b/linux/drivers/media/dvb/b2c2/flexcop-reg.h index 491f9bd6e..7599fccc1 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-reg.h +++ b/linux/drivers/media/dvb/b2c2/flexcop-reg.h @@ -25,6 +25,8 @@ typedef enum { FC_SKY_OLD, FC_CABLE, FC_AIR_ATSC3, + FC_SKY_REV27, + FC_SKY_REV28, } flexcop_device_type_t; typedef enum { diff --git a/linux/drivers/media/dvb/frontends/cx24113.h b/linux/drivers/media/dvb/frontends/cx24113.h new file mode 100644 index 000000000..d549041b2 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/cx24113.h @@ -0,0 +1,55 @@ +/* + * Driver for Conexant CX24113/CX24128 Tuner (Satelite) + * + * Copyright (C) 2007-8 Patrick Boettcher + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= + */ + +#ifndef CX24113_H +#define CX24113_H + +struct dvb_frontend; + +struct cx24113_config { + u8 i2c_addr; /* 0x14 or 0x54 */ + + u32 xtal_khz; +}; + +/* TODO: #if defined(CONFIG_DVB_TUNER_CX24113) || \ + * (defined(CONFIG_DVB_TUNER_CX24113_MODULE) && defined(MODULE)) */ + +#if 0 +extern struct dvb_frontend *cx24113_attach(struct dvb_frontend *, + const struct cx24113_config *config, struct i2c_adapter *i2c); + +extern void cx24113_agc_callback(struct dvb_frontend *fe); +#else +static inline struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, + const struct cx24113_config *config, struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} + +static inline void cx24113_agc_callback(struct dvb_frontend *fe) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); +} +#endif + +#endif /* CX24113_H */ -- cgit v1.2.3 From 65f4d651251094e1a340a767bd9c3d14423b4a44 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 29 Mar 2008 22:30:49 +0100 Subject: [PATCH] reworked patch to support TT connect S-2400 From: Andre Weidemann Added support for Technotrend connect S-2400. Signed-off-by: Andre Weidemann Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 + linux/drivers/media/dvb/dvb-usb/ttusb2.c | 62 +++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index aa4844ef8..2cbfd6694 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -40,6 +40,7 @@ #define USB_VID_MSI 0x0db0 #define USB_VID_OPERA1 0x695c #define USB_VID_PINNACLE 0x2304 +#define USB_VID_TECHNOTREND 0x0b48 #define USB_VID_TERRATEC 0x0ccd #define USB_VID_VISIONPLUS 0x13d3 #define USB_VID_TWINHAN 0x1822 @@ -134,6 +135,7 @@ #define USB_PID_AVERMEDIA_EXPRESS 0xb568 #define USB_PID_AVERMEDIA_VOLAR 0xa807 #define USB_PID_AVERMEDIA_VOLAR_2 0xb808 +#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a #define USB_PID_PINNACLE_PCTV2000E 0x022c #define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228 diff --git a/linux/drivers/media/dvb/dvb-usb/ttusb2.c b/linux/drivers/media/dvb/dvb-usb/ttusb2.c index bafe82f66..572760414 100644 --- a/linux/drivers/media/dvb/dvb-usb/ttusb2.c +++ b/linux/drivers/media/dvb/dvb-usb/ttusb2.c @@ -182,17 +182,23 @@ static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap) /* DVB USB Driver stuff */ static struct dvb_usb_device_properties ttusb2_properties; +static struct dvb_usb_device_properties ttusb2_properties_s2400; static int ttusb2_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf,&ttusb2_properties,THIS_MODULE,NULL); + if (dvb_usb_device_init(intf, &ttusb2_properties, THIS_MODULE, NULL) == 0 || + dvb_usb_device_init(intf, &ttusb2_properties_s2400, THIS_MODULE, NULL) == 0) + return 0; + return -ENODEV; } static struct usb_device_id ttusb2_table [] = { - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) }, - {} /* Terminating entry */ + { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) }, + { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) }, + { USB_DEVICE(USB_VID_TECHNOTREND, + USB_PID_TECHNOTREND_CONNECT_S2400) }, + {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, ttusb2_table); @@ -248,6 +254,54 @@ static struct dvb_usb_device_properties ttusb2_properties = { } }; +static struct dvb_usb_device_properties ttusb2_properties_s2400 = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-tt-s2400-01.fw", + + .size_of_priv = sizeof(struct ttusb2_state), + + .num_adapters = 1, + .adapter = { + { + .streaming_ctrl = NULL, + + .frontend_attach = ttusb2_frontend_attach, + .tuner_attach = ttusb2_tuner_attach, + + /* parameter for the MPEG2-data transfer */ + .stream = { + .type = USB_ISOC, + .count = 5, + .endpoint = 0x02, + .u = { + .isoc = { + .framesperurb = 4, + .framesize = 940, + .interval = 1, + } + } + } + } + }, + + .power_ctrl = ttusb2_power_ctrl, + .identify_state = ttusb2_identify_state, + + .i2c_algo = &ttusb2_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + + .num_device_descs = 1, + .devices = { + { "Technotrend TT-connect S-2400", + { &ttusb2_table[2], NULL }, + { NULL }, + }, + } +}; + static struct usb_driver ttusb2_driver = { .name = "dvb_usb_ttusb2", .probe = ttusb2_probe, -- cgit v1.2.3 From a2bd872e5bb2acb1cc46a1e15a39cf3f0ce76628 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 29 Mar 2008 22:35:57 +0100 Subject: PATCH for various Dibcom based devices From: Albert Comerma This patch introduces support for dvb-t for the following DiBcom based cards: - Terratec Cinergy HT USB XE (USB-ID: 0ccd:0058) - Terratec Cinergy HT Express (USB-ID: 0ccd:0060) - Pinnacle 320CX (USB-ID: 2304:022e) - Pinnacle PCTV72e (USB-ID: 2304:0236) - Pinnacle PCTV73e (USB-ID: 2304:0237) - Yuan EC372S (USB-ID: 1164:1edc) Signed-off-by: Hans-Frieder Vogt Signed-off-by: Felix Apitzsch Signed-off-by: Antti Palosaari Signed-off-by: Albert Comerma Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 259 +++++++++++++++++++--- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 9 +- 2 files changed, 238 insertions(+), 30 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index e7093826e..9fd8399e5 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -13,6 +13,7 @@ #include "dib7000p.h" #include "mt2060.h" #include "mt2266.h" +#include "tuner-xc2028.h" #include "dib0070.h" static int force_lna_activation; @@ -297,6 +298,149 @@ static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap) &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;; } +/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */ +struct dibx000_agc_config xc3028_agc_config = { + BAND_VHF | BAND_UHF, /* band_caps */ + + /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0, + * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, + * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */ + (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | + (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */ + + 712, /* inv_gain */ + 21, /* time_stabiliz */ + + 0, /* alpha_level */ + 118, /* thlock */ + + 0, /* wbd_inv */ + 2867, /* wbd_ref */ + 0, /* wbd_sel */ + 2, /* wbd_alpha */ + + 0, /* agc1_max */ + 0, /* agc1_min */ + 39718, /* agc2_max */ + 9930, /* agc2_min */ + 0, /* agc1_pt1 */ + 0, /* agc1_pt2 */ + 0, /* agc1_pt3 */ + 0, /* agc1_slope1 */ + 0, /* agc1_slope2 */ + 0, /* agc2_pt1 */ + 128, /* agc2_pt2 */ + 29, /* agc2_slope1 */ + 29, /* agc2_slope2 */ + + 17, /* alpha_mant */ + 27, /* alpha_exp */ + 23, /* beta_mant */ + 51, /* beta_exp */ + + 1, /* perform_agc_softsplit */ +}; + +/* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */ +struct dibx000_bandwidth_config xc3028_bw_config = { + 60000, 30000, /* internal, sampling */ + 1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */ + 0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, + modulo */ + (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */ + (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */ + 20452225, /* timf */ + 30000000, /* xtal_hz */ +}; + +static struct dib7000p_config stk7700ph_dib7700_xc3028_config = { + .output_mpeg2_in_188_bytes = 1, + .tuner_is_baseband = 1, + + .agc_config_count = 1, + .agc = &xc3028_agc_config, + .bw = &xc3028_bw_config, + + .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, +}; + +static int stk7700ph_xc3028_callback(void *ptr, int command, int arg) +{ + struct dvb_usb_adapter *adap = ptr; + + switch (command) { + case XC2028_TUNER_RESET: + /* Send the tuner in then out of reset */ + dib7000p_set_gpio(adap->fe, 8, 0, 0); msleep(10); + dib7000p_set_gpio(adap->fe, 8, 0, 1); + break; + case XC2028_RESET_CLK: + break; + default: + err("%s: unknown command %d, arg %d\n", __func__, + command, arg); + return -EINVAL; + } + return 0; +} + +static struct xc2028_ctrl stk7700ph_xc3028_ctrl = { + .fname = XC2028_DEFAULT_FIRMWARE, + .max_len = 64, + .demod = XC3028_FE_DIBCOM52, +}; + +static struct xc2028_config stk7700ph_xc3028_config = { + .i2c_addr = 0x61, + .callback = stk7700ph_xc3028_callback, + .ctrl = &stk7700ph_xc3028_ctrl, +}; + +static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct usb_device_descriptor *desc = &adap->dev->udev->descriptor; + + if (desc->idVendor == USB_VID_PINNACLE && + desc->idProduct == USB_PID_PINNACLE_EXPRESSCARD_320CX) + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); + else + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(20); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + msleep(10); + + dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + &stk7700ph_dib7700_xc3028_config); + + adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + &stk7700ph_dib7700_xc3028_config); + + return adap->fe == NULL ? -ENODEV : 0; +} + +static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct i2c_adapter *tun_i2c; + + tun_i2c = dib7000p_get_i2c_master(adap->fe, + DIBX000_I2C_INTERFACE_TUNER, 1); + + stk7700ph_xc3028_config.i2c_adap = tun_i2c; + stk7700ph_xc3028_config.video_dev = adap; + + return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config) + == NULL ? -ENODEV : 0; +} + #define DEFAULT_RC_INTERVAL 150 static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; @@ -794,6 +938,10 @@ static struct dib7000p_config dib7070p_dib7000p_config = { /* STK7070P */ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) { + if (adap->dev->udev->descriptor.idVendor == USB_VID_PINNACLE && + adap->dev->udev->descriptor.idProduct == USB_PID_PINNACLE_PCTV72E) + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); + else dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); @@ -808,9 +956,11 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) msleep(10); dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, &dib7070p_dib7000p_config); + dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + &dib7070p_dib7000p_config); - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &dib7070p_dib7000p_config); + adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + &dib7070p_dib7000p_config); return adap->fe == NULL ? -ENODEV : 0; } @@ -878,34 +1028,41 @@ static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap) /* DVB-USB and USB stuff follows */ struct usb_device_id dib0700_usb_id_table[] = { /* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) }, - { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P_PC) }, - - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P_PC) }, + { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) }, + { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) }, + { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) }, /* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) }, - { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500) }, - { USB_DEVICE(USB_VID_UNIWILL, USB_PID_UNIWILL_STK7700P) }, - { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) }, + { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500) }, + { USB_DEVICE(USB_VID_UNIWILL, USB_PID_UNIWILL_STK7700P) }, + { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P) }, + { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) }, /* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV2000E) }, - { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) }, - { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700D) }, + { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV2000E) }, + { USB_DEVICE(USB_VID_TERRATEC, + USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) }, + { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700D) }, /* 15 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070P) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DVB_T_FLASH) }, - { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070PD) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) }, - { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) }, + { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DVB_T_FLASH) }, + { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070PD) }, + { USB_DEVICE(USB_VID_PINNACLE, + USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) }, + { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) }, /* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) }, - { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) }, - { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) }, - { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) }, - { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) }, -/* 25 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) }, - { 0 } /* Terminating entry */ + { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) }, + { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) }, + { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) }, + { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) }, +/* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) }, + { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) }, + { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_USB_XE) }, + { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_EXPRESSCARD_320CX) }, + { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV72E) }, +/* 30 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73E) }, + { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_EC372S) }, + { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) }, + { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1069,12 +1226,16 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 1, + .num_device_descs = 2, .devices = { { "ASUS My Cinema U3000 Mini DVBT Tuner", { &dib0700_usb_id_table[23], NULL }, { NULL }, }, + { "Yuan EC372S", + { &dib0700_usb_id_table[31], NULL }, + { NULL }, + } } }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -1090,7 +1251,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 6, + .num_device_descs = 8, .devices = { { "DiBcom STK7070P reference design", { &dib0700_usb_id_table[15], NULL }, @@ -1116,6 +1277,14 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[26], NULL }, { NULL }, }, + { "Pinnacle PCTV 72e", + { &dib0700_usb_id_table[29], NULL }, + { NULL }, + }, + { "Pinnacle PCTV 73e", + { &dib0700_usb_id_table[30], NULL }, + { NULL }, + }, }, .rc_interval = DEFAULT_RC_INTERVAL, @@ -1155,6 +1324,40 @@ struct dvb_usb_device_properties dib0700_devices[] = { { NULL }, } } + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + + .num_adapters = 1, + .adapter = { + { + .frontend_attach = stk7700ph_frontend_attach, + .tuner_attach = stk7700ph_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + + .size_of_priv = sizeof(struct + dib0700_adapter_state), + }, + }, + + .num_device_descs = 3, + .devices = { + { "Terratec Cinergy HT USB XE", + { &dib0700_usb_id_table[27], NULL }, + { NULL }, + }, + { "Pinnacle Expresscard 320cx", + { &dib0700_usb_id_table[28], NULL }, + { NULL }, + }, + { "Terratec Cinergy HT Express", + { &dib0700_usb_id_table[32], NULL }, + { NULL }, + }, + }, + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_key_map = dib0700_rc_keys, + .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), + .rc_query = dib0700_rc_query }, }; diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 2cbfd6694..2214bfe80 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -47,8 +47,8 @@ #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 #define USB_VID_UNIWILL 0x1584 #define USB_VID_WIDEVIEW 0x14aa -/* dom : pour gigabyte u7000 */ #define USB_VID_GIGABYTE 0x1044 +#define USB_VID_YUAN 0x1164 /* Product IDs */ @@ -137,9 +137,14 @@ #define USB_PID_AVERMEDIA_VOLAR_2 0xb808 #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a +#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 +#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060 +#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e #define USB_PID_PINNACLE_PCTV2000E 0x022c #define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228 #define USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T 0x0229 +#define USB_PID_PINNACLE_PCTV72E 0x0236 +#define USB_PID_PINNACLE_PCTV73E 0x0237 #define USB_PID_PCTV_200E 0x020e #define USB_PID_PCTV_400E 0x020f #define USB_PID_PCTV_450E 0x0222 @@ -185,9 +190,9 @@ #define USB_PID_OPERA1_WARM 0x3829 #define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514 #define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513 -/* dom pour gigabyte u7000 */ #define USB_PID_GIGABYTE_U7000 0x7001 #define USB_PID_ASUS_U3000 0x171f #define USB_PID_ASUS_U3100 0x173f +#define USB_PID_YUAN_EC372S 0x1edc #endif -- cgit v1.2.3 From dccd5e9ec5e1abee6e6ea82fe609c71ff643d868 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 29 Mar 2008 22:37:01 +0100 Subject: [PATCH] support key repeat with dib0700 ir receiver From: Patrick Boettcher This patch enables support for repeating last event when a key is holded down with dib0700 devices. It works with rc5 and nec remotes. It also fixes an annoying bug that floods kernel log with "Unknown key" messages after each keypress. This happened because the driver was not resetting infrared register after each poll so it kept polling last key even if nothing was being pressed. Fixing this, (calling rc_setup after each poll), permits to implement key repeat. Signed-off-by: Filippo Argiolas Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700.h | 4 ++ linux/drivers/media/dvb/dvb-usb/dib0700_core.c | 4 +- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 58 +++++++++++++++++++++-- 3 files changed, 61 insertions(+), 5 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700.h b/linux/drivers/media/dvb/dvb-usb/dib0700.h index 4a903ea95..66d4dc6ba 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700.h +++ b/linux/drivers/media/dvb/dvb-usb/dib0700.h @@ -37,6 +37,7 @@ struct dib0700_state { u8 channel_state; u16 mt2060_if1[2]; u8 rc_toggle; + u8 rc_counter; u8 is_dib7000pc; }; @@ -44,12 +45,15 @@ extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3); extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen); extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw); +extern int dib0700_rc_setup(struct dvb_usb_device *d); extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); extern struct i2c_algorithm dib0700_i2c_algo; extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, int *cold); extern int dib0700_device_count; +extern int dvb_usb_dib0700_ir_proto; extern struct dvb_usb_device_properties dib0700_devices[]; extern struct usb_device_id dib0700_usb_id_table[]; + #endif diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_core.c b/linux/drivers/media/dvb/dvb-usb/dib0700_core.c index d48425f4a..9d3217983 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -13,7 +13,7 @@ int dvb_usb_dib0700_debug; module_param_named(debug,dvb_usb_dib0700_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS); -static int dvb_usb_dib0700_ir_proto = 1; +int dvb_usb_dib0700_ir_proto = 1; module_param(dvb_usb_dib0700_ir_proto, int, 0644); MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6)."); @@ -261,7 +261,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) return dib0700_ctrl_wr(adap->dev, b, 4); } -static int dib0700_rc_setup(struct dvb_usb_device *d) +int dib0700_rc_setup(struct dvb_usb_device *d) { u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0}; int i = dib0700_ctrl_wr(d, rc_setup, 3); diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index 9fd8399e5..fe96f7957 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -445,6 +445,9 @@ static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap) static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; +/* Number of keypresses to ignore before start repeating */ +#define RC_REPEAT_DELAY 2 + static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { u8 key[4]; @@ -458,18 +461,67 @@ static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) err("RC Query Failed"); return -1; } + + /* losing half of KEY_0 events from Philipps rc5 remotes.. */ if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0; - if (key[3-1]!=st->rc_toggle) { + + /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]); */ + + dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */ + + switch (dvb_usb_dib0700_ir_proto) { + case 0: { + /* NEC protocol sends repeat code as 0 0 0 FF */ + if ((key[3-2] == 0x00) && (key[3-3] == 0x00) && + (key[3] == 0xFF)) { + st->rc_counter++; + if (st->rc_counter > RC_REPEAT_DELAY) { + *event = d->last_event; + *state = REMOTE_KEY_PRESSED; + st->rc_counter = RC_REPEAT_DELAY; + } + return 0; + } for (i=0;iprops.rc_key_map_size; i++) { if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) { + st->rc_counter = 0; + *event = keymap[i].event; + *state = REMOTE_KEY_PRESSED; + d->last_event = keymap[i].event; + return 0; + } + } + break; + } + default: { + /* RC-5 protocol changes toggle bit on new keypress */ + for (i = 0; i < d->props.rc_key_map_size; i++) { + if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) { + if (d->last_event == keymap[i].event && + key[3-1] == st->rc_toggle) { + st->rc_counter++; + /* prevents unwanted double hits */ + if (st->rc_counter > RC_REPEAT_DELAY) { + *event = d->last_event; + *state = REMOTE_KEY_PRESSED; + st->rc_counter = RC_REPEAT_DELAY; + } + + return 0; + } + st->rc_counter = 0; *event = keymap[i].event; *state = REMOTE_KEY_PRESSED; - st->rc_toggle=key[3-1]; + st->rc_toggle = key[3-1]; + d->last_event = keymap[i].event; return 0; } } - err("Unknown remote controller key : %2X %2X",(int)key[3-2],(int)key[3-3]); + break; + } } + err("Unknown remote controller key: %2X %2X %2X %2X", (int) key[3-2], (int) key[3-3], (int) key[3-1], (int) key[3]); + d->last_event = 0; return 0; } -- cgit v1.2.3 From 746c9f11dafbaa6597681934507b7b6f6b7c0557 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 29 Mar 2008 22:37:54 +0100 Subject: Added support for Terratec Cinergy T USB XXS From: Alexander Simon Alexander Simon found out that the Terratec Cinergy T USB XXS is just a clone of another DiB7070P-based device. Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 7 ++++++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index fe96f7957..e052e89bf 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1114,6 +1114,7 @@ struct usb_device_id dib0700_usb_id_table[] = { /* 30 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73E) }, { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_EC372S) }, { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) }, + { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1303,7 +1304,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { }, }, - .num_device_descs = 8, + .num_device_descs = 9, .devices = { { "DiBcom STK7070P reference design", { &dib0700_usb_id_table[15], NULL }, @@ -1337,6 +1338,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { { &dib0700_usb_id_table[30], NULL }, { NULL }, }, + { "Terratec Cinergy T USB XXS", + { &dib0700_usb_id_table[33], NULL }, + { NULL }, + }, }, .rc_interval = DEFAULT_RC_INTERVAL, diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 2214bfe80..9757fb2c3 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -139,6 +139,7 @@ #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a #define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 #define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060 +#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 #define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e #define USB_PID_PINNACLE_PCTV2000E 0x022c #define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228 @@ -193,6 +194,6 @@ #define USB_PID_GIGABYTE_U7000 0x7001 #define USB_PID_ASUS_U3000 0x171f #define USB_PID_ASUS_U3100 0x173f -#define USB_PID_YUAN_EC372S 0x1edc +#define USB_PID_YUAN_EC372S 0x1edc #endif -- cgit v1.2.3 From 01407df1fca0fa2aa38ce08078b074f16fc83120 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Sat, 29 Mar 2008 22:47:43 +0100 Subject: New USB ID for Leadtek DVB-T USB From: Darryl Green Detect Leadtek Winfast USB DTV Dongle with ID of 0x6f01 Signed-off-by: Darryl Green Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-usb/dib0700_devices.c | 3 ++- linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb') diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c index e052e89bf..6477fc66c 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1115,6 +1115,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_EC372S) }, { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) }, { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) }, + { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1179,7 +1180,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { { NULL }, }, { "Leadtek Winfast DTV Dongle (STK7700P based)", - { &dib0700_usb_id_table[8], NULL }, + { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] }, { NULL }, }, { "AVerMedia AVerTV DVB-T Express", diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 9757fb2c3..34245d1b7 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -180,6 +180,7 @@ #define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025 #define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 #define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 +#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01 #define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200 #define USB_PID_GENPIX_8PSK_REV_1_WARM 0x0201 #define USB_PID_GENPIX_8PSK_REV_2 0x0202 -- cgit v1.2.3