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

📄 saa7134-core.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		dprintk("buffer_next %p\n",NULL);		saa7134_set_dmabits(dev);		del_timer(&q->timeout);	}}void saa7134_buffer_timeout(unsigned long data){	struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue*)data;	struct saa7134_dev *dev = q->dev;	unsigned long flags;	spin_lock_irqsave(&dev->slock,flags);	/* try to reset the hardware (SWRST) */	saa_writeb(SAA7134_REGION_ENABLE, 0x00);	saa_writeb(SAA7134_REGION_ENABLE, 0x80);	saa_writeb(SAA7134_REGION_ENABLE, 0x00);	/* flag current buffer as failed,	   try to start over with the next one. */	if (q->curr) {		dprintk("timeout on %p\n",q->curr);		saa7134_buffer_finish(dev,q,STATE_ERROR);	}	saa7134_buffer_next(dev,q);	spin_unlock_irqrestore(&dev->slock,flags);}/* ------------------------------------------------------------------ */int saa7134_set_dmabits(struct saa7134_dev *dev){	u32 split, task=0, ctrl=0, irq=0;	enum v4l2_field cap = V4L2_FIELD_ANY;	enum v4l2_field ov  = V4L2_FIELD_ANY;	assert_spin_locked(&dev->slock);	/* video capture -- dma 0 + video task A */	if (dev->video_q.curr) {		task |= 0x01;		ctrl |= SAA7134_MAIN_CTRL_TE0;		irq  |= SAA7134_IRQ1_INTE_RA0_1 |			SAA7134_IRQ1_INTE_RA0_0;		cap = dev->video_q.curr->vb.field;	}	/* video capture -- dma 1+2 (planar modes) */	if (dev->video_q.curr &&	    dev->video_q.curr->fmt->planar) {		ctrl |= SAA7134_MAIN_CTRL_TE4 |			SAA7134_MAIN_CTRL_TE5;	}	/* screen overlay -- dma 0 + video task B */	if (dev->ovenable) {		task |= 0x10;		ctrl |= SAA7134_MAIN_CTRL_TE1;		ov = dev->ovfield;	}	/* vbi capture -- dma 0 + vbi task A+B */	if (dev->vbi_q.curr) {		task |= 0x22;		ctrl |= SAA7134_MAIN_CTRL_TE2 |			SAA7134_MAIN_CTRL_TE3;		irq  |= SAA7134_IRQ1_INTE_RA0_7 |			SAA7134_IRQ1_INTE_RA0_6 |			SAA7134_IRQ1_INTE_RA0_5 |			SAA7134_IRQ1_INTE_RA0_4;	}	/* audio capture -- dma 3 */	if (dev->dmasound.dma_running) {		ctrl |= SAA7134_MAIN_CTRL_TE6;		irq  |= SAA7134_IRQ1_INTE_RA3_1 |			SAA7134_IRQ1_INTE_RA3_0;	}	/* TS capture -- dma 5 */	if (dev->ts_q.curr) {		ctrl |= SAA7134_MAIN_CTRL_TE5;		irq  |= SAA7134_IRQ1_INTE_RA2_3 |			SAA7134_IRQ1_INTE_RA2_2 |			SAA7134_IRQ1_INTE_RA2_1 |			SAA7134_IRQ1_INTE_RA2_0;	}	/* set task conditions + field handling */	if (V4L2_FIELD_HAS_BOTH(cap) || V4L2_FIELD_HAS_BOTH(ov) || cap == ov) {		/* default config -- use full frames */		saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);		saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);		saa_writeb(SAA7134_FIELD_HANDLING(TASK_A),  0x02);		saa_writeb(SAA7134_FIELD_HANDLING(TASK_B),  0x02);		split = 0;	} else {		/* split fields between tasks */		if (V4L2_FIELD_TOP == cap) {			/* odd A, even B, repeat */			saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);			saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0e);		} else {			/* odd B, even A, repeat */			saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0e);			saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);		}		saa_writeb(SAA7134_FIELD_HANDLING(TASK_A),  0x01);		saa_writeb(SAA7134_FIELD_HANDLING(TASK_B),  0x01);		split = 1;	}	/* irqs */	saa_writeb(SAA7134_REGION_ENABLE, task);	saa_writel(SAA7134_IRQ1,          irq);	saa_andorl(SAA7134_MAIN_CTRL,		   SAA7134_MAIN_CTRL_TE0 |		   SAA7134_MAIN_CTRL_TE1 |		   SAA7134_MAIN_CTRL_TE2 |		   SAA7134_MAIN_CTRL_TE3 |		   SAA7134_MAIN_CTRL_TE4 |		   SAA7134_MAIN_CTRL_TE5 |		   SAA7134_MAIN_CTRL_TE6,		   ctrl);	dprintk("dmabits: task=0x%02x ctrl=0x%02x irq=0x%x split=%s\n",		task, ctrl, irq, split ? "no" : "yes");	return 0;}/* ------------------------------------------------------------------ *//* IRQ handler + helpers                                              */static char *irqbits[] = {	"DONE_RA0", "DONE_RA1", "DONE_RA2", "DONE_RA3",	"AR", "PE", "PWR_ON", "RDCAP", "INTL", "FIDT", "MMC",	"TRIG_ERR", "CONF_ERR", "LOAD_ERR",	"GPIO16?", "GPIO18", "GPIO22", "GPIO23"};#define IRQBITS ARRAY_SIZE(irqbits)static void print_irqstatus(struct saa7134_dev *dev, int loop,			    unsigned long report, unsigned long status){	unsigned int i;	printk(KERN_DEBUG "%s/irq[%d,%ld]: r=0x%lx s=0x%02lx",	       dev->name,loop,jiffies,report,status);	for (i = 0; i < IRQBITS; i++) {		if (!(report & (1 << i)))			continue;		printk(" %s",irqbits[i]);	}	if (report & SAA7134_IRQ_REPORT_DONE_RA0) {		printk(" | RA0=%s,%s,%s,%ld",		       (status & 0x40) ? "vbi"  : "video",		       (status & 0x20) ? "b"    : "a",		       (status & 0x10) ? "odd"  : "even",		       (status & 0x0f));	}	printk("\n");}static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs){	struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;	unsigned long report,status;	int loop, handled = 0;	for (loop = 0; loop < 10; loop++) {		report = saa_readl(SAA7134_IRQ_REPORT);		status = saa_readl(SAA7134_IRQ_STATUS);		if (0 == report) {			if (irq_debug > 1)				printk(KERN_DEBUG "%s/irq: no (more) work\n",				       dev->name);			goto out;		}		/* If dmasound support is active and we get a sound report, exit		   and let the saa7134-alsa/oss module deal with it */		if ((report & SAA7134_IRQ_REPORT_DONE_RA3) &&			(dev->dmasound.priv_data != NULL) )		{			if (irq_debug > 1)				printk(KERN_DEBUG "%s/irq: ignoring interrupt for DMA sound\n",				       dev->name);			goto out;		}		handled = 1;		saa_writel(SAA7134_IRQ_REPORT,report);		if (irq_debug)			print_irqstatus(dev,loop,report,status);		if (report & SAA7134_IRQ_REPORT_RDCAP /* _INTL */)			saa7134_irq_video_intl(dev);		if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&		    (status & 0x60) == 0)			saa7134_irq_video_done(dev,status);		if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&		    (status & 0x40) == 0x40)			saa7134_irq_vbi_done(dev,status);		if ((report & SAA7134_IRQ_REPORT_DONE_RA2) &&		    card_has_mpeg(dev))			saa7134_irq_ts_done(dev,status);		if ((report & (SAA7134_IRQ_REPORT_GPIO16 |			       SAA7134_IRQ_REPORT_GPIO18)) &&		    dev->remote)			saa7134_input_irq(dev);	}	if (10 == loop) {		print_irqstatus(dev,loop,report,status);		if (report & SAA7134_IRQ_REPORT_PE) {			/* disable all parity error */			printk(KERN_WARNING "%s/irq: looping -- "			       "clearing PE (parity error!) enable bit\n",dev->name);			saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE);		} else if (report & (SAA7134_IRQ_REPORT_GPIO16 |				     SAA7134_IRQ_REPORT_GPIO18)) {			/* disable gpio IRQs */			printk(KERN_WARNING "%s/irq: looping -- "			       "clearing GPIO enable bits\n",dev->name);			saa_clearl(SAA7134_IRQ2, (SAA7134_IRQ2_INTE_GPIO16 |						  SAA7134_IRQ2_INTE_GPIO18));		} else {			/* disable all irqs */			printk(KERN_WARNING "%s/irq: looping -- "			       "clearing all enable bits\n",dev->name);			saa_writel(SAA7134_IRQ1,0);			saa_writel(SAA7134_IRQ2,0);		}	} out:	return IRQ_RETVAL(handled);}/* ------------------------------------------------------------------ *//* early init (no i2c, no irq) */static int saa7134_hwinit1(struct saa7134_dev *dev){	dprintk("hwinit1\n");	saa_writel(SAA7134_IRQ1, 0);	saa_writel(SAA7134_IRQ2, 0);	init_MUTEX(&dev->lock);	spin_lock_init(&dev->slock);	saa7134_track_gpio(dev,"pre-init");	saa7134_video_init1(dev);	saa7134_vbi_init1(dev);	if (card_has_mpeg(dev))		saa7134_ts_init1(dev);	saa7134_input_init1(dev);	/* RAM FIFO config */	saa_writel(SAA7134_FIFO_SIZE, 0x08070503);	saa_writel(SAA7134_THRESHOULD,0x02020202);	/* enable audio + video processing */	saa_writel(SAA7134_MAIN_CTRL,		   SAA7134_MAIN_CTRL_VPLLE |		   SAA7134_MAIN_CTRL_APLLE |		   SAA7134_MAIN_CTRL_EXOSC |		   SAA7134_MAIN_CTRL_EVFE1 |		   SAA7134_MAIN_CTRL_EVFE2 |		   SAA7134_MAIN_CTRL_ESFE  |		   SAA7134_MAIN_CTRL_EBDAC);	/*	 * Initialize OSS _after_ enabling audio clock PLL and audio processing.	 * OSS initialization writes to registers via the audio DSP; these	 * writes will fail unless the audio clock has been started.  At worst,	 * audio will not work.	 */	/* enable peripheral devices */	saa_writeb(SAA7134_SPECIAL_MODE, 0x01);	/* set vertical line numbering start (vbi needs this) */	saa_writeb(SAA7134_SOURCE_TIMING2, 0x20);	return 0;}/* late init (with i2c + irq) */static int saa7134_hwinit2(struct saa7134_dev *dev){	unsigned int irq2_mask;	dprintk("hwinit2\n");	saa7134_video_init2(dev);	saa7134_tvaudio_init2(dev);	/* enable IRQ's */	irq2_mask =		SAA7134_IRQ2_INTE_DEC3    |		SAA7134_IRQ2_INTE_DEC2    |		SAA7134_IRQ2_INTE_DEC1    |		SAA7134_IRQ2_INTE_DEC0    |		SAA7134_IRQ2_INTE_PE      |		SAA7134_IRQ2_INTE_AR;	if (dev->has_remote == SAA7134_REMOTE_GPIO)		irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18  |			      SAA7134_IRQ2_INTE_GPIO18A |			      SAA7134_IRQ2_INTE_GPIO16  );	saa_writel(SAA7134_IRQ1, 0);	saa_writel(SAA7134_IRQ2, irq2_mask);	return 0;}/* shutdown */static int saa7134_hwfini(struct saa7134_dev *dev){	dprintk("hwfini\n");	if (card_has_mpeg(dev))		saa7134_ts_fini(dev);	saa7134_input_fini(dev);	saa7134_vbi_fini(dev);	saa7134_video_fini(dev);	saa7134_tvaudio_fini(dev);	return 0;}static void __devinit must_configure_manually(void){	unsigned int i,p;	printk(KERN_WARNING	       "saa7134: <rant>\n"	       "saa7134:  Congratulations!  Your TV card vendor saved a few\n"	       "saa7134:  cents for a eeprom, thus your pci board has no\n"	       "saa7134:  subsystem ID and I can't identify it automatically\n"	       "saa7134: </rant>\n"	       "saa7134: I feel better now.  Ok, here are the good news:\n"	       "saa7134: You can use the card=<nr> insmod option to specify\n"	       "saa7134: which board do you have.  The list:\n");	for (i = 0; i < saa7134_bcount; i++) {		printk(KERN_WARNING "saa7134:   card=%d -> %-40.40s",		       i,saa7134_boards[i].name);		for (p = 0; saa7134_pci_tbl[p].driver_data; p++) {			if (saa7134_pci_tbl[p].driver_data != i)				continue;			printk(" %04x:%04x",			       saa7134_pci_tbl[p].subvendor,			       saa7134_pci_tbl[p].subdevice);		}		printk("\n");	}}static struct video_device *vdev_init(struct saa7134_dev *dev,				      struct video_device *template,				      char *type){	struct video_device *vfd;	vfd = video_device_alloc();	if (NULL == vfd)		return NULL;	*vfd = *template;	vfd->minor   = -1;	vfd->dev     = &dev->pci->dev;	vfd->release = video_device_release;	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",		 dev->name, type, saa7134_boards[dev->board].name);	return vfd;}static void saa7134_unregister_video(struct saa7134_dev *dev){	if (dev->video_dev) {		if (-1 != dev->video_dev->minor)			video_unregister_device(dev->video_dev);		else			video_device_release(dev->video_dev);		dev->video_dev = NULL;	}	if (dev->vbi_dev) {		if (-1 != dev->vbi_dev->minor)			video_unregister_device(dev->vbi_dev);		else			video_device_release(dev->vbi_dev);		dev->vbi_dev = NULL;

⌨️ 快捷键说明

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