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

📄 dib7000p.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	1, 198,		0x800, // P_equal_thres_wgn	1, 222,		0x0010, // P_fec_ber_rs_len=2	1, 235,		0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard	2, 901,		0x0006, // P_clk_cfg1		(3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1	1, 905,		0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive	0,};static int dib7000p_demod_reset(struct dib7000p_state *state){	dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);	dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);	/* restart all parts */	dib7000p_write_word(state,  770, 0xffff);	dib7000p_write_word(state,  771, 0xffff);	dib7000p_write_word(state,  772, 0x001f);	dib7000p_write_word(state,  898, 0x0003);	/* except i2c, sdio, gpio - control interfaces */	dib7000p_write_word(state, 1280, 0x01fc - ((1 << 7) | (1 << 6) | (1 << 5)) );	dib7000p_write_word(state,  770, 0);	dib7000p_write_word(state,  771, 0);	dib7000p_write_word(state,  772, 0);	dib7000p_write_word(state,  898, 0);	dib7000p_write_word(state, 1280, 0);	/* default */	dib7000p_reset_pll(state);	if (dib7000p_reset_gpio(state) != 0)		dprintk( "GPIO reset was not successful.");	if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)		dprintk( "OUTPUT_MODE could not be reset.");	/* unforce divstr regardless whether i2c enumeration was done or not */	dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1) );	dib7000p_set_bandwidth(state, 8000);	dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);	dib7000p_sad_calib(state);	dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);	// P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...	if(state->cfg.tuner_is_baseband)		dib7000p_write_word(state, 36,0x0755);	else		dib7000p_write_word(state, 36,0x1f55);	dib7000p_write_tab(state, dib7000p_defaults);	dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);	return 0;}static void dib7000p_pll_clk_cfg(struct dib7000p_state *state){	u16 tmp = 0;	tmp = dib7000p_read_word(state, 903);	dib7000p_write_word(state, 903, (tmp | 0x1));   //pwr-up pll	tmp = dib7000p_read_word(state, 900);	dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));     //use High freq clock}static void dib7000p_restart_agc(struct dib7000p_state *state){	// P_restart_iqc & P_restart_agc	dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));	dib7000p_write_word(state, 770, 0x0000);}static int dib7000p_update_lna(struct dib7000p_state *state){	u16 dyn_gain;	// when there is no LNA to program return immediatly	if (state->cfg.update_lna) {		// read dyn_gain here (because it is demod-dependent and not fe)		dyn_gain = dib7000p_read_word(state, 394);		if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed			dib7000p_restart_agc(state);			return 1;		}	}	return 0;}static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band){	struct dibx000_agc_config *agc = NULL;	int i;	if (state->current_band == band && state->current_agc != NULL)		return 0;	state->current_band = band;	for (i = 0; i < state->cfg.agc_config_count; i++)		if (state->cfg.agc[i].band_caps & band) {			agc = &state->cfg.agc[i];			break;		}	if (agc == NULL) {		dprintk( "no valid AGC configuration found for band 0x%02x",band);		return -EINVAL;	}	state->current_agc = agc;	/* AGC */	dib7000p_write_word(state, 75 ,  agc->setup );	dib7000p_write_word(state, 76 ,  agc->inv_gain );	dib7000p_write_word(state, 77 ,  agc->time_stabiliz );	dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);	// Demod AGC loop configuration	dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);	dib7000p_write_word(state, 102, (agc->beta_mant << 6)  | agc->beta_exp);	/* AGC continued */	dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",		state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);	if (state->wbd_ref != 0)		dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);	else		dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);	dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));	dib7000p_write_word(state, 107,  agc->agc1_max);	dib7000p_write_word(state, 108,  agc->agc1_min);	dib7000p_write_word(state, 109,  agc->agc2_max);	dib7000p_write_word(state, 110,  agc->agc2_min);	dib7000p_write_word(state, 111, (agc->agc1_pt1    << 8) | agc->agc1_pt2);	dib7000p_write_word(state, 112,  agc->agc1_pt3);	dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);	dib7000p_write_word(state, 114, (agc->agc2_pt1    << 8) | agc->agc2_pt2);	dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);	return 0;}static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch){	struct dib7000p_state *state = demod->demodulator_priv;	int ret = -1;	u8 *agc_state = &state->agc_state;	u8 agc_split;	switch (state->agc_state) {		case 0:			// set power-up level: interf+analog+AGC			dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);			dib7000p_set_adc_state(state, DIBX000_ADC_ON);			dib7000p_pll_clk_cfg(state);			if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)				return -1;			ret = 7;			(*agc_state)++;			break;		case 1:			// AGC initialization			if (state->cfg.agc_control)				state->cfg.agc_control(&state->demod, 1);			dib7000p_write_word(state, 78, 32768);			if (!state->current_agc->perform_agc_softsplit) {				/* we are using the wbd - so slow AGC startup */				/* force 0 split on WBD and restart AGC */				dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));				(*agc_state)++;				ret = 5;			} else {				/* default AGC startup */				(*agc_state) = 4;				/* wait AGC rough lock time */				ret = 7;			}			dib7000p_restart_agc(state);			break;		case 2: /* fast split search path after 5sec */			dib7000p_write_word(state,  75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */			dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */			(*agc_state)++;			ret = 14;			break;	case 3: /* split search ended */			agc_split = (u8)dib7000p_read_word(state, 396); /* store the split value for the next time */			dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */			dib7000p_write_word(state, 75,  state->current_agc->setup);   /* std AGC loop */			dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */			dib7000p_restart_agc(state);			dprintk( "SPLIT %p: %hd", demod, agc_split);			(*agc_state)++;			ret = 5;			break;		case 4: /* LNA startup */			// wait AGC accurate lock time			ret = 7;			if (dib7000p_update_lna(state))				// wait only AGC rough lock time				ret = 5;			else // nothing was done, go to the next state				(*agc_state)++;			break;		case 5:			if (state->cfg.agc_control)				state->cfg.agc_control(&state->demod, 0);			(*agc_state)++;			break;		default:			break;	}	return ret;}static void dib7000p_update_timf(struct dib7000p_state *state){	u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);	state->timf = timf * 160 / (state->current_bandwidth / 50);	dib7000p_write_word(state, 23, (u16) (timf >> 16));	dib7000p_write_word(state, 24, (u16) (timf & 0xffff));	dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->cfg.bw->timf);}static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq){	u16 value, est[4];    dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));	/* nfft, guard, qam, alpha */	value = 0;	switch (ch->u.ofdm.transmission_mode) {		case TRANSMISSION_MODE_2K: value |= (0 << 7); break;		case /* 4K MODE */ 255: value |= (2 << 7); break;		default:		case TRANSMISSION_MODE_8K: value |= (1 << 7); break;	}	switch (ch->u.ofdm.guard_interval) {		case GUARD_INTERVAL_1_32: value |= (0 << 5); break;		case GUARD_INTERVAL_1_16: value |= (1 << 5); break;		case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;		default:		case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;	}	switch (ch->u.ofdm.constellation) {		case QPSK:  value |= (0 << 3); break;		case QAM_16: value |= (1 << 3); break;		default:		case QAM_64: value |= (2 << 3); break;	}	switch (HIERARCHY_1) {		case HIERARCHY_2: value |= 2; break;		case HIERARCHY_4: value |= 4; break;		default:		case HIERARCHY_1: value |= 1; break;	}	dib7000p_write_word(state, 0, value);	dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */	/* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */	value = 0;	if (1 != 0)		value |= (1 << 6);	if (ch->u.ofdm.hierarchy_information == 1)		value |= (1 << 4);	if (1 == 1)		value |= 1;	switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {		case FEC_2_3: value |= (2 << 1); break;		case FEC_3_4: value |= (3 << 1); break;		case FEC_5_6: value |= (5 << 1); break;		case FEC_7_8: value |= (7 << 1); break;		default:		case FEC_1_2: value |= (1 << 1); break;	}	dib7000p_write_word(state, 208, value);	/* offset loop parameters */	dib7000p_write_word(state, 26, 0x6680); // timf(6xxx)	dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3)	dib7000p_write_word(state, 29, 0x1273); // isi	dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5)	/* P_dvsy_sync_wait */	switch (ch->u.ofdm.transmission_mode) {		case TRANSMISSION_MODE_8K: value = 256; break;		case /* 4K MODE */ 255: value = 128; break;		case TRANSMISSION_MODE_2K:		default: value = 64; break;	}	switch (ch->u.ofdm.guard_interval) {		case GUARD_INTERVAL_1_16: value *= 2; break;		case GUARD_INTERVAL_1_8:  value *= 4; break;		case GUARD_INTERVAL_1_4:  value *= 8; break;		default:		case GUARD_INTERVAL_1_32: value *= 1; break;	}	state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO	/* deactive the possibility of diversity reception if extended interleaver */	state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;	dib7000p_set_diversity_in(&state->demod, state->div_state);	/* channel estimation fine configuration */	switch (ch->u.ofdm.constellation) {		case QAM_64:			est[0] = 0x0148;       /* P_adp_regul_cnt 0.04 */			est[1] = 0xfff0;       /* P_adp_noise_cnt -0.002 */			est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */			est[3] = 0xfff8;       /* P_adp_noise_ext -0.001 */			break;		case QAM_16:			est[0] = 0x023d;       /* P_adp_regul_cnt 0.07 */			est[1] = 0xffdf;       /* P_adp_noise_cnt -0.004 */			est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */			est[3] = 0xfff0;       /* P_adp_noise_ext -0.002 */			break;		default:			est[0] = 0x099a;       /* P_adp_regul_cnt 0.3 */			est[1] = 0xffae;       /* P_adp_noise_cnt -0.01 */			est[2] = 0x0333;       /* P_adp_regul_ext 0.1 */			est[3] = 0xfff8;       /* P_adp_noise_ext -0.002 */			break;	}	for (value = 0; value < 4; value++)		dib7000p_write_word(state, 187 + value, est[value]);}static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch){	struct dib7000p_state *state = demod->demodulator_priv;	struct dvb_frontend_parameters schan;	u32 value, factor;	schan = *ch;	schan.u.ofdm.constellation = QAM_64;	schan.u.ofdm.guard_interval         = GUARD_INTERVAL_1_32;	schan.u.ofdm.transmission_mode          = TRANSMISSION_MODE_8K;	schan.u.ofdm.code_rate_HP  = FEC_2_3;	schan.u.ofdm.code_rate_LP  = FEC_3_4;	schan.u.ofdm.hierarchy_information          = 0;	dib7000p_set_channel(state, &schan, 7);	factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);	if (factor >= 5000)		factor = 1;	else		factor = 6;	// always use the setting for 8MHz here lock_time for 7,6 MHz are longer	value = 30 * state->cfg.bw->internal * factor;	dib7000p_write_word(state, 6,  (u16) ((value >> 16) & 0xffff)); // lock0 wait time	dib7000p_write_word(state, 7,  (u16)  (value        & 0xffff)); // lock0 wait time	value = 100 * state->cfg.bw->internal * factor;	dib7000p_write_word(state, 8,  (u16) ((value >> 16) & 0xffff)); // lock1 wait time	dib7000p_write_word(state, 9,  (u16)  (value        & 0xffff)); // lock1 wait time	value = 500 * state->cfg.bw->internal * factor;	dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time	dib7000p_write_word(state, 11, (u16)  (value        & 0xffff)); // lock2 wait time	value = dib7000p_read_word(state, 0);	dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));	dib7000p_read_word(state, 1284);	dib7000p_write_word(state, 0, (u16) value);	return 0;}static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod){	struct dib7000p_state *state = demod->demodulator_priv;	u16 irq_pending = dib7000p_read_word(state, 1284);	if (irq_pending & 0x1) // failed		return 1;	if (irq_pending & 0x2) // succeeded		return 2;	return 0; // still pending}static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw){	static s16 notch[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392};	static u8 sine [] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,	24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,	53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,	82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,	107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,	128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,	147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,	166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,	183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,	199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,	213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,	225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,	235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,	244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,	250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,	254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,	255, 255, 255, 255, 255, 255};	u32 xtal = state->cfg.bw->xtal_hz / 1000;	int f_rel = ( (rf_khz + xtal/2) / xtal) * xtal - rf_khz;	int k;	int coef_re[8],coef_im[8];	int bw_khz = bw;	u32 pha;	dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);	if (f_rel < -bw_khz/2 || f_rel > bw_khz/2)		return;	bw_khz /= 100;	dib7000p_write_word(state, 142 ,0x0610);	for (k = 0; k < 8; k++) {		pha = ((f_rel * (k+1) * 112 * 80/bw_khz) /1000) & 0x3ff;		if (pha==0) {			coef_re[k] = 256;			coef_im[k] = 0;		} else if(pha < 256) {			coef_re[k] = sine[256-(pha&0xff)];			coef_im[k] = sine[pha&0xff];		} else if (pha == 256) {			coef_re[k] = 0;			coef_im[k] = 256;		} else if (pha < 512) {			coef_re[k] = -sine[pha&0xff];			coef_im[k] = sine[256 - (pha&0xff)];		} else if (pha == 512) {			coef_re[k] = -256;			coef_im[k] = 0;		} else if (pha < 768) {			coef_re[k] = -sine[256-(pha&0xff)];			coef_im[k] = -sine[pha&0xff];

⌨️ 快捷键说明

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