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

📄 stv0299.c

📁 linux环境下的dvb驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
		else if (((first_ZF >= 1350) && (first_ZF < 1420)) ||			 ((first_ZF >= 1950) && (first_ZF < 2150)))			reg0[1] = 0x0B;		else if ((first_ZF >= 1420) && (first_ZF < 1455))			reg0[1] = 0x0F;	}	if (first_ZF > 1525)		reg1[1] |= 0x80;	else		reg1[1] &= 0x7F;	if (_fband == 2) {	        if (first_ZF > 1430) { /* 1430MHZ */	                reg1[1] &= 0xCF; /* N2 */			reg2[1] &= 0xCF; /* R2 */			reg2[1] |= 0x10;	        } else {        		reg1[1] &= 0xCF; /* N2 */			reg1[1] |= 0x20;			reg2[1] &= 0xCF; /* R2 */			reg2[1] |= 0x10;		}	}	if (_fband == 3) {        	if ((first_ZF >= 1455) &&		    (first_ZF < 1630)) {			reg1[1] &= 0xCF; /* N2 */			reg1[1] |= 0x20;			reg2[1] &= 0xCF; /* R2 */	        } else {			if (first_ZF < 1455) {	                        reg1[1] &= 0xCF; /* N2 */				reg1[1] |= 0x20;                	        reg2[1] &= 0xCF; /* R2 */                        	reg2[1] |= 0x10;	                } else {	                        if (first_ZF >= 1630) {        	                        reg1[1] &= 0xCF; /* N2 */                        	        reg2[1] &= 0xCF; /* R2 */                                	reg2[1] |= 0x10;	                        }        	        }	        }	}        /* set ports, enable P0 for symbol rates > 4Ms/s */	if (srate >= 4000000)		reg1[1] |= 0x0c;	else		reg1[1] |= 0x04;	reg2[1] |= 0x0c;	R = 64;	A = 64;	P = 64;  //32	M = (freq * R) / 4;		/* in Mhz */	N = (M - A * 1000) / (P * 1000);	reg1[1] |= (N >> 9) & 0x03;	reg1[2]  = (N >> 1) & 0xff;	reg1[3]  = (N << 7) & 0x80;	reg2[1] |= (R >> 8) & 0x03;	reg2[2]  = R & 0xFF;	/* R */	reg1[3] |= A & 0x7f;	/* A */	if (P == 64)		reg1[1] |= 0x40; /* Prescaler 64/65 */	reg0[1] |= 0x03;	if ((err = pll_write(i2c, 0x60, reg0, sizeof(reg0))))		return err;	if ((err = pll_write(i2c, 0x60, reg1, sizeof(reg1))))		return err;	if ((err = pll_write(i2c, 0x60, reg2, sizeof(reg2))))		return err;	return 0;}static int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, int srate){	switch(ftype) {	case SAMSUNG_TBMU24112IMB:	        return sl1935_set_tv_freq(i2c, freq, ftype);		case LG_TDQF_S001F:		return sl1935_set_tv_freq(i2c, freq, ftype);	    	case PHILIPS_SU1278_TUA:		return tua6100_set_tv_freq(i2c, freq, ftype, srate);	default:		return tsa5059_set_tv_freq(i2c, freq, ftype, srate);	}}#if 0static int 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];}#endifstatic int stv0299_init (struct dvb_i2c_bus *i2c, int ftype){	int i;	dprintk("stv0299: init chip\n");	switch(ftype) {	case SAMSUNG_TBMU24112IMB:		dprintk("%s: init stv0299 chip for Samsung TBMU24112IMB\n", __FUNCTION__);		for (i=0; i<sizeof(init_tab_samsung); i+=2)		{			dprintk("%s: reg == 0x%02x, val == 0x%02x\n", __FUNCTION__, init_tab_samsung[i], init_tab_samsung[i+1]);			stv0299_writereg (i2c, init_tab_samsung[i], init_tab_samsung[i+1]);		}		break;	case PHILIPS_SU1278_TSA_TT:	        for (i=0; i<sizeof(init_tab_su1278_tsa_tt); i+=2) {			stv0299_writereg (i2c, init_tab_su1278_tsa_tt[i], init_tab_su1278_tsa_tt[i+1]);		}	        break;	    	default:		stv0299_writereg (i2c, 0x01, 0x15);		stv0299_writereg (i2c, 0x02, ftype == PHILIPS_SU1278_TUA ? 0x00 : 0x30);		stv0299_writereg (i2c, 0x03, 0x00);		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_SU1278_TSA)		  stv0299_writereg (i2c, 0x0f, 0x92);  /* Iagc = Inverse, m1 = 18 */		else if (ftype == PHILIPS_SU1278_TUA)		  stv0299_writereg (i2c, 0x0f, 0x94);  /* Iagc = Inverse, m1 = 20 */		else		  stv0299_writereg (i2c, 0x0f, 0x52);  /* Iagc = Normal,  m1 = 18 */		break;	}	switch(stv0299_status) {	case STATUS_BER:		stv0299_writereg(i2c, 0x34, 0x93);		break;	case STATUS_UCBLOCKS:		stv0299_writereg(i2c, 0x34, 0xB3);		break;	}	return 0;}static int stv0299_set_FEC (struct dvb_i2c_bus *i2c, fe_code_rate_t fec){	dprintk ("%s\n", __FUNCTION__);	switch (fec) {	case FEC_AUTO:	{		dprintk ("%s : FEC_AUTO\n", __FUNCTION__);		return stv0299_writereg (i2c, 0x31, 0x1f);	}	case FEC_1_2:	{		dprintk ("%s : FEC_1_2\n", __FUNCTION__);		return stv0299_writereg (i2c, 0x31, 0x01);	}	case FEC_2_3:	{		dprintk ("%s : FEC_2_3\n", __FUNCTION__);		return stv0299_writereg (i2c, 0x31, 0x02);	}	case FEC_3_4:	{		dprintk ("%s : FEC_3_4\n", __FUNCTION__);		return stv0299_writereg (i2c, 0x31, 0x04);	}	case FEC_5_6:	{		dprintk ("%s : FEC_5_6\n", __FUNCTION__);		return stv0299_writereg (i2c, 0x31, 0x08);	}	case FEC_7_8:	{		dprintk ("%s : FEC_7_8\n", __FUNCTION__);		return stv0299_writereg (i2c, 0x31, 0x10);	}	default:	{		dprintk ("%s : FEC invalid\n", __FUNCTION__);		return -EINVAL;	}    }}static fe_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];}static int 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;		}		dvb_delay(10);	};	return 0;}static int stv0299_wait_diseqc_idle (struct dvb_i2c_bus *i2c, int timeout){	unsigned long start = jiffies;	dprintk ("%s\n", __FUNCTION__);	while ((stv0299_readreg(i2c, 0x0a) & 3) != 2 ) {		if (jiffies - start > timeout) {			dprintk ("%s: timeout!!\n", __FUNCTION__);			return -ETIMEDOUT;		}		dvb_delay(10);	};	return 0;}static int stv0299_send_diseqc_msg (struct dvb_i2c_bus *i2c,			     struct dvb_diseqc_master_cmd *m){	u8 val;	int i;	dprintk ("%s\n", __FUNCTION__);	if (stv0299_wait_diseqc_idle (i2c, 100) < 0)		return -ETIMEDOUT;	val = stv0299_readreg (i2c, 0x08);	if (stv0299_writereg (i2c, 0x08, (val & ~0x7) | 0x6))  /* DiSEqC mode */		return -EREMOTEIO;	for (i=0; i<m->msg_len; i++) {		if (stv0299_wait_diseqc_fifo (i2c, 100) < 0)			return -ETIMEDOUT;		if (stv0299_writereg (i2c, 0x09, m->msg[i]))			return -EREMOTEIO;	}	if (stv0299_wait_diseqc_idle (i2c, 100) < 0)		return -ETIMEDOUT;	return 0;}static int stv0299_send_diseqc_burst (struct dvb_i2c_bus *i2c, fe_sec_mini_cmd_t burst){	u8 val;	dprintk ("%s\n", __FUNCTION__);	if (stv0299_wait_diseqc_idle (i2c, 100) < 0)		return -ETIMEDOUT;	val = stv0299_readreg (i2c, 0x08);	if (stv0299_writereg (i2c, 0x08, (val & ~0x7) | 0x2))   /* burst mode */		return -EREMOTEIO;	if (stv0299_writereg (i2c, 0x09, burst == SEC_MINI_A ? 0x00 : 0xff))		return -EREMOTEIO;	if (stv0299_wait_diseqc_idle (i2c, 100) < 0)		return -ETIMEDOUT;	if (stv0299_writereg (i2c, 0x08, val))		return -EREMOTEIO;	return 0;}static int stv0299_set_tone (struct dvb_i2c_bus *i2c, fe_sec_tone_mode_t tone){	u8 val;	dprintk("%s: %s\n", __FUNCTION__,		tone == SEC_TONE_ON ? "SEC_TONE_ON" :		tone == SEC_TONE_OFF ? "SEC_TONE_OFF" : "??");	if (stv0299_wait_diseqc_idle (i2c, 100) < 0)		return -ETIMEDOUT;	val = stv0299_readreg (i2c, 0x08);	switch (tone) {	case SEC_TONE_ON:	{	    	dprintk("%s: TONE_ON\n", __FUNCTION__);		return stv0299_writereg (i2c, 0x08, val | 0x3);	}	case SEC_TONE_OFF:	{	    	dprintk("%s: TONE_OFF\n", __FUNCTION__);		return stv0299_writereg (i2c, 0x08, (val & ~0x3) | 0x02);	}	default:	{	    	dprintk("%s: TONE INVALID\n", __FUNCTION__);		return -EINVAL;	}	};}static int stv0299_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage){	u8 reg0x08;	u8 reg0x0c;	dprintk("%s: %s\n", __FUNCTION__,		voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :		voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");	reg0x08 = stv0299_readreg (i2c, 0x08);	reg0x0c = stv0299_readreg (i2c, 0x0c);	/**	 *  H/V switching over OP0, OP1 and OP2 are LNB power enable bits	 */	reg0x0c &= 0x0f;	if (voltage == SEC_VOLTAGE_OFF) {		stv0299_writereg (i2c, 0x08, reg0x08 & ~0x40);		return stv0299_writereg (i2c, 0x0c, reg0x0c & ~0x40);	} else {		stv0299_writereg (i2c, 0x08, reg0x08 | 0x40);		reg0x0c |= 0x40;   /* LNB power on */		switch (voltage) {		case SEC_VOLTAGE_13:			return stv0299_writereg (i2c, 0x0c, reg0x0c);		case SEC_VOLTAGE_18:			return stv0299_writereg (i2c, 0x0c, reg0x0c | 0x10);		default:			return -EINVAL;		};	}}static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate, int tuner_type){	u64 big = srate;	u32 ratio;	u8 aclk = 0;	u8 bclk = 0;	u8 m1;        int Mclk = M_CLK;            // check rate is within limits	if ((srate < 1000000) || (srate > 45000000)) return -EINVAL;            // calculate value to program	if (tuner_type == PHILIPS_SU1278_TSA_TT) Mclk = M_CLK_SU1278_TSA_TT;        big = big << 20;        big += (Mclk-1); // round correctly        do_div(big, Mclk);        ratio = big << 4;            // program registers	switch(tuner_type) {	case PHILIPS_SU1278_TSA_TT:	        stv0299_writereg (i2c, 0x0e, 0x44);	        if (srate >= 10000000) {		        stv0299_writereg (i2c, 0x13, 0x97);		        stv0299_writereg (i2c, 0x14, 0x95);		        stv0299_writereg (i2c, 0x15, 0xc9);		        stv0299_writereg (i2c, 0x17, 0x8c);		        stv0299_writereg (i2c, 0x1a, 0xfe);		        stv0299_writereg (i2c, 0x1c, 0x7f);		        stv0299_writereg (i2c, 0x2d, 0x09);		} else {		        stv0299_writereg (i2c, 0x13, 0x99);		        stv0299_writereg (i2c, 0x14, 0x8d);		        stv0299_writereg (i2c, 0x15, 0xce);		        stv0299_writereg (i2c, 0x17, 0x43);

⌨️ 快捷键说明

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