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

📄 nxt2002.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
		case VSB_8:				buf[0] = 0x70;				break;		default:				return -EINVAL;				break;	}	i2c_writebytes(state,0x42,buf,1);	/* configure sdm */	buf[0] = 0x87;	i2c_writebytes(state,0x57,buf,1);	/* write sdm1 input */	buf[0] = 0x10;	buf[1] = 0x00;	nxt2002_writereg_multibyte(state,0x58,buf,2);	/* write sdmx input */	switch (p->u.vsb.modulation) {		case QAM_64:				buf[0] = 0x68;				break;		case QAM_256:				buf[0] = 0x64;				break;		case VSB_8:				buf[0] = 0x60;				break;		default:				return -EINVAL;				break;	}	buf[1] = 0x00;	nxt2002_writereg_multibyte(state,0x5C,buf,2);	/* write adc power lpf fc */	buf[0] = 0x05;	i2c_writebytes(state,0x43,buf,1);	/* write adc power lpf fc */	buf[0] = 0x05;	i2c_writebytes(state,0x43,buf,1);	/* write accumulator2 input */	buf[0] = 0x80;	buf[1] = 0x00;	nxt2002_writereg_multibyte(state,0x4B,buf,2);	/* write kg1 */	buf[0] = 0x00;	i2c_writebytes(state,0x4D,buf,1);	/* write sdm12 lpf fc */	buf[0] = 0x44;	i2c_writebytes(state,0x55,buf,1);	/* write agc control reg */	buf[0] = 0x04;	i2c_writebytes(state,0x41,buf,1);	/* write agc ucgp0 */	switch (p->u.vsb.modulation) {		case QAM_64:				buf[0] = 0x02;				break;		case QAM_256:				buf[0] = 0x03;				break;		case VSB_8:				buf[0] = 0x00;				break;		default:				return -EINVAL;				break;	}	i2c_writebytes(state,0x30,buf,1);	/* write agc control reg */	buf[0] = 0x00;	i2c_writebytes(state,0x41,buf,1);	/* write accumulator2 input */	buf[0] = 0x80;	buf[1] = 0x00;	nxt2002_writereg_multibyte(state,0x49,buf,2);	nxt2002_writereg_multibyte(state,0x4B,buf,2);	/* write agc control reg */	buf[0] = 0x04;	i2c_writebytes(state,0x41,buf,1);	nxt2002_microcontroller_start(state);	/* adjacent channel detection should be done here, but I don't	have any stations with this need so I cannot test it */	return 0;}static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status){	struct nxt2002_state* state = fe->demodulator_priv;	u8 lock;	i2c_readbytes(state,0x31,&lock,1);	*status = 0;	if (lock & 0x20) {		*status |= FE_HAS_SIGNAL;		*status |= FE_HAS_CARRIER;		*status |= FE_HAS_VITERBI;		*status |= FE_HAS_SYNC;		*status |= FE_HAS_LOCK;	}	return 0;}static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber){	struct nxt2002_state* state = fe->demodulator_priv;	u8 b[3];	nxt2002_readreg_multibyte(state,0xE6,b,3);	*ber = ((b[0] << 8) + b[1]) * 8;	return 0;}static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength){	struct nxt2002_state* state = fe->demodulator_priv;	u8 b[2];	u16 temp = 0;	/* setup to read cluster variance */	b[0] = 0x00;	i2c_writebytes(state,0xA1,b,1);	/* get multreg val */	nxt2002_readreg_multibyte(state,0xA6,b,2);	temp = (b[0] << 8) | b[1];	*strength = ((0x7FFF - temp) & 0x0FFF) * 16;	return 0;}static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr){	struct nxt2002_state* state = fe->demodulator_priv;	u8 b[2];	u16 temp = 0, temp2;	u32 snrdb = 0;	/* setup to read cluster variance */	b[0] = 0x00;	i2c_writebytes(state,0xA1,b,1);	/* get multreg val from 0xA6 */	nxt2002_readreg_multibyte(state,0xA6,b,2);	temp = (b[0] << 8) | b[1];	temp2 = 0x7FFF - temp;	/* snr will be in db */	if (temp2 > 0x7F00)		snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );	else if (temp2 > 0x7EC0)		snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );	else if (temp2 > 0x7C00)		snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );	else		snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );	/* the value reported back from the frontend will be FFFF=32db 0000=0db */	*snr = snrdb * (0xFFFF/32000);	return 0;}static int nxt2002_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks){	struct nxt2002_state* state = fe->demodulator_priv;	u8 b[3];	nxt2002_readreg_multibyte(state,0xE6,b,3);	*ucblocks = b[2];	return 0;}static int nxt2002_sleep(struct dvb_frontend* fe){	return 0;}static int nxt2002_init(struct dvb_frontend* fe){	struct nxt2002_state* state = fe->demodulator_priv;	const struct firmware *fw;	int ret;	u8 buf[2];	if (!state->initialised) {		/* request the firmware, this will block until someone uploads it */		printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);		ret = state->config->request_firmware(fe, &fw, NXT2002_DEFAULT_FIRMWARE);		printk("nxt2002: Waiting for firmware upload(2)...\n");		if (ret) {			printk("nxt2002: no firmware upload (timeout or file not found?)\n");			return ret;		}		ret = nxt2002_load_firmware(fe, fw);		if (ret) {			printk("nxt2002: writing firmware to device failed\n");			release_firmware(fw);			return ret;		}		printk("nxt2002: firmware upload complete\n");		/* Put the micro into reset */		nxt2002_microcontroller_stop(state);		/* ensure transfer is complete */		buf[0]=0;		i2c_writebytes(state,0x2B,buf,1);		/* Put the micro into reset for real this time */		nxt2002_microcontroller_stop(state);		/* soft reset everything (agc,frontend,eq,fec)*/		buf[0] = 0x0F;		i2c_writebytes(state,0x08,buf,1);		buf[0] = 0x00;		i2c_writebytes(state,0x08,buf,1);		/* write agc sdm configure */		buf[0] = 0xF1;		i2c_writebytes(state,0x57,buf,1);		/* write mod output format */		buf[0] = 0x20;		i2c_writebytes(state,0x09,buf,1);		/* write fec mpeg mode */		buf[0] = 0x7E;		buf[1] = 0x00;		i2c_writebytes(state,0xE9,buf,2);		/* write mux selection */		buf[0] = 0x00;		i2c_writebytes(state,0xCC,buf,1);		state->initialised = 1;	}	return 0;}static int nxt2002_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings){	fesettings->min_delay_ms = 500;	fesettings->step_size = 0;	fesettings->max_drift = 0;	return 0;}static void nxt2002_release(struct dvb_frontend* fe){	struct nxt2002_state* state = fe->demodulator_priv;	kfree(state);}static struct dvb_frontend_ops nxt2002_ops;struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,				   struct i2c_adapter* i2c){	struct nxt2002_state* state = NULL;	u8 buf [] = {0,0,0,0,0};	/* allocate memory for the internal state */	state = kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL);	if (state == NULL) goto error;	/* setup the state */	state->config = config;	state->i2c = i2c;	memcpy(&state->ops, &nxt2002_ops, sizeof(struct dvb_frontend_ops));	state->initialised = 0;	/* Check the first 5 registers to ensure this a revision we can handle */	i2c_readbytes(state, 0x00, buf, 5);	if (buf[0] != 0x04) goto error;		/* device id */	if (buf[1] != 0x02) goto error;		/* fab id */	if (buf[2] != 0x11) goto error;		/* month */	if (buf[3] != 0x20) goto error;		/* year msb */	if (buf[4] != 0x00) goto error;		/* year lsb */	/* create dvb_frontend */	state->frontend.ops = &state->ops;	state->frontend.demodulator_priv = state;	return &state->frontend;error:	kfree(state);	return NULL;}static struct dvb_frontend_ops nxt2002_ops = {	.info = {		.name = "Nextwave nxt2002 VSB/QAM frontend",		.type = FE_ATSC,		.frequency_min =  54000000,		.frequency_max = 860000000,		/* stepsize is just a guess */		.frequency_stepsize = 166666,		.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_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256	},	.release = nxt2002_release,	.init = nxt2002_init,	.sleep = nxt2002_sleep,	.set_frontend = nxt2002_setup_frontend_parameters,	.get_tune_settings = nxt2002_get_tune_settings,	.read_status = nxt2002_read_status,	.read_ber = nxt2002_read_ber,	.read_signal_strength = nxt2002_read_signal_strength,	.read_snr = nxt2002_read_snr,	.read_ucblocks = nxt2002_read_ucblocks,};module_param(debug, int, 0644);MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");MODULE_DESCRIPTION("NXT2002 ATSC (8VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");MODULE_AUTHOR("Taylor Jacob");MODULE_LICENSE("GPL");EXPORT_SYMBOL(nxt2002_attach);

⌨️ 快捷键说明

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