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

📄 zoran_driver.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
			/* since there is at least one unused buffer there's room for at			 *least one more pend[] entry */			zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] =			    num;			zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND;			fh->jpg_buffers.buffer[num] =			    zr->jpg_buffers.buffer[num];			zoran_feed_stat_com(zr);			break;		default:		case BUZ_STATE_DMA:		case BUZ_STATE_PEND:			if (zr->jpg_buffers.active == ZORAN_FREE) {				fh->jpg_buffers.active = ZORAN_FREE;				zr->jpg_buffers.allocated = 0;			}			res = -EBUSY;	/* what are you doing? */			break;		}	}	spin_unlock_irqrestore(&zr->spinlock, flags);	if (!res && zr->jpg_buffers.active == ZORAN_FREE) {		zr->jpg_buffers.active = fh->jpg_buffers.active;	}	return res;}static intjpg_qbuf (struct file          *file,	  int                   frame,	  enum zoran_codec_mode mode){	struct zoran_fh *fh = file->private_data;	struct zoran *zr = fh->zr;	int res = 0;	/* Does the user want to stop streaming? */	if (frame < 0) {		if (zr->codec_mode == mode) {			if (fh->jpg_buffers.active == ZORAN_FREE) {				dprintk(1,					KERN_ERR					"%s: jpg_qbuf(-1) - session not active\n",					ZR_DEVNAME(zr));				return -EINVAL;			}			fh->jpg_buffers.active = zr->jpg_buffers.active =			    ZORAN_FREE;			zr->jpg_buffers.allocated = 0;			zr36057_enable_jpg(zr, BUZ_MODE_IDLE);			return 0;		} else {			dprintk(1,				KERN_ERR				"%s: jpg_qbuf() - stop streaming but not in streaming mode\n",				ZR_DEVNAME(zr));			return -EINVAL;		}	}	if ((res = zoran_jpg_queue_frame(file, frame, mode)))		return res;	/* Start the jpeg codec when the first frame is queued  */	if (!res && zr->jpg_que_head == 1)		jpeg_start(zr);	return res;}/* *   Sync on a MJPEG buffer */static intjpg_sync (struct file       *file,	  struct zoran_sync *bs){	struct zoran_fh *fh = file->private_data;	struct zoran *zr = fh->zr;	unsigned long flags;	int frame;	if (fh->jpg_buffers.active == ZORAN_FREE) {		dprintk(1,			KERN_ERR			"%s: jpg_sync() - capture is not currently active\n",			ZR_DEVNAME(zr));		return -EINVAL;	}	if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS &&	    zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) {		dprintk(1,			KERN_ERR			"%s: jpg_sync() - codec not in streaming mode\n",			ZR_DEVNAME(zr));		return -EINVAL;	}	if (!wait_event_interruptible_timeout(zr->jpg_capq,			(zr->jpg_que_tail != zr->jpg_dma_tail ||			 zr->jpg_dma_tail == zr->jpg_dma_head),			10*HZ)) {		int isr;		btand(~ZR36057_JMC_Go_en, ZR36057_JMC);		udelay(1);		zr->codec->control(zr->codec, CODEC_G_STATUS,					   sizeof(isr), &isr);		dprintk(1,			KERN_ERR			"%s: jpg_sync() - timeout: codec isr=0x%02x\n",			ZR_DEVNAME(zr), isr);		return -ETIME;	}	if (signal_pending(current))		return -ERESTARTSYS;	spin_lock_irqsave(&zr->spinlock, flags);	if (zr->jpg_dma_tail != zr->jpg_dma_head)		frame = zr->jpg_pend[zr->jpg_que_tail++ & BUZ_MASK_FRAME];	else		frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];	/* buffer should now be in BUZ_STATE_DONE */	if (*zr_debug > 0)		if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE)			dprintk(2,				KERN_ERR				"%s: jpg_sync() - internal state error\n",				ZR_DEVNAME(zr));	*bs = zr->jpg_buffers.buffer[frame].bs;	bs->frame = frame;	zr->jpg_buffers.buffer[frame].state = BUZ_STATE_USER;	fh->jpg_buffers.buffer[frame] = zr->jpg_buffers.buffer[frame];	spin_unlock_irqrestore(&zr->spinlock, flags);	return 0;}static voidzoran_open_init_session (struct file *file){	int i;	struct zoran_fh *fh = file->private_data;	struct zoran *zr = fh->zr;	/* Per default, map the V4L Buffers */	fh->map_mode = ZORAN_MAP_MODE_RAW;	/* take over the card's current settings */	fh->overlay_settings = zr->overlay_settings;	fh->overlay_settings.is_set = 0;	fh->overlay_settings.format = zr->overlay_settings.format;	fh->overlay_active = ZORAN_FREE;	/* v4l settings */	fh->v4l_settings = zr->v4l_settings;	/* v4l_buffers */	memset(&fh->v4l_buffers, 0, sizeof(struct zoran_v4l_struct));	for (i = 0; i < VIDEO_MAX_FRAME; i++) {		fh->v4l_buffers.buffer[i].state = BUZ_STATE_USER;	/* nothing going on */		fh->v4l_buffers.buffer[i].bs.frame = i;	}	fh->v4l_buffers.allocated = 0;	fh->v4l_buffers.ready_to_be_freed = 0;	fh->v4l_buffers.active = ZORAN_FREE;	fh->v4l_buffers.buffer_size = v4l_bufsize;	fh->v4l_buffers.num_buffers = v4l_nbufs;	/* jpg settings */	fh->jpg_settings = zr->jpg_settings;	/* jpg_buffers */	memset(&fh->jpg_buffers, 0, sizeof(struct zoran_jpg_struct));	for (i = 0; i < BUZ_MAX_FRAME; i++) {		fh->jpg_buffers.buffer[i].state = BUZ_STATE_USER;	/* nothing going on */		fh->jpg_buffers.buffer[i].bs.frame = i;	}	fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous;	fh->jpg_buffers.allocated = 0;	fh->jpg_buffers.ready_to_be_freed = 0;	fh->jpg_buffers.active = ZORAN_FREE;	fh->jpg_buffers.buffer_size = jpg_bufsize;	fh->jpg_buffers.num_buffers = jpg_nbufs;}static voidzoran_close_end_session (struct file *file){	struct zoran_fh *fh = file->private_data;	struct zoran *zr = fh->zr;	/* overlay */	if (fh->overlay_active != ZORAN_FREE) {		fh->overlay_active = zr->overlay_active = ZORAN_FREE;		zr->v4l_overlay_active = 0;		if (!zr->v4l_memgrab_active)			zr36057_overlay(zr, 0);		zr->overlay_mask = NULL;	}	/* v4l capture */	if (fh->v4l_buffers.active != ZORAN_FREE) {		zr36057_set_memgrab(zr, 0);		zr->v4l_buffers.allocated = 0;		zr->v4l_buffers.active = fh->v4l_buffers.active =		    ZORAN_FREE;	}	/* v4l buffers */	if (fh->v4l_buffers.allocated ||	    fh->v4l_buffers.ready_to_be_freed) {		v4l_fbuffer_free(file);	}	/* jpg capture */	if (fh->jpg_buffers.active != ZORAN_FREE) {		zr36057_enable_jpg(zr, BUZ_MODE_IDLE);		zr->jpg_buffers.allocated = 0;		zr->jpg_buffers.active = fh->jpg_buffers.active =		    ZORAN_FREE;	}	/* jpg buffers */	if (fh->jpg_buffers.allocated ||	    fh->jpg_buffers.ready_to_be_freed) {		jpg_fbuffer_free(file);	}}/* *   Open a zoran card. Right now the flags stuff is just playing */static intzoran_open (struct inode *inode,	    struct file  *file){	unsigned int minor = iminor(inode);	struct zoran *zr = NULL;	struct zoran_fh *fh;	int i, res, first_open = 0, have_module_locks = 0;	/* find the device */	for (i = 0; i < zoran_num; i++) {		if (zoran[i].video_dev->minor == minor) {			zr = &zoran[i];			break;		}	}	if (!zr) {		dprintk(1, KERN_ERR "%s: device not found!\n", ZORAN_NAME);		res = -ENODEV;		goto open_unlock_and_return;	}	/* see fs/device.c - the kernel already locks during open(),	 * so locking ourselves only causes deadlocks */	/*down(&zr->resource_lock);*/	if (!zr->decoder) {		dprintk(1,			KERN_ERR "%s: no TV decoder loaded for device!\n",			ZR_DEVNAME(zr));		res = -EIO;		goto open_unlock_and_return;	}	/* try to grab a module lock */	if (!try_module_get(THIS_MODULE)) {		dprintk(1,			KERN_ERR			"%s: failed to acquire my own lock! PANIC!\n",			ZR_DEVNAME(zr));		res = -ENODEV;		goto open_unlock_and_return;	}	if (!try_module_get(zr->decoder->driver->owner)) {		dprintk(1,			KERN_ERR			"%s: failed to grab ownership of i2c decoder\n",			ZR_DEVNAME(zr));		res = -EIO;		module_put(THIS_MODULE);		goto open_unlock_and_return;	}	if (zr->encoder &&	    !try_module_get(zr->encoder->driver->owner)) {		dprintk(1,			KERN_ERR			"%s: failed to grab ownership of i2c encoder\n",			ZR_DEVNAME(zr));		res = -EIO;		module_put(zr->decoder->driver->owner);		module_put(THIS_MODULE);		goto open_unlock_and_return;	}	have_module_locks = 1;	if (zr->user >= 2048) {		dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",			ZR_DEVNAME(zr), zr->user);		res = -EBUSY;		goto open_unlock_and_return;	}	dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",		ZR_DEVNAME(zr), current->comm, current->pid, zr->user);	/* now, create the open()-specific file_ops struct */	fh = kmalloc(sizeof(struct zoran_fh), GFP_KERNEL);	if (!fh) {		dprintk(1,			KERN_ERR			"%s: zoran_open() - allocation of zoran_fh failed\n",			ZR_DEVNAME(zr));		res = -ENOMEM;		goto open_unlock_and_return;	}	memset(fh, 0, sizeof(struct zoran_fh));	/* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows	 * on norm-change! */	fh->overlay_mask =	    kmalloc(((768 + 31) / 32) * 576 * 4, GFP_KERNEL);	if (!fh->overlay_mask) {		dprintk(1,			KERN_ERR			"%s: zoran_open() - allocation of overlay_mask failed\n",			ZR_DEVNAME(zr));		kfree(fh);		res = -ENOMEM;		goto open_unlock_and_return;	}	if (zr->user++ == 0)		first_open = 1;	/*up(&zr->resource_lock);*/	/* default setup - TODO: look at flags */	if (first_open) {	/* First device open */		zr36057_restart(zr);		zoran_open_init_params(zr);		zoran_init_hardware(zr);		btor(ZR36057_ICR_IntPinEn, ZR36057_ICR);	}	/* set file_ops stuff */	file->private_data = fh;	fh->zr = zr;	zoran_open_init_session(file);	return 0;open_unlock_and_return:	/* if we grabbed locks, release them accordingly */	if (have_module_locks) {		module_put(zr->decoder->driver->owner);		if (zr->encoder) {			module_put(zr->encoder->driver->owner);		}		module_put(THIS_MODULE);	}	/* if there's no device found, we didn't obtain the lock either */	if (zr) {		/*up(&zr->resource_lock);*/	}	return res;}static intzoran_close (struct inode *inode,	     struct file  *file){	struct zoran_fh *fh = file->private_data;	struct zoran *zr = fh->zr;	dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",		ZR_DEVNAME(zr), current->comm, current->pid, zr->user);	/* kernel locks (fs/device.c), so don't do that ourselves	 * (prevents deadlocks) */	/*down(&zr->resource_lock);*/	zoran_close_end_session(file);	if (zr->user-- == 1) {	/* Last process */		/* Clean up JPEG process */		wake_up_interruptible(&zr->jpg_capq);		zr36057_enable_jpg(zr, BUZ_MODE_IDLE);		zr->jpg_buffers.allocated = 0;		zr->jpg_buffers.active = ZORAN_FREE;		/* disable interrupts */		btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);		if (*zr_debug > 1)			print_interrupts(zr);		/* Overlay off */		zr->v4l_overlay_active = 0;		zr36057_overlay(zr, 0);		zr->overlay_mask = NULL;		/* capture off */		wake_up_interruptible(&zr->v4l_capq);		zr36057_set_memgrab(zr, 0);		zr->v4l_buffers.allocated = 0;		zr->v4l_buffers.active = ZORAN_FREE;		zoran_set_pci_master(zr, 0);		if (!pass_through) {	/* Switch to color bar */			int zero = 0, two = 2;			decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);			encoder_command(zr, ENCODER_SET_INPUT, &two);		}	}	file->private_data = NULL;	kfree(fh->overlay_mask);	kfree(fh);	/* release locks on the i2c modules */	module_put(zr->decoder->driver->owner);	if (zr->encoder) {		 module_put(zr->encoder->driver->owner);	}	module_put(THIS_MODULE);	/*up(&zr->resource_lock);*/	dprintk(4, KERN_INFO "%s: zoran_close() done\n", ZR_DEVNAME(zr));	return 0;}static ssize_tzoran_read (struct file *file,	    char        __user *data,	    size_t       count,	    loff_t      *ppos){	/* we simply don't support read() (yet)... */	return -EINVAL;}static ssize_tzoran_write (struct file *file,	     const char  __user *data,	     size_t       count,	     loff_t      *ppos){	/* ...and the same goes for write() */	return -EINVAL;}static intsetup_fbuffer (struct file               *file,	       void                      *base,	       const struct zoran_format *fmt,	       int                        width,	       int                        height,	       int                        bytesperline){	struct zoran_fh *fh = file->private_data;	struct zoran *zr = fh->zr;	/* (Ronald) v4l/v4l2 guidelines */	if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))		return -EPERM;	/* we need a bytesperline value, even if not given */	if (!bytesperline)		bytesperline = width * ((fmt->depth + 7) & ~7) / 8;#if 0	if (zr->overlay_active) {		/* dzjee... stupid users... don't even bother to turn off		 * overlay before changing the memory location...		 * normally, we would return errors here. However, one of		 * the tools that does this is... xawtv! and since xawtv		 * is used by +/- 99% of the users, we'd rather be user-		 * friendly and silently do as if nothing went wrong */		dprintk(3,			KERN_ERR			"%s: setup_fbuffer() - forced overlay turnoff because framebuffer changed\n",			ZR_DEVNAME(zr));		zr36057_overlay(zr, 0);	}#endif	if (!(fmt->flags & ZORAN_FORMAT_OVERLAY)) {		dprintk(1,			KERN_ERR			"%s: setup_fbuffer() - no valid overlay format given\n",			ZR_DEVNAME(zr));

⌨️ 快捷键说明

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