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

📄 dib3000mb.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	else		inv_test1 = 2;	dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB);	deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB));	if (dds_val < threshold)		inv_test2 = 0;	else if (dds_val == threshold)		inv_test2 = 1;	else		inv_test2 = 2;	fep->inversion =		((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) ||		((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?		INVERSION_ON : INVERSION_OFF;	deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion);	switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) {		case DIB3000_CONSTELLATION_QPSK:			deb_getf("QPSK ");			ofdm->constellation = QPSK;			break;		case DIB3000_CONSTELLATION_16QAM:			deb_getf("QAM16 ");			ofdm->constellation = QAM_16;			break;		case DIB3000_CONSTELLATION_64QAM:			deb_getf("QAM64 ");			ofdm->constellation = QAM_64;			break;		default:			err("Unexpected constellation returned by TPS (%d)", tps_val);			break; 	}	deb_getf("TPS: %d\n", tps_val);	if (rd(DIB3000MB_REG_TPS_HRCH)) {		deb_getf("HRCH ON\n");		cr = &ofdm->code_rate_LP;		ofdm->code_rate_HP = FEC_NONE;		switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) {			case DIB3000_ALPHA_0:				deb_getf("HIERARCHY_NONE ");				ofdm->hierarchy_information = HIERARCHY_NONE;				break;			case DIB3000_ALPHA_1:				deb_getf("HIERARCHY_1 ");				ofdm->hierarchy_information = HIERARCHY_1;				break;			case DIB3000_ALPHA_2:				deb_getf("HIERARCHY_2 ");				ofdm->hierarchy_information = HIERARCHY_2;				break;			case DIB3000_ALPHA_4:				deb_getf("HIERARCHY_4 ");				ofdm->hierarchy_information = HIERARCHY_4;				break;			default:				err("Unexpected ALPHA value returned by TPS (%d)", tps_val);				break;		}		deb_getf("TPS: %d\n", tps_val);		tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP);	} else {		deb_getf("HRCH OFF\n");		cr = &ofdm->code_rate_HP;		ofdm->code_rate_LP = FEC_NONE;		ofdm->hierarchy_information = HIERARCHY_NONE;		tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP);	}	switch (tps_val) {		case DIB3000_FEC_1_2:			deb_getf("FEC_1_2 ");			*cr = FEC_1_2;			break;		case DIB3000_FEC_2_3:			deb_getf("FEC_2_3 ");			*cr = FEC_2_3;			break;		case DIB3000_FEC_3_4:			deb_getf("FEC_3_4 ");			*cr = FEC_3_4;			break;		case DIB3000_FEC_5_6:			deb_getf("FEC_5_6 ");			*cr = FEC_4_5;			break;		case DIB3000_FEC_7_8:			deb_getf("FEC_7_8 ");			*cr = FEC_7_8;			break;		default:			err("Unexpected FEC returned by TPS (%d)", tps_val);			break;	}	deb_getf("TPS: %d\n",tps_val);	switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) {		case DIB3000_GUARD_TIME_1_32:			deb_getf("GUARD_INTERVAL_1_32 ");			ofdm->guard_interval = GUARD_INTERVAL_1_32;			break;		case DIB3000_GUARD_TIME_1_16:			deb_getf("GUARD_INTERVAL_1_16 ");			ofdm->guard_interval = GUARD_INTERVAL_1_16;			break;		case DIB3000_GUARD_TIME_1_8:			deb_getf("GUARD_INTERVAL_1_8 ");			ofdm->guard_interval = GUARD_INTERVAL_1_8;			break;		case DIB3000_GUARD_TIME_1_4:			deb_getf("GUARD_INTERVAL_1_4 ");			ofdm->guard_interval = GUARD_INTERVAL_1_4;			break;		default:			err("Unexpected Guard Time returned by TPS (%d)", tps_val);			break;	}	deb_getf("TPS: %d\n", tps_val);	switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) {		case DIB3000_TRANSMISSION_MODE_2K:			deb_getf("TRANSMISSION_MODE_2K ");			ofdm->transmission_mode = TRANSMISSION_MODE_2K;			break;		case DIB3000_TRANSMISSION_MODE_8K:			deb_getf("TRANSMISSION_MODE_8K ");			ofdm->transmission_mode = TRANSMISSION_MODE_8K;			break;		default:			err("unexpected transmission mode return by TPS (%d)", tps_val);			break;	}	deb_getf("TPS: %d\n", tps_val);	return 0;}static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat){	struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;	*stat = 0;	if (rd(DIB3000MB_REG_AGC_LOCK))		*stat |= FE_HAS_SIGNAL;	if (rd(DIB3000MB_REG_CARRIER_LOCK))		*stat |= FE_HAS_CARRIER;	if (rd(DIB3000MB_REG_VIT_LCK))		*stat |= FE_HAS_VITERBI;	if (rd(DIB3000MB_REG_TS_SYNC_LOCK))		*stat |= (FE_HAS_SYNC | FE_HAS_LOCK);	deb_info("actual status is %2x\n",*stat);	deb_getf("tps %x %x %x %x %x\n",			rd(DIB3000MB_REG_TPS_1),			rd(DIB3000MB_REG_TPS_2),			rd(DIB3000MB_REG_TPS_3),			rd(DIB3000MB_REG_TPS_4),			rd(DIB3000MB_REG_TPS_5));		deb_info("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n",			rd(DIB3000MB_REG_TPS_LOCK),			rd(DIB3000MB_REG_TPS_QAM),			rd(DIB3000MB_REG_TPS_HRCH),			rd(DIB3000MB_REG_TPS_VIT_ALPHA),			rd(DIB3000MB_REG_TPS_CODE_RATE_HP),			rd(DIB3000MB_REG_TPS_CODE_RATE_LP),			rd(DIB3000MB_REG_TPS_GUARD_TIME),			rd(DIB3000MB_REG_TPS_FFT),			rd(DIB3000MB_REG_TPS_CELL_ID));	//*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;	return 0;}static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber){	struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;	*ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB) );	return 0;}/* * Amaury: * signal strength is measured with dBm (power compared to mW) * the standard range is -90dBm(low power) to -10 dBm (strong power), * but the calibration is done for -100 dBm to 0dBm */#define DIB3000MB_AGC_REF_dBm		-14#define DIB3000MB_GAIN_SLOPE_dBm	100#define DIB3000MB_GAIN_DELTA_dBm	-2static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength){	struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;/* TODO log10 	u16 sigpow = rd(DIB3000MB_REG_SIGNAL_POWER), 		n_agc_power = rd(DIB3000MB_REG_AGC_POWER),		rf_power = rd(DIB3000MB_REG_RF_POWER);	double rf_power_dBm, ad_power_dBm, minar_power_dBm;		if (n_agc_power == 0 )		n_agc_power = 1 ;	ad_power_dBm    = 10 * log10 ( (float)n_agc_power / (float)(1<<16) );	minor_power_dBm = ad_power_dBm - DIB3000MB_AGC_REF_dBm;	rf_power_dBm = (-DIB3000MB_GAIN_SLOPE_dBm * (float)rf_power / (float)(1<<16) + 			DIB3000MB_GAIN_DELTA_dBm) + minor_power_dBm;	// relative rf_power 	*strength = (u16) ((rf_power_dBm + 100) / 100 * 0xffff);*/	*strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170;	return 0;}/* * Amaury:  * snr is the signal quality measured in dB. * snr = 10*log10(signal power / noise power) * the best quality is near 35dB (cable transmission & good modulator) * the minimum without errors depend of transmission parameters * some indicative values are given in en300744 Annex A * ex : 16QAM 2/3 (Gaussian)  = 11.1 dB * * If SNR is above 20dB, BER should be always 0. * choose 0dB as the minimum */static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr){	struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;	short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER);	int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) |		rd(DIB3000MB_REG_NOISE_POWER_LSB);/*	float snr_dBm=0;	if (sigpow > 0 && icipow > 0)		snr_dBm = 10.0 * log10( (float) (sigpow<<8) / (float)icipow )  ;	else if (sigpow > 0)		snr_dBm = 35;		*snr = (u16) ((snr_dBm / 35) * 0xffff);*/	*snr = (sigpow << 8) / ((icipow > 0) ? icipow : 1);	return 0;}static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc){	struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;	*unc = rd(DIB3000MB_REG_UNC);	return 0;}static int dib3000mb_sleep(struct dvb_frontend* fe){	struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;	wr(DIB3000MB_REG_POWER_CONTROL,DIB3000MB_POWER_DOWN);	return 0;}static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune){	tune->min_delay_ms = 800;	tune->step_size = 166667;	tune->max_drift = 166667*2;						return 0;}static int dib3000mb_fe_init_nonmobile(struct dvb_frontend* fe){	return dib3000mb_fe_init(fe, 0);}static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep){	return dib3000mb_set_frontend(fe, fep, 1);}static void dib3000mb_release(struct dvb_frontend* fe){	struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;	kfree(state);}/* pid filter and transfer stuff */static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff){	struct dib3000_state *state = fe->demodulator_priv;	pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);		wr(index+DIB3000MB_REG_FIRST_PID,pid);	return 0;}static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff){	struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;	deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");	if (onoff) {		wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_ACTIVATE);	} else {		wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);	}	return 0;	}static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff){	//struct dib3000_state *state = fe->demodulator_priv;	/* switch it off and on */	return 0;	}static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr){	struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;	if (onoff) {		wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));	} else {		wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));	}	return 0;}static struct dvb_frontend_ops dib3000mb_ops;struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,				      struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops){	struct dib3000_state* state = NULL;	/* allocate memory for the internal state */	state = (struct dib3000_state*) kmalloc(sizeof(struct dib3000_state), GFP_KERNEL);	if (state == NULL)		goto error;	/* setup the state */	state->i2c = i2c;	memcpy(&state->config,config,sizeof(struct dib3000_config));	memcpy(&state->ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops));	/* check for the correct demod */	if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)		goto error;	if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID)		goto error;	/* create dvb_frontend */	state->frontend.ops = &state->ops;	state->frontend.demodulator_priv = state;	/* set the xfer operations */	xfer_ops->pid_parse = dib3000mb_pid_parse;	xfer_ops->fifo_ctrl = dib3000mb_fifo_control;	xfer_ops->pid_ctrl = dib3000mb_pid_control;	xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl;	return &state->frontend;error:	if (state)	kfree(state);	return NULL;	}static struct dvb_frontend_ops dib3000mb_ops = {	.info = {		.name			= "DiBcom 3000-MB DVB-T",		.type 			= FE_OFDM,		.frequency_min 		= 44250000,		.frequency_max 		= 867250000,		.frequency_stepsize	= 62500,		.caps = FE_CAN_INVERSION_AUTO |				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 |				FE_CAN_RECOVER |				FE_CAN_HIERARCHY_AUTO,	},	.release = dib3000mb_release,	.init = dib3000mb_fe_init_nonmobile,	.sleep = dib3000mb_sleep,	.set_frontend = dib3000mb_set_frontend_and_tuner,	.get_frontend = dib3000mb_get_frontend,	.get_tune_settings = dib3000mb_fe_get_tune_settings,	.read_status = dib3000mb_read_status,	.read_ber = dib3000mb_read_ber,	.read_signal_strength = dib3000mb_read_signal_strength,	.read_snr = dib3000mb_read_snr,	.read_ucblocks = dib3000mb_read_unc_blocks,};MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE("GPL");EXPORT_SYMBOL(dib3000mb_attach);

⌨️ 快捷键说明

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