/* * camif_open() */ static int camif_open(struct inode *inode, struct file *file) { struct s3c2440camif_dev *pdev; struct s3c2440camif_fh *fh; int ret; if (!has_ov9650) { return -ENODEV; } pdev = &camera; fh = kzalloc(sizeof(*fh),GFP_KERNEL); // alloc memory for filehandle if (NULL == fh) { return -ENOMEM; } fh->dev = pdev; pdev->state = CAMIF_STATE_READY; init_camif_config(fh); ret = init_image_buffer(); // init image buffer. if (ret < 0) { goto error1; } request_irq(IRQ_S3C2440_CAM_C, on_camif_irq_c, IRQF_DISABLED, "CAM_C", pdev); // setup ISRs if (ret < 0) { goto error2; } request_irq(IRQ_S3C2440_CAM_P, on_camif_irq_p, IRQF_DISABLED, "CAM_P", pdev); if (ret < 0) { goto error3; } clk_enable(pdev->clk); // and enable camif clock. soft_reset_camif(); file->private_data = fh; fh->dev = pdev; update_camif_config(fh, 0); return 0; error3: free_irq(IRQ_S3C2440_CAM_C, pdev); error2: free_image_buffer(); error1: kfree(fh); return ret; }
/* * camif_open() */ static int camif_open(struct file *file) { struct video_device *vdev = video_devdata(file); s3c2440camif_dev *pcam = (s3c2440camif_dev *)video_get_drvdata(vdev); int ret; if (!has_ov9650) { return -ENODEV; } file->private_data = vdev; pcam->state = CAMIF_STATE_READY; init_camif_config(pcam); pcam->last_frame=-1; if((ret=request_irq(IRQ_S3C2440_CAM_C, on_camif_irq_c, IRQF_DISABLED, "CAM_C", pcam))<0) // setup ISRs goto error2; if((ret=request_irq(IRQ_S3C2440_CAM_P, on_camif_irq_p, IRQF_DISABLED, "CAM_P", pcam))<0) goto error3; clk_enable(pcam->clk); // and enable camif clock. //soft_reset_camif(); //update_camif_config(pcam, 0); //make sure frames are up-to date if((ret=s3c2410camif_set_format(pcam, pcam->v2f.fmt.pix.pixelformat, pcam->v2f.fmt.pix.width, pcam->v2f.fmt.pix.height))<0) goto error1; //start streaming if (start_capture(pcam, 1) != 0) goto error3; return 0; error3: free_irq(IRQ_S3C2440_CAM_C, pcam); error2: s3c2440camif_deallocate_frame_buf(pcam,S3C2440_FRAME_NUM); error1: return ret; }
static int s3c2410camif_set_format(s3c2440camif_dev *pcam,u32 format,u32 width,u32 height) { int ret=0; u32 scH,scV; int last_state=pcam->state; if(pcam->state == CAMIF_STATE_PREVIEWING || pcam->state == CAMIF_STATE_CODECING) { pcam->cmdcode = CAMIF_CMD_STOP; ret = wait_event_interruptible(pcam->cmdqueue, pcam->cmdcode == CAMIF_CMD_NONE); } disable_irq(IRQ_S3C2440_CAM_C); disable_irq(IRQ_S3C2440_CAM_P); //deallocate old buffers if(!static_allocate) s3c2440camif_deallocate_frame_buf(pcam,S3C2440_FRAME_NUM); //try to get something close from the sensor pcam->sensor.width=width; pcam->sensor.height=height; pcam->sensor.pixel_fmt=V4L2_PIX_FMT_YUYV; pcam->sensor_op->set_format(&pcam->sensor); //copy data back pcam->wndHsize = pcam->sensor.width; pcam->wndVsize = pcam->sensor.height; if(width >pcam->sensor.width) width=pcam->sensor.width; if(height>pcam->sensor.height) height=pcam->sensor.height; //round up to an integer scaling factor scH=pcam->sensor.width/width; scV=pcam->sensor.height/height; width=pcam->sensor.width/scH; height=pcam->sensor.height/scV; //TODO: add support for other formats pcam->v2f.fmt.pix.pixelformat=V4L2_PIX_FMT_YUV422P; pcam->v2f.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; pcam->v2f.fmt.pix.width=width; pcam->v2f.fmt.pix.height=height; pcam->v2f.fmt.pix.bytesperline=width; pcam->v2f.fmt.pix.field=V4L2_FIELD_NONE; pcam->v2f.fmt.pix.bytesperline=width; pcam->v2f.fmt.pix.sizeimage=width*height*2; //setup for YCrCb422p mode //TODO: add switch for other modes pcam->Ysize= pcam->v2f.fmt.pix.width*pcam->v2f.fmt.pix.height; pcam->CbCrsize=pcam->v2f.fmt.pix.width*pcam->v2f.fmt.pix.height/2; if(!static_allocate) { if((ret=s3c2440camif_allocate_frame_buf(pcam,S3C2440_FRAME_NUM))<0) return ret; } //update_camif_config(pcam,0); init_camif_config(pcam); enable_irq(IRQ_S3C2440_CAM_C); enable_irq(IRQ_S3C2440_CAM_P); pcam->last_frame=-1;//wait for fresh frame if(last_state==CAMIF_STATE_CODECING || last_state== CAMIF_STATE_PREVIEWING) return start_capture(pcam,1); else return 0; }