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

📄 s3c2440_camif.c

📁 2440mmc-and-camera-linux-driver 2440mmc-and-camera-linux-driver
💻 C
📖 第 1 页 / 共 3 页
字号:
				break;			}		case VIDIOC_ENUMINPUT:			{				struct v4l2_input *vi = arg;				if (vi->index < 0 || vi->index >= 1) {					DPRINTK("ENUMINPUT outof range input=%d\n", vi->index);					return -EINVAL;				}				*vi = dev->source.input;				DPRINTK("VIDIOC_ENUMINPUT\n");				break;			}		case VIDIOC_QUERYCTRL:			{				struct v4l2_queryctrl *qc = arg;				int index;				index = find_queryctrl(qc->id);				if (-EINVAL == index) {					qc->flags = V4L2_CTRL_FLAG_DISABLED;					break;				}				if (index < 0)					return -EINVAL;#if 0				capture_control[index].category = qc->category;				memcpy(capture_control[index].group, qc->group,						sizeof(qc->group));#else				memcpy(qc, &capture_control[index], 						sizeof(struct v4l2_queryctrl));#endif				DPRINTK("VIDIOC_QUERYCTRL\n");				break;			}		case VIDIOC_G_CTRL:			{				struct v4l2_control *vc = arg;				int index;				index = find_queryctrl(vc->id);				if (index < 0)					return -EINVAL;				vc->value = dev->source.control[index];				DPRINTK("VIDIOC_G_CTRL\n");				break;			}		case VIDIOC_S_CTRL:			{				struct v4l2_control *vc = arg;				int index;				index = find_queryctrl(vc->id);				if (index < 0)					return -EINVAL;#if 0 // needless				/* memcpy */				dev->source.control[index] = vc->value;#endif				hw_capture_control(dev, index, vc);				DPRINTK("VIDIOC_S_CTRL\n");				break;			}#if 0 // NEEDLESS		case VIDIOC_QUERYMENU:			{				DPRINTK("VIDIOC_QUERYMENU\n");				break;			}		case VIDIOC_REQBUFS: 			{				struct v4l2_requestbuffers *req = arg;				if (o->noncapturing) {					printk("REQBUFS illegal in non-capturing open\n");					return -EPERM;				}				if (dev->stream_buffers_mapped) {					printk("Can't request buffers if buffers are "		                  "already mapped\n");					return -EPERM;				}								mmap_unrequest_buffers(dev);#if 0 // TODO				capture_begin(dev);#endif				if (!mmap_request_buffers(dev, req))					return -EINVAL;				DPRINTK("VIDIOC_REQBUFS\n");				break;			}		case VIDIOC_G_PARM:			{				struct v4l2_streamparm *sp = arg;				if (sp->type != V4L2_BUF_TYPE_CAPTURE) {					printk("G_PARM Bad parameter\n");					return -EINVAL;				}				sp->parm.capture = dev->capture;				DPRINTK("VIDIOC_G_PARM\n");				break;			}		case VIDIOC_S_PARM:			{				struct v4l2_streamparm *sp = arg;				struct v4l2_captureparm *vp = &sp->parm.capture;				if (vp->capturemode & ~dev->capture.capability) {					printk("PARM unsupported capture capability %08X\n",							vp->capturemode);					return -EINVAL;				}				if ((dev->capture.capability & V4L2_CAP_TIMEPERFRAME) &&						vp->timeperframe < 10000) {					printk("PARM time per frame out of range %ld\n",							vp->timeperframe);					return -EINVAL;				}				if (vp->capturemode != dev->capture.capturemode &&						!o->noncapturing && dev->streaming) {					printk("???\n");					return -EINVAL;				}				if (o->noncapturing)					break; /// ??? - BUSHI				if (vp->capturemode != dev->capture.capturemode) {					dev->capture.capturemode = vp->capturemode;#if 0 // TODO					capture_new_format(dev);#endif				}#if 0 // TODO, needless ??? - BUSHI				if ((vp->capturemode & V4L2_CAP_TIMEPERFRAME) &&						vp->timeperframe >= dev->videc.frame_period)					dev->capture.timeperframe = vp->timeperframe;				else					dev->capture.timeperframe = dev->videc.frame_period;#endif				DPRINTK("VIDIOC_S_PARM\n");				break;			}		case VIDIOC_G_STD:			{				struct v4l2_standard *std = arg;				DPRINTK("VIDIOC_G_STD\n");				v4l2_video_std_construct(std, 0, 0);				break;			}		case VIDIOC_S_STD:			{					// TODO				DPRINTK("VIDIOC_S_STD\n");				break;			}		case VIDIOC_ENUMSTD:			{					// TODO				DPRINTK("VIDIOC_ENUMSTD\n");				break;			}		case VIDIOC_QUERYBUF:			{				struct v4l2_buffer *buf = arg;		        int i;				if (o->noncapturing) {					printk("QUERYBUF illegal in non-capturing open\n");						return -EPERM;				}				i = buf->index;				if (i<0 || i >= MAX_NUM_FRAMES ||						!dev->stream_buf[i].requested ||						(buf->type & V4L2_BUF_TYPE_field) !=						(dev->stream_buf[i].vidbuf.type & V4L2_BUF_TYPE_field)) {					printk("QUERYBUF bad parameter\n");					return -EINVAL;					}				*buf = dev->stream_buf[i].vidbuf;				DPRINTK("VIDIOC_QUERYBUF\n");				break;			}		case VIDIOC_QBUF:			{				struct v4l2_buffer *buf = arg;		        if (o->noncapturing) {					printk("QBUF illegal in non-capturing open\n");					return -EPERM;				}				if (!dev->stream_buffers_mapped) {					printk("QBUF no buffers are mapped\n");					return -EINVAL;				}#if 0 // TODO				if (!capture_queuebuffer(dev, buf))					return -EINVAL;#endif				DPRINTK("VIDIOC_QBUF\n");				break;			}		case VIDIOC_DQBUF:			{				struct v4l2_buffer *buf = arg;				if (o->noncapturing) {					printk("DQBUF illegal in non-capturing open\n");						return -EPERM;				}#if 0 // TODO				if (!capture_dequeuebuffer(dev, buf))					return -EINVAL;#endif				DPRINTK("VIDIOC_DQBUF\n");				break;			}		case VIDIOC_STREAMON:			{				unsigned long *type = arg;				if (o->noncapturing) {					printk("STREAMON illegal in non-capturing open\n");					return -EPERM;				}#if 0 // TODO				if (!capture_streamon(dev, *type))					return -EINVAL;#endif				DPRINTK("VIDIOC_STREAMON\n");				break;			}		case VIDIOC_STREAMOFF:			{				unsigned long *type = arg;				if (o->noncapturing) {					printk("STREAMOFF illegal in non-capturing open\n");					return -EPERM;				}#if 0 // TODO				capture_streamoff(dev, *type);#endif				DPRINTK("VIDIOC_STREAMOFF\n");				break;			}		case VIDIOC_G_PERF:			{				memcpy(arg, &dev->perf, sizeof(dev->perf));				DPRINTK("VIDIOC_G_PERF\n");				break;			}		case VIDIOC_G_WIN:		case VIDIOC_S_WIN:		case VIDIOC_ENUM_FBUFFMT:		case VIDIOC_G_FBUF:		case VIDIOC_S_FBUF:		case VIDIOC_G_COMP:		case VIDIOC_S_COMP:		case VIDIOC_PREVIEW:		case VIDIOC_G_TUNER:		case VIDIOC_S_TUNER:		case VIDIOC_G_FREQ:		case VIDIOC_S_FREQ:		case VIDIOC_G_AUDIO:		case VIDIOC_S_AUDIO:#endif // NEEDLESS		default:			return -ENOIOCTLCMD; // return to V4L2	}	return 0;}static long v4l2_cam_read(void *id, char *buf, unsigned long count, int noblock){	struct device_open *o = (struct device_open *)id;	struct s3c2440_camif *dev = o->dev;	if (o->noncapturing) {		printk("read() illegal in non-capturing open\n");		return -EPERM;	}	if (dev->streaming) {		printk("Can't read() when streaming is on\n");		return -EPERM;	}	if (IS_CAM(CAM_CAPTURING))		wait_for_completion(&dev->capture_done);	if (!dev->captured)		capture_frame(dev);	if (!dev->captured) {		DPRINTK("Can't grab frames!\n");		return 0;	}	dev->captured = 0;	return capture_read(dev, buf, count);}#if 0 // needlessstatic int v4l2_cam_mmap(void *id, struct vm_area_struct *vma){	return -EPERM;}static long v4l2_cam_write(void *id, const char *buf, unsigned long count, int noblock){	return -EPERM;}#endifstatic int v4l2_cam_poll(void *id, struct file *file, poll_table * table){	struct device_open *o = (struct device_open *)id;	struct s3c2440_camif *dev = o->dev;	if (o->noncapturing) {		DPRINTK("poll() illegal in non-capturing open\n");		return POLLERR;	}	if (!IS_CAM(CAM_CAPTURING)) {		__pre_capture_frame(dev);		poll_wait(file, &(dev->capture_done.wait), table);		__post_capture_frame(dev);	} else {		poll_wait(file, &(dev->capture_done.wait), table);	}	return (dev->captured) ? (POLLIN | POLLRDNORM) : 0;}static int v4l2_cam_initdone (struct v4l2_device *v){	struct s3c2440_camif *dev = (struct s3c2440_camif *)v;	struct v4l2_pix_format *cfmt = &(dev->clientfmt);	struct video_source *src = &(dev->source);	DPRINTK("%s():\n", __FUNCTION__);	cfmt->width = 240;	cfmt->height = 160;	cfmt->depth = 16;	cfmt->pixelformat = V4L2_PIX_FMT_RGB565;	cfmt->sizeimage = cfmt->width * (cfmt->depth+7) / 8 * cfmt->height;	s3c2440_camif_cfg.use_vpost = 0; /* Not supported */	s3c2440_camif_cfg.dev = dev;	src->input.index = 0;	src->input.type = V4L2_INPUT_TYPE_CAMERA;	src->input.capability = 0;	src->control[VCTRL_BRIGHTNESS] =		capture_control[VCTRL_BRIGHTNESS].default_value;		return 0;}int s3c2440_camif_register_camhw(struct s3c2440_cam_hw *camhw){	if (camif.hw)		return -EBUSY;	camif.hw = camhw;	s3c2440_camif_cfg.src_x = camhw->max_width;	s3c2440_camif_cfg.src_y = camhw->max_height;	hw_control_func[VCTRL_BRIGHTNESS] = camhw->encode_brightness;	hw_control_func[VCTRL_REDBALANCE] = camhw->encode_redbalance;	hw_control_func[VCTRL_BLUEBALANCE] = camhw->encode_bluebalance;	hw_control_func[VCTRL_AUTOWHITEBALANCE] = camhw->encode_autowhitebalance;	hw_control_func[VCTRL_EXPOSURE] = camhw->encode_exposure;		snprintf(camif.source.input.name, 31, "%s::%s", 			camif.v.name, &(camhw->name[0]));	return 0;}int s3c2440_camif_unregister_camhw(struct s3c2440_cam_hw *camhw){	if (!camif.hw || camif.hw != camhw)		return -ENODEV;	if (camif.open_count)		return -EBUSY;	camif.hw = NULL;	snprintf(camif.source.input.name, 31, "%s", camif.v.name);	return 0;}void inline config_camif_v4l2(void){	DPRINTK("%s():\n", __FUNCTION__);	sprintf(camif.v.name,"%s","S3C2440_CAMIF");	camif.v.priv = (void*)&camif;	camif.v.open = v4l2_cam_open;	camif.v.close = v4l2_cam_close;	camif.v.read = v4l2_cam_read;	camif.v.ioctl = v4l2_cam_ioctl;	camif.v.poll = v4l2_cam_poll;#if 0 // needless	camif.v.mmap = v4l2_cam_mmap;	camif.v.write = v4l2_cam_write;#endif	camif.v.initialize = v4l2_cam_initdone;	camif.hw = NULL;}int __init s3c2440_camif_initialize(void){	int ret = 0;	DPRINTK("%s():\n", __FUNCTION__);	s3c2440_camif_init();	init_completion(&camif.capture_done);	INIT_TQUEUE(&cam_s_task, cam_s_task_handler, (void*)&s3c2440_camif_cfg);	camif_yuv_buf = 			consistent_alloc(GFP_KERNEL, YUV_IMG_BUF_SIZE, &camif_yuv_buf_dma);	camif_rgb_buf = 			consistent_alloc(GFP_KERNEL, RGB_IMG_BUF_SIZE, &camif_rgb_buf_dma);	if (!camif_yuv_buf || !camif_rgb_buf ) {		ret = -ENOMEM;		goto mem_err;	}	memset(camif_yuv_buf, 0, YUV_IMG_BUF_SIZE);	memset(camif_rgb_buf, 0, RGB_IMG_BUF_SIZE);	if ((ret = request_irq(IRQ_CAM_S, s3c2440_camif_isr_s, SA_INTERRUPT,			"CAM_S", NULL))) {		printk("request_irq(CAM_S) failed.\n");		goto err_irq_s;	}	disable_irq(IRQ_CAM_S);	config_camif_v4l2();		if ((ret = v4l2_register_device ((struct v4l2_device *)&camif)) != 0) {		printk("V4L2 registering failed!\n");		goto error_v4l2_register;	}	init_yuvtable();#ifdef MODULE	/* CPU : FIXME */	flush_scheduled_tasks();#endif	return 0;error_v4l2_register:	free_irq(IRQ_CAM_S, NULL);err_irq_s:	s3c2440_camif_deinit();mem_err:	if (camif_yuv_buf)		consistent_free(camif_yuv_buf, YUV_IMG_BUF_SIZE , camif_yuv_buf_dma);	if (camif_rgb_buf)		consistent_free(camif_rgb_buf, RGB_IMG_BUF_SIZE , camif_rgb_buf_dma);	return ret;}void __exit s3c2440_camif_exit(void){	DPRINTK("%s():\n", __FUNCTION__);	disable_irq(IRQ_CAM_S);	complete(&camif.capture_done);	flush_scheduled_tasks();	v4l2_unregister_device((struct v4l2_device *) &camif);		s3c2440_camif_deinit();	free_irq(IRQ_CAM_S, NULL);	if (camif_yuv_buf)		consistent_free(camif_yuv_buf, YUV_IMG_BUF_SIZE , camif_yuv_buf_dma);	if (camif_rgb_buf)		consistent_free(camif_rgb_buf, RGB_IMG_BUF_SIZE , camif_rgb_buf_dma);}module_exit(s3c2440_camif_exit);module_init(s3c2440_camif_initialize);MODULE_LICENSE("GPL");EXPORT_SYMBOL(s3c2440_camif_register_camhw);EXPORT_SYMBOL(s3c2440_camif_unregister_camhw);

⌨️ 快捷键说明

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