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

📄 nxt200x.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
		case NXT2004:			buf[0] = 0x07;			break;		default:			return -EINVAL;			break;	}	nxt200x_writebytes(state, 0x57, buf, 1);	/* write sdm1 input */	buf[0] = 0x10;	buf[1] = 0x00;	nxt200x_writebytes(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;	nxt200x_writebytes(state, 0x5C, buf, 2);	/* write adc power lpf fc */	buf[0] = 0x05;	nxt200x_writebytes(state, 0x43, buf, 1);	if (state->demod_chip == NXT2004) {		/* write ??? */		buf[0] = 0x00;		buf[1] = 0x00;		nxt200x_writebytes(state, 0x46, buf, 2);	}	/* write accumulator2 input */	buf[0] = 0x80;	buf[1] = 0x00;	nxt200x_writebytes(state, 0x4B, buf, 2);	/* write kg1 */	buf[0] = 0x00;	nxt200x_writebytes(state, 0x4D, buf, 1);	/* write sdm12 lpf fc */	buf[0] = 0x44;	nxt200x_writebytes(state, 0x55, buf, 1);	/* write agc control reg */	buf[0] = 0x04;	nxt200x_writebytes(state, 0x41, buf, 1);	if (state->demod_chip == NXT2004) {		nxt200x_readreg_multibyte(state, 0x80, buf, 1);		buf[0] = 0x24;		nxt200x_writereg_multibyte(state, 0x80, buf, 1);		/* soft reset? */		nxt200x_readreg_multibyte(state, 0x08, buf, 1);		buf[0] = 0x10;		nxt200x_writereg_multibyte(state, 0x08, buf, 1);		nxt200x_readreg_multibyte(state, 0x08, buf, 1);		buf[0] = 0x00;		nxt200x_writereg_multibyte(state, 0x08, buf, 1);		nxt200x_readreg_multibyte(state, 0x80, buf, 1);		buf[0] = 0x04;		nxt200x_writereg_multibyte(state, 0x80, buf, 1);		buf[0] = 0x00;		nxt200x_writereg_multibyte(state, 0x81, buf, 1);		buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;		nxt200x_writereg_multibyte(state, 0x82, buf, 3);		nxt200x_readreg_multibyte(state, 0x88, buf, 1);		buf[0] = 0x11;		nxt200x_writereg_multibyte(state, 0x88, buf, 1);		nxt200x_readreg_multibyte(state, 0x80, buf, 1);		buf[0] = 0x44;		nxt200x_writereg_multibyte(state, 0x80, 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;	}	nxt200x_writebytes(state, 0x30, buf, 1);	/* write agc control reg */	buf[0] = 0x00;	nxt200x_writebytes(state, 0x41, buf, 1);	/* write accumulator2 input */	buf[0] = 0x80;	buf[1] = 0x00;	nxt200x_writebytes(state, 0x49, buf,2);	nxt200x_writebytes(state, 0x4B, buf,2);	/* write agc control reg */	buf[0] = 0x04;	nxt200x_writebytes(state, 0x41, buf, 1);	nxt200x_microcontroller_start(state);	if (state->demod_chip == NXT2004) {		nxt2004_microcontroller_init(state);		/* ???? */		buf[0] = 0xF0;		buf[1] = 0x00;		nxt200x_writebytes(state, 0x5C, buf, 2);	}	/* 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 nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status){	struct nxt200x_state* state = fe->demodulator_priv;	u8 lock;	nxt200x_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 nxt200x_read_ber(struct dvb_frontend* fe, u32* ber){	struct nxt200x_state* state = fe->demodulator_priv;	u8 b[3];	nxt200x_readreg_multibyte(state, 0xE6, b, 3);	*ber = ((b[0] << 8) + b[1]) * 8;	return 0;}static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength){	struct nxt200x_state* state = fe->demodulator_priv;	u8 b[2];	u16 temp = 0;	/* setup to read cluster variance */	b[0] = 0x00;	nxt200x_writebytes(state, 0xA1, b, 1);	/* get multreg val */	nxt200x_readreg_multibyte(state, 0xA6, b, 2);	temp = (b[0] << 8) | b[1];	*strength = ((0x7FFF - temp) & 0x0FFF) * 16;	return 0;}static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr){	struct nxt200x_state* state = fe->demodulator_priv;	u8 b[2];	u16 temp = 0, temp2;	u32 snrdb = 0;	/* setup to read cluster variance */	b[0] = 0x00;	nxt200x_writebytes(state, 0xA1, b, 1);	/* get multreg val from 0xA6 */	nxt200x_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 nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks){	struct nxt200x_state* state = fe->demodulator_priv;	u8 b[3];	nxt200x_readreg_multibyte(state, 0xE6, b, 3);	*ucblocks = b[2];	return 0;}static int nxt200x_sleep(struct dvb_frontend* fe){	return 0;}static int nxt2002_init(struct dvb_frontend* fe){	struct nxt200x_state* state = fe->demodulator_priv;	const struct firmware *fw;	int ret;	u8 buf[2];	/* request the firmware, this will block until someone uploads it */	printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);	ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, &state->i2c->dev);	printk("nxt2002: Waiting for firmware upload(2)...\n");	if (ret) {		printk("nxt2002: No firmware uploaded (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 */	nxt200x_microcontroller_stop(state);	/* ensure transfer is complete */	buf[0]=0x00;	nxt200x_writebytes(state, 0x2B, buf, 1);	/* Put the micro into reset for real this time */	nxt200x_microcontroller_stop(state);	/* soft reset everything (agc,frontend,eq,fec)*/	buf[0] = 0x0F;	nxt200x_writebytes(state, 0x08, buf, 1);	buf[0] = 0x00;	nxt200x_writebytes(state, 0x08, buf, 1);	/* write agc sdm configure */	buf[0] = 0xF1;	nxt200x_writebytes(state, 0x57, buf, 1);	/* write mod output format */	buf[0] = 0x20;	nxt200x_writebytes(state, 0x09, buf, 1);	/* write fec mpeg mode */	buf[0] = 0x7E;	buf[1] = 0x00;	nxt200x_writebytes(state, 0xE9, buf, 2);	/* write mux selection */	buf[0] = 0x00;	nxt200x_writebytes(state, 0xCC, buf, 1);	return 0;}static int nxt2004_init(struct dvb_frontend* fe){	struct nxt200x_state* state = fe->demodulator_priv;	const struct firmware *fw;	int ret;	u8 buf[3];	/* ??? */	buf[0]=0x00;	nxt200x_writebytes(state, 0x1E, buf, 1);	/* request the firmware, this will block until someone uploads it */	printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE);	ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, &state->i2c->dev);	printk("nxt2004: Waiting for firmware upload(2)...\n");	if (ret) {		printk("nxt2004: No firmware uploaded (timeout or file not found?)\n");		return ret;	}	ret = nxt2004_load_firmware(fe, fw);	if (ret) {		printk("nxt2004: Writing firmware to device failed\n");		release_firmware(fw);		return ret;	}	printk("nxt2004: Firmware upload complete\n");	/* ensure transfer is complete */	buf[0] = 0x01;	nxt200x_writebytes(state, 0x19, buf, 1);	nxt2004_microcontroller_init(state);	nxt200x_microcontroller_stop(state);	nxt200x_microcontroller_stop(state);	nxt2004_microcontroller_init(state);	nxt200x_microcontroller_stop(state);	/* soft reset everything (agc,frontend,eq,fec)*/	buf[0] = 0xFF;	nxt200x_writereg_multibyte(state, 0x08, buf, 1);	buf[0] = 0x00;	nxt200x_writereg_multibyte(state, 0x08, buf, 1);	/* write agc sdm configure */	buf[0] = 0xD7;	nxt200x_writebytes(state, 0x57, buf, 1);	/* ???*/	buf[0] = 0x07;	buf[1] = 0xfe;	nxt200x_writebytes(state, 0x35, buf, 2);	buf[0] = 0x12;	nxt200x_writebytes(state, 0x34, buf, 1);	buf[0] = 0x80;	nxt200x_writebytes(state, 0x21, buf, 1);	/* ???*/	buf[0] = 0x21;	nxt200x_writebytes(state, 0x0A, buf, 1);	/* ???*/	buf[0] = 0x01;	nxt200x_writereg_multibyte(state, 0x80, buf, 1);	/* write fec mpeg mode */	buf[0] = 0x7E;	buf[1] = 0x00;	nxt200x_writebytes(state, 0xE9, buf, 2);	/* write mux selection */	buf[0] = 0x00;	nxt200x_writebytes(state, 0xCC, buf, 1);	/* ???*/	nxt200x_readreg_multibyte(state, 0x80, buf, 1);	buf[0] = 0x00;	nxt200x_writereg_multibyte(state, 0x80, buf, 1);	/* soft reset? */	nxt200x_readreg_multibyte(state, 0x08, buf, 1);	buf[0] = 0x10;	nxt200x_writereg_multibyte(state, 0x08, buf, 1);	nxt200x_readreg_multibyte(state, 0x08, buf, 1);	buf[0] = 0x00;	nxt200x_writereg_multibyte(state, 0x08, buf, 1);	/* ???*/	nxt200x_readreg_multibyte(state, 0x80, buf, 1);	buf[0] = 0x01;	nxt200x_writereg_multibyte(state, 0x80, buf, 1);	buf[0] = 0x70;	nxt200x_writereg_multibyte(state, 0x81, buf, 1);	buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66;	nxt200x_writereg_multibyte(state, 0x82, buf, 3);	nxt200x_readreg_multibyte(state, 0x88, buf, 1);	buf[0] = 0x11;	nxt200x_writereg_multibyte(state, 0x88, buf, 1);	nxt200x_readreg_multibyte(state, 0x80, buf, 1);	buf[0] = 0x40;	nxt200x_writereg_multibyte(state, 0x80, buf, 1);	nxt200x_readbytes(state, 0x10, buf, 1);	buf[0] = 0x10;	nxt200x_writebytes(state, 0x10, buf, 1);	nxt200x_readbytes(state, 0x0A, buf, 1);	buf[0] = 0x21;	nxt200x_writebytes(state, 0x0A, buf, 1);	nxt2004_microcontroller_init(state);	buf[0] = 0x21;	nxt200x_writebytes(state, 0x0A, buf, 1);	buf[0] = 0x7E;	nxt200x_writebytes(state, 0xE9, buf, 1);	buf[0] = 0x00;	nxt200x_writebytes(state, 0xEA, buf, 1);	nxt200x_readreg_multibyte(state, 0x80, buf, 1);	buf[0] = 0x00;	nxt200x_writereg_multibyte(state, 0x80, buf, 1);	nxt200x_readreg_multibyte(state, 0x80, buf, 1);	buf[0] = 0x00;	nxt200x_writereg_multibyte(state, 0x80, buf, 1);	/* soft reset? */	nxt200x_readreg_multibyte(state, 0x08, buf, 1);	buf[0] = 0x10;	nxt200x_writereg_multibyte(state, 0x08, buf, 1);	nxt200x_readreg_multibyte(state, 0x08, buf, 1);	buf[0] = 0x00;	nxt200x_writereg_multibyte(state, 0x08, buf, 1);	nxt200x_readreg_multibyte(state, 0x80, buf, 1);	buf[0] = 0x04;	nxt200x_writereg_multibyte(state, 0x80, buf, 1);	buf[0] = 0x00;	nxt200x_writereg_multibyte(state, 0x81, buf, 1);	buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;	nxt200x_writereg_multibyte(state, 0x82, buf, 3);	nxt200x_readreg_multibyte(state, 0x88, buf, 1);	buf[0] = 0x11;	nxt200x_writereg_multibyte(state, 0x88, buf, 1);	nxt200x_readreg_multibyte(state, 0x80, buf, 1);	buf[0] = 0x44;	nxt200x_writereg_multibyte(state, 0x80, buf, 1);	/* initialize tuner */	nxt200x_readbytes(state, 0x10, buf, 1);	buf[0] = 0x12;	nxt200x_writebytes(state, 0x10, buf, 1);	buf[0] = 0x04;	nxt200x_writebytes(state, 0x13, buf, 1);	buf[0] = 0x00;	nxt200x_writebytes(state, 0x16, buf, 1);	buf[0] = 0x04;	nxt200x_writebytes(state, 0x14, buf, 1);	buf[0] = 0x00;	nxt200x_writebytes(state, 0x14, buf, 1);	nxt200x_writebytes(state, 0x17, buf, 1);	nxt200x_writebytes(state, 0x14, buf, 1);	nxt200x_writebytes(state, 0x17, buf, 1);	return 0;}static int nxt200x_init(struct dvb_frontend* fe){	struct nxt200x_state* state = fe->demodulator_priv;	int ret = 0;	if (!state->initialised) {		switch (state->demod_chip) {			case NXT2002:				ret = nxt2002_init(fe);				break;			case NXT2004:				ret = nxt2004_init(fe);				break;			default:				return -EINVAL;				break;		}		state->initialised = 1;	}	return ret;}static int nxt200x_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 nxt200x_release(struct dvb_frontend* fe){	struct nxt200x_state* state = fe->demodulator_priv;	kfree(state);}static struct dvb_frontend_ops nxt200x_ops;struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,				   struct i2c_adapter* i2c){	struct nxt200x_state* state = NULL;	u8 buf [] = {0,0,0,0,0};	/* allocate memory for the internal state */	state = (struct nxt200x_state*) kmalloc(sizeof(struct nxt200x_state), GFP_KERNEL);	if (state == NULL)		goto error;	memset(state,0,sizeof(*state));	/* setup the state */	state->config = config;	state->i2c = i2c;	memcpy(&state->ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));	state->initialised = 0;	/* read card id */	nxt200x_readbytes(state, 0x00, buf, 5);	dprintk("NXT info: %02X %02X %02X %02X %02X\n",		buf[0], buf[1], buf[2],	buf[3], buf[4]);	/* set demod chip */	switch (buf[0]) {		case 0x04:			state->demod_chip = NXT2002;			printk("nxt200x: NXT2002 Detected\n");			break;		case 0x05:			state->demod_chip = NXT2004;			printk("nxt200x: NXT2004 Detected\n");			break;		default:			goto error;	}	/* make sure demod chip is supported */	switch (state->demod_chip) {		case NXT2002:			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 */			break;		case NXT2004:			if (buf[0] != 0x05) goto error;		/* device id */			break;		default:			goto error;	}	/* create dvb_frontend */	state->frontend.ops = &state->ops;	state->frontend.demodulator_priv = state;	return &state->frontend;error:	kfree(state);	printk("Unknown/Unsupported NXT chip: %02X %02X %02X %02X %02X\n",		buf[0], buf[1], buf[2], buf[3], buf[4]);	return NULL;}static struct dvb_frontend_ops nxt200x_ops = {	.info = {		.name = "Nextwave NXT200X VSB/QAM frontend",		.type = FE_ATSC,		.frequency_min =  54000000,		.frequency_max = 860000000,		.frequency_stepsize = 166666,	/* stepsize is just a guess */		.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 = nxt200x_release,	.init = nxt200x_init,	.sleep = nxt200x_sleep,	.set_frontend = nxt200x_setup_frontend_parameters,	.get_tune_settings = nxt200x_get_tune_settings,	.read_status = nxt200x_read_status,	.read_ber = nxt200x_read_ber,	.read_signal_strength = nxt200x_read_signal_strength,	.read_snr = nxt200x_read_snr,	.read_ucblocks = nxt200x_read_ucblocks,};module_param(debug, int, 0644);MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");MODULE_AUTHOR("Kirk Lapray, Jean-Francois Thibert, and Taylor Jacob");MODULE_LICENSE("GPL");EXPORT_SYMBOL(nxt200x_attach);

⌨️ 快捷键说明

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