📄 chg-pxa_ov_camera.c
字号:
goto camera_init_err; } // set frame rate ci_set_frame_rate(p_ovcam_ctx->frame_rate); return 0;camera_init_err: ovcamera_deinit(p_ovcam_ctx); return -1; }static int ovcamera_deinit ( p_ovcamera_context_t p_ovcam_ctx ){ int ret; // deinit sensor ret = p_ovcam_ctx->camera_functions->deinit(p_ovcam_ctx); // capture interface deinit ci_deinit(); return ret;}/////////////////////////////////////////////////////////////////////////////////////////////Configure Quick Capture Interface accoding to current setting///////////////////////////////////////////////////////////////////////////////////////////static int ovcamera_set_capture_format(p_ovcamera_context_t p_ovcam_ctx){ int ret; unsigned int frame_size; unsigned int block_number = 0; struct dma_buf_struct *buf_entry; struct list_head *head; CI_IMAGE_FORMAT ci_input_format, ci_output_format; CI_MP_TIMING timing; p_ovcamera_context_t camera_context = p_ovcam_ctx; ovcamprint("ovcamera_set_capture_format( + ) \n"); if (p_ovcam_ctx->cf.in > CAMERA_IMAGE_FORMAT_MAX || p_ovcam_ctx->cf.out > CAMERA_IMAGE_FORMAT_MAX ) { ovcamprint("ovcamera_set_capture_format( -0 ) \n"); return STATUS_WRONG_PARAMETER; } ci_input_format = FORMAT_MAPPINGS[p_ovcam_ctx->cf.in]; ci_output_format = FORMAT_MAPPINGS[p_ovcam_ctx->cf.out]; if (ci_input_format == CI_INVALID_FORMAT || ci_output_format == CI_INVALID_FORMAT) { ovcamprint("ovcamera_set_capture_format( -1 ) \n"); return STATUS_WRONG_PARAMETER; } ci_set_image_format(ci_input_format, ci_output_format); if(ci_input_format == CI_JPEG) { ovcamprint("ovcamera_set_capture_format( +JPEG ) \n"); timing.BFW = timing.BLW = 0; ci_configure_mp(1023,2047, &timing); } else { timing.BFW = timing.BLW = 0; ci_configure_mp(p_ovcam_ctx->vw.width-1, p_ovcam_ctx->vw.height-1, &timing); } ret = p_ovcam_ctx->camera_functions->capture_set_format(p_ovcam_ctx); if (ret) { ovcamprint("ovcamera_set_capture_format( -2 ) \n"); return ret; } switch(p_ovcam_ctx->cf.out) { case CAMERA_IMAGE_FORMAT_RGB565: frame_size = p_ovcam_ctx->vw.width * p_ovcam_ctx->vw.height * 2; p_ovcam_ctx->fifo0_transfer_size = frame_size; p_ovcam_ctx->fifo1_transfer_size = 0; p_ovcam_ctx->fifo2_transfer_size = 0; break; case CAMERA_IMAGE_FORMAT_YCBCR422_PACKED: frame_size = p_ovcam_ctx->vw.width * p_ovcam_ctx->vw.height * 2; p_ovcam_ctx->fifo0_transfer_size = frame_size; p_ovcam_ctx->fifo1_transfer_size = 0; p_ovcam_ctx->fifo2_transfer_size = 0; break; case CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR: frame_size = p_ovcam_ctx->vw.width * p_ovcam_ctx->vw.height * 2; p_ovcam_ctx->fifo0_transfer_size = frame_size / 2; p_ovcam_ctx->fifo1_transfer_size = frame_size / 4; p_ovcam_ctx->fifo2_transfer_size = frame_size / 4; break; case CAMERA_IMAGE_FORMAT_RGB666_PLANAR: frame_size = p_ovcam_ctx->vw.width * p_ovcam_ctx->vw.height * 4; p_ovcam_ctx->fifo0_transfer_size = frame_size; p_ovcam_ctx->fifo1_transfer_size = 0; p_ovcam_ctx->fifo2_transfer_size = 0; break; case CAMERA_IMAGE_FORMAT_RGB666_PACKED: frame_size = p_ovcam_ctx->vw.width * p_ovcam_ctx->vw.height * 3; p_ovcam_ctx->fifo0_transfer_size = frame_size; p_ovcam_ctx->fifo1_transfer_size = 0; p_ovcam_ctx->fifo2_transfer_size = 0; break; case CAMERA_IMAGE_FORMAT_RGB888_PLANAR: frame_size = p_ovcam_ctx->vw.width * p_ovcam_ctx->vw.height * 4; p_ovcam_ctx->fifo0_transfer_size = frame_size; p_ovcam_ctx->fifo1_transfer_size = 0; p_ovcam_ctx->fifo2_transfer_size = 0; break; case CAMERA_IMAGE_FORMAT_JPEG: frame_size = p_ovcam_ctx->vw.width * p_ovcam_ctx->vw.height ; //compression ration > 2:1 p_ovcam_ctx->fifo0_transfer_size = frame_size; p_ovcam_ctx->fifo1_transfer_size = 0; p_ovcam_ctx->fifo2_transfer_size = 0; break; default: return STATUS_WRONG_PARAMETER; break; }#if 0 p_ovcam_ctx->block_size = frame_size; block_number = p_ovcam_ctx->ui_buffer_size / frame_size; p_ovcam_ctx->block_number = block_number > MAX_BLOCK_NUM ? MAX_BLOCK_NUM : block_number; p_ovcam_ctx->block_header = p_ovcam_ctx->block_tail = 0;#endif if ( frame_size <= camera_context->buf_size ) { camera_context->block_size = frame_size; block_number = 0; head = (camera_context->buf_head).next; while(head && head != &(camera_context->buf_head)){ buf_entry = container_of(head, struct dma_buf_struct, queue); if (!buf_entry){ printk("ovcamera_set_capture_format()\n"); printk("<Camera Driver> alloc buffer entry error, NOMEN.\n"); return -ENOMEM; } //block_number += buf_entry->size /frame_size; head = head->next; } block_number = p_ovcam_ctx->ui_buffer_size / frame_size; camera_context->block_number = block_number > MAX_BLOCK_NUM ? MAX_BLOCK_NUM : block_number; camera_context->block_header = camera_context->block_tail = 0; camera_context->block_header_t = 0; camera_context->block_tail_t = 0; // generate dma descriptor chain ret = update_dma_chain(camera_context); } else if (frame_size > 800*600*2){ printk("larger buffer need\n"); camera_context->block_number = 1; ret = update_dma_chain(camera_context); }else { printk("<camera driver> This size of Image isn't supported.\n"); ret = -1; } // generate dma descriptor chain if (ret <0 ) { ovcamprint("ovcamera_set_capture_format( -3 ) \n"); return -1; } ovcamprint("ovcamera_set_capture_format( - ) \n"); return 0;}static int ovcamera_video_capture_start(p_ovcamera_context_t p_ovcam_ctx, unsigned int block_id){ int ret; ovcamprint("ovcamera_video_capture_start( + ) \n"); // init buffer status & capture p_ovcam_ctx->block_header = p_ovcam_ctx->block_tail = block_id; p_ovcam_ctx->block_tail_t = block_id; p_ovcam_ctx->ui_capture_status = CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS; ret = capture_start( p_ovcam_ctx, block_id, 0 ); ovcamprint("ovcamera_video_capture_start( - ) \n"); return ret;}static int ovcamera_video_capture_stop(p_ovcamera_context_t p_ovcam_ctx){ int ret; ovcamprint("ovcamera_video_capture_stop( ) \n"); ret = p_ovcam_ctx->camera_functions->capture_stop( p_ovcam_ctx); dma_transfer_stop( p_ovcam_ctx); if ( !( p_ovcam_ctx->ui_capture_status & CAMERA_STATUS_RING_BUFFER_FULL) ) p_ovcam_ctx->ui_capture_status &= ~CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS; return ret;}static int ovcamera_stillimage_capture(p_ovcamera_context_t p_ovcam_ctx, unsigned int block_id){ int ret; ovcamprint("ovcamera_video_capture_start( + ) \n"); // init buffer status & capture p_ovcam_ctx->block_header = p_ovcam_ctx->block_tail = block_id; p_ovcam_ctx->block_header_t = p_ovcam_ctx->block_tail_t = block_id; p_ovcam_ctx->ui_capture_status = CAMERA_STATUS_STILLIMAGE_CAPTURE_IN_PROCESS; ret = capture_start( p_ovcam_ctx, block_id, 1 ); ovcamprint("ovcamera_video_capture_start( - ) \n"); return ret;}static int pxa_ovcamera_VIDIOCGCAP(p_ovcamera_context_t p_ovcam_ctx,void* param){ struct video_capability vc; strcpy(vc.name,"OmniVsion Camera Driver for OV2640"); vc.maxwidth= 1600; vc.maxheight= 1200; vc.minwidth =8; vc.minheight =8; if(copy_to_user(param,&vc,sizeof(struct video_capability))) return -EFAULT; return 0;}static int pxa_ovcamera_VIDIOCGWIN(p_ovcamera_context_t p_ovcam_ctx,void* param){ struct video_window vw; vw.width= p_ovcam_ctx->vw.width; vw.height= p_ovcam_ctx->vw.height; if(copy_to_user(param,&vw,sizeof(struct video_window))) return -EFAULT; return 0;}static int pxa_ovcamera_VIDIOCSWIN(p_ovcamera_context_t p_ovcam_ctx,void* param){ struct video_window vw; int retval = 0; if(copy_from_user(&vw,param,sizeof(struct video_window))) { ovcamprint("parameter error 0 "); return -EFAULT; } if(vw.width > 1600 || vw.height > 1200 || vw.width < 8 || vw.height < 8) { ovcamprint("parameter error 1"); return -EFAULT; } p_ovcam_ctx->vw.width = (vw.width + 7) / 8; p_ovcam_ctx->vw.width *=8; p_ovcam_ctx->vw.height = (vw.height + 7) / 8; p_ovcam_ctx->vw.height *=8; if(vw.width == 1280 && vw.height == 1024){ if(dma_buf_setup(vw.width, vw.height) <0) return -ENOMEM; } if(vw.width == 1600 && vw.height ==1200){ if (dma_buf_setup(vw.width, vw.height)<0) return -ENOMEM; } p_ovcam_ctx->capture_width = p_ovcam_ctx->vw.width; p_ovcam_ctx->capture_height = p_ovcam_ctx->vw.height; if( ovcamera_set_capture_format(p_ovcam_ctx) <0) retval = -EFAULT; g_camera_control.still_image_rdy = 0; return retval;}static int pxa_ovcamera_VIDIOCSPICT(p_ovcamera_context_t p_ovcam_ctx,void* param){ struct video_picture vp; if(copy_to_user(&vp,param,sizeof(struct video_picture))) return -EFAULT; return 0;}static int pxa_ovcamera_VIDIOCGPICT(p_ovcamera_context_t p_ovcam_ctx,void* param){ struct video_picture vp; if(copy_from_user(&vp,param,sizeof(struct video_picture))) return -EFAULT; return 0;}static int pxa_ovcamera_VIDIOCCAPTURE(p_ovcamera_context_t p_ovcam_ctx,void* param){ int retval = 0; int stream_flag=(int)param; ovcamprint("pxa_ovcamera_VIDIOCCAPTURE ( + ) "); if( 0 < stream_flag ) // Still image mode { //ovcamprint("pxa_ovcamera_VIDIOCCAPTURE ( +1 ) "); if (g_camera_control.capture_status ==1) { printk("<camera driver>Preview should been stoped first!\n"); retval = -EFAULT; return retval; } ovcamera_set_int_mask( p_ovcam_ctx,0x3f9 | 0x0400 ); p_ovcam_ctx->block_header = 0; p_ovcam_ctx->block_tail = 0; p_ovcam_ctx->capture_mode = CAPTURE_STILL_IMAGE; g_camera_control.frames_captured = 0; still_image_mode = 1; retval = ovcamera_set_capture_format(p_ovcam_ctx); if (retval < 0){ printk("<Camera Driver> Setting capture format error.\n"); return -EFAULT; } ovcamera_stillimage_capture ( p_ovcam_ctx,0 ); } else if(0 == stream_flag ) //start video mode { ovcamprint("pxa_ovcamera_VIDIOCCAPTURE ( +2 ) "); if (g_camera_control.capture_status ==1) { printk("<camera driver> Preview have been start yet!\n"); retval = -EFAULT; return retval; } ovcamera_set_int_mask ( p_ovcam_ctx,0x3f9 | 0x0400 ); //g_sensor_mode.preview_mode = g_sensor_mode.capture_mode; p_ovcam_ctx->block_header = 0; p_ovcam_ctx->block_tail = 0; p_ovcam_ctx->block_header_t = 0; p_ovcam_ctx->block_tail_t = 0; p_ovcam_ctx->capture_mode = CAPTURE_VIDEO_DATA; g_camera_control.frames_captured = 0; still_image_mode = 0; first_video_frame = 1; g_camera_control.first_video_frame = 1; retval = ovcamera_set_capture_format(p_ovcam_ctx); ovcamera_video_capture_start ( p_ovcam_ctx,0 ); g_camera_control.capture_status = 1; //start capture } else if( -1 == stream_flag ) //stop video mode { ovcamprint("pxa_ovcamera_VIDIOCCAPTURE ( +3 ) "); if (g_camera_control.capture_status == 0) { printk("<camera driver> Preview been stoped yet!\n"); retval = -EFAULT; return retval; } g_camera_control.capture_status = 0;//stop capture ovcamera_video_capture_stop ( p_ovcam_ctx ); } else { ovcamprint("pxa_ovcamera_VIDIOCCAPTURE ( +0 ) "); } ovcamprint("pxa_ovcamera_VIDIOCCAPTURE ( - ) "); return 0;}static int pxa_ovcamera_VIDIOCGMBUF(p_ovcamera_context_t p_ovcam_ctx,void* param){ struct video_mbuf vm; int i; memset(&vm,0,sizeof(vm));#if 0 vm.size = 256; vm.frames = 3; for(i = 0; i < vm.frames; i++) vm.offsets[i] = p_ovcam_ctx->page_aligned_block_size*i;#endif vm.size = p_ovcam_ctx->buf_size; vm.frames = p_ovcam_ctx->block_number; for(i = 0; i < vm.frames; i++) vm.offsets[i] = p_ovcam_ctx->block_size*i; if(copy_to_user((void*)param,(void*)&vm,sizeof(struct video_mbuf))) return -EFAULT; return 0;}static int pxa_ovcamera_WCAM_VIDIOCSCAMREG(p_ovcamera_context_t p_ovcam_ctx,void* param){ int ret; camerachip_protocol_t cp; if(copy_from_user(&cp,param,sizeof(camerachip_protocol_t))) { ovcamprint("parameter error 0 "); return -EFAULT; } cp.cmd = OVCAMCHIP_CMD_REG_SET; ret = p_ovcam_ctx->camera_functions->command(p_ovcam_ctx, cp.cmd, (void*)&cp); if(copy_to_user((void*)param,(void*)&cp,sizeof(camerachip_protocol_t))) { return -EFAULT; } return ret;}static int pxa_ovcamera_WCAM_VIDIOCGCAMREG(p_ovcamera_context_t p_ovcam_ctx,void* param){ int ret; camerachip_protocol_t cp; if(copy_from_user(&cp,param,sizeof(camerachip_protocol_t))) { ovcamprint("parameter error 0 "); return -EFAULT; } cp.cmd = OVCAMCHIP_CMD_REG_GET; ret = p_ovcam_ctx->camera_functions->command(p_ovcam_ctx, cp.cmd, (void*)&cp); if(copy_to_user((void*)param,(void*)&cp,sizeof(camerachip_protocol_t))) { return -EFAULT; } return ret;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -