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

📄 chg-pxa_ov_camera.c

📁 ov2640驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:
}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 + -