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

📄 chg-pxa_ov_camera.c_bak

📁 ov2640驱动开发
💻 C_BAK
📖 第 1 页 / 共 5 页
字号:
                ciclk = (13 * cccr_l) * 100;
        else if (cccr_l < 17) // L = [8 - 16]
               ciclk = ((13 * cccr_l) * 100) >> 1;
        else if (cccr_l < 32) // L = [17 - 31]
               ciclk = ((13 * cccr_l) * 100) >> 2;

        // want a divisor that gives us a clock rate as close to, but not more than the given mclk.
        div = (ciclk / (2 * mclk_khz));
	div = div - 1;

	// write cicr4
	value = CICR4;
	value &= ~(CI_CICR4_PCLK_EN | CI_CICR4_MCLK_EN | CI_CICR4_DIV_SMASK<<CI_CICR4_DIV_SHIFT);
	value |= (pclk_enable) ? CI_CICR4_PCLK_EN : 0;
	value |= (mclk_enable) ? CI_CICR4_MCLK_EN : 0;
	value |= div << CI_CICR4_DIV_SHIFT;
	CICR4 = value;   
	ovcamprint("CICR4 =%16x\n",value);		
	
	ovcamprint("ci_set_clock( - ) \n");		
	return; 
}

void ci_set_polarity(int pclk_sample_falling, int hsync_active_low, int vsync_active_low)
{
	unsigned int value;
	
	// write cicr4
	value = CICR4;
	value &= ~(CI_CICR4_PCP | CI_CICR4_HSP | CI_CICR4_VSP);
	value |= (pclk_sample_falling)? CI_CICR4_PCP : 0;
	value |= (hsync_active_low) ? CI_CICR4_HSP : 0;
	value |= (vsync_active_low) ? CI_CICR4_VSP : 0;
	CICR4 = value;   
	
	return; 
}

////////////////////////////////////////////////////////////////////////////////////////
//FIFO control 
////////////////////////////////////////////////////////////////////////////////////////
void ci_set_fifo(unsigned int timeout, CI_FIFO_THRESHOLD threshold, int fifo1_enable,
               int fifo2_enable)
{
	unsigned int value;

	// write citor
	CITOR = timeout; 
	
	// write cifr: always enable fifo 0! also reset input fifo 
	value = CIFR;
	value &= ~(CI_CIFR_FEN0 | CI_CIFR_FEN1 | CI_CIFR_FEN2 | CI_CIFR_RESETF | 
	CI_CIFR_THL_0_SMASK<<CI_CIFR_THL_0_SHIFT);
	value |= (unsigned int)threshold << CI_CIFR_THL_0_SHIFT;
	value |= (fifo1_enable) ? CI_CIFR_FEN1 : 0;
	value |= (fifo2_enable) ? CI_CIFR_FEN2 : 0;
	value |= CI_CIFR_RESETF | CI_CIFR_FEN0;
	CIFR = value;
	return; 
}

///////////////////////////////////////////////////////////////////////////////
//reset fifo of quick capture interface
///////////////////////////////////////////////////////////////////////////////
void ci_reset_fifo(void)
{
	unsigned int value;
	value = CIFR;
	value |= CI_CIFR_RESETF;
	CIFR = value;
}

void ci_set_int_mask(unsigned int mask)
{
	unsigned int value;

	// write mask in cicr0  
	value = CICR0;
	value &= ~CI_CICR0_INTERRUPT_MASK;
	value |= (mask & CI_CICR0_INTERRUPT_MASK);
	CICR0 = value;   
	
	return; 
}

unsigned int ci_get_int_mask(void)
{
	unsigned int value;

	// write mask in cicr0  
	value = CICR0;
	return (value & CI_CICR0_INTERRUPT_MASK);
}

//////////////////////////////////////////////////////////
//Clear all interrupt status
//////////////////////////////////////////////////////////
void ci_clear_int_status(unsigned int status)
{
	// write 1 to clear
	CISR = status;
}

unsigned int ci_get_int_status(void)
{
	int value;

	value = CISR;

	return  value;
}

void ci_set_reg_value(unsigned int reg_offset, unsigned int value)
{
	CI_REG((u32)(ci_regs_base) + reg_offset) = value;
}

