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

📄 av7110.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		for (i = 0; i < demux->filternum; i++) {			if (demux->filter[i].state != DMX_STATE_READY)				continue;			if (demux->filter[i].type != DMX_TYPE_SEC)				continue;			if (demux->filter[i].filter.parent != &feed->feed.sec)				continue;			demux->filter[i].state = DMX_STATE_GO;			if (demux->dmx.frontend->source != DMX_MEMORY_FE) {				ret = StartHWFilter(&demux->filter[i]);				if (ret)					break;			}		}	}	return ret;}static int av7110_stop_feed(struct dvb_demux_feed *feed){	struct dvb_demux *demux = feed->demux;	struct av7110 *av7110 = demux->priv;	int i, rc, ret = 0;	dprintk(4, "%p\n", av7110);	if (feed->type == DMX_TYPE_TS) {		if (feed->ts_type & TS_DECODER) {			if (feed->pes_type >= DMX_TS_PES_OTHER ||			    !demux->pesfilter[feed->pes_type])				return -EINVAL;			demux->pids[feed->pes_type] |= 0x8000;			demux->pesfilter[feed->pes_type] = NULL;		}		if (feed->ts_type & TS_DECODER &&		    feed->pes_type < DMX_TS_PES_OTHER) {			ret = dvb_feed_stop_pid(feed);		} else			if ((feed->ts_type & TS_PACKET) &&			    (demux->dmx.frontend->source != DMX_MEMORY_FE))				ret = StopHWFilter(feed->filter);	}	if (!ret && feed->type == DMX_TYPE_SEC) {		for (i = 0; i<demux->filternum; i++) {			if (demux->filter[i].state == DMX_STATE_GO &&			    demux->filter[i].filter.parent == &feed->feed.sec) {				demux->filter[i].state = DMX_STATE_READY;				if (demux->dmx.frontend->source != DMX_MEMORY_FE) {					rc = StopHWFilter(&demux->filter[i]);					if (!ret)						ret = rc;					/* keep going, stop as many filters as possible */				}			}		}	}	return ret;}static void restart_feeds(struct av7110 *av7110){	struct dvb_demux *dvbdmx = &av7110->demux;	struct dvb_demux_feed *feed;	int mode;	int i;	dprintk(4, "%p\n", av7110);	mode = av7110->playing;	av7110->playing = 0;	av7110->rec_mode = 0;	for (i = 0; i < dvbdmx->filternum; i++) {		feed = &dvbdmx->feed[i];		if (feed->state == DMX_STATE_GO)			av7110_start_feed(feed);	}	if (mode)		av7110_av_start_play(av7110, mode);}static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,		       uint64_t *stc, unsigned int *base){	int ret;	u16 fwstc[4];	u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC);	struct dvb_demux *dvbdemux;	struct av7110 *av7110;	/* pointer casting paranoia... */	if (!demux)		BUG();	dvbdemux = (struct dvb_demux *) demux->priv;	if (!dvbdemux)		BUG();	av7110 = (struct av7110 *) dvbdemux->priv;	dprintk(4, "%p\n", av7110);	if (num != 0)		return -EINVAL;	ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);	if (ret) {		printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);		return ret;	}	dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",		fwstc[0], fwstc[1], fwstc[2], fwstc[3]);	*stc =	(((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |		(((uint64_t)  fwstc[1]) << 16) | ((uint64_t) fwstc[0]);	*base = 1;	dprintk(4, "stc = %lu\n", (unsigned long)*stc);	return 0;}/****************************************************************************** * SEC device file operations ******************************************************************************/static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone){	struct av7110* av7110 = (struct av7110*) fe->dvb->priv;	switch (tone) {	case SEC_TONE_ON:		return Set22K(av7110, 1);	case SEC_TONE_OFF:		return Set22K(av7110, 0);	default:		return -EINVAL;	}}static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,					 struct dvb_diseqc_master_cmd* cmd){	struct av7110* av7110 = fe->dvb->priv;	return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);}static int av7110_diseqc_send_burst(struct dvb_frontend* fe,				    fe_sec_mini_cmd_t minicmd){	struct av7110* av7110 = fe->dvb->priv;	return av7110_diseqc_send(av7110, 0, NULL, minicmd);}/* simplified code from budget-core.c */static int stop_ts_capture(struct av7110 *budget){	dprintk(2, "budget: %p\n", budget);	if (--budget->feeding1)		return budget->feeding1;	saa7146_write(budget->dev, MC1, MASK_20);	/* DMA3 off */	SAA7146_IER_DISABLE(budget->dev, MASK_10);	SAA7146_ISR_CLEAR(budget->dev, MASK_10);	return 0;}static int start_ts_capture(struct av7110 *budget){	dprintk(2, "budget: %p\n", budget);	if (budget->feeding1)		return ++budget->feeding1;	memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);	budget->tsf = 0xff;	budget->ttbp = 0;	SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */	saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */	return ++budget->feeding1;}static int budget_start_feed(struct dvb_demux_feed *feed){	struct dvb_demux *demux = feed->demux;	struct av7110 *budget = (struct av7110 *) demux->priv;	int status;	dprintk(2, "av7110: %p\n", budget);	spin_lock(&budget->feedlock1);	feed->pusi_seen = 0; /* have a clean section start */	status = start_ts_capture(budget);	spin_unlock(&budget->feedlock1);	return status;}static int budget_stop_feed(struct dvb_demux_feed *feed){	struct dvb_demux *demux = feed->demux;	struct av7110 *budget = (struct av7110 *) demux->priv;	int status;	dprintk(2, "budget: %p\n", budget);	spin_lock(&budget->feedlock1);	status = stop_ts_capture(budget);	spin_unlock(&budget->feedlock1);	return status;}static void vpeirq(unsigned long data){	struct av7110 *budget = (struct av7110 *) data;	u8 *mem = (u8 *) (budget->grabbing);	u32 olddma = budget->ttbp;	u32 newdma = saa7146_read(budget->dev, PCI_VDP3);	if (!budgetpatch) {		printk("av7110.c: vpeirq() called while budgetpatch disabled!"		       " check saa7146 IER register\n");		BUG();	}	/* nearest lower position divisible by 188 */	newdma -= newdma % 188;	if (newdma >= TS_BUFLEN)		return;	budget->ttbp = newdma;	if (!budget->feeding1 || (newdma == olddma))		return;#if 0	/* track rps1 activity */	printk("vpeirq: %02x Event Counter 1 0x%04x\n",	       mem[olddma],	       saa7146_read(budget->dev, EC1R) & 0x3fff);#endif	if (newdma > olddma)		/* no wraparound, dump olddma..newdma */		dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (newdma - olddma) / 188);	else {		/* wraparound, dump olddma..buflen and 0..newdma */		dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (TS_BUFLEN - olddma) / 188);		dvb_dmx_swfilter_packets(&budget->demux1, mem, newdma / 188);	}}static int av7110_register(struct av7110 *av7110){	int ret, i;	struct dvb_demux *dvbdemux = &av7110->demux;	struct dvb_demux *dvbdemux1 = &av7110->demux1;	dprintk(4, "%p\n", av7110);	if (av7110->registered)		return -1;	av7110->registered = 1;	dvbdemux->priv = (void *) av7110;	for (i = 0; i < 32; i++)		av7110->handle2filter[i] = NULL;	dvbdemux->filternum = 32;	dvbdemux->feednum = 32;	dvbdemux->start_feed = av7110_start_feed;	dvbdemux->stop_feed = av7110_stop_feed;	dvbdemux->write_to_decoder = av7110_write_to_decoder;	dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |				      DMX_MEMORY_BASED_FILTERING);	dvb_dmx_init(&av7110->demux);	av7110->demux.dmx.get_stc = dvb_get_stc;	av7110->dmxdev.filternum = 32;	av7110->dmxdev.demux = &dvbdemux->dmx;	av7110->dmxdev.capabilities = 0;	dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter);	av7110->hw_frontend.source = DMX_FRONTEND_0;	ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend);	if (ret < 0)		return ret;	av7110->mem_frontend.source = DMX_MEMORY_FE;	ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend);	if (ret < 0)		return ret;	ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx,					     &av7110->hw_frontend);	if (ret < 0)		return ret;	av7110_av_register(av7110);	av7110_ca_register(av7110);#ifdef CONFIG_DVB_AV7110_OSD	dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,			    &dvbdev_osd, av7110, DVB_DEVICE_OSD);#endif	dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);	if (budgetpatch) {		/* initialize software demux1 without its own frontend		 * demux1 hardware is connected to frontend0 of demux0		 */		dvbdemux1->priv = (void *) av7110;		dvbdemux1->filternum = 256;		dvbdemux1->feednum = 256;		dvbdemux1->start_feed = budget_start_feed;		dvbdemux1->stop_feed = budget_stop_feed;		dvbdemux1->write_to_decoder = NULL;		dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |					       DMX_MEMORY_BASED_FILTERING);		dvb_dmx_init(&av7110->demux1);		av7110->dmxdev1.filternum = 256;		av7110->dmxdev1.demux = &dvbdemux1->dmx;		av7110->dmxdev1.capabilities = 0;		dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter);		dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);		printk("dvb-ttpci: additional demux1 for budget-patch registered\n");	}	return 0;}static void dvb_unregister(struct av7110 *av7110){	struct dvb_demux *dvbdemux = &av7110->demux;	struct dvb_demux *dvbdemux1 = &av7110->demux1;	dprintk(4, "%p\n", av7110);	if (!av7110->registered)		return;	if (budgetpatch) {		dvb_net_release(&av7110->dvb_net1);		dvbdemux->dmx.close(&dvbdemux1->dmx);		dvb_dmxdev_release(&av7110->dmxdev1);		dvb_dmx_release(&av7110->demux1);	}	dvb_net_release(&av7110->dvb_net);	dvbdemux->dmx.close(&dvbdemux->dmx);	dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend);	dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend);	dvb_dmxdev_release(&av7110->dmxdev);	dvb_dmx_release(&av7110->demux);	if (av7110->fe != NULL)		dvb_unregister_frontend(av7110->fe);	dvb_unregister_device(av7110->osd_dev);	av7110_av_unregister(av7110);	av7110_ca_unregister(av7110);}/**************************************************************************** * I2C client commands ****************************************************************************/int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val){	u8 msg[2] = { reg, val };	struct i2c_msg msgs;	msgs.flags = 0;	msgs.addr = id / 2;	msgs.len = 2;	msgs.buf = msg;	return i2c_transfer(&av7110->i2c_adap, &msgs, 1);}#if 0u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg){	u8 mm1[] = {0x00};	u8 mm2[] = {0x00};	struct i2c_msg msgs[2];	msgs[0].flags = 0;	msgs[1].flags = I2C_M_RD;	msgs[0].addr = msgs[1].addr = id / 2;	mm1[0] = reg;	msgs[0].len = 1; msgs[1].len = 1;	msgs[0].buf = mm1; msgs[1].buf = mm2;	i2c_transfer(&av7110->i2c_adap, msgs, 2);	return mm2[0];}#endif/**************************************************************************** * INITIALIZATION ****************************************************************************/static int check_firmware(struct av7110* av7110){	u32 crc = 0, len = 0;	unsigned char *ptr;	/* check for firmware magic */	ptr = av7110->bin_fw;	if (ptr[0] != 'A' || ptr[1] != 'V' ||	    ptr[2] != 'F' || ptr[3] != 'W') {		printk("dvb-ttpci: this is not an av7110 firmware\n");		return -EINVAL;	}	ptr += 4;	/* check dpram file */	crc = ntohl(*(u32*) ptr);	ptr += 4;	len = ntohl(*(u32*) ptr);	ptr += 4;	if (len >= 512) {		printk("dvb-ttpci: dpram file is way to big.\n");		return -EINVAL;	}	if (crc != crc32_le(0, ptr, len)) {		printk("dvb-ttpci: crc32 of dpram file does not match.\n");		return -EINVAL;	}	av7110->bin_dpram = ptr;	av7110->size_dpram = len;	ptr += len;	/* check root file */	crc = ntohl(*(u32*) ptr);	ptr += 4;	len = ntohl(*(u32*) ptr);	ptr += 4;	if (len <= 200000 || len >= 300000 ||	    len > ((av7110->bin_fw + av7110->size_fw) - ptr)) {		printk("dvb-ttpci: root file has strange size (%d). aborting.\n", len);		return -EINVAL;	}	if( crc != crc32_le(0, ptr, len)) {		printk("dvb-ttpci: crc32 of root file does not match.\n");		return -EINVAL;	}	av7110->bin_root = ptr;	av7110->size_root = len;	return 0;}#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE#include "av7110_firm.h"static void put_firmware(struct av7110* av7110){	av7110->bin_fw = NULL;}static inline int get_firmware(struct av7110* av7110){

⌨️ 快捷键说明

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