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

📄 meye.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
					remove_wait_queue(&meye.grabq.proc_list, &wait);					current->state = TASK_RUNNING;					return -EINTR;				}			}			remove_wait_queue(&meye.grabq.proc_list, &wait);			current->state = TASK_RUNNING;			/* fall through */		case MEYE_BUF_DONE:			meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;		}		break;	}	case VIDIOCMCAPTURE: {		struct video_mmap *vm = arg;		int restart = 0;		if (vm->frame >= gbuffers || vm->frame < 0)			return -EINVAL;		if (vm->format != VIDEO_PALETTE_YUV422)			return -EINVAL;		if (vm->height * vm->width * 2 > gbufsize)			return -EINVAL;		if (!meye.grab_fbuffer)			return -EINVAL;		if (meye.grab_buffer[vm->frame].state != MEYE_BUF_UNUSED)			return -EBUSY;		down(&meye.lock);		if (vm->width == 640 && vm->height == 480) {			if (meye.params.subsample) {				meye.params.subsample = 0;				restart = 1;			}		}		else if (vm->width == 320 && vm->height == 240) {			if (!meye.params.subsample) {				meye.params.subsample = 1;				restart = 1;			}		}		else {			up(&meye.lock);			return -EINVAL;		}		if (restart || meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT)			mchip_continuous_start();		meye.grab_buffer[vm->frame].state = MEYE_BUF_USING;		meye_pushq(&meye.grabq, vm->frame);		up(&meye.lock);		break;	}	case VIDIOCGMBUF: {		struct video_mbuf *vm = arg;		int i;		memset(vm, 0 , sizeof(*vm));		vm->size = gbufsize * gbuffers;		vm->frames = gbuffers;		for (i = 0; i < gbuffers; i++)			vm->offsets[i] = i * gbufsize;		break;	}	case MEYEIOC_G_PARAMS: {		struct meye_params *p = arg;		*p = meye.params;		break;	}	case MEYEIOC_S_PARAMS: {		struct meye_params *jp = arg;		if (jp->subsample > 1)			return -EINVAL;		if (jp->quality > 10)			return -EINVAL;		if (jp->sharpness > 63 || jp->agc > 63 || jp->picture > 63)			return -EINVAL;		if (jp->framerate > 31)			return -EINVAL;		down(&meye.lock);		if (meye.params.subsample != jp->subsample ||		    meye.params.quality != jp->quality)			mchip_hic_stop();	/* need restart */		meye.params = *jp;		sonypi_camera_command(SONYPI_COMMAND_SETCAMERASHARPNESS,				      meye.params.sharpness);		sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC,				      meye.params.agc);		sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE,				      meye.params.picture);		up(&meye.lock);		break;	}	case MEYEIOC_QBUF_CAPT: {		int *nb = arg;		if (!meye.grab_fbuffer) 			return -EINVAL;		if (*nb >= gbuffers)			return -EINVAL;		if (*nb < 0) {			/* stop capture */			mchip_hic_stop();			return 0;		}		if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED)			return -EBUSY;		down(&meye.lock);		if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)			mchip_cont_compression_start();		meye.grab_buffer[*nb].state = MEYE_BUF_USING;		meye_pushq(&meye.grabq, *nb);		up(&meye.lock);		break;	}	case MEYEIOC_SYNC: {		int *i = arg;		DECLARE_WAITQUEUE(wait, current);		if (*i < 0 || *i >= gbuffers)			return -EINVAL;		switch (meye.grab_buffer[*i].state) {		case MEYE_BUF_UNUSED:			return -EINVAL;		case MEYE_BUF_USING:			add_wait_queue(&meye.grabq.proc_list, &wait);			current->state = TASK_INTERRUPTIBLE;			while (meye.grab_buffer[*i].state == MEYE_BUF_USING) {				schedule();				if(signal_pending(current)) {					remove_wait_queue(&meye.grabq.proc_list, &wait);					current->state = TASK_RUNNING;					return -EINTR;				}			}			remove_wait_queue(&meye.grabq.proc_list, &wait);			current->state = TASK_RUNNING;			/* fall through */		case MEYE_BUF_DONE:			meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;		}		*i = meye.grab_buffer[*i].size;		break;	}	case MEYEIOC_STILLCAPT: {		if (!meye.grab_fbuffer) 			return -EINVAL;		if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)			return -EBUSY;		down(&meye.lock);		meye.grab_buffer[0].state = MEYE_BUF_USING;		mchip_take_picture();		mchip_get_picture(			meye.grab_fbuffer,			mchip_hsize() * mchip_vsize() * 2);		meye.grab_buffer[0].state = MEYE_BUF_DONE;		up(&meye.lock);		break;	}	case MEYEIOC_STILLJCAPT: {		int *len = arg;		if (!meye.grab_fbuffer) 			return -EINVAL;		if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)			return -EBUSY;		down(&meye.lock);		meye.grab_buffer[0].state = MEYE_BUF_USING;		*len = -1;		while (*len == -1) {			mchip_take_picture();			*len = mchip_compress_frame(meye.grab_fbuffer, gbufsize);		}		meye.grab_buffer[0].state = MEYE_BUF_DONE;		up(&meye.lock);		break;	}	default:		return -ENOIOCTLCMD;			} /* switch */	return 0;}static int meye_ioctl(struct inode *inode, struct file *file,		     unsigned int cmd, unsigned long arg){	return video_usercopy(inode, file, cmd, arg, meye_do_ioctl);}static int meye_mmap(struct file *file, struct vm_area_struct *vma) {	unsigned long start = vma->vm_start;	unsigned long size  = vma->vm_end - vma->vm_start;	unsigned long page, pos;	down(&meye.lock);	if (size > gbuffers * gbufsize) {		up(&meye.lock);		return -EINVAL;	}	if (!meye.grab_fbuffer) {		/* lazy allocation */		meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize);		if (!meye.grab_fbuffer) {			printk(KERN_ERR "meye: v4l framebuffer allocation failed\n");			up(&meye.lock);			return -ENOMEM;		}	}	pos = (unsigned long)meye.grab_fbuffer;	while (size > 0) {		page = kvirt_to_pa(pos);		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {			up(&meye.lock);			return -EAGAIN;		}		start += PAGE_SIZE;		pos += PAGE_SIZE;		size -= PAGE_SIZE;	}	up(&meye.lock);	return 0;}static struct file_operations meye_fops = {	owner:		THIS_MODULE,	open:		meye_open,	release:	meye_release,	mmap:		meye_mmap,	ioctl:		meye_ioctl,	llseek:		no_llseek,};static struct video_device meye_template = {	owner:		THIS_MODULE,	name:		"meye",	type:		VID_TYPE_CAPTURE,	hardware:	VID_HARDWARE_MEYE,	fops:		&meye_fops,};static int __devinit meye_probe(struct pci_dev *pcidev, 		                const struct pci_device_id *ent) {	int ret;	unsigned long mchip_adr;	u8 revision;	if (meye.mchip_dev != NULL) {		printk(KERN_ERR "meye: only one device allowed!\n");		ret = -EBUSY;		goto out1;	}	sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 1);	meye.mchip_dev = pcidev;	memcpy(&meye.video_dev, &meye_template, sizeof(meye_template));	if (mchip_dma_alloc()) {		printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");		ret = -ENOMEM;		goto out2;	}	if ((ret = pci_enable_device(meye.mchip_dev))) {		printk(KERN_ERR "meye: pci_enable_device failed\n");		goto out3;	}	meye.mchip_irq = pcidev->irq;	mchip_adr = pci_resource_start(meye.mchip_dev,0);	if (!mchip_adr) {		printk(KERN_ERR "meye: mchip has no device base address\n");		ret = -EIO;		goto out4;	}	if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0),			        pci_resource_len(meye.mchip_dev, 0),				"meye")) {		ret = -EIO;		printk(KERN_ERR "meye: request_mem_region failed\n");		goto out4;	}	pci_read_config_byte(meye.mchip_dev, PCI_REVISION_ID, &revision);	pci_set_master(meye.mchip_dev);	pci_write_config_byte(meye.mchip_dev, PCI_CACHE_LINE_SIZE, 8);	pci_write_config_byte(meye.mchip_dev, PCI_LATENCY_TIMER, 64);	if ((ret = request_irq(meye.mchip_irq, meye_irq, 			       SA_INTERRUPT | SA_SHIRQ, "meye", meye_irq))) {		printk(KERN_ERR "meye: request_irq failed (ret=%d)\n", ret);		goto out5;	}	meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS);	if (!meye.mchip_mmregs) {		printk(KERN_ERR "meye: ioremap failed\n");		ret = -EIO;		goto out6;	}		/* Ask the camera to perform a soft reset. */	pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);	mchip_delay(MCHIP_HIC_CMD, 0);	mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);	wait_ms(1);	mchip_set(MCHIP_VRJ_SOFT_RESET, 1);	wait_ms(1);	mchip_set(MCHIP_MM_PCI_MODE, 5);	wait_ms(1);	mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);	if (video_register_device(&meye.video_dev, VFL_TYPE_GRABBER, video_nr) < 0) {		printk(KERN_ERR "meye: video_register_device failed\n");		ret = -EIO;		goto out7;	}		printk(KERN_INFO "meye: Motion Eye Camera Driver v%d.%d.\n",	       MEYE_DRIVER_MAJORVERSION,	       MEYE_DRIVER_MINORVERSION);	printk(KERN_INFO "meye: mchip KL5A72002 rev. %d, base %lx, irq %d\n", 		revision, mchip_adr, meye.mchip_irq);	/* init all fields */	init_MUTEX(&meye.lock);	meye.picture.depth = 2;	meye.picture.palette = VIDEO_PALETTE_YUV422;	meye.picture.brightness = 32 << 10;	meye.picture.hue = 32 << 10;	meye.picture.colour = 32 << 10;	meye.picture.contrast = 32 << 10;	meye.picture.whiteness = 0;	meye.params.subsample = 0;	meye.params.quality = 7;	meye.params.sharpness = 32;	meye.params.agc = 48;	meye.params.picture = 0;	meye.params.framerate = 0;	sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, 32);	sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, 32);	sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR, 32);	sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST, 32);	sonypi_camera_command(SONYPI_COMMAND_SETCAMERASHARPNESS, 32);	sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE, 0);	sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC, 48);	return 0;out7:	iounmap(meye.mchip_mmregs);out6:	free_irq(meye.mchip_irq, meye_irq);out5:	release_mem_region(pci_resource_start(meye.mchip_dev, 0),			   pci_resource_len(meye.mchip_dev, 0));out4:	pci_disable_device(meye.mchip_dev);out3:	mchip_dma_free();out2:	sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0);out1:	return ret;}static void __devexit meye_remove(struct pci_dev *pcidev) {	video_unregister_device(&meye.video_dev);	mchip_hic_stop();	/* disable interrupts */	mchip_set(MCHIP_MM_INTA, 0x0);	free_irq(meye.mchip_irq, meye_irq);	iounmap(meye.mchip_mmregs);	release_mem_region(pci_resource_start(meye.mchip_dev, 0),			   pci_resource_len(meye.mchip_dev, 0));	pci_disable_device(meye.mchip_dev);	mchip_dma_free();	if (meye.grab_fbuffer)		rvfree(meye.grab_fbuffer, gbuffers*gbufsize);	sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0);	printk(KERN_INFO "meye: removed\n");}static struct pci_device_id meye_pci_tbl[] __devinitdata = {	{ PCI_VENDOR_ID_KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002, 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	{ }};MODULE_DEVICE_TABLE(pci, meye_pci_tbl);static struct pci_driver meye_driver = {	name:		"meye",	id_table:	meye_pci_tbl,	probe:		meye_probe,	remove:		__devexit_p(meye_remove),};static int __init meye_init_module(void) {	if (gbuffers < 2)		gbuffers = 2;	if (gbuffers > MEYE_MAX_BUFNBRS)		gbuffers = MEYE_MAX_BUFNBRS;	if (gbufsize < 0 || gbufsize > MEYE_MAX_BUFSIZE)		gbufsize = MEYE_MAX_BUFSIZE;	printk(KERN_INFO "meye: using %d buffers with %dk (%dk total) for capture\n",	       gbuffers, gbufsize/1024, gbuffers*gbufsize/1024);	return pci_module_init(&meye_driver);}static void __exit meye_cleanup_module(void) {	pci_unregister_driver(&meye_driver);}#ifndef MODULEstatic int __init meye_setup(char *str) {	int ints[4];	str = get_options(str, ARRAY_SIZE(ints), ints);	if (ints[0] <= 0) 		goto out;	gbuffers = ints[1];	if (ints[0] == 1)		goto out;	gbufsize = ints[2];	if (ints[0] == 2)		goto out;	video_nr = ints[3];out:	return 1;}__setup("meye=", meye_setup);#endifMODULE_AUTHOR("Stelian Pop <stelian.pop@fr.alcove.com>");MODULE_DESCRIPTION("video4linux driver for the MotionEye camera");MODULE_LICENSE("GPL");EXPORT_NO_SYMBOLS;MODULE_PARM(gbuffers,"i");MODULE_PARM_DESC(gbuffers,"number of capture buffers, default is 2 (32 max)");MODULE_PARM(gbufsize,"i");MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 614400");MODULE_PARM(video_nr,"i");MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)");/* Module entry points */module_init(meye_init_module);module_exit(meye_cleanup_module);

⌨️ 快捷键说明

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