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

📄 tda1004x.c

📁 linux数字电视播放器,比先的版本高一些.
💻 C
📖 第 1 页 / 共 3 页
字号:
	// Initialise the DSP and check upload was OK	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x10, 0);	tda1004x_write_byte(i2c, tda_state, TDA1004X_DSP_CMD, 0x67);	if ((tda1004x_read_byte(i2c, tda_state, TDA1004X_DSP_DATA1) != 0x67) ||	    (tda1004x_read_byte(i2c, tda_state, TDA1004X_DSP_DATA2) != 0x2c)) {		printk("%s: firmware upload failed!\n", __FUNCTION__);		return -EIO;	}	// tda setup	tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 8, 0);        tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 0x10, 0x10);        tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF2, 0xC0, 0x0);        tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 0x20, 0);        tda1004x_write_byte(i2c, tda_state, TDA1004X_CONFADC1, 0x2e);	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x80, 0x80);	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x40, 0);	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x10, 0);        tda1004x_write_byte(i2c, tda_state, TDA1004X_REG1E, 0);	tda1004x_write_byte(i2c, tda_state, TDA1004X_REG1F, 0);	tda1004x_write_mask(i2c, tda_state, TDA1004X_VBER_MSB, 0xe0, 0xa0);	// done	return 0;}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;}static int tda1004x_set_frequency(struct dvb_i2c_bus *i2c,			   struct tda1004x_state *tda_state,			   struct dvb_frontend_parameters *fe_params){	u8 tuner_buf[4];	struct i2c_msg tuner_msg = {.addr=0, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };	int tuner_frequency;        u8 band, cp, filter;	int counter, counter2;	dprintk("%s\n", __FUNCTION__);	// setup the frequency buffer	switch (tda_state->tuner_address) {	case TD1344_ADDRESS:		// setup tuner buffer		tuner_frequency =                        (((fe_params->frequency / 1000) * 6) + 217502) / 1000;		tuner_buf[0] = tuner_frequency >> 8;		tuner_buf[1] = tuner_frequency & 0xff;		tuner_buf[2] = 0x88;		if (fe_params->frequency < 550000000) {			tuner_buf[3] = 0xab;		} else {			tuner_buf[3] = 0xeb;		}		// tune it		tda1004x_enable_tuner_i2c(i2c, tda_state);		tuner_msg.addr = tda_state->tuner_address;		tuner_msg.len = 4;		i2c->xfer(i2c, &tuner_msg, 1);		// wait for it to finish		tuner_msg.len = 1;		tuner_msg.flags = I2C_M_RD;		counter = 0;		counter2 = 0;		while (counter++ < 100) {			if (i2c->xfer(i2c, &tuner_msg, 1) == 1) {				if (tuner_buf[0] & 0x40) {					counter2++;				} else {					counter2 = 0;				}			}			if (counter2 > 10) {				break;			}		}		tda1004x_disable_tuner_i2c(i2c, tda_state);		break;	case TDM1316L_ADDRESS:		// determine charge pump		tuner_frequency = fe_params->frequency + 36130000;		if (tuner_frequency < 87000000) {			return -EINVAL;		} else if (tuner_frequency < 130000000) {                        cp = 3;		} else if (tuner_frequency < 160000000) {			cp = 5;		} else if (tuner_frequency < 200000000) {			cp = 6;		} else if (tuner_frequency < 290000000) {			cp = 3;		} else if (tuner_frequency < 420000000) {			cp = 5;		} else if (tuner_frequency < 480000000) {			cp = 6;		} else if (tuner_frequency < 620000000) {			cp = 3;		} else if (tuner_frequency < 830000000) {			cp = 5;		} else if (tuner_frequency < 895000000) {			cp = 7;		} else {			return -EINVAL;		}		// determine band		if (fe_params->frequency < 49000000) {                        return -EINVAL;		} else if (fe_params->frequency < 159000000) {                        band = 1;		} else if (fe_params->frequency < 444000000) {			band = 2;		} else if (fe_params->frequency < 861000000) {			band = 4;		} else {			return -EINVAL;		}		// work out filter		switch (fe_params->u.ofdm.bandwidth) {		case BANDWIDTH_6_MHZ:                        // 6 MHz isn't supported directly, but set this to                        // the 8 MHz setting in case we can fiddle it later                        filter = 1;                        break;                case BANDWIDTH_7_MHZ:			filter = 0;			break;		case BANDWIDTH_8_MHZ:			filter = 1;			break;		default:			return -EINVAL;		}		// calculate tuner parameters		tuner_frequency =                        (((fe_params->frequency / 1000) * 6) + 217280) / 1000;		tuner_buf[0] = tuner_frequency >> 8;		tuner_buf[1] = tuner_frequency & 0xff;		tuner_buf[2] = 0xca;		tuner_buf[3] = (cp << 5) | (filter << 3) | band;		// tune it		tda1004x_enable_tuner_i2c(i2c, tda_state);		tuner_msg.addr = tda_state->tuner_address;		tuner_msg.len = 4;                if (i2c->xfer(i2c, &tuner_msg, 1) != 1) {			return -EIO;		}		dvb_delay(1);		tda1004x_disable_tuner_i2c(i2c, tda_state);		break;	default:		return -EINVAL;	}	dprintk("%s: success\n", __FUNCTION__);	// done	return 0;}static int tda1004x_set_fe(struct dvb_i2c_bus *i2c,	 	           struct tda1004x_state *tda_state,		           struct dvb_frontend_parameters *fe_params){	int tmp;	dprintk("%s\n", __FUNCTION__);	// set frequency	tmp = tda1004x_set_frequency(i2c, tda_state, fe_params);	if (tmp < 0)		return tmp;        // hardcoded to use auto as much as possible        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(i2c, tda_state, TDA1004X_AUTO, 1, 1);	// enable auto		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x03, 0);	// turn off constellation bits		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x60, 0);	// turn off hierarchy bits		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF2, 0x3f, 0);	// turn off FEC bits	} else {		tda1004x_write_mask(i2c, tda_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(i2c, tda_state, TDA1004X_IN_CONF2, 7, tmp);		// set LP FEC		if (fe_params->u.ofdm.code_rate_LP != FEC_NONE) {			tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP);			if (tmp < 0) return tmp;			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF2, 0x38, tmp << 3);		}		// set constellation		switch (fe_params->u.ofdm.constellation) {		case QPSK:			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 3, 0);			break;		case QAM_16:			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 3, 1);			break;		case QAM_64:			tda1004x_write_mask(i2c, tda_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(i2c, tda_state, TDA1004X_IN_CONF1, 0x60, 0 << 5);			break;		case HIERARCHY_1:			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x60, 1 << 5);			break;		case HIERARCHY_2:			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x60, 2 << 5);			break;		case HIERARCHY_4:			tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x60, 3 << 5);			break;		default:			return -EINVAL;		}	}        // set bandwidth        switch(tda_state->tda1004x_address) {        case TDA10045H_ADDRESS:                tda10045h_set_bandwidth(i2c, tda_state, fe_params->u.ofdm.bandwidth);                break;        }	// set inversion	switch (fe_params->inversion) {	case INVERSION_OFF:		tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC1, 0x20, 0);		break;	case INVERSION_ON:		tda1004x_write_mask(i2c, tda_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(i2c, tda_state, TDA1004X_AUTO, 2, 0);		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);		break;	case GUARD_INTERVAL_1_16:		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 2, 0);		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x0c, 1 << 2);		break;	case GUARD_INTERVAL_1_8:		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 2, 0);		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x0c, 2 << 2);		break;	case GUARD_INTERVAL_1_4:		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 2, 0);		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x0c, 3 << 2);		break;	case GUARD_INTERVAL_AUTO:		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 2, 2);		tda1004x_write_mask(i2c, tda_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(i2c, tda_state, TDA1004X_AUTO, 4, 0);		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x10, 0 << 4);		break;	case TRANSMISSION_MODE_8K:		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 4, 0);		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x10, 1 << 4);		break;	case TRANSMISSION_MODE_AUTO:		tda1004x_write_mask(i2c, tda_state, TDA1004X_AUTO, 4, 4);		tda1004x_write_mask(i2c, tda_state, TDA1004X_IN_CONF1, 0x10, 0);		break;	default:		return -EINVAL;	}	// reset DSP	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 8);	tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 8, 0);	dvb_delay(10);	// done	return 0;}static int tda1004x_get_fe(struct dvb_i2c_bus *i2c, struct tda1004x_state* tda_state, struct dvb_frontend_parameters *fe_params){	dprintk("%s\n", __FUNCTION__);	// inversion status	fe_params->inversion = INVERSION_OFF;	if (tda1004x_read_byte(i2c, tda_state, TDA1004X_CONFC1) & 0x20) {		fe_params->inversion = INVERSION_ON;	}	// bandwidth	switch (tda1004x_read_byte(i2c, tda_state, TDA1004X_WREF_LSB)) {

⌨️ 快捷键说明

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