int ci_get_reg_value(unsigned int reg_offset)
{
	int value;

	value = CI_REG((u32)(ci_regs_base) + reg_offset);
	return value;
}

void ovcamera_set_int_mask(p_ovcamera_context_t ovcam_ctx, unsigned int mask)
{
	pxa_dma_desc *end_des_virtual;
	int dmaend_irq_enable,i;
	
	/* set QCI interrupt mask to enable/disable interrupt */
	//ci_set_int_mask( mask & CI_CICR0_INTERRUPT_MASK);
	
	//set dma end interrupt
	if ( mask & CAMERA_INTMASK_END_OF_DMA )
	{
		dmaend_irq_enable = 1;
	}
	else
	{
		dmaend_irq_enable = 0;
	}

	// set fifo0 dma chains' flag
	end_des_virtual = (pxa_dma_desc*)ovcam_ctx->fifo0_descriptors_virtual 
		+ ovcam_ctx->fifo0_num_descriptors - 1;
	for(i=0; i<ovcam_ctx->block_number; i++) 
	{
		if (dmaend_irq_enable)
		{
		    end_des_virtual->dcmd |= DCMD_ENDIRQEN;
		}
		else
		{
			end_des_virtual->dcmd &= ~DCMD_ENDIRQEN;
		}
		//end_des_virtual += ovcam_ctx->fifo0_num_descriptors;
		end_des_virtual += (ovcam_ctx->fifo0_num_descriptors + ovcam_ctx->fifo1_num_descriptors +ovcam_ctx->fifo2_num_descriptors );
	}
	
	return;
}

void ovcamerachip_gpio_init ( void )
{
	set_GPIO_mode(  81 | GPIO_ALT_FN_2_IN); /* CIF_DD[0] */
	set_GPIO_mode(  55 | GPIO_ALT_FN_1_IN); /* CIF_DD[1] */
	set_GPIO_mode(  51 | GPIO_ALT_FN_1_IN); /* CIF_DD[2] */
	set_GPIO_mode(  50 | GPIO_ALT_FN_1_IN); /* CIF_DD[3] */
	set_GPIO_mode(  52 | GPIO_ALT_FN_1_IN); /* CIF_DD[4] */
	set_GPIO_mode(  48 | GPIO_ALT_FN_1_IN); /* CIF_DD[5] */
	set_GPIO_mode(  93 | GPIO_ALT_FN_2_IN); /* CIF_DD[6] */
	set_GPIO_mode(  108 | GPIO_ALT_FN_1_IN); /* CIF_DD[7] */
	set_GPIO_mode(  53 | GPIO_ALT_FN_2_OUT); /* CIF_MCLK */
	set_GPIO_mode(  54 | GPIO_ALT_FN_3_IN);  /* CIF_PCLK */
	set_GPIO_mode(  85 | GPIO_ALT_FN_3_IN);  /* CIF_LV */
	set_GPIO_mode(  84 | GPIO_ALT_FN_3_IN);  /* CIF_FV */

//jhy	
	GAFR0_U &= ~0x00000003;
		
	GPDR0 |= 0x00010000;
	GPSR0 |= 0x00010000;
	mdelay(10);
	GAFR3_L &= ~0x00000003;
	GPDR3 |= 0x00000001;
	GPCR3 |= 0x00000001;
	mdelay(10);
	GPSR3 |= 0x00000001;
	mdelay(10);		
	return;
}

void ovcamerachip_clock_set ( unsigned int clk_regs_base, int pclk_enable, int mclk_enable, unsigned int mclk_khz)
{
	unsigned int ciclk=0,value,div,cccr_l;
	
	cccr_l = ( CCCR & 0x0000001F ); 
	
	if ( cccr_l < 8 ) 
	{
		ciclk = ( 13 * cccr_l ) * 100;
	}
	else if ( cccr_l < 17 ) 
	{
		ciclk = (( 13 * cccr_l ) * 100 ) >> 1;
	}
	else if ( cccr_l < 32 )
	{
		ciclk = (( 13 * cccr_l ) * 100 ) >> 2;
	}

	ovcamprint("the mclk = %d \n", mclk_khz);
	

	div = ( ciclk + mclk_khz ) / (2 * mclk_khz ) -1; /* zhudavid: ciclk > mclk_khz ?*/
	
	value = CICR4;
	value &= ~( CI_CICR4_PCLK_EN | CI_CICR4_MCLK_EN | CI_CICR4_DIV_SMASK << CI_CICR4_DIV_SHIFT);
	value |= (mclk_enable) ? CI_CICR4_MCLK_EN : 0;
	value |= (pclk_enable) ? CI_CICR4_PCLK_EN : 0;
	value |= div << CI_CICR4_DIV_SHIFT;
	
	CICR4 = value;
}

