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

📄 tda1004x.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		case 0x14:			fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;			break;		case 0xdb:			fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;			break;		case 0x4f:			fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;			break;		}		break;	case TDA1004X_DEMOD_TDA10046:		switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) {		case 0x60:			fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;			break;		case 0x6e:			fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;			break;		case 0x80:			fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;			break;		}		break;	}	// FEC	fe_params->u.ofdm.code_rate_HP =	    tda1004x_decode_fec(tda1004x_read_byte(state, TDA1004X_OUT_CONF2) & 7);	fe_params->u.ofdm.code_rate_LP =	    tda1004x_decode_fec((tda1004x_read_byte(state, TDA1004X_OUT_CONF2) >> 3) & 7);	// constellation	switch (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 3) {	case 0:		fe_params->u.ofdm.constellation = QPSK;		break;	case 1:		fe_params->u.ofdm.constellation = QAM_16;		break;	case 2:		fe_params->u.ofdm.constellation = QAM_64;		break;	}	// transmission mode	fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;	if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10)		fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;	// guard interval	switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) {	case 0:		fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;		break;	case 1:		fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;		break;	case 2:		fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;		break;	case 3:		fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;		break;	}	// hierarchy	switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x60) >> 5) {	case 0:		fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE;		break;	case 1:		fe_params->u.ofdm.hierarchy_information = HIERARCHY_1;		break;	case 2:		fe_params->u.ofdm.hierarchy_information = HIERARCHY_2;		break;	case 3:		fe_params->u.ofdm.hierarchy_information = HIERARCHY_4;		break;	}	return 0;}static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status){	struct tda1004x_state* state = fe->demodulator_priv;	int status;	int cber;	int vber;	dprintk("%s\n", __FUNCTION__);	// read status	status = tda1004x_read_byte(state, TDA1004X_STATUS_CD);	if (status == -1)		return -EIO;	// decode	*fe_status = 0;	if (status & 4)		*fe_status |= FE_HAS_SIGNAL;	if (status & 2)		*fe_status |= FE_HAS_CARRIER;	if (status & 8)		*fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;	// if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi	// is getting anything valid	if (!(*fe_status & FE_HAS_VITERBI)) {		// read the CBER		cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB);		if (cber == -1)			return -EIO;		status = tda1004x_read_byte(state, TDA1004X_CBER_MSB);		if (status == -1)			return -EIO;		cber |= (status << 8);		tda1004x_read_byte(state, TDA1004X_CBER_RESET);		if (cber != 65535)			*fe_status |= FE_HAS_VITERBI;	}	// if we DO have some valid VITERBI output, but don't already have SYNC	// bytes (i.e. not LOCKED), see if the RS decoder is getting anything valid.	if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) {		// read the VBER		vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB);		if (vber == -1)			return -EIO;		status = tda1004x_read_byte(state, TDA1004X_VBER_MID);		if (status == -1)			return -EIO;		vber |= (status << 8);		status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);		if (status == -1)			return -EIO;		vber |= ((status << 16) & 0x0f);		tda1004x_read_byte(state, TDA1004X_CVBER_LUT);		// if RS has passed some valid TS packets, then we must be		// getting some SYNC bytes		if (vber < 16632)			*fe_status |= FE_HAS_SYNC;	}	// success	dprintk("%s: fe_status=0x%x\n", __FUNCTION__, *fe_status);	return 0;}static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal){	struct tda1004x_state* state = fe->demodulator_priv;	int tmp;	int reg = 0;	dprintk("%s\n", __FUNCTION__);	// determine the register to use	switch (state->demod_type) {	case TDA1004X_DEMOD_TDA10045:		reg = TDA10045H_S_AGC;		break;	case TDA1004X_DEMOD_TDA10046:		reg = TDA10046H_AGC_IF_LEVEL;		break;	}	// read it	tmp = tda1004x_read_byte(state, reg);	if (tmp < 0)		return -EIO;	*signal = (tmp << 8) | tmp;	dprintk("%s: signal=0x%x\n", __FUNCTION__, *signal);	return 0;}static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr){	struct tda1004x_state* state = fe->demodulator_priv;	int tmp;	dprintk("%s\n", __FUNCTION__);	// read it	tmp = tda1004x_read_byte(state, TDA1004X_SNR);	if (tmp < 0)		return -EIO;	tmp = 255 - tmp;	*snr = ((tmp << 8) | tmp);	dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr);	return 0;}static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks){	struct tda1004x_state* state = fe->demodulator_priv;	int tmp;	int tmp2;	int counter;	dprintk("%s\n", __FUNCTION__);	// read the UCBLOCKS and reset	counter = 0;	tmp = tda1004x_read_byte(state, TDA1004X_UNCOR);	if (tmp < 0)		return -EIO;	tmp &= 0x7f;	while (counter++ < 5) {		tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);		tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);		tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);		tmp2 = tda1004x_read_byte(state, TDA1004X_UNCOR);		if (tmp2 < 0)			return -EIO;		tmp2 &= 0x7f;		if ((tmp2 < tmp) || (tmp2 == 0))			break;	}	if (tmp != 0x7f)		*ucblocks = tmp;	else		*ucblocks = 0xffffffff;	dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks);	return 0;}static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber){	struct tda1004x_state* state = fe->demodulator_priv;	int tmp;	dprintk("%s\n", __FUNCTION__);	// read it in	tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB);	if (tmp < 0)		return -EIO;	*ber = tmp << 1;	tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB);	if (tmp < 0)		return -EIO;	*ber |= (tmp << 9);	tda1004x_read_byte(state, TDA1004X_CBER_RESET);	dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber);	return 0;}static int tda1004x_sleep(struct dvb_frontend* fe){	struct tda1004x_state* state = fe->demodulator_priv;	switch (state->demod_type) {	case TDA1004X_DEMOD_TDA10045:		tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10);		break;	case TDA1004X_DEMOD_TDA10046:		if (state->config->pll_sleep != NULL) {			tda1004x_enable_tuner_i2c(state);			state->config->pll_sleep(fe);			if (state->config->if_freq != TDA10046_FREQ_052) {				/* special hack for Philips EUROPA Based boards:				 * keep the I2c bridge open for tuner access in analog mode				 */				tda1004x_disable_tuner_i2c(state);			}		}		tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);		break;	}	state->initialised = 0;	return 0;}static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings){	fesettings->min_delay_ms = 800;	/* Drift compensation makes no sense for DVB-T */	fesettings->step_size = 0;	fesettings->max_drift = 0;	return 0;}static void tda1004x_release(struct dvb_frontend* fe){	struct tda1004x_state *state = fe->demodulator_priv;	kfree(state);}static struct dvb_frontend_ops tda10045_ops = {	.info = {		.name = "Philips TDA10045H DVB-T",		.type = FE_OFDM,		.frequency_min = 51000000,		.frequency_max = 858000000,		.frequency_stepsize = 166667,		.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_FEC_AUTO |		    FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |		    FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO	},	.release = tda1004x_release,	.init = tda10045_init,	.sleep = tda1004x_sleep,	.set_frontend = tda1004x_set_fe,	.get_frontend = tda1004x_get_fe,	.get_tune_settings = tda1004x_get_tune_settings,	.read_status = tda1004x_read_status,	.read_ber = tda1004x_read_ber,	.read_signal_strength = tda1004x_read_signal_strength,	.read_snr = tda1004x_read_snr,	.read_ucblocks = tda1004x_read_ucblocks,};struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,				     struct i2c_adapter* i2c){	struct tda1004x_state *state;	/* allocate memory for the internal state */	state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);	if (!state)		return NULL;	/* setup the state */	state->config = config;	state->i2c = i2c;	memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));	state->initialised = 0;	state->demod_type = TDA1004X_DEMOD_TDA10045;	/* check if the demod is there */	if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) {		kfree(state);		return NULL;	}	/* create dvb_frontend */	state->frontend.ops = &state->ops;	state->frontend.demodulator_priv = state;	return &state->frontend;}static struct dvb_frontend_ops tda10046_ops = {	.info = {		.name = "Philips TDA10046H DVB-T",		.type = FE_OFDM,		.frequency_min = 51000000,		.frequency_max = 858000000,		.frequency_stepsize = 166667,		.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_FEC_AUTO |		    FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |		    FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO	},	.release = tda1004x_release,	.init = tda10046_init,	.sleep = tda1004x_sleep,	.set_frontend = tda1004x_set_fe,	.get_frontend = tda1004x_get_fe,	.get_tune_settings = tda1004x_get_tune_settings,	.read_status = tda1004x_read_status,	.read_ber = tda1004x_read_ber,	.read_signal_strength = tda1004x_read_signal_strength,	.read_snr = tda1004x_read_snr,	.read_ucblocks = tda1004x_read_ucblocks,};struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,				     struct i2c_adapter* i2c){	struct tda1004x_state *state;	/* allocate memory for the internal state */	state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);	if (!state)		return NULL;	/* setup the state */	state->config = config;	state->i2c = i2c;	memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));	state->initialised = 0;	state->demod_type = TDA1004X_DEMOD_TDA10046;	/* check if the demod is there */	if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) {		kfree(state);		return NULL;	}	/* create dvb_frontend */	state->frontend.ops = &state->ops;	state->frontend.demodulator_priv = state;	return &state->frontend;}module_param(debug, int, 0644);MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");MODULE_DESCRIPTION("Philips TDA10045H & TDA10046H DVB-T Demodulator");MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach");MODULE_LICENSE("GPL");EXPORT_SYMBOL(tda10045_attach);EXPORT_SYMBOL(tda10046_attach);EXPORT_SYMBOL(tda1004x_write_byte);

⌨️ 快捷键说明

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