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

📄 tda1004x.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c);		break;	case TDA10046_FREQ_3613:		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x13);		break;	case TDA10046_FREQ_045:		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b);		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3);		break;	case TDA10046_FREQ_052:		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x06);		break;	}	tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz}static int tda10046_fwupload(struct dvb_frontend* fe){	struct tda1004x_state* state = fe->demodulator_priv;	int ret;	const struct firmware *fw;	/* reset + wake up chip */	tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);	tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);	/* let the clocks recover from sleep */	msleep(5);	/* don't re-upload unless necessary */	if (tda1004x_check_upload_ok(state) == 0)		return 0;	/* set parameters */	tda10046_init_plls(fe);	if (state->config->request_firmware != NULL) {		/* request the firmware, this will block until someone uploads it */		printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");		ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);		if (ret) {			printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");			return ret;		}		tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST		ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);		release_firmware(fw);		if (ret)			return ret;	} else {		/* boot from firmware eeprom */		/* Hac Note: we might need to do some GPIO Magic here */		printk(KERN_INFO "tda1004x: booting from eeprom\n");		tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);		msleep(300);	}	return tda1004x_check_upload_ok(state);}static int tda1004x_encode_fec(int fec){	// convert known FEC values	switch (fec) {	case FEC_1_2:		return 0;	case FEC_2_3:		return 1;	case FEC_3_4:		return 2;	case FEC_5_6:		return 3;	case FEC_7_8:		return 4;	}	// unsupported	return -EINVAL;}static int tda1004x_decode_fec(int tdafec){	// convert known FEC values	switch (tdafec) {	case 0:		return FEC_1_2;	case 1:		return FEC_2_3;	case 2:		return FEC_3_4;	case 3:		return FEC_5_6;	case 4:		return FEC_7_8;	}	// unsupported	return -1;}int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data){	struct tda1004x_state* state = fe->demodulator_priv;	return tda1004x_write_byteI(state, reg, data);}static int tda10045_init(struct dvb_frontend* fe){	struct tda1004x_state* state = fe->demodulator_priv;	dprintk("%s\n", __FUNCTION__);	if (state->initialised)		return 0;	if (tda10045_fwupload(fe)) {		printk("tda1004x: firmware upload failed\n");		return -EIO;	}	tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC	// Init the PLL	if (state->config->pll_init) {		tda1004x_enable_tuner_i2c(state);		state->config->pll_init(fe);		tda1004x_disable_tuner_i2c(state);	}	// tda setup	tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer	tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream	tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0); // set polarity of VAGC signal	tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0x80); // enable pulse killer	tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10); // enable auto offset	tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0x0); // no frequency offset	tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 0); // setup MPEG2 TS interface	tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0); // setup MPEG2 TS interface	tda1004x_write_mask(state, TDA1004X_VBER_MSB, 0xe0, 0xa0); // 10^6 VBER measurement bits	tda1004x_write_mask(state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity	tda1004x_write_byteI(state, TDA1004X_CONFADC1, 0x2e);	tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk);	state->initialised = 1;	return 0;}static int tda10046_init(struct dvb_frontend* fe){	struct tda1004x_state* state = fe->demodulator_priv;	dprintk("%s\n", __FUNCTION__);	if (state->initialised)		return 0;	if (tda10046_fwupload(fe)) {		printk("tda1004x: firmware upload failed\n");			return -EIO;	}	// Init the tuner PLL	if (state->config->pll_init) {		tda1004x_enable_tuner_i2c(state);		if (state->config->pll_init(fe)) {			printk(KERN_ERR "tda1004x: pll init failed\n");			return 	-EIO;		}		tda1004x_disable_tuner_i2c(state);	}	// tda setup	tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer	tda1004x_write_byteI(state, TDA1004X_AUTO, 7); // select HP stream	tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer	tda10046_init_plls(fe);	switch (state->config->agc_config) {	case TDA10046_AGC_DEFAULT:		tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup		tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities		break;	case TDA10046_AGC_IFO_AUTO_NEG:		tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup		tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities		break;	case TDA10046_AGC_IFO_AUTO_POS:		tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup		tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities		break;	case TDA10046_AGC_TDA827X:		tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02);   // AGC setup		tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70);    // AGC Threshold		tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x0E); // Gain Renormalize		tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities		break;	}	tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on	tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0);	  // }	tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values	tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0);	  // }	tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff);  // }	tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1	tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits	tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config	tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config	tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);	tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup	tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config	tda1004x_write_byteI(state, TDA10046H_GPIO_SELECT, 8); // GPIO select	state->initialised = 1;	return 0;}static int tda1004x_set_fe(struct dvb_frontend* fe,			   struct dvb_frontend_parameters *fe_params){	struct tda1004x_state* state = fe->demodulator_priv;	int tmp;	int inversion;	dprintk("%s\n", __FUNCTION__);	if (state->demod_type == TDA1004X_DEMOD_TDA10046) {		// setup auto offset		tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10);		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x80, 0);		tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0);		// disable agc_conf[2]		tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 0);	}	// set frequency	tda1004x_enable_tuner_i2c(state);	if (state->config->pll_set(fe, fe_params)) {		printk(KERN_ERR "tda1004x: pll set failed\n");		return 	-EIO;	}	tda1004x_disable_tuner_i2c(state);	// Hardcoded to use auto as much as possible on the TDA10045 as it	// is very unreliable if AUTO mode is _not_ used.	if (state->demod_type == TDA1004X_DEMOD_TDA10045) {		fe_params->u.ofdm.code_rate_HP = FEC_AUTO;		fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;		fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;	}	// Set standard params.. or put them to auto	if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) ||	    (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) ||	    (fe_params->u.ofdm.constellation == QAM_AUTO) ||	    (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) {		tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1);	// enable auto		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0);	// turn off constellation bits		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0);	// turn off hierarchy bits		tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x3f, 0);	// turn off FEC bits	} else {		tda1004x_write_mask(state, TDA1004X_AUTO, 1, 0);	// disable auto		// set HP FEC		tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP);		if (tmp < 0)			return tmp;		tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp);		// set LP FEC		tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP);		if (tmp < 0)			return tmp;		tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3);		// set constellation		switch (fe_params->u.ofdm.constellation) {		case QPSK:			tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 0);			break;		case QAM_16:			tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 1);			break;		case QAM_64:			tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 2);			break;		default:			return -EINVAL;		}		// set hierarchy		switch (fe_params->u.ofdm.hierarchy_information) {		case HIERARCHY_NONE:			tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0 << 5);			break;		case HIERARCHY_1:			tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 1 << 5);			break;		case HIERARCHY_2:			tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 2 << 5);			break;		case HIERARCHY_4:			tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 3 << 5);			break;		default:			return -EINVAL;		}	}	// set bandwidth	switch (state->demod_type) {	case TDA1004X_DEMOD_TDA10045:		tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth);		break;	case TDA1004X_DEMOD_TDA10046:		tda10046h_set_bandwidth(state, fe_params->u.ofdm.bandwidth);		break;	}	// set inversion	inversion = fe_params->inversion;	if (state->config->invert)		inversion = inversion ? INVERSION_OFF : INVERSION_ON;	switch (inversion) {	case INVERSION_OFF:		tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0);		break;	case INVERSION_ON:		tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0x20);		break;	default:		return -EINVAL;	}	// set guard interval	switch (fe_params->u.ofdm.guard_interval) {	case GUARD_INTERVAL_1_32:		tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);		break;	case GUARD_INTERVAL_1_16:		tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 1 << 2);		break;	case GUARD_INTERVAL_1_8:		tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 2 << 2);		break;	case GUARD_INTERVAL_1_4:		tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 3 << 2);		break;	case GUARD_INTERVAL_AUTO:		tda1004x_write_mask(state, TDA1004X_AUTO, 2, 2);		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);		break;	default:		return -EINVAL;	}	// set transmission mode	switch (fe_params->u.ofdm.transmission_mode) {	case TRANSMISSION_MODE_2K:		tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0 << 4);		break;	case TRANSMISSION_MODE_8K:		tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 1 << 4);		break;	case TRANSMISSION_MODE_AUTO:		tda1004x_write_mask(state, TDA1004X_AUTO, 4, 4);		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0);		break;	default:		return -EINVAL;	}	// start the lock	switch (state->demod_type) {	case TDA1004X_DEMOD_TDA10045:		tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);		tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);		break;	case TDA1004X_DEMOD_TDA10046:		tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);		msleep(1);		tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1);		break;	}	msleep(10);	return 0;}static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params){	struct tda1004x_state* state = fe->demodulator_priv;	dprintk("%s\n", __FUNCTION__);	// inversion status	fe_params->inversion = INVERSION_OFF;	if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20)		fe_params->inversion = INVERSION_ON;	if (state->config->invert)		fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON;	// bandwidth	switch (state->demod_type) {	case TDA1004X_DEMOD_TDA10045:		switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) {

⌨️ 快捷键说明

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