📄 chg-pxa_ov_camera.c_bak
字号:
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;
}
static int pxa_ovcamera_WCAM_VIDIOCSINFOR(p_ovcamera_context_t p_ovcam_ctx,void* param)
{
int ret;
struct capture_format cf;
if (copy_from_user(&cf, param, sizeof(struct capture_format)))
{
return -EFAULT;
}
p_ovcam_ctx->cf = cf;
ret = ovcamera_set_capture_format ( p_ovcam_ctx );
return ret;
}
static int pxa_ovcamera_WCAM_VIDIOCGINFOR(p_ovcamera_context_t p_ovcam_ctx,void* param)
{
struct capture_format cf;
if (copy_from_user(&cf, param, sizeof(int) * 2))
{
return -EFAULT;
}
cf.out = ci_get_reg_value (cf.in);
if (copy_to_user(param, &cf, sizeof(int) * 2))
{
return -EFAULT;
}
return 0;
}
static int pxa_ovcamera_WCAM_VIDIOCCAMERACHIP(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)))
{
return -EFAULT;
}
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;
}
void pxa_dma_repeat(ovcamera_context_t *ovcam_ctx)
{
pxa_dma_desc *cnt_head, *cnt_tail;
int cnt_block;
cnt_block = (ovcam_ctx->block_header + 1) % ovcam_ctx->block_number;
// FIFO0
(pxa_dma_desc *)cnt_head = (pxa_dma_desc *)ovcam_ctx->fifo0_descriptors_virtual + cnt_block * ovcam_ctx->fifo0_num_descriptors;
cnt_tail = cnt_head + ovcam_ctx->fifo0_num_descriptors - 1;
cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc);
// FIFO1
if (ovcam_ctx->fifo1_transfer_size)
{
cnt_head = (pxa_dma_desc *)ovcam_ctx->fifo1_descriptors_virtual + cnt_block * ovcam_ctx->fifo1_num_descriptors;
cnt_tail = cnt_head + ovcam_ctx->fifo1_num_descriptors - 1;
cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc);
}
// FIFO2
if (ovcam_ctx->fifo2_transfer_size)
{
cnt_head = (pxa_dma_desc *)ovcam_ctx->fifo2_descriptors_virtual + cnt_block * ovcam_ctx->fifo2_num_descriptors;
cnt_tail = cnt_head + ovcam_ctx->fifo2_num_descriptors - 1;
cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc);
}
return;
}
void pxa_dma_continue(ovcamera_context_t *ovcam_ctx)
{
pxa_dma_desc *cnt_head, *cnt_tail;
pxa_dma_desc *next_head;
int cnt_block, next_block;
cnt_block = ovcam_ctx->block_header;
next_block = (cnt_block + 1) % ovcam_ctx->block_number;
// FIFO0
cnt_head = (pxa_dma_desc *)ovcam_ctx->fifo0_descriptors_virtual + cnt_block * ovcam_ctx->fifo0_num_descriptors;
cnt_tail = cnt_head + ovcam_ctx->fifo0_num_descriptors - 1;
next_head = (pxa_dma_desc *)ovcam_ctx->fifo0_descriptors_virtual + next_block * ovcam_ctx->fifo0_num_descriptors;
cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc);
// FIFO1
if (ovcam_ctx->fifo1_transfer_size)
{
cnt_head = (pxa_dma_desc *)ovcam_ctx->fifo1_descriptors_virtual + cnt_block * ovcam_ctx->fifo1_num_descriptors;
cnt_tail = cnt_head + ovcam_ctx->fifo1_num_descriptors - 1;
next_head = (pxa_dma_desc *)ovcam_ctx->fifo1_descriptors_virtual + next_block * ovcam_ctx->fifo1_num_descriptors;
cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc);
}
// FIFO2
if (ovcam_ctx->fifo2_transfer_size)
{
cnt_head = (pxa_dma_desc *)ovcam_ctx->fifo2_descriptors_virtual + cnt_block * ovcam_ctx->fifo2_num_descriptors;
cnt_tail = cnt_head + ovcam_ctx->fifo2_num_descriptors - 1;
next_head = (pxa_dma_desc *)ovcam_ctx->fifo2_descriptors_virtual + next_block * ovcam_ctx->fifo2_num_descriptors;
cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc);
}
return;
}
void pxa_ci_dma_irq_y(int channel, void *data, struct pt_regs *regs)
{
int irq_flag;
int dcsr;
static int dma_repeated=0;
ovcamera_context_t *cam_ctx = g_ovcamera_context;
local_irq_save(irq_flag);
dcsr = DCSR(channel);
DCSR(channel) = dcsr & ~DCSR_STOPIRQEN;
#if 0
if (still_image_mode == 1)
{
if (task_waiting == 1)
{
wake_up_interruptible (&ovcamera_wait_q);
task_waiting = 0;
}
else
{
still_image_ready = 1;
}
}
else if (dma_repeated == 0
&& (ovcam_ctx->block_tail == ((ovcam_ctx->block_header + 2) % ovcam_ctx->block_number)))
{
dma_repeated = 1;
pxa_dma_repeat(ovcam_ctx);
ovcam_ctx->block_header = (ovcam_ctx->block_header + 1) % ovcam_ctx->block_number;
}
else if (dma_repeated == 1 &&
(ovcam_ctx->block_tail != ((ovcam_ctx->block_header + 1) % ovcam_ctx->block_number))
&& (ovcam_ctx->block_tail != ((ovcam_ctx->block_header + 2) % ovcam_ctx->block_number)))
{
pxa_dma_continue(ovcam_ctx);
dma_repeated = 0;
}
else if (dma_repeated == 0)
{
ovcam_ctx->block_header = (ovcam_ctx->block_header + 1) % ovcam_ctx->block_number;
}
if (task_waiting == 1 && !(ovcam_ctx->block_header == ovcam_ctx->block_tail))
{
wake_up_interruptible (&ovcamera_wait_q);
task_waiting = 0;
}
#endif
if ((dcsr & DCSR_ENDINTR)==0)
{
printk("<Camera driver> DMA interrupt isn't trigered by DCSR_ENDINTR.\n");
/*
*DMA BUS ERROR. DROPING CURRENT BUFFER.
*/
cam_ctx->block_header = (cam_ctx->block_header +1) % cam_ctx->block_number;
cam_ctx->block_tail = cam_ctx->block_header;
cam_ctx->block_header_t = (cam_ctx->block_header_t +1) % cam_ctx->block_number;
cam_ctx->block_tail_t = cam_ctx->block_header_t;
goto ret;
}
g_camera_control.frames_captured ++;
if (cam_ctx->capture_mode == CAPTURE_STILL_IMAGE)
{
g_camera_control.still_image_rdy = 1;
cam_ctx->camera_functions->capture_stop(cam_ctx);
//printk("%d : %d image ready, dcsr %X\n",jiffies ,g_camera_control.frames_captured, dcsr);
wake_up(&dma_read_wait);
goto ret;
}
/*
* FOR DV
*/
if (g_camera_control.frames_captured < 6){
cam_ctx->block_header = (cam_ctx->block_header + 1) % cam_ctx->block_number;
cam_ctx->block_tail = cam_ctx->block_header;
cam_ctx->block_header_t = (cam_ctx->block_header_t + 1) % cam_ctx->block_number;
cam_ctx->block_tail_t = cam_ctx->block_header_t;
//printk("%s: Drop frame %d, DCSR=%X.\n", __FUNCTION__, g_camera_control.frames_captured, dcsr);
}else{
cam_ctx->block_tail = cam_ctx->block_header;
cam_ctx->block_header = (cam_ctx->block_header +1) % cam_ctx->block_number;
cam_ctx->block_tail_t = cam_ctx->block_header_t;
cam_ctx->block_header_t = (cam_ctx->block_header_t +1) % cam_ctx->block_number;
wake_up(&dma_wait);
}
ret:
local_irq_restore(irq_flag);
return;
}
void pxa_ci_dma_irq_u(int channel, void *data, struct pt_regs *regs)
{
int dcsr;
dcsr = DCSR(channel);
DCSR(channel) = dcsr & ~DCSR_STOPIRQEN;
if ((dcsr & DCSR_ENDINTR)==0)
printk("<Camera driver> DMA interrupt isn't trigered by DCSR_ENDINTR.\n");
return;
}
void pxa_ci_dma_irq_v(int channel, void *data, struct pt_regs *regs)
{
int dcsr;
dcsr = DCSR(channel);
DCSR(channel) = dcsr & ~DCSR_STOPIRQEN;
if ((dcsr & DCSR_ENDINTR)==0)
printk("<Camera driver> DMA interrupt isn't trigered by DCSR_ENDINTR.\n");
return;
}
void pxa_ovcamera_irq(int irq, void* dev_id, struct pt_regs *regs)
{
int cisr;
static int dma_started=0;
ovcamera_context_t *ovcam_ctx = g_ovcamera_context;
disable_irq(IRQ_CAMERA);
cisr = CISR;
if (cisr & CI_CISR_SOF) //start of frame
{
if(still_image_mode)
{
if( ovcam_ctx->ui_capture_status & CAMERA_STATUS_STILLIMAGE_CAPTURE_IN_PROCESS )
{
if( ovcam_ctx->cf.in == CAMERA_IMAGE_FORMAT_JPEG )
{
if( dma_started)
{
ovcamprint("pxa_ovcamera_irq( ) JPEG END\n");
dma_transfer_stop(ovcam_ctx);
if (task_waiting == 1)
{
ovcamprint("pxa_ovcamera_irq( +1 ) \n");
wake_up_interruptible (&ovcamera_wait_q);
task_waiting = 0;
}
else
{
ovcamprint("pxa_ci_dma_irq_y( +2 ) \n");
still_image_ready = 1;
}
ovcam_ctx->ui_capture_status &=~ CAMERA_STATUS_STILLIMAGE_CAPTURE_IN_PROCESS;
still_image_mode=0;
dma_started = 0;
}
else if(dma_started ==0)
{
dma_started = 1;
ovcamprint("pxa_ovcamera_irq( ) JPEG STAT\n");
}
}
}
}
CISR |= CI_CISR_SOF;
}
if (cisr & CI_CISR_EOF) //end of frame
{
CISR |= CI_CISR_EOF;
dma_started=0;
}
ci_clear_int_status(0xffffffff);
enable_irq(IRQ_CAMERA);
}
/*########################################################################################
/
/ API: Open
/
/########################################################################################*/
static int pxa_ovcamera_open(struct inode *inode, struct file *file)
{
int ret;
ovcamera_context_t *ovcam_ctx;
ovcamprint("pxa_ovcamera_open( + ) \n");
if ( (CKEN & CKEN16_LCD) == 0 ) {
printk( "<Camera Driver> LCD is not enabled.\n" );
down(&(g_camera_control.mutex));
g_camera_control.refcount --;
up(&(g_camera_control.mutex));
return -1;
}
init_waitqueue_head(&ovcamera_wait_q);
ovcam_ctx=g_ovcamera_context;
if(atomic_read(&ovcam_ctx->count))
{
ovcamprint("pxa_ovcamera_open( -1 ) \n");
return -EBUSY;
}
atomic_inc(&ovcam_ctx->count);
ovcam_ctx->vw.width = WIDTH_DEFAULT;
ovcam_ctx->vw.height = HEIGHT_DEFAULT;
ovcam_ctx->cf.in = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR;
ovcam_ctx->cf.out = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR;
ovcam_ctx->frame_rate = FRAMERATE_DEFAULT;
ovcam_ctx->camera_functions = &camerachip_func;
ovcam_ctx->ui_ost_reg_base =0;
ovcam_ctx->ui_gpio_reg_base=0;
ovcam_ctx->ui_ci_reg_base=0;
ovcam_ctx->ui_board_reg_base=0;
#if 0
ovcam_ctx->p_dmadest_virtual=dma_alloc_writecombine(NULL,MAX_DESCRIPTORS_NUM * sizeof(pxa_dma_desc),
(void*)&ovcam_ctx->p_dmadest_physical,GFP_KERNEL);
#endif
ovcam_ctx->p_dmadest_virtual=dma_alloc_writecombine(NULL,MAX_DESC_NUM * sizeof(pxa_dma_desc),
(void*)&ovcam_ctx->p_dmadest_physical,GFP_KERNEL);
if (NULL == ovcam_ctx->p_dmadest_virtual)
{
ovcamprint("can't alloc mem\n");
ovcamprint("pxa_ovcamera_open( -1 ) \n");
goto open_error_0;
}
ovcam_ctx->ui_dmadest_size = MAX_DESC_NUM;
ovcam_ctx->dma_descriptors_virtual = ovcam_ctx->p_dmadest_virtual;
ovcam_ctx->dma_descriptors_physical = ovcam_ctx->p_dmadest_physical;
ovcam_ctx->dma_descriptors_size = MAX_DESC_NUM;
#if 0
ovcam_ctx->ui_buffer_size = BUFFER_SIZE_DEFAULT;
ovcam_ctx->p_buffer_virtual = dma_alloc_writecombine(NULL,ovcam_ctx->ui_buffer_size,
(void*)&ovcam_ctx->p_buffer_physical,GFP_KERNEL);
if( NULL == ovcam_ctx->p_buffer_virtual )
{
ovcamprint("pxa_ovcamera_open( -2 ) \n");
goto open_error_0;
}
#endif
ret = ovcamera_init(ovcam_ctx);
g_camera_control.capture_status = 0;//Added by Gensane
PM_INC_DEV_USER(PM_DEV_CS);
ovcamprint("pxa_ovcamera_open( - ) \n");
return ret;
open_error_0:
return -1;
}
static void pxa_ovcamera_close(struct inode *inode, struct file *file)
{
int free;
struct dma_buf_struct *buf_entry;
struct list_head *next;
ovcamera_context_t *cam_ctx = g_ovcamera_context;
ovcamera_context_t *ovcam_ctx = g_ovcamera_context;
ovcamprint("pxa_ovcamera_close ( )\n");
atomic_dec(&ovcam_ctx->count);
ovcamera_deinit(ovcam_ctx);
if (ovcam_ctx->p_dmadest_virtual)
dma_free_writecombine (NULL, MAX_DESCRIPTORS_NUM * sizeof (pxa_dma_desc),
ovcam_ctx->p_dmadest_virtual,
(int)ovcam_ctx->p_dmadest_physical);
#if 0
if (ovcam_ctx->p_buffer_virtual)
dma_free_writecombine (NULL,ovcam_ctx->ui_buffer_size,
ovcam_ctx->p_buffer_virtual,
(int)ovcam_ctx->p_buffer_physical);
#endif
/*free added alloced buffers*/
next = (cam_ctx->buf_head).next;
free = 0;
while(next != &(cam_ctx->buf_head)){
buf_entry = container_of(next, struct dma_buf_struct, queue);
if (!buf_entry){
printk("%s %d BUG\n", __FUNCTION__, __LINE__);
}
next = next->next;
if (buf_entry->size > PAGE_SIZE)//added alloced buffer size is PAGE_SIZE.
continue;
list_del (next->prev);
if (buf_entry->vaddr){
dma_free_writecombine (NULL, buf_entry->size,(void *)buf_entry->vaddr, (int)buf_entry->paddr);
free += buf_entry->size;
}
kfree(buf_entry);
}
PM_DEC_DEV_USER(PM_DEV_CS);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//API - Read
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static long pxa_ovcamera_read(struct file *file, char __user *buf,
size_t count, loff_t *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -