📄 chg-pxa_ov_camera.c
字号:
}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;}#if 0static 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;}#endifvoid 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); //printk("irqy dcsr %x\n", dcsr); 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) { ovcamprint("<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); //ovcamprint("%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_DESC_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 *ppos){ ovcamera_context_t *ovcam_ctx = g_ovcamera_context; // int offset = 0; ovcamera_context_t *cam_ctx = g_ovcamera_context; int size;// unsigned int frame_size = cam_ctx->capture_width * cam_ctx->capture_height * 2; unsigned int frame_size = cam_ctx->block_size; struct dma_buf_struct *buf_entry; struct list_head *head; int real_size = frame_size; head = &cam_ctx->buf_head; ovcamprint("frame_size =%d\n", frame_size); //if (buf != NULL && count == frame_size && cam_ctx->capture_mode == CAPTURE_STILL_IMAGE) if (buf != NULL && cam_ctx->capture_mode == CAPTURE_STILL_IMAGE) { if (g_camera_control.still_image_rdy == 0){ if (file->f_mode & O_NONBLOCK) return -EAGAIN; else interruptible_sleep_on(&dma_read_wait); //timeout = interruptible_sleep_on_timeout(&dma_read_wait, 120); } cam_ctx->camera_functions->capture_stop(cam_ctx); //jhy for split img g_camera_control.still_image_rdy
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -