📄 camif.c
字号:
cmd = CAMIF_ITU656; } printk("camif_source_fmt, ITU set: CISRCFMT Setting %x\n", cmd); cmd |= SOURCE_HSIZE(gc->source_x)| SOURCE_VSIZE(gc->source_y); printk("camif_source_fmt,size set: CISRCFMT Setting %x\n", cmd); /* Order422 */ cmd |= gc->order422; printk("camif_source_fmt, order: CISRCFMT Setting %x\n", cmd); rCISRCFMT = cmd;#endif printk("camif_source_fmt: rCISRCFMT = 0x%x\n",rCISRCFMT); printk("camif_source_fmt: end\n"); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0 ;}/* * Codec Input YCBCR422 will be Fixed */static int camif_target_fmt(camif_cfg_t *cfg){ u32 cmd = 0; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin if (cfg->dma_type & CAMIF_CODEC) { /* YCBCR setting */ cmd = TARGET_HSIZE(cfg->target_x)| TARGET_VSIZE(cfg->target_y); if ( cfg->fmt & CAMIF_OUT_YCBCR420 ) { cmd |= OUT_YCBCR420|IN_YCBCR422; } else { assert(cfg->fmt & CAMIF_OUT_YCBCR422); cmd |= OUT_YCBCR422|IN_YCBCR422; } rCICOTRGFMT = cmd | cfg->flip; } else { assert(cfg->dma_type & CAMIF_PREVIEW); rCIPRTRGFMT = TARGET_HSIZE(cfg->target_x)|TARGET_VSIZE(cfg->target_y)|cfg->flip; } DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}void camif_change_flip(camif_cfg_t *cfg){ u32 cmd = 0; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin if (cfg->dma_type & CAMIF_CODEC ) { /* YCBCR setting */ cmd = rCICOTRGFMT; cmd &= ~(BIT14|BIT15); /* Clear FLIP Mode */ cmd |= cfg->flip; rCICOTRGFMT = cmd; } else { cmd = rCIPRTRGFMT; cmd &= ~(BIT14|BIT15); cmd |= cfg->flip; rCICOTRGFMT = cmd; } DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin}/* Must: * Before calling this function, * you must use "camif_dynamic_open" * If you want to enable both CODEC and preview * you must do it at the same time. */int camif_capture_start(camif_cfg_t *cfg){ u32 n_cmd = 0; /* Next Command */ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin switch(cfg->exec) { case CAMIF_BOTH_DMA_ON: camif_reset(CAMIF_RESET,0); /* Flush Camera Core Buffer */ rCIPRSCCTRL |= SCALERSTART; rCICOSCCTRL |= SCALERSTART; n_cmd = CAMIF_CAP_PREVIEW_ON|CAMIF_CAP_CODEC_ON; break; case CAMIF_DMA_ON: camif_reset(CAMIF_RESET,0); /* Flush Camera Core Buffer */ if (cfg->dma_type&CAMIF_CODEC) { rCICOSCCTRL |= SCALERSTART; n_cmd = CAMIF_CAP_CODEC_ON; }else { rCIPRSCCTRL |= SCALERSTART; n_cmd = CAMIF_CAP_PREVIEW_ON; } /* wait until Sync Time expires */ /* First settting, to wait VSYNC fall */ /* By VESA spec,in 640x480 @60Hz MAX Delay Time is around 64us which "while" has.*/ while(VSYNC & rCICOSTATUS); break; default: break; } rCIIMGCPT = n_cmd|CAMIF_CAP_ON; DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}int camif_capture_stop(camif_cfg_t *cfg){ u32 n_cmd = rCIIMGCPT; /* Next Command */ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin switch(cfg->exec) { case CAMIF_BOTH_DMA_OFF: rCIPRSCCTRL &= ~SCALERSTART; rCICOSCCTRL &= ~SCALERSTART; n_cmd = 0; break; case CAMIF_DMA_OFF_L_IRQ: /* fall thru */ case CAMIF_DMA_OFF: if (cfg->dma_type&CAMIF_CODEC) { rCICOSCCTRL &= ~SCALERSTART; n_cmd &= ~CAMIF_CAP_CODEC_ON; if (!(n_cmd & CAMIF_CAP_PREVIEW_ON)) n_cmd = 0; }else { rCIPRSCCTRL &= ~SCALERSTART; n_cmd &= ~CAMIF_CAP_PREVIEW_ON; if (!(n_cmd & CAMIF_CAP_CODEC_ON)) n_cmd = 0; } break; default: panic("Unexpected \n"); } rCIIMGCPT = n_cmd; if(cfg->exec == CAMIF_DMA_OFF_L_IRQ) { /* Last IRQ */ if (cfg->dma_type & CAMIF_CODEC) rCICOCTRL |= LAST_IRQ_EN; else rCIPRCTRL |= LAST_IRQ_EN; } #if 0 else { /* to make internal state machine of CAMERA stop */ camif_reset(CAMIF_RESET, 0); }#endif DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}/* LastIRQEn is autoclear */void camif_last_irq_en(camif_cfg_t *cfg){ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin if(cfg->exec == CAMIF_BOTH_DMA_ON) { rCIPRCTRL |= LAST_IRQ_EN; rCICOCTRL |= LAST_IRQ_EN; } else { if (cfg->dma_type & CAMIF_CODEC) rCICOCTRL |= LAST_IRQ_EN; else rCIPRCTRL |= LAST_IRQ_EN; } DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin}static int camif_scaler_internal(u32 srcWidth, u32 dstWidth, u32 *ratio, u32 *shift){ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin if(srcWidth>=64*dstWidth){ printk(KERN_ERR"CAMERA:out of prescaler range: srcWidth /dstWidth = %d(< 64)\n", srcWidth/dstWidth); return 1; } else if(srcWidth>=32*dstWidth){ *ratio=32; *shift=5; } else if(srcWidth>=16*dstWidth){ *ratio=16; *shift=4; } else if(srcWidth>=8*dstWidth){ *ratio=8; *shift=3; } else if(srcWidth>=4*dstWidth){ *ratio=4; *shift=2; } else if(srcWidth>=2*dstWidth){ *ratio=2; *shift=1; } else { *ratio=1; *shift=0; } DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}int camif_g_fifo_status(camif_cfg_t *cfg) { u32 reg; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin if (cfg->dma_type & CAMIF_CODEC) { u32 flag = CO_OVERFLOW_Y|CO_OVERFLOW_CB|CO_OVERFLOW_CR; reg = rCICOSTATUS; if (reg & flag) { printk("CODEC: FIFO error(0x%08x) and corrected\n",reg); /* FIFO Error Count ++ */ rCIWDOFST |= CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR; rCIWDOFST &= ~(CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR); return 1; /* Error */ } } if (cfg->dma_type & CAMIF_PREVIEW) { u32 flag = PR_OVERFLOW_CB|PR_OVERFLOW_CR; reg = rCIPRSTATUS; if (reg & flag) { printk("PREVIEW:FIFO error(0x%08x) and corrected\n",reg); rCIWDOFST |= PR_FIFO_CB|PR_FIFO_CR; rCIWDOFST &= ~(CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR); /* FIFO Error Count ++ */ return 1; /* Error */ } } DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0; /* No Error */}/* Policy: * if codec or preview define the win offset, * other must follow that value. */int camif_win_offset(camif_gc_t *gc ){ u32 h = gc->win_hor_ofst; u32 v = gc->win_ver_ofst; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin /*Clear Overflow */ rCIWDOFST = CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR|PR_FIFO_CB|PR_FIFO_CB; rCIWDOFST = 0; /* ? Dummy */ if (!h && !v) { rCIWDOFST = 0; return 0; } rCIWDOFST = WINOFEN | WINHOROFST(h) | WINVEROFST(v); //rCIWDOFST = WINOFEN | WINVEROFST(v); //rCIWDOFST &= 0x7fffffff; printk("\tcamif_win_offset: CIWDOFST 0x%08x\n", rCIWDOFST ); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}/* * when you change the resolution in a specific camera, * sometimes, it is necessary to change the polarity * -- SW.LEE */static void camif_polarity(camif_gc_t *gc){ u32 cmd = rCIGCTRL; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin cmd = cmd & ~(BIT26|BIT25|BIT24); /* clear polarity */ if (gc->polarity_pclk) cmd |= GC_INVPOLPCLK; if (gc->polarity_vsync) cmd |= GC_INVPOLVSYNC; if (gc->polarity_href) cmd |= GC_INVPOLHREF; rCIGCTRL |= cmd; DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin}int camif_dynamic_open(camif_cfg_t *cfg){ camif_win_offset(cfg->gc); camif_polarity(cfg->gc); DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin if(camif_scaler(cfg)) { printk(KERN_ERR "CAMERA:Preview Scaler, Change WinHorOfset or Target Size\n"); return 1; } camif_target_fmt(cfg); if (camif_dma_burst(cfg)) { printk(KERN_ERR "CAMERA:DMA Busrt Length Error \n"); return 1; } if(camif_malloc(cfg) ) { printk(KERN_ERR " Instead of using consistent_alloc()\n" " lease use dedicated memory allocation for DMA memory\n"); return -1; } camif_pingpong(cfg); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}int camif_dynamic_close(camif_cfg_t *cfg){ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin camif_demalloc(cfg); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}static int camif_target_area(camif_cfg_t *cfg) { DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin u32 rect = cfg->target_x * cfg->target_y; if (cfg->dma_type & CAMIF_CODEC ) { rCICOTAREA = rect; } if (cfg->dma_type & CAMIF_PREVIEW) { rCIPRTAREA = rect; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -