⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stv0299.c

📁 linux TV 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Universal driver for STV0299/TDA5059/SL1935 based    DVB QPSK frontends    Alps BSRU6, LG TDQB-S00x    Copyright (C) 2001-2002 Convergence Integrated Media GmbH	<ralph@convergence.de>,	<holger@convergence.de>,	<js@convergence.de>        Philips SU1278/SH    Copyright (C) 2002 by Peter Schildmann        <peter.schildmann@web.de>    LG TDQF-S001F    Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>                     & Andreas Oberritter <andreas@oberritter.de>    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/    #include <asm/errno.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/string.h>#include "dvb_frontend.h"#include "compat.h"static int debug = 0;#define dprintk	if (debug) printkstaticinline void ddelay(int i){	current->state=TASK_INTERRUPTIBLE;	schedule_timeout((HZ*i)/1000);}/* frontend types */#define UNKNOWN_FRONTEND  -1#define PHILIPS_SU1278SH   0#define ALPS_BSRU6         1#define LG_TDQF_S001F      2/* Master Clock = 88 MHz */#define M_CLK (88000000UL) staticstruct dvb_frontend_info uni0299_info = {	name: "STV0299/TSA5059/SL1935 based",	type: FE_QPSK,	frequency_min: 950000,	frequency_max: 2150000,	frequency_stepsize: 125,   /* kHz for QPSK frontends */	frequency_tolerance: M_CLK/2000,	symbol_rate_min: 1000000,	symbol_rate_max: 45000000,	symbol_rate_tolerance: 500,  /* ppm */	notifier_delay: 0,	caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |	      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |	      FE_CAN_QPSK |	      FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO |	      FE_CAN_CLEAN_SETUP};staticu8 init_tab [] = {        /* clock registers */        0x01, 0x15,   /* K = 0, DIRCLK = 0, M = 0x15                  */	0x02, 0x30,   /* STDBY = 0, VCO = 0 (ON), SERCLK = 0, P = 0   */                      /* f_VCO = 4MHz * 4 * (M+1) / (K+1) = 352 MHz   */	0x03, 0x00,   /* auxiliary clock not used                     */	0x04, 0x7d,   /* F22FR = 0x7d                                 */		      /* F22 = f_VCO / 128 / 0x7d = 22 kHz            */        /* I2C bus repeater */	0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1                 */ 	/* general purpose DAC registers */	0x06, 0x40,   /* DAC not used, set to high impendance mode    */	0x07, 0x00,   /* DAC LSB                                      */	/* DiSEqC registers */	0x08, 0x40,   /* DiSEqC off                                   */	0x09, 0x00,   /* FIFO                                         */        /* Input/Output configuration register */	0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */	              /* OP0 ctl = Normal, OP0 val = 1 (18 V)         */                      /* Nyquist filter = 00, QPSK reverse = 0        */                           /* AGC1 control register */	0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2   */        /* Timing loop register */	0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3                  */	0x10, 0x3f,   // AGC2  0x3d	0x11, 0x84,	0x12, 0xb5,   // Lock detect: -64  Carrier freq detect:on	0x13, 0xb6,   // alpha_car b:4 a:0  noise est:256ks  derot:on	0x14, 0x93,   // beat carc:0 d:0 e:0xf  phase detect algo: 1	0x15, 0xc9,   // lock detector threshold	0x16, 0x1d,   /* AGC1 integrator value                        */	0x17, 0x00,	0x18, 0x14,	0x19, 0xf2,	0x1a, 0x11,	0x1b, 0x9c,	0x1c, 0x00,	0x1d, 0x00,	0x1e, 0x0b,	0x1f, 0x50,	0x20, 0x00,	0x21, 0x00,	0x22, 0x00,	0x23, 0x00,	0x24, 0xff,	0x25, 0xff,	0x26, 0xff,	0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0	0x29, 0x1e,  // 1/2 threshold	0x2a, 0x14,  // 2/3 threshold	0x2b, 0x0f,  // 3/4 threshold	0x2c, 0x09,  // 5/6 threshold	0x2d, 0x05,  // 7/8 threshold	0x2e, 0x01,	0x31, 0x1f,  // test all FECs	0x32, 0x19,  // viterbi and synchro search	0x33, 0xfc,  // rs control	0x34, 0x93,  // error control	0x0b, 0x00,	0x27, 0x00,	0x2f, 0x00,	0x30, 0x00,	0x35, 0x00,	0x36, 0x00,	0x37, 0x00,	0x38, 0x00,	0x39, 0x00,	0x3a, 0x00,	0x3b, 0x00,	0x3c, 0x00,	0x3d, 0x00,	0x3e, 0x00,	0x3f, 0x00,	0x40, 0x00,	0x41, 0x00,	0x42, 0x00,	0x43, 0x00,	0x44, 0x00,	0x45, 0x00,	0x46, 0x00,	0x47, 0x00,	0x48, 0x00,	0x49, 0x00,	0x4a, 0x00,	0x4b, 0x00,	0x4c, 0x00,	0x4d, 0x00,	0x4e, 0x00,	0x4f, 0x00};staticint stv0299_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data){	int ret;	u8 buf [] = { reg, data };	struct i2c_msg msg = { addr: 0x68, flags: 0, buf: buf, len: 2 };	dprintk ("%s\n", __FUNCTION__);	ret = i2c->xfer (i2c, &msg, 1);	if (ret != 1) 		dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "			"ret == %i)\n", __FUNCTION__, reg, data, ret);	return (ret != 1) ? -1 : 0;}staticu8 stv0299_readreg (struct dvb_i2c_bus *i2c, u8 reg){	int ret;	u8 b0 [] = { reg };	u8 b1 [] = { 0 };	struct i2c_msg msg [] = { { addr: 0x68, flags: 0, buf: b0, len: 1 },			   { addr: 0x68, flags: I2C_M_RD, buf: b1, len: 1 } };	dprintk ("%s\n", __FUNCTION__);	ret = i2c->xfer (i2c, msg, 2);        	if (ret != 2) 		dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);	return b1[0];}staticint stv0299_readregs (struct dvb_i2c_bus *i2c, u8 reg1, u8 *b, u8 len){        int ret;        struct i2c_msg msg [] = { { addr: 0x68, flags: 0, buf: &reg1, len: 1 },                           { addr: 0x68, flags: I2C_M_RD, buf: b, len: len } };	dprintk ("%s\n", __FUNCTION__);        ret = i2c->xfer (i2c, msg, 2);        if (ret != 2)                dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);        return ret == 2 ? 0 : -1;}staticint pll_write (struct dvb_i2c_bus *i2c, u8 data [4], int ftype){	int ret;	u8 rpt1 [] = { 0x05, 0xb5 };  /*  enable i2c repeater on stv0299  */	/* TSA5059 i2c-bus address */	u8 addr = (ftype == PHILIPS_SU1278SH) ? 0x60 : 0x61;	struct i2c_msg msg [] = {{ addr: 0x68, flags: 0, buf: rpt1, len: 2 },			         { addr: addr, flags: 0, buf: data, len: 4 }};	dprintk ("%s\n", __FUNCTION__);	ret = i2c->xfer (i2c, msg, 2);	if (ret != 2)		dprintk("%s: i/o error (ret == %i)\n", __FUNCTION__, ret);	return (ret != 2) ? -1 : 0;}staticint sl1935_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype){	u8 buf[4];	u32 div;	u32 ratios[] = { 2000, 1000, 500, 250, 125 };	u8 ratio;	for (ratio = 4; ratio > 0; ratio--)		if ((freq / ratios[ratio]) <= 0x3fff)			break;	div = freq / ratios[ratio];	buf[0] = (freq >> 8) & 0x7f;	buf[1] = freq & 0xff;	buf[2] = 0x80 | ratio;	if (freq < 1531000)		buf[3] = 0x10;	else		buf[3] = 0x00;	return pll_write (i2c, buf, ftype);}/** *   set up the downconverter frequency divisor for a  *   reference clock comparision frequency of 125 kHz. */staticint tsa5059_set_tv_freq	(struct dvb_i2c_bus *i2c, u32 freq, int ftype){        u32 div = freq / 125;	u8 buf[4] = { (div >> 8) & 0x7f, div & 0xff, 0x84 };	if (ftype == PHILIPS_SU1278SH)		/* activate f_xtal/f_comp signal output */		/* charge pump current C0/C1 = 00 */		buf[3] = 0x20;	else		buf[3] = freq > 1530000 ? 0xc0 : 0xc4;	dprintk ("%s\n", __FUNCTION__);	return pll_write (i2c, buf, ftype);}staticint pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype){	if (ftype == LG_TDQF_S001F)		return sl1935_set_tv_freq(i2c, freq, ftype);	else		return tsa5059_set_tv_freq(i2c, freq, ftype);}#if 0staticint tsa5059_read_status	(struct dvb_i2c_bus *i2c){	int ret;	u8 rpt1 [] = { 0x05, 0xb5 };	u8 stat [] = { 0 };	struct i2c_msg msg [] = {{ addr: 0x68, flags: 0, buf: rpt1, len: 2 },			  { addr: 0x60, flags: I2C_M_RD, buf: stat, len: 1 }};	dprintk ("%s\n", __FUNCTION__);	ret = i2c->xfer (i2c, msg, 2);	if (ret != 2)		dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);	return stat[0];}#endifstaticint stv0299_init (struct dvb_i2c_bus *i2c, int ftype){	int i;	dprintk("stv0299: init chip\n");	for (i=0; i<sizeof(init_tab); i+=2)		stv0299_writereg (i2c, init_tab[i], init_tab[i+1]);        /* AGC1 reference register setup */	if (ftype == PHILIPS_SU1278SH)	  stv0299_writereg (i2c, 0x0f, 0xd2);  /* Iagc = Inverse, m1 = 18 */	else	  stv0299_writereg (i2c, 0x0f, 0x52);  /* Iagc = Normal,  m1 = 18 */	return 0;}staticint stv0299_check_inversion (struct dvb_i2c_bus *i2c){	dprintk ("%s\n", __FUNCTION__);	if ((stv0299_readreg (i2c, 0x1b) & 0x98) != 0x98) {		ddelay(30);		if ((stv0299_readreg (i2c, 0x1b) & 0x98) != 0x98) {			u8 val = stv0299_readreg (i2c, 0x0c);			dprintk ("toggle inversion\n");			return stv0299_writereg (i2c, 0x0c, val ^ 0x01);		}	}	return 0;}staticint stv0299_set_FEC (struct dvb_i2c_bus *i2c, fe_code_rate_t fec){	dprintk ("%s\n", __FUNCTION__);	switch (fec) {	case FEC_AUTO:		return stv0299_writereg (i2c, 0x31, 0x1f);	case FEC_1_2:		return stv0299_writereg (i2c, 0x31, 0x01);	case FEC_2_3:		return stv0299_writereg (i2c, 0x31, 0x02);	case FEC_3_4:		return stv0299_writereg (i2c, 0x31, 0x04);	case FEC_5_6:		return stv0299_writereg (i2c, 0x31, 0x08);	case FEC_7_8:		return stv0299_writereg (i2c, 0x31, 0x10);	default:		return -EINVAL;	}}staticfe_code_rate_t stv0299_get_fec (struct dvb_i2c_bus *i2c){	static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6,					     FEC_7_8, FEC_1_2 };	u8 index;	dprintk ("%s\n", __FUNCTION__);	index = stv0299_readreg (i2c, 0x1b);	index &= 0x7;	if (index > 4)		return FEC_AUTO;	return fec_tab [index];}staticint stv0299_wait_diseqc_fifo (struct dvb_i2c_bus *i2c, int timeout){	unsigned long start = jiffies;	dprintk ("%s\n", __FUNCTION__);	while (stv0299_readreg(i2c, 0x0a) & 1) {		if (jiffies - start > timeout) {			dprintk ("%s: timeout!!\n", __FUNCTION__);			return -ETIMEDOUT;		}		ddelay(10);	};	return 0;}staticint stv0299_wait_diseqc_idle (struct dvb_i2c_bus *i2c, int timeout)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -