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

📄 omap24xxcam.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	else		vb->state = STATE_DONE;	wake_up(&vb->done);	spin_unlock(&cam->vbq_lock);}static voidomap24xxcam_vbq_release(struct file *file, struct videobuf_buffer *vb){	videobuf_waiton(vb, 0, 0);	videobuf_dma_pci_unmap(NULL, &vb->dma);	videobuf_dma_free(&vb->dma);		vb->state = STATE_NEEDS_INIT;}/* Limit the number of available kernel image capture buffers based on the  * number requested, the currently selected image size, and the maximum  * amount of memory permitted for kernel capture buffers. */static intomap24xxcam_vbq_setup(struct file *file, unsigned int *cnt, unsigned int *size){	struct omap24xxcam_fh *fh = file->private_data;	struct omap24xxcam_device *cam = fh->cam;	if (*cnt <= 0)		*cnt = VIDEO_MAX_FRAME;	/* supply a default number of buffers */	if (*cnt > VIDEO_MAX_FRAME)		*cnt = VIDEO_MAX_FRAME;	spin_lock(&cam->img_lock);	*size = cam->pix.sizeimage;	spin_unlock(&cam->img_lock);	while (*size * *cnt > capture_mem)		(*cnt)--;	return 0;}static intomap24xxcam_vbq_prepare(struct file *file, struct videobuf_buffer *vb, 	enum v4l2_field field){	struct omap24xxcam_fh *fh = file->private_data;	struct omap24xxcam_device *cam = fh->cam;	int err = 0;	spin_lock(&cam->img_lock);	if (vb->baddr) {		/* This is a userspace buffer. */		 if (cam->pix.sizeimage > vb->bsize) {		 	/* The buffer isn't big enough. */			err = -EINVAL;		} else			vb->size = cam->pix.sizeimage;	}	else if (!vb->baddr) {		if (vb->state != STATE_NEEDS_INIT) {			/* We have a kernel bounce buffer that has already been 			 * allocated.			 */			if (cam->pix.sizeimage > vb->size) {				/* The image size has been changed to a larger 				 * size since this buffer was allocated, so we 				 * need to free and reallocate it.				 */				spin_unlock(&cam->img_lock);				omap24xxcam_vbq_release(file, vb);				spin_lock(&cam->img_lock);				vb->size = cam->pix.sizeimage;			}		}		else {			/* We need to allocate a new kernel bounce buffer. */			vb->size = cam->pix.sizeimage;		}	}	vb->width = cam->pix.width;	vb->height = cam->pix.height;	vb->field = field;	spin_unlock(&cam->img_lock);	if (err)		return err;	if (vb->state == STATE_NEEDS_INIT)		err = videobuf_iolock(NULL, vb, NULL);	if (!err)		vb->state = STATE_PREPARED;	else		omap24xxcam_vbq_release(file, vb);	return err;}static voidomap24xxcam_vbq_queue(struct file *file, struct videobuf_buffer *vb){	struct omap24xxcam_fh *fh = file->private_data;	struct omap24xxcam_device *cam = fh->cam;	enum videobuf_state state = vb->state;	int err;	vb->state = STATE_QUEUED;	err = omap24xxcam_sg_dma_queue(cam, vb->dma.sglist, vb->dma.sglen, 		omap24xxcam_vbq_complete, vb);	if (err) {		/* Oops.  We're not supposed to get any errors here.  The only 		 * way we could get an error is if we ran out of scatter-gather 		 * DMA slots, but we are supposed to have at least as many 		 * scatter-gather DMA slots as video buffers so that can't 		 * happen.		 */		 printk(KERN_DEBUG CAM_NAME 			": Failed to queue a video buffer for DMA!\n");		 vb->state = state;	}}/* -------------------------------------------------------------------------- */static intomap24xxcam_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 		     void *arg){	struct omap24xxcam_fh *fh  = file->private_data;	struct omap24xxcam_device *cam = fh->cam;	int err;	switch (cmd) {		/* for time being below IOCTL cmd is here */		case VIDIOC_ENUMINPUT:		{			/* default handler assumes 1 video input (the camera) */			struct v4l2_input *input = (struct v4l2_input *) arg;			int index = input->index;			memset(input, 0, sizeof(*input));			input->index = index;			if (index > 0)				return -EINVAL;			strlcpy(input->name, "camera", sizeof(input->name));			input->type = V4L2_INPUT_TYPE_CAMERA;			return 0;		}		case VIDIOC_G_INPUT:		{			unsigned int *input = arg;			*input = 0;			return 0;		}		case VIDIOC_S_INPUT:		{			unsigned int *input = arg;			if (*input > 0)				return -EINVAL;			return 0;		}		case VIDIOC_QUERYCAP:		{			struct v4l2_capability *cap = 				(struct v4l2_capability *) arg;			memset(cap, 0, sizeof(*cap));                	strlcpy(cap->driver, CAM_NAME, sizeof(cap->driver));                	strlcpy(cap->card, cam->vfd->name, sizeof(cap->card));			cap->bus_info[0] = '\0';			cap->version = KERNEL_VERSION(0, 0, 0);			cap->capabilities =				V4L2_CAP_VIDEO_CAPTURE |				V4L2_CAP_VIDEO_OVERLAY |				V4L2_CAP_READWRITE | 				V4L2_CAP_STREAMING;			return 0;		}		case VIDIOC_G_FMT:		{			struct v4l2_format *f = (struct v4l2_format *) arg;						switch (f->type) {				case V4L2_BUF_TYPE_VIDEO_CAPTURE:				{					struct v4l2_pix_format *pix = 						&f->fmt.pix;					memset(pix, 0, sizeof(*pix));					spin_lock(&cam->img_lock);					*pix = cam->pix;					spin_unlock(&cam->img_lock);					return 0;				}				case V4L2_BUF_TYPE_VIDEO_OVERLAY:				{					struct v4l2_window *win = &f->fmt.win;					memset(win, 0, sizeof(*win));					/* The API has a bit of a problem here. 					 * We're returning a v4l2_window 					 * structure, but that structure 					 * contains pointers to variable-sized 					 * objects for clipping rectangles and 					 * clipping bitmaps.  We will just 					 * return NULLs for those pointers.					 */					spin_lock(&cam->img_lock);					win->w = cam->win.w;					win->field = cam->win.field;					win->chromakey = cam->win.chromakey;					spin_unlock(&cam->img_lock);					return 0;				}				default:				{					return -EINVAL;				}			}		}		case VIDIOC_TRY_FMT:		{			struct v4l2_format *f = (struct v4l2_format *) arg;						switch (f->type) {				case V4L2_BUF_TYPE_VIDEO_OVERLAY:				{					struct v4l2_window *win = &f->fmt.win;					spin_lock(&cam->img_lock);					err=omap24xxcam_try_preview_window(cam,						win);					spin_unlock(&cam->img_lock);					return err;				}				case V4L2_BUF_TYPE_VIDEO_CAPTURE:				{					return cam->cam_sensor->try_format(&f->fmt.pix, cam->sensor);				}				default:				{					return -EINVAL;				}			}		}		case VIDIOC_S_FMT:		{			struct v4l2_format *f = (struct v4l2_format *) arg;						switch (f->type) {				case V4L2_BUF_TYPE_VIDEO_OVERLAY:				{					struct v4l2_window *win = &f->fmt.win;					spin_lock(&cam->img_lock);					if (cam->previewing)					{						spin_unlock(&cam->img_lock);						return -EBUSY;					}					err=omap24xxcam_new_preview_window(cam,						win);					spin_unlock(&cam->img_lock);					return err;				}				case V4L2_BUF_TYPE_VIDEO_CAPTURE:				{					spin_lock(&cam->img_lock);					if (cam->streaming || cam->previewing)					{						spin_unlock(&cam->img_lock);						return -EBUSY;					}					cam->cam_sensor->try_format(&f->fmt.pix, cam->sensor);					/* set the new capture format */					cam->pix = f->fmt.pix;					/* adjust the capture frame rate */					cam->xclk = cam->cam_sensor->calc_xclk(&cam->pix,						&cam->nominal_timeperframe, cam->sensor);					omap24xxcam_adjust_xclk(cam);					cam->cparm.timeperframe = cam->nominal_timeperframe; 					/* intialize the preview parameters */					omap24xxcam_new_capture_format(cam);					spin_unlock(&cam->img_lock);					/* program xclk */					omap24xxcam_set_xclk(cam);					/* program the sensor */					err = cam->cam_sensor->configure(&cam->pix, cam->xclk, 						&cam->cparm.timeperframe, cam->sensor);					return err;				}				default:				{					return -EINVAL;				}			}		}		case VIDIOC_G_FBUF:		{			struct v4l2_framebuffer *fbuf = 				(struct v4l2_framebuffer *) arg;			spin_lock(&cam->img_lock);			*fbuf = cam->fbuf;			spin_unlock(&cam->img_lock);			return 0;		}		case VIDIOC_S_FBUF:		{			struct v4l2_framebuffer *fbuf = 				(struct v4l2_framebuffer *) arg;			unsigned int flags = fbuf->flags;			/* The only field the user is allowed to change is 			 * fbuf->flags.			 */			spin_lock(&cam->img_lock);			if (cam->previewing) {				spin_unlock(&cam->img_lock);				return -EBUSY;			}			if (flags & V4L2_FBUF_FLAG_CHROMAKEY)				cam->fbuf.flags |=  V4L2_FBUF_FLAG_CHROMAKEY;			else				cam->fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY;			spin_unlock(&cam->img_lock);			return 0;		}		case VIDIOC_CROPCAP:		{			struct v4l2_cropcap *cropcap = 				(struct v4l2_cropcap *) arg;			enum v4l2_buf_type type = cropcap->type; 			memset(cropcap, 0, sizeof(*cropcap));			cropcap->type = type;			switch (type) {				case V4L2_BUF_TYPE_VIDEO_OVERLAY:				{					struct v4l2_pix_format *pix = &cam->pix;					spin_lock(&cam->img_lock);					cropcap->bounds.width = pix->width & ~1;					cropcap->bounds.height = 						pix->height & ~1;					omap24xxcam_default_crop_rect(cam, 						&cropcap->defrect);					spin_unlock(&cam->img_lock);					cropcap->pixelaspect.numerator = 1;					cropcap->pixelaspect.denominator = 1;					return 0;				}				case V4L2_BUF_TYPE_VIDEO_CAPTURE:				{					/* We're required to support the CROPCAP					 * ioctl even though the G_CROP/S_CROP 					 * ioctls are optional, which seems a 					 * little strange.  We don't support 					 * cropping of captured images.					 */					spin_lock(&cam->img_lock);					cropcap->bounds.width = cam->pix.width;					cropcap->bounds.height = 						cam->pix.height;					spin_unlock(&cam->img_lock);					cropcap->defrect.width = 						cropcap->bounds.width;					cropcap->defrect.height = 						cropcap->bounds.height;					cropcap->pixelaspect.numerator = 1;					cropcap->pixelaspect.denominator = 1;					return 0;				}								default:				{					return -EINVAL;				}			}		}		case VIDIOC_G_CROP:		{			struct v4l2_crop *crop = (struct v4l2_crop *) arg;			switch (crop->type) {				case V4L2_BUF_TYPE_VIDEO_OVERLAY:				{					spin_lock(&cam->img_lock);					crop->c = cam->crop;					spin_unlock(&cam->img_lock);					return 0;				}				case V4L2_BUF_TYPE_VIDEO_CAPTURE:				{					/* We don't support cropping of captured					 * images.					 */					return -EINVAL;				}								default:				{					return -EINVAL;				}			}		}		case VIDIOC_S_CROP:		{			struct v4l2_crop *crop = (struct v4l2_crop *) arg;			switch (crop->type) {				case V4L2_BUF_TYPE_VIDEO_OVERLAY:				{					spin_lock(&cam->img_lock);					if (cam->previewing) {						spin_unlock(&cam->img_

⌨️ 快捷键说明

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