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

📄 av7110.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	txbuf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);	len = (av7110->debilen + 3) & ~3;	print_time("gpio");	dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen);	switch (av7110->debitype & 0xff) {	case DATA_TS_PLAY:	case DATA_PES_PLAY:		break;	case DATA_MPEG_VIDEO_EVENT:	{		u32 h_ar;		struct video_event event;		av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2);		h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2);		iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);		iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);		av7110->video_size.h = h_ar & 0xfff;		dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",			av7110->video_size.w,			av7110->video_size.h,			av7110->video_size.aspect_ratio);		event.type = VIDEO_EVENT_SIZE_CHANGED;		event.u.size.w = av7110->video_size.w;		event.u.size.h = av7110->video_size.h;		switch ((h_ar >> 12) & 0xf)		{		case 3:			av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;			event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;			av7110->videostate.video_format = VIDEO_FORMAT_16_9;			break;		case 4:			av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1;			event.u.size.aspect_ratio = VIDEO_FORMAT_221_1;			av7110->videostate.video_format = VIDEO_FORMAT_221_1;			break;		default:			av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3;			event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;			av7110->videostate.video_format = VIDEO_FORMAT_4_3;		}		dvb_video_add_event(av7110, &event);		break;	}	case DATA_CI_PUT:	{		int avail;		struct dvb_ringbuffer *cibuf = &av7110->ci_wbuffer;		avail = dvb_ringbuffer_avail(cibuf);		if (avail <= 2) {			iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);			iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);			iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);			break;		}		len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;		len |= DVB_RINGBUFFER_PEEK(cibuf, 1);		if (avail < len + 2) {			iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);			iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);			iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);			break;		}		DVB_RINGBUFFER_SKIP(cibuf, 2);		dvb_ringbuffer_read(cibuf, av7110->debi_virt, len, 0);		iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);		iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);		dprintk(8, "DMA: CI\n");		start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);		spin_unlock(&av7110->debilock);		wake_up(&cibuf->queue);		return;	}	case DATA_MPEG_PLAY:		if (!av7110->playing) {			iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);			iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);			iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);			break;		}		len = 0;		if (av7110->debitype & 0x100) {			spin_lock(&av7110->aout.lock);			len = av7110_pes_play(av7110->debi_virt, &av7110->aout, 2048);			spin_unlock(&av7110->aout.lock);		}		if (len <= 0 && (av7110->debitype & 0x200)		    &&av7110->videostate.play_state != VIDEO_FREEZED) {			spin_lock(&av7110->avout.lock);			len = av7110_pes_play(av7110->debi_virt, &av7110->avout, 2048);			spin_unlock(&av7110->avout.lock);		}		if (len <= 0) {			iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);			iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);			iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);			break;		}		dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);		iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);		iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);		dprintk(8, "DMA: MPEG_PLAY\n");		start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);		spin_unlock(&av7110->debilock);		return;	case DATA_BMP_LOAD:		len = av7110->debilen;		dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len);		if (!len) {			av7110->bmp_state = BMP_LOADED;			iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);			iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);			iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);			wake_up(&av7110->bmpq);			dprintk(8, "gpio DATA_BMP_LOAD done\n");			break;		}		if (len > av7110->bmplen)			len = av7110->bmplen;		if (len > 2 * 1024)			len = 2 * 1024;		iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);		iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);		memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);		av7110->bmpp += len;		av7110->bmplen -= len;		dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len);		start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len);		spin_unlock(&av7110->debilock);		return;	case DATA_CI_GET:	case DATA_COMMON_INTERFACE:	case DATA_FSECTION:	case DATA_IPMPE:	case DATA_PIPING:		if (!len || len > 4 * 1024) {			iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);			break;		}		/* fall through */	case DATA_TS_RECORD:	case DATA_PES_RECORD:		dprintk(8, "DMA: TS_REC etc.\n");		start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len);		spin_unlock(&av7110->debilock);		return;	case DATA_DEBUG_MESSAGE:		if (!len || len > 0xff) {			iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);			break;		}		start_debi_dma(av7110, DEBI_READ, Reserved, len);		spin_unlock(&av7110->debilock);		return;	case DATA_IRCOMMAND:		if (av7110->ir_handler)			av7110->ir_handler(av7110,				swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));		iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);		break;	default:		printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n",		       av7110->debitype, av7110->debilen);		break;	}	av7110->debitype = -1;	ARM_ClearMailBox(av7110);	spin_unlock(&av7110->debilock);}#ifdef CONFIG_DVB_AV7110_OSDstatic int dvb_osd_ioctl(struct inode *inode, struct file *file,			 unsigned int cmd, void *parg){	struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;	struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;	dprintk(4, "%p\n", av7110);	if (cmd == OSD_SEND_CMD)		return av7110_osd_cmd(av7110, (osd_cmd_t *) parg);	if (cmd == OSD_GET_CAPABILITY)		return av7110_osd_capability(av7110, (osd_cap_t *) parg);	return -EINVAL;}static struct file_operations dvb_osd_fops = {	.owner		= THIS_MODULE,	.ioctl		= dvb_generic_ioctl,	.open		= dvb_generic_open,	.release	= dvb_generic_release,};static struct dvb_device dvbdev_osd = {	.priv		= NULL,	.users		= 1,	.writers	= 1,	.fops		= &dvb_osd_fops,	.kernel_ioctl	= dvb_osd_ioctl,};#endif /* CONFIG_DVB_AV7110_OSD */static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,			  u16 subpid, u16 pcrpid){	dprintk(4, "%p\n", av7110);	if (vpid == 0x1fff || apid == 0x1fff ||	    ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {		vpid = apid = ttpid = subpid = pcrpid = 0;		av7110->pids[DMX_PES_VIDEO] = 0;		av7110->pids[DMX_PES_AUDIO] = 0;		av7110->pids[DMX_PES_TELETEXT] = 0;		av7110->pids[DMX_PES_PCR] = 0;	}	return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 5,			     pcrpid, vpid, apid, ttpid, subpid);}int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,		u16 subpid, u16 pcrpid){	int ret = 0;	dprintk(4, "%p\n", av7110);	if (down_interruptible(&av7110->pid_mutex))		return -ERESTARTSYS;	if (!(vpid & 0x8000))		av7110->pids[DMX_PES_VIDEO] = vpid;	if (!(apid & 0x8000))		av7110->pids[DMX_PES_AUDIO] = apid;	if (!(ttpid & 0x8000))		av7110->pids[DMX_PES_TELETEXT] = ttpid;	if (!(pcrpid & 0x8000))		av7110->pids[DMX_PES_PCR] = pcrpid;	av7110->pids[DMX_PES_SUBTITLE] = 0;	if (av7110->fe_synced) {		pcrpid = av7110->pids[DMX_PES_PCR];		ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);	}	up(&av7110->pid_mutex);	return ret;}/****************************************************************************** * hardware filter functions ******************************************************************************/static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter){	struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed;	struct av7110 *av7110 = (struct av7110 *) dvbdmxfeed->demux->priv;	u16 buf[20];	int ret, i;	u16 handle;//	u16 mode = 0x0320;	u16 mode = 0xb96a;	dprintk(4, "%p\n", av7110);	if (dvbdmxfilter->type == DMX_TYPE_SEC) {		if (hw_sections) {			buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) |				dvbdmxfilter->maskandmode[0];			for (i = 3; i < 18; i++)				buf[i + 4 - 2] =					(dvbdmxfilter->filter.filter_value[i] << 8) |					dvbdmxfilter->maskandmode[i];			mode = 4;		}	} else if ((dvbdmxfeed->ts_type & TS_PACKET) &&		   !(dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)) {		av7110_p2t_init(&av7110->p2t_filter[dvbdmxfilter->index], dvbdmxfeed);	}	buf[0] = (COMTYPE_PID_FILTER << 8) + AddPIDFilter;	buf[1] = 16;	buf[2] = dvbdmxfeed->pid;	buf[3] = mode;	ret = av7110_fw_request(av7110, buf, 20, &handle, 1);	if (ret != 0 || handle >= 32) {		printk("dvb-ttpci: %s error  buf %04x %04x %04x %04x  "				"ret %d  handle %04x\n",				__FUNCTION__, buf[0], buf[1], buf[2], buf[3],				ret, handle);		dvbdmxfilter->hw_handle = 0xffff;		if (!ret)			ret = -1;		return ret;	}	av7110->handle2filter[handle] = dvbdmxfilter;	dvbdmxfilter->hw_handle = handle;	return ret;}static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter){	struct av7110 *av7110 = (struct av7110 *) dvbdmxfilter->feed->demux->priv;	u16 buf[3];	u16 answ[2];	int ret;	u16 handle;	dprintk(4, "%p\n", av7110);	handle = dvbdmxfilter->hw_handle;	if (handle >= 32) {		printk("%s tried to stop invalid filter %04x, filter type = %x\n",				__FUNCTION__, handle, dvbdmxfilter->type);		return -EINVAL;	}	av7110->handle2filter[handle] = NULL;	buf[0] = (COMTYPE_PID_FILTER << 8) + DelPIDFilter;	buf[1] = 1;	buf[2] = handle;	ret = av7110_fw_request(av7110, buf, 3, answ, 2);	if (ret != 0 || answ[1] != handle) {		printk("dvb-ttpci: %s error  cmd %04x %04x %04x  ret %x  "				"resp %04x %04x  pid %d\n",				__FUNCTION__, buf[0], buf[1], buf[2], ret,				answ[0], answ[1], dvbdmxfilter->feed->pid);		if (!ret)			ret = -1;	}	return ret;}static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed){	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;	struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;	u16 *pid = dvbdmx->pids, npids[5];	int i;	int ret = 0;	dprintk(4, "%p\n", av7110);	npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;	i = dvbdmxfeed->pes_type;	npids[i] = (pid[i]&0x8000) ? 0 : pid[i];	if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {		npids[i] = 0;		ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);		if (!ret)			ret = StartHWFilter(dvbdmxfeed->filter);		return ret;	}	if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) {		ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);		if (ret)			return ret;	}	if (dvbdmxfeed->pes_type < 2 && npids[0])		if (av7110->fe_synced)		{			ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);			if (ret)				return ret;		}	if ((dvbdmxfeed->ts_type & TS_PACKET)) {		if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))			ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);		if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))			ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);	}	return ret;}static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed){	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;	struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;	u16 *pid = dvbdmx->pids, npids[5];	int i;	int ret = 0;	dprintk(4, "%p\n", av7110);	if (dvbdmxfeed->pes_type <= 1) {		ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ?  RP_VIDEO : RP_AUDIO);		if (ret)			return ret;		if (!av7110->rec_mode)			dvbdmx->recording = 0;		if (!av7110->playing)			dvbdmx->playing = 0;	}	npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;	i = dvbdmxfeed->pes_type;	switch (i) {	case 2: //teletext		if (dvbdmxfeed->ts_type & TS_PACKET)			ret = StopHWFilter(dvbdmxfeed->filter);		npids[2] = 0;		break;	case 0:	case 1:	case 4:		if (!pids_off)			return 0;		npids[i] = (pid[i]&0x8000) ? 0 : pid[i];		break;	}	if (!ret)		ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);	return ret;}static int av7110_start_feed(struct dvb_demux_feed *feed){	struct dvb_demux *demux = feed->demux;	struct av7110 *av7110 = demux->priv;	int ret = 0;	dprintk(4, "%p\n", av7110);	if (!demux->dmx.frontend)		return -EINVAL;	if (feed->pid > 0x1fff)		return -EINVAL;	if (feed->type == DMX_TYPE_TS) {		if ((feed->ts_type & TS_DECODER) &&		    (feed->pes_type < DMX_TS_PES_OTHER)) {			switch (demux->dmx.frontend->source) {			case DMX_MEMORY_FE:				if (feed->ts_type & TS_DECODER)				       if (feed->pes_type < 2 &&					   !(demux->pids[0] & 0x8000) &&					   !(demux->pids[1] & 0x8000)) {					       dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);					       dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);					       ret = av7110_av_start_play(av7110,RP_AV);					       if (!ret)						       demux->playing = 1;					}				break;			default:				ret = dvb_feed_start_pid(feed);				break;			}		} else if ((feed->ts_type & TS_PACKET) &&			   (demux->dmx.frontend->source != DMX_MEMORY_FE)) {			ret = StartHWFilter(feed->filter);		}	}	else if (feed->type == DMX_TYPE_SEC) {		int i;

⌨️ 快捷键说明

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