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

📄 vfc_dev.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 2 页
字号:
	case NORMMODE:		vfc_lock_device(dev);		dev->control_reg &= ~VFC_CONTROL_DIAGMODE;		sbus_writel(dev->control_reg, &dev->regs->control);		vfc_unlock_device(dev);		ret = 0;		break;	case CAPTRSTR:		vfc_capture_start(dev);		ret = 0;		break;	case CAPTRWAIT:		vfc_capture_poll(dev);		ret = 0;		break;	default:		ret = -EINVAL;		break;	};	return ret;}int vfc_port_change_ioctl(struct inode *inode, struct file *file, 			  struct vfc_dev *dev, unsigned long arg) {	int ret = 0;	int cmd;	if(copy_from_user(&cmd, (void *)arg, sizeof(unsigned int))) {		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: User passed bogus pointer to "					"vfc_port_change_ioctl\n",					dev->instance));		return -EFAULT;	}		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCPORTCHG) arg=0x%x\n",				dev->instance, cmd));	switch(cmd) {	case 1:	case 2:		VFC_SAA9051_SA(dev,VFC_SAA9051_HSY_START) = 0x72; 		VFC_SAA9051_SA(dev,VFC_SAA9051_HSY_STOP) = 0x52;		VFC_SAA9051_SA(dev,VFC_SAA9051_HC_START) = 0x36;		VFC_SAA9051_SA(dev,VFC_SAA9051_HC_STOP) = 0x18;		VFC_SAA9051_SA(dev,VFC_SAA9051_HORIZ_PEAK) = VFC_SAA9051_BP2;		VFC_SAA9051_SA(dev,VFC_SAA9051_C3) = VFC_SAA9051_CT | VFC_SAA9051_SS3;		VFC_SAA9051_SA(dev,VFC_SAA9051_SECAM_DELAY) = 0x3e;		break;	case 3:		VFC_SAA9051_SA(dev,VFC_SAA9051_HSY_START) = 0x3a;		VFC_SAA9051_SA(dev,VFC_SAA9051_HSY_STOP) = 0x17;		VFC_SAA9051_SA(dev,VFC_SAA9051_HC_START) = 0xfa;		VFC_SAA9051_SA(dev,VFC_SAA9051_HC_STOP) = 0xde;		VFC_SAA9051_SA(dev,VFC_SAA9051_HORIZ_PEAK) =			VFC_SAA9051_BY | VFC_SAA9051_PF | VFC_SAA9051_BP2;		VFC_SAA9051_SA(dev,VFC_SAA9051_C3) = VFC_SAA9051_YC;		VFC_SAA9051_SA(dev,VFC_SAA9051_SECAM_DELAY) = 0;		VFC_SAA9051_SA(dev,VFC_SAA9051_C2) &=			~(VFC_SAA9051_SS0 | VFC_SAA9051_SS1);		break;	default:		ret = -EINVAL;		return ret;		break;	}	switch(cmd) {	case 1:		VFC_SAA9051_SA(dev,VFC_SAA9051_C2) |=			(VFC_SAA9051_SS0 | VFC_SAA9051_SS1);		break;	case 2:		VFC_SAA9051_SA(dev,VFC_SAA9051_C2) &=			~(VFC_SAA9051_SS0 | VFC_SAA9051_SS1);		VFC_SAA9051_SA(dev,VFC_SAA9051_C2) |= VFC_SAA9051_SS0; 		break;	case 3:		break;	default:		ret = -EINVAL;		return ret;		break;	}	VFC_SAA9051_SA(dev,VFC_SAA9051_C3) &= ~(VFC_SAA9051_SS2);	ret=vfc_update_saa9051(dev);	udelay(500);	VFC_SAA9051_SA(dev,VFC_SAA9051_C3) |= (VFC_SAA9051_SS2);	ret=vfc_update_saa9051(dev);	return ret;}int vfc_set_video_ioctl(struct inode *inode, struct file *file, 			struct vfc_dev *dev, unsigned long arg) {	int ret = 0;	int cmd;	if(copy_from_user(&cmd, (void *)arg, sizeof(unsigned int))) {		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: User passed bogus pointer to "					"vfc_set_video_ioctl\n",					dev->instance));		return ret;	}		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCSVID) arg=0x%x\n",				dev->instance, cmd));	switch(cmd) {	case STD_NTSC:		VFC_SAA9051_SA(dev,VFC_SAA9051_C1) &= ~VFC_SAA9051_ALT;		VFC_SAA9051_SA(dev,VFC_SAA9051_C1) |= VFC_SAA9051_YPN | 			VFC_SAA9051_CCFR0 | VFC_SAA9051_CCFR1 | VFC_SAA9051_FS;		ret = vfc_update_saa9051(dev);		break;	case STD_PAL:		VFC_SAA9051_SA(dev,VFC_SAA9051_C1) &= ~(VFC_SAA9051_YPN | 							VFC_SAA9051_CCFR1 | 							VFC_SAA9051_CCFR0 |							VFC_SAA9051_FS);		VFC_SAA9051_SA(dev,VFC_SAA9051_C1) |= VFC_SAA9051_ALT;		ret = vfc_update_saa9051(dev);		break;	case COLOR_ON:		VFC_SAA9051_SA(dev,VFC_SAA9051_C1) |= VFC_SAA9051_CO;		VFC_SAA9051_SA(dev,VFC_SAA9051_HORIZ_PEAK) &=			~(VFC_SAA9051_BY | VFC_SAA9051_PF);		ret = vfc_update_saa9051(dev);		break;	case MONO:		VFC_SAA9051_SA(dev,VFC_SAA9051_C1) &= ~(VFC_SAA9051_CO);		VFC_SAA9051_SA(dev,VFC_SAA9051_HORIZ_PEAK) |=			(VFC_SAA9051_BY | VFC_SAA9051_PF);		ret = vfc_update_saa9051(dev);		break;	default:		ret = -EINVAL;		break;	};	return ret;}int vfc_get_video_ioctl(struct inode *inode, struct file *file, 			struct vfc_dev *dev, unsigned long arg) {	int ret = 0;	unsigned int status = NO_LOCK;	unsigned char buf[1];	if(vfc_i2c_recvbuf(dev, VFC_SAA9051_ADDR, buf, 1)) {		printk(KERN_ERR "vfc%d: Unable to get status\n",		       dev->instance);		return -EIO;	}	if(buf[0] & VFC_SAA9051_HLOCK) {		status = NO_LOCK;	} else if(buf[0] & VFC_SAA9051_FD) {		if(buf[0] & VFC_SAA9051_CD)			status = NTSC_COLOR;		else			status = NTSC_NOCOLOR;	} else {		if(buf[0] & VFC_SAA9051_CD)			status = PAL_COLOR;		else			status = PAL_NOCOLOR;	}	VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCGVID) returning status 0x%x; "				"buf[0]=%x\n", dev->instance, status, buf[0]));	if (copy_to_user((void *)arg,&status,sizeof(unsigned int))) {		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: User passed bogus pointer to "					"vfc_get_video_ioctl\n",					dev->instance));		return ret;	}	return ret;}static int vfc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,	      unsigned long arg) {	int ret = 0;	unsigned int tmp;	struct vfc_dev *dev;	dev = vfc_get_dev_ptr(MINOR(inode->i_rdev));	if(dev == NULL)		return -ENODEV;		switch(cmd & 0x0000ffff) {	case VFCGCTRL:#if 0		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCGCTRL)\n", dev->instance));#endif		tmp = sbus_readl(&dev->regs->control);		if(copy_to_user((void *)arg, &tmp, sizeof(unsigned int))) {			ret = -EFAULT;			break;		}		ret = 0;		break;	case VFCSCTRL:		ret = vfc_set_control_ioctl(inode, file, dev, arg);		break;	case VFCGVID:		ret = vfc_get_video_ioctl(inode, file, dev, arg);		break;	case VFCSVID:		ret = vfc_set_video_ioctl(inode, file, dev, arg);		break;	case VFCHUE:		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCHUE)\n", dev->instance));		if(copy_from_user(&tmp,(void *)arg,sizeof(unsigned int))) {			VFC_IOCTL_DEBUG_PRINTK(("vfc%d: User passed bogus pointer "						"to IOCTL(VFCHUE)", dev->instance));			ret = -EFAULT;		} else {			VFC_SAA9051_SA(dev,VFC_SAA9051_HUE) = tmp;			vfc_update_saa9051(dev);			ret = 0;		}		break;	case VFCPORTCHG:		ret = vfc_port_change_ioctl(inode, file, dev, arg);		break;	case VFCRDINFO:		ret = -EINVAL;		VFC_IOCTL_DEBUG_PRINTK(("vfc%d: IOCTL(VFCRDINFO)\n", dev->instance));		break;	default:		ret = vfc_debug(vfc_get_dev_ptr(MINOR(inode->i_rdev)),				cmd, arg);		break;	};	return ret;}static int vfc_mmap(struct inode *inode, struct file *file, 		    struct vm_area_struct *vma) {	unsigned int map_size, ret, map_offset;	struct vfc_dev *dev;		dev = vfc_get_dev_ptr(MINOR(inode->i_rdev));	if(dev == NULL)		return -ENODEV;	map_size = vma->vm_end - vma->vm_start;	if(map_size > sizeof(struct vfc_regs)) 		map_size = sizeof(struct vfc_regs);	vma->vm_flags |=		(VM_SHM | VM_LOCKED | VM_IO | VM_MAYREAD | VM_MAYWRITE | VM_MAYSHARE);	map_offset = (unsigned int) (long)dev->phys_regs;	ret = io_remap_page_range(vma->vm_start, map_offset, map_size, 				  vma->vm_page_prot, dev->which_io);	if(ret)		return -EAGAIN;	return 0;}static struct file_operations vfc_fops = {	owner:		THIS_MODULE,	llseek:		no_llseek,	ioctl:		vfc_ioctl,	mmap:		vfc_mmap,	open:		vfc_open,	release:	vfc_release,};static int vfc_probe(void){	struct sbus_bus *sbus;	struct sbus_dev *sdev = NULL;	int ret;	int instance = 0, cards = 0;	for_all_sbusdev(sdev, sbus) {		if (strcmp(sdev->prom_name, "vfc") == 0) {			cards++;			continue;		}	}	if (!cards)		return -ENODEV;	vfc_dev_lst = (struct vfc_dev **)kmalloc(sizeof(struct vfc_dev *) *						 (cards+1),						 GFP_KERNEL);	if (vfc_dev_lst == NULL)		return -ENOMEM;	memset(vfc_dev_lst, 0, sizeof(struct vfc_dev *) * (cards + 1));	vfc_dev_lst[cards] = NULL;	ret = devfs_register_chrdev(VFC_MAJOR, vfcstr, &vfc_fops);	if(ret) {		printk(KERN_ERR "Unable to get major number %d\n", VFC_MAJOR);		kfree(vfc_dev_lst);		return -EIO;	}	devfs_handle = devfs_mk_dir (NULL, "vfc", NULL);	instance = 0;	for_all_sbusdev(sdev, sbus) {		if (strcmp(sdev->prom_name, "vfc") == 0) {			vfc_dev_lst[instance]=(struct vfc_dev *)				kmalloc(sizeof(struct vfc_dev), GFP_KERNEL);			if (vfc_dev_lst[instance] == NULL)				return -ENOMEM;			ret = init_vfc_device(sdev,					      vfc_dev_lst[instance],					      instance);			if(ret) {				printk(KERN_ERR "Unable to initialize"				       " vfc%d device\n",				       instance);			} else {			}					instance++;			continue;		}	}	return 0;}#ifdef MODULEint init_module(void)#else int vfc_init(void)#endif{	return vfc_probe();}#ifdef MODULEstatic void deinit_vfc_device(struct vfc_dev *dev){	if(dev == NULL)		return;	devfs_unregister (dev->de);	sbus_iounmap((unsigned long)dev->regs, sizeof(struct vfc_regs));	kfree(dev);}void cleanup_module(void){	struct vfc_dev **devp;	devfs_unregister_chrdev(VFC_MAJOR,vfcstr);	for (devp = vfc_dev_lst; *devp; devp++)		deinit_vfc_device(*devp);	devfs_unregister (devfs_handle);	kfree(vfc_dev_lst);	return;}#endif

⌨️ 快捷键说明

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