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

📄 bcm3510.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Pulse Byte */	c.ctl_dat[15].ctrl.size = BITS_3;	c.ctl_dat[15].ctrl.clk_off = 1;	c.ctl_dat[15].ctrl.cs1  = 1;	c.ctl_dat[15].data      = 0x40;	return bcm3510_do_hab_cmd(st,CMD_TUNE, MSGID_TUNE,(u8 *) &c,sizeof(c), NULL, 0);}static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq){	u8 bc,a;	u16 n;	s32 YIntercept,Tfvco1;	freq /= 1000;	deb_info("%dkHz:",freq);	/* set Band Switch */	if (freq <= 168000)		bc = 0x1c;	else if (freq <= 378000)		bc = 0x2c;	else		bc = 0x30;	if (freq >= 470000) {		freq -= 470001;		YIntercept = 18805;	} else if (freq >= 90000) {		freq -= 90001;		YIntercept = 15005;	} else if (freq >= 76000){		freq -= 76001;		YIntercept = 14865;	} else {		freq -= 54001;		YIntercept = 14645;	}	Tfvco1 = (((freq/6000)*60 + YIntercept)*4)/10;	n = Tfvco1 >> 6;	a = Tfvco1 & 0x3f;	deb_info(" BC1_2_3_4: %x, N: %x A: %x\n", bc, n, a);	if (n >= 16 && n <= 2047)		return bcm3510_tuner_cmd(st,bc,n,a);	return -EINVAL;}static int bcm3510_set_frontend(struct dvb_frontend* fe,					     struct dvb_frontend_parameters *p){	struct bcm3510_state* st = fe->demodulator_priv;	struct bcm3510_hab_cmd_ext_acquire cmd;	struct bcm3510_hab_cmd_bert_control bert;	int ret;	memset(&cmd,0,sizeof(cmd));	switch (p->u.vsb.modulation) {		case QAM_256:			cmd.ACQUIRE0.MODE = 0x1;			cmd.ACQUIRE1.SYM_RATE = 0x1;			cmd.ACQUIRE1.IF_FREQ = 0x1;			break;		case QAM_64:			cmd.ACQUIRE0.MODE = 0x2;			cmd.ACQUIRE1.SYM_RATE = 0x2;			cmd.ACQUIRE1.IF_FREQ = 0x1;			break;/*		case QAM_256:			cmd.ACQUIRE0.MODE = 0x3;			break;		case QAM_128:			cmd.ACQUIRE0.MODE = 0x4;			break;		case QAM_64:			cmd.ACQUIRE0.MODE = 0x5;			break;		case QAM_32:			cmd.ACQUIRE0.MODE = 0x6;			break;		case QAM_16:			cmd.ACQUIRE0.MODE = 0x7;			break;*/		case VSB_8:			cmd.ACQUIRE0.MODE = 0x8;			cmd.ACQUIRE1.SYM_RATE = 0x0;			cmd.ACQUIRE1.IF_FREQ = 0x0;			break;		case VSB_16:			cmd.ACQUIRE0.MODE = 0x9;			cmd.ACQUIRE1.SYM_RATE = 0x0;			cmd.ACQUIRE1.IF_FREQ = 0x0;		default:			return -EINVAL;	};	cmd.ACQUIRE0.OFFSET = 0;	cmd.ACQUIRE0.NTSCSWEEP = 1;	cmd.ACQUIRE0.FA = 1;	cmd.ACQUIRE0.BW = 0;/*	if (enableOffset) {		cmd.IF_OFFSET0 = xx;		cmd.IF_OFFSET1 = xx;		cmd.SYM_OFFSET0 = xx;		cmd.SYM_OFFSET1 = xx;		if (enableNtscSweep) {			cmd.NTSC_OFFSET0;			cmd.NTSC_OFFSET1;		}	} */	bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0);/* doing it with different MSGIDs, data book and source differs */	bert.BE = 0;	bert.unused = 0;	bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0);	bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0);	bcm3510_bert_reset(st);	if ((ret = bcm3510_set_freq(st,p->frequency)) < 0)		return ret;	memset(&st->status1,0,sizeof(st->status1));	memset(&st->status2,0,sizeof(st->status2));	st->status_check_interval = 500;/* Give the AP some time */	msleep(200);	return 0;}static int bcm3510_sleep(struct dvb_frontend* fe){	return 0;}static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s){	s->min_delay_ms = 1000;	s->step_size = 0;	s->max_drift = 0;	return 0;}static void bcm3510_release(struct dvb_frontend* fe){	struct bcm3510_state* state = fe->demodulator_priv;	kfree(state);}/* firmware download: * firmware file is build up like this: * 16bit addr, 16bit length, 8byte of length */#define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw"static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, u8 *b, u16 len){	int ret = 0,i;	bcm3510_register_value vH, vL,vD;	vH.MADRH_a9 = addr >> 8;	vL.MADRL_aa = addr;	if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret;	if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret;	for (i = 0; i < len; i++) {		vD.MDATA_ab = b[i];		if ((ret = bcm3510_writeB(st,0xab,vD)) < 0)			return ret;	}	return 0;}static int bcm3510_download_firmware(struct dvb_frontend* fe){	struct bcm3510_state* st = fe->demodulator_priv;	const struct firmware *fw;	u16 addr,len;	u8  *b;	int ret,i;	deb_info("requesting firmware\n");	if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) {		err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);		return ret;	}	deb_info("got firmware: %d\n",fw->size);	b = fw->data;	for (i = 0; i < fw->size;) {		addr = le16_to_cpu( *( (u16 *)&b[i] ) );		len  = le16_to_cpu( *( (u16 *)&b[i+2] ) );		deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04x\n",addr,len,fw->size);		if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {			err("firmware download failed: %d\n",ret);			return ret;		}		i += 4 + len;	}	release_firmware(fw);	deb_info("firmware download successfully completed\n");	return 0;}static int bcm3510_check_firmware_version(struct bcm3510_state *st){	struct bcm3510_hab_cmd_get_version_info ver;	bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver));	deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n",		ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version);	if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION &&		ver.config_version == BCM3510_DEF_CONFIG_VERSION &&		ver.demod_version  == BCM3510_DEF_DEMOD_VERSION)		return 0;	deb_info("version check failed\n");	return -ENODEV;}/* (un)resetting the AP */static int bcm3510_reset(struct bcm3510_state *st){	int ret;	unsigned long  t;	bcm3510_register_value v;	bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1;	if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)		return ret;    t = jiffies + 3*HZ;	while (time_before(jiffies, t)) {		msleep(10);		if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)			return ret;		if (v.APSTAT1_a2.RESET)			return 0;	}	deb_info("reset timed out\n");	return -ETIMEDOUT;}static int bcm3510_clear_reset(struct bcm3510_state *st){	bcm3510_register_value v;	int ret;	unsigned long t;	v.raw = 0;	if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)		return ret;    t = jiffies + 3*HZ;	while (time_before(jiffies, t)) {		msleep(10);		if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)			return ret;		/* verify that reset is cleared */		if (!v.APSTAT1_a2.RESET)			return 0;	}	deb_info("reset clear timed out\n");	return -ETIMEDOUT;}static int bcm3510_init_cold(struct bcm3510_state *st){	int ret;	bcm3510_register_value v;	/* read Acquisation Processor status register and check it is not in RUN mode */	if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)		return ret;	if (v.APSTAT1_a2.RUN) {		deb_info("AP is already running - firmware already loaded.\n");		return 0;	}	deb_info("reset?\n");	if ((ret = bcm3510_reset(st)) < 0)		return ret;	deb_info("tristate?\n");	/* tri-state */	v.TSTCTL_2e.CTL = 0;	if ((ret = bcm3510_writeB(st,0x2e,v)) < 0)		return ret;	deb_info("firmware?\n");	if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 ||		(ret = bcm3510_clear_reset(st)) < 0)		return ret;	/* anything left here to Let the acquisition processor begin execution at program counter 0000 ??? */	return 0;}static int bcm3510_init(struct dvb_frontend* fe){	struct bcm3510_state* st = fe->demodulator_priv;	bcm3510_register_value j;	struct bcm3510_hab_cmd_set_agc c;	int ret;	if ((ret = bcm3510_readB(st,0xca,&j)) < 0)		return ret;	deb_info("JDEC: %02x\n",j.raw);	switch (j.JDEC_ca.JDEC) {		case JDEC_WAIT_AT_RAM:			deb_info("attempting to download firmware\n");			if ((ret = bcm3510_init_cold(st)) < 0)				return ret;		case JDEC_EEPROM_LOAD_WAIT: /* fall-through is wanted */			deb_info("firmware is loaded\n");			bcm3510_check_firmware_version(st);			break;		default:			return -ENODEV;	}	memset(&c,0,1);	c.SEL = 1;	bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0);	return 0;}static struct dvb_frontend_ops bcm3510_ops;struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,				   struct i2c_adapter *i2c){	struct bcm3510_state* state = NULL;	int ret;	bcm3510_register_value v;	/* allocate memory for the internal state */	state = kmalloc(sizeof(struct bcm3510_state), GFP_KERNEL);	if (state == NULL)		goto error;	memset(state,0,sizeof(struct bcm3510_state));	/* setup the state */	state->config = config;	state->i2c = i2c;	memcpy(&state->ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops));	/* create dvb_frontend */	state->frontend.ops = &state->ops;	state->frontend.demodulator_priv = state;	sema_init(&state->hab_sem, 1);	if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)		goto error;	deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER);	if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) && /* cold */		(v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0))   /* warm */		goto error;	info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER);	bcm3510_reset(state);	return &state->frontend;error:	kfree(state);	return NULL;}EXPORT_SYMBOL(bcm3510_attach);static struct dvb_frontend_ops bcm3510_ops = {	.info = {		.name = "Broadcom BCM3510 VSB/QAM frontend",		.type = FE_ATSC,		.frequency_min =  54000000,		.frequency_max = 803000000,		/* stepsize is just a guess */		.frequency_stepsize = 0,		.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_16VSB |			FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256	},	.release = bcm3510_release,	.init = bcm3510_init,	.sleep = bcm3510_sleep,	.set_frontend = bcm3510_set_frontend,	.get_tune_settings = bcm3510_get_tune_settings,	.read_status = bcm3510_read_status,	.read_ber = bcm3510_read_ber,	.read_signal_strength = bcm3510_read_signal_strength,	.read_snr = bcm3510_read_snr,	.read_ucblocks = bcm3510_read_unc,};MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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