⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chg-pxa_ov_camera.c_bak

📁 ov2640驱动开发
💻 C_BAK
📖 第 1 页 / 共 5 页
字号:

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 + -