📄 camif.c
字号:
DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}static int inline camif_hw_reg(camif_cfg_t *cfg){ u32 cmd = 0; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin if (cfg->dma_type & CAMIF_CODEC) { rCICOSCPRERATIO = PRE_SHIFT(cfg->sc.shfactor) |PRE_HRATIO(cfg->sc.prehratio)|PRE_VRATIO(cfg->sc.prevratio); rCICOSCPREDST = PRE_DST_WIDTH(cfg->sc.predst_x)|PRE_DST_HEIGHT(cfg->sc.predst_y); /* Differ from Preview */ if (cfg->sc.scalerbypass) cmd |= SCALERBYPASS; if (cfg->sc.scaleup_h & cfg->sc.scaleup_v) cmd |= BIT30|BIT29; rCICOSCCTRL = cmd | MAIN_HRATIO(cfg->sc.mainhratio) |MAIN_VRATIO(cfg->sc.mainvratio); return 0; } else if (cfg->dma_type & CAMIF_PREVIEW) { rCIPRSCPRERATIO = PRE_SHIFT(cfg->sc.shfactor) |PRE_HRATIO(cfg->sc.prehratio)|PRE_VRATIO(cfg->sc.prevratio); rCIPRSCPREDST = PRE_DST_WIDTH(cfg->sc.predst_x)|PRE_DST_HEIGHT(cfg->sc.predst_y); /* Differ from Codec */ if (cfg->fmt & CAMIF_RGB24) { cmd |= RGB_FMT24; } else { /* RGB16 */; } if (cfg->sc.scaleup_h & cfg->sc.scaleup_v) cmd |= BIT29|BIT28; rCIPRSCCTRL = cmd |MAIN_HRATIO(cfg->sc.mainhratio)|S_METHOD |MAIN_VRATIO(cfg->sc.mainvratio); }else { panic("CAMERA:DMA_TYPE Wrong \n"); } DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}/* Configure Pre-scaler control & main scaler control register */static int camif_scaler(camif_cfg_t *cfg){ int tx = cfg->target_x,ty=cfg->target_y; int sx, sy; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin if (tx <= 0 || ty<= 0) panic("CAMERA: Invalid target size \n"); sx = cfg->gc->source_x - 2*cfg->gc->win_hor_ofst; sy = cfg->gc->source_y - 2*cfg->gc->win_ver_ofst; printk("camif_scaler: src(x,y=%d,%d), target(x,y=%d,%d)\n", sx,sy,tx,ty); if (sx <= 0 || sy<= 0) panic("CAMERA: Invalid source size \n"); cfg->sc.modified_src_x = sx; cfg->sc.modified_src_y = sy; /* Pre-scaler control register 1 */ camif_scaler_internal(sx,tx,&cfg->sc.prehratio,&cfg->sc.hfactor); camif_scaler_internal(sy,ty,&cfg->sc.prevratio,&cfg->sc.vfactor); if (cfg->dma_type & CAMIF_PREVIEW) { if ( (sx /cfg->sc.prehratio) <= 640 ) {} else { printk(KERN_INFO "CAMERA: Internal Preview line buffer is 640 pixels\n"); return 1; /* Error */ } } cfg->sc.shfactor = 10-(cfg->sc.hfactor+cfg->sc.vfactor); /* Pre-scaler control register 2 */ cfg->sc.predst_x = sx / cfg->sc.prehratio; cfg->sc.predst_y = sy / cfg->sc.prevratio; /* Main-scaler control register */ cfg->sc.mainhratio = (sx << 8)/(tx << cfg->sc.hfactor); cfg->sc.mainvratio = (sy << 8)/(ty << cfg->sc.vfactor); DPRINTK(" sx %d, sy %d tx %d ty %d \n",sx,sy,tx,ty); DPRINTK(" hfactor %d vfactor %d \n",cfg->sc.hfactor,cfg->sc.vfactor); cfg->sc.scaleup_h = (sx <= tx) ? 1: 0; cfg->sc.scaleup_v = (sy <= ty) ? 1: 0; if ( cfg->sc.scaleup_h != cfg->sc.scaleup_v) { printk("(sx = %d, sy = %d) -> (tx = %d, ty = %d)\n", sx, sy, tx, ty); printk(KERN_ERR "scaleup_h must be same to scaleup_v \n"); } camif_hw_reg(cfg); camif_target_area(cfg); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}/****************************************************** CalculateBurstSize - Calculate the busrt lengths Description: - dstHSize: the number of the byte of H Size.********************************************************/static void camif_g_bsize(u32 hsize, u32 *mburst, u32 *rburst){ u32 tmp; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin tmp = (hsize/4) % 16; switch(tmp) { case 0: *mburst=16; *rburst=16; break; case 4: *mburst=16; *rburst=4; break; case 8: *mburst=16; *rburst=8; break; default: tmp=(hsize/4)%8; switch(tmp) { case 0: *mburst=8; *rburst=8; break; case 4: *mburst=8; *rburst=4; default: *mburst=4; tmp=(hsize/4)%4; *rburst= (tmp) ? tmp: 4; break; } break; } DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin}/* SXGA 1028x1024*//* XGA 1024x768 *//* SVGA 800x600 *//* VGA 640x480 *//* CIF 352x288 *//* QVGA 320x240 *//* QCIF 176x144 *//* ret val 1 : DMA Size Error */#define BURST_ERR 1 static int camif_dma_burst(camif_cfg_t *cfg){ int width = cfg->target_x; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin if (cfg->dma_type & CAMIF_CODEC ) { u32 yburst_m, yburst_r; u32 cburst_m, cburst_r; /* CODEC DMA WIDHT is multiple of 16 */ if (width %16 != 0 ) return BURST_ERR; /* DMA Burst Length Error */ camif_g_bsize(width,&yburst_m,&yburst_r); camif_g_bsize(width/2,&cburst_m,&cburst_r); rCICOCTRL =YBURST_M(yburst_m)|CBURST_M(cburst_m) |YBURST_R(yburst_r)|CBURST_R(cburst_r); } if (cfg->dma_type & CAMIF_PREVIEW) { u32 rgburst_m, rgburst_r; if(cfg->fmt == CAMIF_RGB24) { if (width %2 != 0 ) return BURST_ERR; /* DMA Burst Length Error */ camif_g_bsize(width*4,&rgburst_m,&rgburst_r); } else { /* CAMIF_RGB16 */ if ((width/2) %2 != 0 ) return BURST_ERR; /* DMA Burst Length Error */ camif_g_bsize(width*2,&rgburst_m,&rgburst_r); } rCIPRCTRL = RGBURST_M(rgburst_m) | RGBURST_R(rgburst_r); } DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}static int camif_gpio_init(void){ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin rGPJCON = 0x2aaaaaa; rGPJUP = 0x1fff; DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}#define ROUND_ADD 0x100000int camif_clock_init(camif_gc_t *gc){ unsigned int upll, camclk_div, camclk; DEBUG0("[ %s() S ]\n",__FUNCTION__); if (!gc) camclk = 24000000; else { camclk = gc->camclk; if (camclk > 48000000) printk(KERN_ERR "Wrong Camera Clock\n"); } rCLKCON |= CLKCON_CAMIF; upll = 47980000;/*elfin_get_bus_clk(GET_UPLL);*/ printk(KERN_INFO "CAMERA:Default UPLL %08d and Assing 96Mhz to UPLL\n",upll); { /*rUPLLCON = FInsrt(60, fPLL_MDIV) | FInsrt(4, fPLL_PDIV)| FInsrt(1, fPLL_SDIV); rCLKDIVN |= DIVN_UPLL; For USB */ upll = 47980000;//elfin_get_bus_clk(GET_UPLL); } camclk_div = (upll+ROUND_ADD) /(camclk * 2) -1; rCAMDIVN = CAMCLK_SET_DIV|(camclk_div&0xf); printk(KERN_INFO "CAMERA:upll %08d cam_clk %08d CAMDIVN 0x%08x \n",upll,camclk, rCAMDIVN); rCIIMGCPT = 0; /* Dummy ? */ DEBUG0("[ %s() E ]\n",__FUNCTION__); return 0;}/* Reset Camera IP in CPU Reset External Sensor */void camif_reset(int is, int delay){#if 0 // removed by zeronine rGPGDAT &= ~(0x1 << 12); // DaeHo Jung modified rGPGCON &= ~(0x3 << 24); // DaeHo Jung modified rGPGCON |= (0x1 << 24); // DaeHo Jung modified rGPGUP |= (0x1 << 12); // DaeHo Jung modified#endif DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin switch (is) { case CAMIF_RESET: rCIGCTRL |= GC_SWRST; mdelay(1); rCIGCTRL &= ~GC_SWRST; break; case CAMIF_EX_RESET_AH: /*Active High */ rCIGCTRL &= ~GC_CAMRST; udelay(200); rCIGCTRL |= GC_CAMRST; udelay(delay); rCIGCTRL &= ~GC_CAMRST; break; case CAMIF_EX_RESET_AL: /*Active Low */ rCIGCTRL |= GC_CAMRST; udelay(200); rCIGCTRL &= ~GC_CAMRST; udelay(delay); rCIGCTRL |= GC_CAMRST; break; default: break; } DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin} /* For Camera Operation, * we can give the high priority to REQ2 of ARBITER1 *//* Please move me into proper place * camif_gc_t is not because "rmmod imgsenor" will delete the instance of camif_gc_t */static u32 old_priority; static void camif_bus_priority(int flag){ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin if (flag) { old_priority = rPRIORITY; #if 0 // original rPRIORITY &= ~(3<<7); rPRIORITY |= (1<<7); /* Arbiter 1, REQ2 first */ rPRIORITY &= ~(1<<1); /* Disable Priority Rotate */#else // zeronine changed rPRIORITY &= ~(3<<9); rPRIORITY |= (1<<9); /* Arbiter 1, REQ2 first */ rPRIORITY &= ~(1<<1); /* Disable Priority Rotate for ARB1 */ rPRIORITY &= ~(1<<6); /* Disable Priority Rotate for ARB6 */#endif } else { rPRIORITY = old_priority; } printk("rPRIORITY = 0x%08x\n", rPRIORITY); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin}static void inline camif_clock_off(void){ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin rCIIMGCPT = 0; rCLKCON &= ~CLKCON_CAMIF; DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin}/* Init external image sensor * Before make some value into image senor, * you must set up the pixel clock. */void camif_setup_sensor(void){ DEBUG0("[ %s() S]\n",__FUNCTION__); // lovejin rCISRCFMT |= (0x1<<31); // by zeronine added camif_reset(CAMIF_RESET, 0); camif_gpio_init(); camif_clock_init(NULL);/* Sometimes ,Before loading I2C module, we need the reset signal */ camif_reset(CAMIF_EX_RESET_AL,1000); // DaeHo Jung modified //rCISRCFMT &= ~(0x1<<31); // DaeHo Jung modified // commented by zeronine DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin}void camif_hw_close(camif_cfg_t *cfg){ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin camif_bus_priority(0); camif_clock_off(); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin}void camif_hw_open(camif_gc_t *gc){ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin camif_source_fmt(gc); camif_win_offset(gc); camif_bus_priority(1); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin}/* * Local variables: * tab-width: 8 * c-indent-level: 8 * c-basic-offset: 8 * c-set-style: "K&R" * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -