📄 chg-pxa_ov_camera.c_bak
字号:
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 + -