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

📄 stradis.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
						saa->endmarkhead) {						if (saa->endmarkhead -							saa->endmarktail < 2)							return -ENOSPC;					} else if (saa->endmarkhead <=						saa->endmarktail) {						if (saa->endmarktail -							saa->endmarkhead >							(MAX_MARKS - 2))							return -ENOSPC;					} else						return -ENOSPC;					saa->endmark[saa->endmarktail] =						saa->audtail;					saa->endmarktail++;					if (saa->endmarktail >= MAX_MARKS)						saa->endmarktail = 0;			}			return -EINVAL;		}	case VIDIOCSWRITEMODE:		{			int mode;			if (copy_from_user((void *) &mode, arg, sizeof(int)))				 return -EFAULT;			if (mode == VID_WRITE_MPEG_AUD ||			    mode == VID_WRITE_MPEG_VID ||			    mode == VID_WRITE_CC ||			    mode == VID_WRITE_TTX ||			    mode == VID_WRITE_OSD) {				saa->writemode = mode;				return 0;			}			return -EINVAL;		}	case VIDIOCSMICROCODE:		{			struct video_code ucode;			__u8 *udata;			int i;			if (copy_from_user((void *) &ucode, arg,			    sizeof(ucode)))				return -EFAULT;			if (ucode.datasize > 65536 || ucode.datasize < 1024 ||			    strncmp(ucode.loadwhat, "dec", 3))				return -EINVAL;			if ((udata = vmalloc(ucode.datasize)) == NULL)				return -ENOMEM;			if (copy_from_user((void *) udata, ucode.data,			    ucode.datasize)) {				vfree(udata);				return -EFAULT;			}			ucode.data = udata;			if (!strncmp(ucode.loadwhat, "decoder.aud", 11)				|| !strncmp(ucode.loadwhat, "decoder.vid", 11))				i = initialize_ibmmpeg2(&ucode);			else				i = initialize_fpga(&ucode);			vfree(udata);			if (i)				return -EINVAL;			return 0;		}	case VIDIOCGCHAN:	/* this makes xawtv happy */		{			struct video_channel v;			if (copy_from_user(&v, arg, sizeof(v)))				return -EFAULT;			v.flags = VIDEO_VC_AUDIO;			v.tuners = 0;			v.type = VID_TYPE_MPEG_DECODER;			v.norm = CurrentMode;			strcpy(v.name, "MPEG2");			if (copy_to_user(arg, &v, sizeof(v)))				return -EFAULT;			return 0;		}	case VIDIOCSCHAN:	/* this makes xawtv happy */		{			struct video_channel v;			if (copy_from_user(&v, arg, sizeof(v)))				return -EFAULT;			/* do nothing */			return 0;		}	default:		return -ENOIOCTLCMD;	}	return 0;}static int saa_mmap(struct video_device *dev, const char *adr,		    unsigned long size){	struct saa7146 *saa = (struct saa7146 *) dev;	printk(KERN_DEBUG "stradis%d: saa_mmap called\n", saa->nr);	return -EINVAL;}static long saa_read(struct video_device *dev, char *buf,		     unsigned long count, int nonblock){	return -EINVAL;}static long saa_write(struct video_device *dev, const char *buf,		      unsigned long count, int nonblock){	struct saa7146 *saa = (struct saa7146 *) dev;	unsigned long todo = count;	int blocksize, split;	unsigned long flags;	while (todo > 0) {		if (saa->writemode == VID_WRITE_MPEG_AUD) {			spin_lock_irqsave(&saa->lock, flags);			if (saa->audhead <= saa->audtail)				blocksize = 65536-(saa->audtail - saa->audhead);			else				blocksize = saa->audhead - saa->audtail;			spin_unlock_irqrestore(&saa->lock, flags);			if (blocksize < 16384) {				saawrite(SAA7146_PSR_DEBI_S |					 SAA7146_PSR_PIN1, SAA7146_IER);				saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);				/* wait for buffer space to open */				interruptible_sleep_on(&saa->audq);			}			spin_lock_irqsave(&saa->lock, flags);			if (saa->audhead <= saa->audtail) {				blocksize = 65536-(saa->audtail - saa->audhead);				split = 65536 - saa->audtail;			} else {				blocksize = saa->audhead - saa->audtail;				split = 65536;			}			spin_unlock_irqrestore(&saa->lock, flags);			blocksize--;			if (blocksize > todo)				blocksize = todo;			/* double check that we really have space */			if (!blocksize)				return -ENOSPC;			if (split < blocksize) {				if (copy_from_user(saa->audbuf +					saa->audtail, buf, split)) 					return -EFAULT;				buf += split;				todo -= split;				blocksize -= split;				saa->audtail = 0;			}			if (copy_from_user(saa->audbuf + saa->audtail, buf,				blocksize)) 				return -EFAULT;			saa->audtail += blocksize;			todo -= blocksize;			buf += blocksize;			saa->audtail &= 0xffff;		} else if (saa->writemode == VID_WRITE_MPEG_VID) {			spin_lock_irqsave(&saa->lock, flags);			if (saa->vidhead <= saa->vidtail)				blocksize=524288-(saa->vidtail - saa->vidhead);			else				blocksize = saa->vidhead - saa->vidtail;			spin_unlock_irqrestore(&saa->lock, flags);			if (blocksize < 65536) {				saawrite(SAA7146_PSR_DEBI_S |					 SAA7146_PSR_PIN1, SAA7146_IER);				saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);				/* wait for buffer space to open */				interruptible_sleep_on(&saa->vidq);			}			spin_lock_irqsave(&saa->lock, flags);			if (saa->vidhead <= saa->vidtail) {				blocksize=524288-(saa->vidtail - saa->vidhead);				split = 524288 - saa->vidtail;			} else {				blocksize = saa->vidhead - saa->vidtail;				split = 524288;			}			spin_unlock_irqrestore(&saa->lock, flags);			blocksize--;			if (blocksize > todo)				blocksize = todo;			/* double check that we really have space */			if (!blocksize)				return -ENOSPC;			if (split < blocksize) {				if (copy_from_user(saa->vidbuf +					saa->vidtail, buf, split)) 					return -EFAULT;				buf += split;				todo -= split;				blocksize -= split;				saa->vidtail = 0;			}			if (copy_from_user(saa->vidbuf + saa->vidtail, buf,				blocksize)) 				return -EFAULT;			saa->vidtail += blocksize;			todo -= blocksize;			buf += blocksize;			saa->vidtail &= 0x7ffff;		} else if (saa->writemode == VID_WRITE_OSD) {			if (count > 131072)				return -ENOSPC;			if (copy_from_user(saa->osdbuf, buf, count))				return -EFAULT;			buf += count;			saa->osdhead = 0;			saa->osdtail = count;			debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR, 0, 2);			debiwrite(saa, debNormal, IBM_MP2_OSD_LINK_ADDR, 0, 2);			debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00d, 2);			debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,				  debiread(saa, debNormal,				  IBM_MP2_DISP_MODE, 2) | 1, 2);			/* trigger osd data transfer */			saawrite(SAA7146_PSR_DEBI_S |				 SAA7146_PSR_PIN1, SAA7146_IER);			saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);		}	}	return count;}static int saa_open(struct video_device *dev, int flags){	struct saa7146 *saa = (struct saa7146 *) dev;	/* FIXME: Don't do it this way, use the video_device->fops	 * registration for a sane implementation of multiple opens */	saa->video_dev.users--;	saa->user++;	if (saa->user > 1)		return 0;	/* device open already, don't reset */	saa->writemode = VID_WRITE_MPEG_VID;	/* default to video */	return 0;}static void saa_close(struct video_device *dev){	struct saa7146 *saa = (struct saa7146 *) dev;	saa->user--;	saa->video_dev.users++;	if (saa->user > 0)	/* still someone using device */		return;	saawrite(0x007f0000, SAA7146_MC1);	/* stop all overlay dma */}/* template for video_device-structure */static struct video_device saa_template ={	owner:		THIS_MODULE,	name:		"SAA7146A",	type:		VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,	hardware:	VID_HARDWARE_SAA7146,	open:		saa_open,	close:		saa_close,	read:		saa_read,	write:		saa_write,	ioctl:		saa_ioctl,	mmap:		saa_mmap,};static int configure_saa7146(struct pci_dev *dev, int num){	int result;	struct saa7146 *saa;	saa = &saa7146s[num];		saa->endmarkhead = saa->endmarktail = 0;	saa->win.x = saa->win.y = 0;	saa->win.width = saa->win.cropwidth = 720;	saa->win.height = saa->win.cropheight = 480;	saa->win.cropx = saa->win.cropy = 0;	saa->win.bpp = 2;	saa->win.depth = 16;	saa->win.color_fmt = palette2fmt[VIDEO_PALETTE_RGB565];	saa->win.bpl = 1024 * saa->win.bpp;	saa->win.swidth = 1024;	saa->win.sheight = 768;	saa->picture.brightness = 32768;	saa->picture.contrast = 38768;	saa->picture.colour = 32768;	saa->cap = 0;	saa->dev = dev;	saa->nr = num;	saa->playmode = VID_PLAY_NORMAL;	memset(saa->boardcfg, 0, 64);	/* clear board config area */	saa->saa7146_mem = NULL;	saa->dmavid1 = saa->dmavid2 = saa->dmavid3 = saa->dmaa1in =	    saa->dmaa1out = saa->dmaa2in = saa->dmaa2out =	    saa->pagevid1 = saa->pagevid2 = saa->pagevid3 = saa->pagea1in =	    saa->pagea1out = saa->pagea2in = saa->pagea2out =	    saa->pagedebi = saa->dmaRPS1 = saa->dmaRPS2 = saa->pageRPS1 =	    saa->pageRPS2 = NULL;	saa->audbuf = saa->vidbuf = saa->osdbuf = saa->dmadebi = NULL;	saa->audhead = saa->vidtail = 0;	init_waitqueue_head(&saa->i2cq);	init_waitqueue_head(&saa->audq);	init_waitqueue_head(&saa->debiq);	init_waitqueue_head(&saa->vidq);	spin_lock_init(&saa->lock);	if (pci_enable_device(dev))		return -EIO;		saa->id = dev->device;	saa->irq = dev->irq;	saa->video_dev.minor = -1;	saa->saa7146_adr = pci_resource_start(dev, 0);	pci_read_config_byte(dev, PCI_CLASS_REVISION, &saa->revision);	saa->saa7146_mem = ioremap(saa->saa7146_adr, 0x200);	if (!saa->saa7146_mem)		return -EIO;	memcpy(&(saa->i2c), &saa7146_i2c_bus_template, sizeof(struct i2c_bus));	memcpy(&saa->video_dev, &saa_template, sizeof(saa_template));	sprintf(saa->i2c.name, "stradis%d", num);	saa->i2c.data = saa;	saawrite(0, SAA7146_IER);	/* turn off all interrupts */	result = request_irq(saa->irq, saa7146_irq,		       SA_SHIRQ | SA_INTERRUPT, "stradis", (void *) saa);	if (result == -EINVAL)		printk(KERN_ERR "stradis%d: Bad irq number or handler\n",		       num);	if (result == -EBUSY)		printk(KERN_ERR "stradis%d: IRQ %ld busy, change your PnP"		       " config in BIOS\n", num, saa->irq);	if (result < 0) {		iounmap(saa->saa7146_mem);		return result;	}	pci_set_master(dev);	if (video_register_device(&saa->video_dev, VFL_TYPE_GRABBER, video_nr) < 0) {		iounmap(saa->saa7146_mem);		return -1;	}#if 0	/* i2c generic interface is currently BROKEN */	i2c_register_bus(&saa->i2c);#endif	return 0;}static int init_saa7146(int i){	struct saa7146 *saa = &saa7146s[i];	saa->user = 0;	/* reset the saa7146 */	saawrite(0xffff0000, SAA7146_MC1);	mdelay(5);	/* enable debi and i2c transfers and pins */	saawrite(((SAA7146_MC1_EDP | SAA7146_MC1_EI2C |		   SAA7146_MC1_TR_E_DEBI) << 16) | 0xffff, SAA7146_MC1);	/* ensure proper state of chip */	saawrite(0x00000000, SAA7146_PAGE1);	saawrite(0x00f302c0, SAA7146_NUM_LINE_BYTE1);	saawrite(0x00000000, SAA7146_PAGE2);	saawrite(0x01400080, SAA7146_NUM_LINE_BYTE2);	saawrite(0x00000000, SAA7146_DD1_INIT);	saawrite(0x00000000, SAA7146_DD1_STREAM_B);	saawrite(0x00000000, SAA7146_DD1_STREAM_A);	saawrite(0x00000000, SAA7146_BRS_CTRL);	saawrite(0x80400040, SAA7146_BCS_CTRL);	saawrite(0x0000e000 /*| (1<<29)*/, SAA7146_HPS_CTRL);	saawrite(0x00000060, SAA7146_CLIP_FORMAT_CTRL);	saawrite(0x00000000, SAA7146_ACON1);	saawrite(0x00000000, SAA7146_ACON2);	saawrite(0x00000600, SAA7146_I2C_STATUS);	saawrite(((SAA7146_MC2_UPLD_D1_B | SAA7146_MC2_UPLD_D1_A |		   SAA7146_MC2_UPLD_BRS | SAA7146_MC2_UPLD_HPS_H |		   SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_DMA2 |	   SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_I2C) << 16) | 0xffff,		 SAA7146_MC2);	/* setup arbitration control registers */	saawrite(0x1412121a, SAA7146_PCI_BT_V1);	/* allocate 32k dma buffer + 4k for page table */	if ((saa->dmadebi = kmalloc(32768 + 4096, GFP_KERNEL)) == NULL) {		printk(KERN_ERR "stradis%d: debi kmalloc failed\n", i);		return -1;	}#if 0	saa->pagedebi = saa->dmadebi + 32768;	/* top 4k is for mmu */	saawrite(virt_to_bus(saa->pagedebi) /*|0x800 */ , SAA7146_DEBI_PAGE);	for (i = 0; i < 12; i++)	/* setup mmu page table */		saa->pagedebi[i] = virt_to_bus((saa->dmadebi + i * 4096));#endif	saa->audhead = saa->vidhead = saa->osdhead = 0;	saa->audtail = saa->vidtail = saa->osdtail = 0;	if (saa->vidbuf == NULL)		if ((saa->vidbuf = vmalloc(524288)) == NULL) {			printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);			return -ENOMEM;		}	if (saa->audbuf == NULL)		if ((saa->audbuf = vmalloc(65536)) == NULL) {			printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);			vfree(saa->vidbuf);			saa->vidbuf = NULL;			return -ENOMEM;		}	if (saa->osdbuf == NULL)		if ((saa->osdbuf = vmalloc(131072)) == NULL) {			printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);			vfree(saa->vidbuf);			vfree(saa->audbuf);			saa->vidbuf = saa->audbuf = NULL;			return -ENOMEM;		}	/* allocate 81920 byte buffer for clipping */	if ((saa->dmavid2 = kmalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) {		printk(KERN_ERR "stradis%d: clip kmalloc failed\n", saa->nr);		vfree(saa->vidbuf);		vfree(saa->audbuf);		vfree(saa->osdbuf);		saa->vidbuf = saa->audbuf = saa->osdbuf = NULL;		saa->dmavid2 = NULL;		return -1;	}	memset(saa->dmavid2, 0x00, VIDEO_CLIPMAP_SIZE);	/* clip everything */	/* setup clipping registers */	saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2);	saawrite(virt_to_bus(saa->dmavid2) + 128, SAA7146_BASE_ODD2);	saawrite(virt_t

⌨️ 快捷键说明

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