int ci_init()
{
	int cken_val;
	(unsigned long*)ci_regs_base = (unsigned long*)ioremap(CI_REGS_PHYS, CI_REG_SIZE);
	if(!ci_regs_base) 
	{
		ovcamprint("Remap Quick Capture Interface I/O registers failed \n");
		return -1;
	}

	// clear all CI registers
	CICR0 = 0x3FF;   // disable all interrupts
	CICR1 = 0;
	CICR2 = 0;
	CICR3 = 0;
	CICR4 = 0;
	CISR = ~0;
	CIFR = 0;
	CITOR = 0;
	
	// enable CI clock
	cken_val = CKEN;
	cken_val |= CKEN24_CAMERA;
	CKEN = cken_val;
	return 0;
}

void ci_deinit()
{
	CKEN &= ~CKEN24_CAMERA;
}

void ci_enable ( int dma_en )
{
	unsigned int value;
	
	value = CICR0;
	value |= CI_CICR0_ENB;
	
	if ( dma_en )
	{
		value |= CI_CICR0_DMA_EN;
	}

	CICR0 = value;
}

int ci_disable ( int quick )
{
	volatile unsigned int value, mask;
	int retry;
	
	value = CICR0;
	if ( quick )
	{
		value &= ~CI_CICR0_ENB;
		mask = CI_CISR_CQD;
	}
	else
	{
		value |= CI_CICR0_DIS;
		mask = CI_CISR_CDD;
	}
	CICR0 = value;
	
	retry = 50;
	while ( 0 < retry-- )
	{
		value = CISR;
		if (value & mask) 
		{
			CISR = mask;
			return 0;
		}
		mdelay(10);
	}
	
	return -1;
}

/*
Generate dma descriptors
Pre-condition: these variables must be set properly
                block_number, fifox_transfer_size 
                dma_descriptors_virtual, dma_descriptors_physical, dma_descirptors_size
Post-condition: these variables will be set
                fifox_descriptors_virtual, fifox_descriptors_physical              
                fifox_num_descriptors 
*/
int update_dma_chain( p_ovcamera_context_t p_ovcam_ctx )
{
	pxa_dma_desc *cur_des_virtual, *cur_des_physical, *last_des_virtual = NULL;
//jhy
	pxa_dma_desc *y_last_virtual = NULL;
	pxa_dma_desc *u_last_virtual = NULL;
	pxa_dma_desc *v_last_virtual = NULL;
	int des_transfer_size, remain_size;
	unsigned int i,j, entry_size, desc_num;
	struct dma_buf_struct *buf_entry;
	struct list_head *cur_node;

	int target_physical;
	int target_virtual;

	p_ovcamera_context_t camera_context = p_ovcam_ctx;
	ovcamprint("update_dma_chain( + ) \n");		
 
	// clear descriptor pointers
	p_ovcam_ctx->fifo0_descriptors_virtual = p_ovcam_ctx->fifo0_descriptors_physical = 0;
	p_ovcam_ctx->fifo1_descriptors_virtual = p_ovcam_ctx->fifo1_descriptors_physical = 0;
	p_ovcam_ctx->fifo2_descriptors_virtual = p_ovcam_ctx->fifo2_descriptors_physical = 0;

	// calculate how many descriptors are needed per frame
	p_ovcam_ctx->fifo0_num_descriptors = ( p_ovcam_ctx->fifo0_transfer_size + SINGLE_DESCRIPTORS_TRANSFER_MAX -1 )
		 / SINGLE_DESCRIPTORS_TRANSFER_MAX;
	p_ovcam_ctx->fifo1_num_descriptors = ( p_ovcam_ctx->fifo1_transfer_size + SINGLE_DESCRIPTORS_TRANSFER_MAX -1 )
		 / SINGLE_DESCRIPTORS_TRANSFER_MAX;
	p_ovcam_ctx->fifo2_num_descriptors = ( p_ovcam_ctx->fifo2_transfer_size + SINGLE_DESCRIPTORS_TRANSFER_MAX -1 )
		 / SINGLE_DESCRIPTORS_TRANSFER_MAX;
	// check if enough memory to generate descriptors
	if ( (p_ovcam_ctx->fifo0_num_descriptors + p_ovcam_ctx->fifo1_num_descriptors + 
 			p_ovcam_ctx->fifo2_num_descriptors) * p_ovcam_ctx->block_number 
			> p_ovcam_ctx->ui_dmadest_size)
	{
		ovcamprint("update_dma_chain( -0 ) \n");		
		return -1;
	}

	// generate fifo0 dma chains
	p_ovcam_ctx->fifo0_descriptors_virtual = (unsigned)p_ovcam_ctx->p_dmadest_virtual;
	p_ovcam_ctx->fifo0_descriptors_physical = (unsigned)p_ovcam_ctx->p_dmadest_physical;
	cur_des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo0_descriptors_virtual;
	cur_des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo0_descriptors_physical;

	
	cur_node = &camera_context->buf_head;
	entry_size = 0;
	desc_num = 0;

	for(i=0; i<p_ovcam_ctx->block_number; i++) 
	{
		// in each iteration, generate one dma chain for one frame
		remain_size = p_ovcam_ctx->fifo0_transfer_size;
		while(remain_size){
			if (desc_num >= camera_context->dma_descriptors_size){
				printk("%s: %d, BUG.\n", __FUNCTION__, __LINE__);
				return -ENOMEM;
			}
			if (entry_size == 0){
				buf_entry = get_list_entry(cur_node);
				if (!buf_entry){
					printk("%s: %d, BUG.\n", __FUNCTION__, __LINE__);
					return -ENOMEM;
				}
				target_physical = (unsigned int)buf_entry->paddr;
				target_virtual = (unsigned int)buf_entry->vaddr;
				entry_size = buf_entry->size;
				cur_node = cur_node->next;
			}
			if (remain_size > FIFO_0_SINGLE_DESC_TRANS_MAX) 
				des_transfer_size = FIFO_0_SINGLE_DESC_TRANS_MAX;
			else
		       		des_transfer_size = remain_size;
			if (entry_size < des_transfer_size){
				des_transfer_size = entry_size;
			}

			cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc);
			cur_des_virtual->dsadr = CIBR0_PHY;       // FIFO0 physical address
			cur_des_virtual->dtadr = target_physical;
			cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32;
			
			if (y_last_virtual){
				y_last_virtual->ddadr = (unsigned)cur_des_physical;
				if (camera_context->capture_mode == CAPTURE_STILL_IMAGE)
					y_last_virtual->ddadr |= 0x1;
				y_last_virtual->dcmd |= DCMD_ENDIRQEN;
				y_last_virtual = NULL;
			}
			// advance pointers
			remain_size -= des_transfer_size;
			entry_size -= des_transfer_size;
			cur_des_virtual++;
			cur_des_physical++;
			target_physical += des_transfer_size;
			camera_context->fifo0_num_descriptors ++;	
			desc_num ++;
		
		}
		last_des_virtual = cur_des_virtual - 1;
		y_last_virtual = last_des_virtual;
		/* setup U Channel*/	
		if (!camera_context->fifo1_descriptors_virtual){
			camera_context->fifo1_descriptors_virtual = (unsigned)cur_des_virtual;
			camera_context->fifo1_descriptors_physical = (unsigned)cur_des_physical;
		}
		remain_size = camera_context->fifo1_transfer_size;
		while(remain_size){
			if (desc_num >= camera_context->dma_descriptors_size){
				printk("%s: %d, BUG.\n", __FUNCTION__, __LINE__);
				return -ENOMEM;
			}
			if (entry_size == 0){
				buf_entry = get_list_entry(cur_node);
				if (!buf_entry){
					printk("%s: %d, BUG.\n", __FUNCTION__, __LINE__);
					return -ENOMEM;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -