meye.c

来自「trident tm5600的linux驱动」· C语言 代码 · 共 2,009 行 · 第 1/4 页

C
2,009
字号
	mutex_lock(&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;	mutex_unlock(&meye.lock);	return 0;}static int vidioc_querycap(struct file *file, void *fh,				struct v4l2_capability *cap){	memset(cap, 0, sizeof(*cap));	strcpy(cap->driver, "meye");	strcpy(cap->card, "meye");	sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev));	cap->version = (MEYE_DRIVER_MAJORVERSION << 8) +		       MEYE_DRIVER_MINORVERSION;	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |			    V4L2_CAP_STREAMING;	return 0;}static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i){	if (i->index != 0)		return -EINVAL;	memset(i, 0, sizeof(*i));	i->index = 0;	strcpy(i->name, "Camera");	i->type = V4L2_INPUT_TYPE_CAMERA;	return 0;}static int vidioc_g_input(struct file *file, void *fh, unsigned int *i){	*i = 0;	return 0;}static int vidioc_s_input(struct file *file, void *fh, unsigned int i){	if (i != 0)		return -EINVAL;	return 0;}static int vidioc_queryctrl(struct file *file, void *fh,				struct v4l2_queryctrl *c){	switch (c->id) {	case V4L2_CID_BRIGHTNESS:		c->type = V4L2_CTRL_TYPE_INTEGER;		strcpy(c->name, "Brightness");		c->minimum = 0;		c->maximum = 63;		c->step = 1;		c->default_value = 32;		c->flags = 0;		break;	case V4L2_CID_HUE:		c->type = V4L2_CTRL_TYPE_INTEGER;		strcpy(c->name, "Hue");		c->minimum = 0;		c->maximum = 63;		c->step = 1;		c->default_value = 32;		c->flags = 0;		break;	case V4L2_CID_CONTRAST:		c->type = V4L2_CTRL_TYPE_INTEGER;		strcpy(c->name, "Contrast");		c->minimum = 0;		c->maximum = 63;		c->step = 1;		c->default_value = 32;		c->flags = 0;		break;	case V4L2_CID_SATURATION:		c->type = V4L2_CTRL_TYPE_INTEGER;		strcpy(c->name, "Saturation");		c->minimum = 0;		c->maximum = 63;		c->step = 1;		c->default_value = 32;		c->flags = 0;		break;	case V4L2_CID_AGC:		c->type = V4L2_CTRL_TYPE_INTEGER;		strcpy(c->name, "Agc");		c->minimum = 0;		c->maximum = 63;		c->step = 1;		c->default_value = 48;		c->flags = 0;		break;	case V4L2_CID_MEYE_SHARPNESS:	case V4L2_CID_SHARPNESS:		c->type = V4L2_CTRL_TYPE_INTEGER;		strcpy(c->name, "Sharpness");		c->minimum = 0;		c->maximum = 63;		c->step = 1;		c->default_value = 32;		/* Continue to report legacy private SHARPNESS ctrl but		 * say it is disabled in preference to ctrl in the spec		 */		c->flags = (c->id == V4L2_CID_SHARPNESS) ? 0 :						V4L2_CTRL_FLAG_DISABLED;		break;	case V4L2_CID_PICTURE:		c->type = V4L2_CTRL_TYPE_INTEGER;		strcpy(c->name, "Picture");		c->minimum = 0;		c->maximum = 63;		c->step = 1;		c->default_value = 0;		c->flags = 0;		break;	case V4L2_CID_JPEGQUAL:		c->type = V4L2_CTRL_TYPE_INTEGER;		strcpy(c->name, "JPEG quality");		c->minimum = 0;		c->maximum = 10;		c->step = 1;		c->default_value = 8;		c->flags = 0;		break;	case V4L2_CID_FRAMERATE:		c->type = V4L2_CTRL_TYPE_INTEGER;		strcpy(c->name, "Framerate");		c->minimum = 0;		c->maximum = 31;		c->step = 1;		c->default_value = 0;		c->flags = 0;		break;	default:		return -EINVAL;	}	return 0;}static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c){	mutex_lock(&meye.lock);	switch (c->id) {	case V4L2_CID_BRIGHTNESS:		sony_pic_camera_command(			SONY_PIC_COMMAND_SETCAMERABRIGHTNESS, c->value);		meye.picture.brightness = c->value << 10;		break;	case V4L2_CID_HUE:		sony_pic_camera_command(			SONY_PIC_COMMAND_SETCAMERAHUE, c->value);		meye.picture.hue = c->value << 10;		break;	case V4L2_CID_CONTRAST:		sony_pic_camera_command(			SONY_PIC_COMMAND_SETCAMERACONTRAST, c->value);		meye.picture.contrast = c->value << 10;		break;	case V4L2_CID_SATURATION:		sony_pic_camera_command(			SONY_PIC_COMMAND_SETCAMERACOLOR, c->value);		meye.picture.colour = c->value << 10;		break;	case V4L2_CID_AGC:		sony_pic_camera_command(			SONY_PIC_COMMAND_SETCAMERAAGC, c->value);		meye.params.agc = c->value;		break;	case V4L2_CID_SHARPNESS:	case V4L2_CID_MEYE_SHARPNESS:		sony_pic_camera_command(			SONY_PIC_COMMAND_SETCAMERASHARPNESS, c->value);		meye.params.sharpness = c->value;		break;	case V4L2_CID_PICTURE:		sony_pic_camera_command(			SONY_PIC_COMMAND_SETCAMERAPICTURE, c->value);		meye.params.picture = c->value;		break;	case V4L2_CID_JPEGQUAL:		meye.params.quality = c->value;		break;	case V4L2_CID_FRAMERATE:		meye.params.framerate = c->value;		break;	default:		mutex_unlock(&meye.lock);		return -EINVAL;	}	mutex_unlock(&meye.lock);	return 0;}static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c){	mutex_lock(&meye.lock);	switch (c->id) {	case V4L2_CID_BRIGHTNESS:		c->value = meye.picture.brightness >> 10;		break;	case V4L2_CID_HUE:		c->value = meye.picture.hue >> 10;		break;	case V4L2_CID_CONTRAST:		c->value = meye.picture.contrast >> 10;		break;	case V4L2_CID_SATURATION:		c->value = meye.picture.colour >> 10;		break;	case V4L2_CID_AGC:		c->value = meye.params.agc;		break;	case V4L2_CID_SHARPNESS:	case V4L2_CID_MEYE_SHARPNESS:		c->value = meye.params.sharpness;		break;	case V4L2_CID_PICTURE:		c->value = meye.params.picture;		break;	case V4L2_CID_JPEGQUAL:		c->value = meye.params.quality;		break;	case V4L2_CID_FRAMERATE:		c->value = meye.params.framerate;		break;	default:		mutex_unlock(&meye.lock);		return -EINVAL;	}	mutex_unlock(&meye.lock);	return 0;}static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,				struct v4l2_fmtdesc *f){	if (f->index > 1)		return -EINVAL;	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)		return -EINVAL;	if (f->index == 0) {		/* standard YUV 422 capture */		memset(f, 0, sizeof(*f));		f->index = 0;		f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;		f->flags = 0;		strcpy(f->description, "YUV422");		f->pixelformat = V4L2_PIX_FMT_YUYV;	} else {		/* compressed MJPEG capture */		memset(f, 0, sizeof(*f));		f->index = 1;		f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;		f->flags = V4L2_FMT_FLAG_COMPRESSED;		strcpy(f->description, "MJPEG");		f->pixelformat = V4L2_PIX_FMT_MJPEG;	}	return 0;}static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,				struct v4l2_format *f){	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)		return -EINVAL;	if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&	    f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)		return -EINVAL;	if (f->fmt.pix.field != V4L2_FIELD_ANY &&	    f->fmt.pix.field != V4L2_FIELD_NONE)		return -EINVAL;	f->fmt.pix.field = V4L2_FIELD_NONE;	if (f->fmt.pix.width <= 320) {		f->fmt.pix.width = 320;		f->fmt.pix.height = 240;	} else {		f->fmt.pix.width = 640;		f->fmt.pix.height = 480;	}	f->fmt.pix.bytesperline = f->fmt.pix.width * 2;	f->fmt.pix.sizeimage = f->fmt.pix.height *			       f->fmt.pix.bytesperline;	f->fmt.pix.colorspace = 0;	f->fmt.pix.priv = 0;	return 0;}static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,				    struct v4l2_format *f){	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)		return -EINVAL;	memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;	switch (meye.mchip_mode) {	case MCHIP_HIC_MODE_CONT_OUT:	default:		f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;		break;	case MCHIP_HIC_MODE_CONT_COMP:		f->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;		break;	}	f->fmt.pix.field = V4L2_FIELD_NONE;	f->fmt.pix.width = mchip_hsize();	f->fmt.pix.height = mchip_vsize();	f->fmt.pix.bytesperline = f->fmt.pix.width * 2;	f->fmt.pix.sizeimage = f->fmt.pix.height *			       f->fmt.pix.bytesperline;	f->fmt.pix.colorspace = 0;	f->fmt.pix.priv = 0;	return 0;}static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,				    struct v4l2_format *f){	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)		return -EINVAL;	if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&	    f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)		return -EINVAL;	if (f->fmt.pix.field != V4L2_FIELD_ANY &&	    f->fmt.pix.field != V4L2_FIELD_NONE)		return -EINVAL;	f->fmt.pix.field = V4L2_FIELD_NONE;	mutex_lock(&meye.lock);	if (f->fmt.pix.width <= 320) {		f->fmt.pix.width = 320;		f->fmt.pix.height = 240;		meye.params.subsample = 1;	} else {		f->fmt.pix.width = 640;		f->fmt.pix.height = 480;		meye.params.subsample = 0;	}	switch (f->fmt.pix.pixelformat) {	case V4L2_PIX_FMT_YUYV:		meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;		break;	case V4L2_PIX_FMT_MJPEG:		meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;		break;	}	mutex_unlock(&meye.lock);	f->fmt.pix.bytesperline = f->fmt.pix.width * 2;	f->fmt.pix.sizeimage = f->fmt.pix.height *			       f->fmt.pix.bytesperline;	f->fmt.pix.colorspace = 0;	f->fmt.pix.priv = 0;	return 0;}static int vidioc_reqbufs(struct file *file, void *fh,				struct v4l2_requestbuffers *req){	int i;	if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)		return -EINVAL;	if (req->memory != V4L2_MEMORY_MMAP)		return -EINVAL;	if (meye.grab_fbuffer && req->count == gbuffers) {		/* already allocated, no modifications */		return 0;	}	mutex_lock(&meye.lock);	if (meye.grab_fbuffer) {		for (i = 0; i < gbuffers; i++)			if (meye.vma_use_count[i]) {				mutex_unlock(&meye.lock);				return -EINVAL;			}		rvfree(meye.grab_fbuffer, gbuffers * gbufsize);		meye.grab_fbuffer = NULL;	}	gbuffers = max(2, min((int)req->count, MEYE_MAX_BUFNBRS));	req->count = gbuffers;	meye.grab_fbuffer = rvmalloc(gbuffers * gbufsize);	if (!meye.grab_fbuffer) {		printk(KERN_ERR "meye: v4l framebuffer allocation"				" failed\n");		mutex_unlock(&meye.lock);		return -ENOMEM;	}	for (i = 0; i < gbuffers; i++)		meye.vma_use_count[i] = 0;	mutex_unlock(&meye.lock);	return 0;}static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf){	int index = buf->index;	if (index < 0 || index >= gbuffers)		return -EINVAL;	memset(buf, 0, sizeof(*buf));	buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;	buf->index = index;	buf->bytesused = meye.grab_buffer[index].size;	buf->flags = V4L2_BUF_FLAG_MAPPED;	if (meye.grab_buffer[index].state == MEYE_BUF_USING)		buf->flags |= V4L2_BUF_FLAG_QUEUED;	if (meye.grab_buffer[index].state == MEYE_BUF_DONE)		buf->flags |= V4L2_BUF_FLAG_DONE;	buf->field = V4L2_FIELD_NONE;	buf->timestamp = meye.grab_buffer[index].timestamp;	buf->sequence = meye.grab_buffer[index].sequence;	buf->memory = V4L2_MEMORY_MMAP;	buf->m.offset = index * gbufsize;	buf->length = gbufsize;	return 0;}static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf){	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)		return -EINVAL;	if (buf->memory != V4L2_MEMORY_MMAP)		return -EINVAL;	if (buf->index < 0 || buf->index >= gbuffers)		return -EINVAL;	if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED)		return -EINVAL;	mutex_lock(&meye.lock);	buf->flags |= V4L2_BUF_FLAG_QUEUED;	buf->flags &= ~V4L2_BUF_FLAG_DONE;	meye.grab_buffer[buf->index].state = MEYE_BUF_USING;	kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int));	mutex_unlock(&meye.lock);	return 0;}static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf){	int reqnr;	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)		return -EINVAL;	if (buf->memory != V4L2_MEMORY_MMAP)		return -EINVAL;

⌨️ 快捷键说明

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