📄 chg-pxa_ov_camera.c_bak
字号:
{
ovcamprint("ovcamera_init ( -7 ) \n");
goto camera_init_err;
}
//dma channels
p_ovcam_ctx->dma_channels[0] = ci_dma_y;
p_ovcam_ctx->dma_channels[1] = ci_dma_u;
p_ovcam_ctx->dma_channels[2] = ci_dma_v;
// set capture format
ret = ovcamera_set_capture_format(p_ovcam_ctx);
if (ret)
{
ovcamprint("ovcamera_init ( -8 ) \n");
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 == 1600*1200*2 || frame_size == 1280*1024*2){
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 = vw.width;
p_ovcam_ctx->capture_height = 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;
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 );
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;
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -