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

📄 sn9c102_core.c

📁 V4l driver for DVB HD
💻 C
📖 第 1 页 / 共 5 页
字号:
	rect.width = scale * pix->width;	rect.height = scale * pix->height;	if (rect.width < 16)		rect.width = 16;	if (rect.height < 16)		rect.height = 16;	if (rect.width > bounds->left + bounds->width - rect.left)		rect.width = bounds->left + bounds->width - rect.left;	if (rect.height > bounds->top + bounds->height - rect.top)		rect.height = bounds->top + bounds->height - rect.top;	rect.width &= ~15L;	rect.height &= ~15L;	{ /* adjust the scaling factor */		u32 a, b;		a = rect.width * rect.height;		b = pix->width * pix->height;		scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;	}	pix->width = rect.width / scale;	pix->height = rect.height / scale;	if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&	    pix->pixelformat != V4L2_PIX_FMT_SBGGR8)		pix->pixelformat = pfmt->pixelformat;	pix->priv = pfmt->priv; /* bpp */	pix->colorspace = pfmt->colorspace;	pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)			    ? 0 : (pix->width * pix->priv) / 8;	pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);	pix->field = V4L2_FIELD_NONE;	if (cmd == VIDIOC_TRY_FMT) {		if (copy_to_user(arg, &format, sizeof(format)))			return -EFAULT;		return 0;	}	if (cam->module_param.force_munmap)		for (i = 0; i < cam->nbuffers; i++)			if (cam->frame[i].vma_use_count) {				DBG(3, "VIDIOC_S_FMT failed. Unmap the "				       "buffers first.");				return -EINVAL;			}	if (cam->stream == STREAM_ON)		if ((err = sn9c102_stream_interrupt(cam)))			return err;	if (copy_to_user(arg, &format, sizeof(format))) {		cam->stream = stream;		return -EFAULT;	}	if (cam->module_param.force_munmap  || cam->io == IO_READ)		sn9c102_release_buffers(cam);	err += sn9c102_set_pix_format(cam, pix);	err += sn9c102_set_crop(cam, &rect);	if (s->set_pix_format)		err += s->set_pix_format(cam, pix);	if (s->set_crop)		err += s->set_crop(cam, &rect);	err += sn9c102_set_scale(cam, scale);	if (err) { /* atomic, no rollback in ioctl() */		cam->state |= DEV_MISCONFIGURED;		DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "		       "use the camera, close and open /dev/video%d again.",		    cam->v4ldev->minor);		return -EIO;	}	memcpy(pfmt, pix, sizeof(*pix));	memcpy(&(s->_rect), &rect, sizeof(rect));	if ((cam->module_param.force_munmap  || cam->io == IO_READ) &&	    nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {		cam->state |= DEV_MISCONFIGURED;		DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "		       "use the camera, close and open /dev/video%d again.",		    cam->v4ldev->minor);		return -ENOMEM;	}	if (cam->io == IO_READ)		sn9c102_empty_framequeues(cam);	else if (cam->module_param.force_munmap)		sn9c102_requeue_outqueue(cam);	cam->stream = stream;	return 0;}static intsn9c102_vidioc_g_jpegcomp(struct sn9c102_device* cam, void __user * arg){	if (copy_to_user(arg, &cam->compression,			 sizeof(cam->compression)))		return -EFAULT;	return 0;}static intsn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg){	struct v4l2_jpegcompression jc;	const enum sn9c102_stream_state stream = cam->stream;	int err = 0;	if (copy_from_user(&jc, arg, sizeof(jc)))		return -EFAULT;	if (jc.quality != 0 && jc.quality != 1)		return -EINVAL;	if (cam->stream == STREAM_ON)		if ((err = sn9c102_stream_interrupt(cam)))			return err;	err += sn9c102_set_compression(cam, &jc);	if (err) { /* atomic, no rollback in ioctl() */		cam->state |= DEV_MISCONFIGURED;		DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "		       "problems. To use the camera, close and open "		       "/dev/video%d again.", cam->v4ldev->minor);		return -EIO;	}	cam->compression.quality = jc.quality;	cam->stream = stream;	return 0;}static intsn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg){	struct v4l2_requestbuffers rb;	u32 i;	int err;	if (copy_from_user(&rb, arg, sizeof(rb)))		return -EFAULT;	if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||	    rb.memory != V4L2_MEMORY_MMAP)		return -EINVAL;	if (cam->io == IO_READ) {		DBG(3, "Close and open the device again to choose the mmap "		       "I/O method");		return -EINVAL;	}	for (i = 0; i < cam->nbuffers; i++)		if (cam->frame[i].vma_use_count) {			DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are "			       "still mapped.");			return -EINVAL;		}	if (cam->stream == STREAM_ON)		if ((err = sn9c102_stream_interrupt(cam)))			return err;	sn9c102_empty_framequeues(cam);	sn9c102_release_buffers(cam);	if (rb.count)		rb.count = sn9c102_request_buffers(cam, rb.count, IO_MMAP);	if (copy_to_user(arg, &rb, sizeof(rb))) {		sn9c102_release_buffers(cam);		cam->io = IO_NONE;		return -EFAULT;	}	cam->io = rb.count ? IO_MMAP : IO_NONE;	return 0;}static intsn9c102_vidioc_querybuf(struct sn9c102_device* cam, void __user * arg){	struct v4l2_buffer b;	if (copy_from_user(&b, arg, sizeof(b)))		return -EFAULT;	if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||	    b.index >= cam->nbuffers || cam->io != IO_MMAP)		return -EINVAL;	memcpy(&b, &cam->frame[b.index].buf, sizeof(b));	if (cam->frame[b.index].vma_use_count)		b.flags |= V4L2_BUF_FLAG_MAPPED;	if (cam->frame[b.index].state == F_DONE)		b.flags |= V4L2_BUF_FLAG_DONE;	else if (cam->frame[b.index].state != F_UNUSED)		b.flags |= V4L2_BUF_FLAG_QUEUED;	if (copy_to_user(arg, &b, sizeof(b)))		return -EFAULT;	return 0;}static intsn9c102_vidioc_qbuf(struct sn9c102_device* cam, void __user * arg){	struct v4l2_buffer b;	unsigned long lock_flags;	if (copy_from_user(&b, arg, sizeof(b)))		return -EFAULT;	if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||	    b.index >= cam->nbuffers || cam->io != IO_MMAP)		return -EINVAL;	if (cam->frame[b.index].state != F_UNUSED)		return -EINVAL;	cam->frame[b.index].state = F_QUEUED;	spin_lock_irqsave(&cam->queue_lock, lock_flags);	list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);	spin_unlock_irqrestore(&cam->queue_lock, lock_flags);	PDBGG("Frame #%lu queued", (unsigned long)b.index);	return 0;}static intsn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp,		     void __user * arg){	struct v4l2_buffer b;	struct sn9c102_frame_t *f;	unsigned long lock_flags;	long timeout;	if (copy_from_user(&b, arg, sizeof(b)))		return -EFAULT;	if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)		return -EINVAL;	if (list_empty(&cam->outqueue)) {		if (cam->stream == STREAM_OFF)			return -EINVAL;		if (filp->f_flags & O_NONBLOCK)			return -EAGAIN;		timeout = wait_event_interruptible_timeout			  ( cam->wait_frame,			    (!list_empty(&cam->outqueue)) ||			    (cam->state & DEV_DISCONNECTED) ||			    (cam->state & DEV_MISCONFIGURED),			    cam->module_param.frame_timeout *			    1000 * msecs_to_jiffies(1) );		if (timeout < 0)			return timeout;		if (cam->state & DEV_DISCONNECTED)			return -ENODEV;		if (!timeout || (cam->state & DEV_MISCONFIGURED))			return -EIO;	}	spin_lock_irqsave(&cam->queue_lock, lock_flags);	f = list_entry(cam->outqueue.next, struct sn9c102_frame_t, frame);	list_del(cam->outqueue.next);	spin_unlock_irqrestore(&cam->queue_lock, lock_flags);	f->state = F_UNUSED;	memcpy(&b, &f->buf, sizeof(b));	if (f->vma_use_count)		b.flags |= V4L2_BUF_FLAG_MAPPED;	if (copy_to_user(arg, &b, sizeof(b)))		return -EFAULT;	PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);	return 0;}static intsn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg){	int type;	if (copy_from_user(&type, arg, sizeof(type)))		return -EFAULT;	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)		return -EINVAL;	if (list_empty(&cam->inqueue))		return -EINVAL;	cam->stream = STREAM_ON;	DBG(3, "Stream on");	return 0;}static intsn9c102_vidioc_streamoff(struct sn9c102_device* cam, void __user * arg){	int type, err;	if (copy_from_user(&type, arg, sizeof(type)))		return -EFAULT;	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)		return -EINVAL;	if (cam->stream == STREAM_ON)		if ((err = sn9c102_stream_interrupt(cam)))			return err;	sn9c102_empty_framequeues(cam);	DBG(3, "Stream off");	return 0;}static intsn9c102_vidioc_g_parm(struct sn9c102_device* cam, void __user * arg){	struct v4l2_streamparm sp;	if (copy_from_user(&sp, arg, sizeof(sp)))		return -EFAULT;	if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)		return -EINVAL;	sp.parm.capture.extendedmode = 0;	sp.parm.capture.readbuffers = cam->nreadbuffers;	if (copy_to_user(arg, &sp, sizeof(sp)))		return -EFAULT;	return 0;}static intsn9c102_vidioc_s_parm(struct sn9c102_device* cam, void __user * arg){	struct v4l2_streamparm sp;	if (copy_from_user(&sp, arg, sizeof(sp)))		return -EFAULT;	if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)		return -EINVAL;	sp.parm.capture.extendedmode = 0;	if (sp.parm.capture.readbuffers == 0)		sp.parm.capture.readbuffers = cam->nreadbuffers;	if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES)		sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES;	if (copy_to_user(arg, &sp, sizeof(sp)))		return -EFAULT;	cam->nreadbuffers = sp.parm.capture.readbuffers;	return 0;}static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,			      unsigned int cmd, void __user * arg){	struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));	switch (cmd) {	case VIDIOC_QUERYCAP:		return sn9c102_vidioc_querycap(cam, arg);	case VIDIOC_ENUMINPUT:		return sn9c102_vidioc_enuminput(cam, arg);	case VIDIOC_G_INPUT:		return sn9c102_vidioc_g_input(cam, arg);	case VIDIOC_S_INPUT:		return sn9c102_vidioc_s_input(cam, arg);	case VIDIOC_QUERYCTRL:		return sn9c102_vidioc_query_ctrl(cam, arg);	case VIDIOC_G_CTRL:		return sn9c102_vidioc_g_ctrl(cam, arg);	case VIDIOC_S_CTRL_OLD:	case VIDIOC_S_CTRL:		return sn9c102_vidioc_s_ctrl(cam, arg);	case VIDIOC_CROPCAP_OLD:	case VIDIOC_CROPCAP:		return sn9c102_vidioc_cropcap(cam, arg);	case VIDIOC_G_CROP:		return sn9c102_vidioc_g_crop(cam, arg);	case VIDIOC_S_CROP:		return sn9c102_vidioc_s_crop(cam, arg);	case VIDIOC_ENUM_FMT:		return sn9c102_vidioc_enum_fmt(cam, arg);	case VIDIOC_G_FMT:		return sn9c102_vidioc_g_fmt(cam, arg);	case VIDIOC_TRY_FMT:	case VIDIOC_S_FMT:		return sn9c102_vidioc_try_s_fmt(cam, cmd, arg);	case VIDIOC_G_JPEGCOMP:		return sn9c102_vidioc_g_jpegcomp(cam, arg);	case VIDIOC_S_JPEGCOMP:		return sn9c102_vidioc_s_jpegcomp(cam, arg);	case VIDIOC_REQBUFS:		return sn9c102_vidioc_reqbufs(cam, arg);	case VIDIOC_QUERYBUF:		return sn9c102_vidioc_querybuf(cam, arg);	case VIDIOC_QBUF:		return sn9c102_vidioc_qbuf(cam, arg);	case VIDIOC_DQBUF:		return sn9c102_vidioc_dqbuf(cam, filp, arg);	case VIDIOC_STREAMON:		return sn9c102_vidioc_streamon(cam, arg);	case VIDIOC_STREAMOFF:		return sn9c102_vidioc_streamoff(cam, arg);	case VIDIOC_G_PARM:		return sn9c102_vidioc_g_parm(cam, arg);	case VIDIOC_S_PARM_OLD:	case VIDIOC_S_PARM:		return sn9c102_vidioc_s_parm(cam, arg);	case VIDIOC_G_STD:	case VIDIOC_S_STD:	case VIDIOC_QUERYSTD:	case VIDIOC_ENUMSTD:	case VIDIOC_QUERYMENU:		return -EINVAL;	default:		return -EINVAL;	}}static int sn9c102_ioctl(struct inode* inode, struct file* filp,			 unsigned int cmd, unsigned long arg){	struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));	int err = 0;	if (mutex_lock_interruptible(&cam->fileop_mutex))		return -ERESTARTSYS;	if (cam->state & DEV_DISCONNECTED) {		DBG(1, "Device not present");		mutex_unlock(&cam->fileop_mutex);		return -ENODEV;	}	if (cam->state & DEV_MISCONFIGURED) {		DBG(1, "The camera is misconfigured. Close and open it "		       "again.");		mutex_unlock(&cam->fileop_mutex);		return -EIO;	}	V4LDBG(3, "sn9c102", cmd);	err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);	mutex_unlock(&cam->fileop_mutex);	return err;}/*****************************************************************************/static struct file_operations sn9c102_fops = {	.owner = THIS_MODULE,	.open =    sn9c102_open,	.release = sn9c102_release,	.ioctl =   sn9c102_ioctl,	.read =    sn9c102_read,	.poll =    sn9c102_poll,	.mmap =    sn9c102_mmap,	.llseek =  no_llseek,};/*****************************************************************************//* It 

⌨️ 快捷键说明

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