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

📄 camif.c

📁 it s a source code for how to integrate your tvp5150 decoder with driver and how to capture an image
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *   Copyright (C) 2004 Samsung Electronics  *       SW.LEE <hitchcar@samsung.com> *    * This file is subject to the terms and conditions of the GNU General Public * License 2. See the file COPYING in the main directory of this archive * for more details. */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/irq.h>//#include <linux/tqueue.h>	/* Helios 2.4 侩 Helios 2.6俊绰 绝栏骨肺 力芭窃 by lovejin *///#include <linux/locks.h>  /* Helios 2.4 侩 Helios 2.6俊绰 绝栏骨肺 力芭窃 by lovejin */#include <linux/completion.h>#include <linux/delay.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <linux/miscdevice.h>#include <linux/wait.h>#include <linux/miscdevice.h>#include <asm/io.h>#include <asm/semaphore.h>#include <asm/hardware.h>#include <asm/uaccess.h>//#include <asm/arch/s3c2410.h>//#include <asm/arch/s3c2440.h> /* Helios 2.4 侩 */#include <asm/arch/map.h> /* Helios 2.6 侩 by lovejin*/#include <asm/arch/bitfield.h> /* Helios 2.6侩, Fld() 鞍篮 概农肺 锭巩俊 by lovejin *///#define SW_DEBUG#include "heliosCam.h"	// by lovejin#include "camif.h"#include "videodev.h"#include "miscdevice.h"/* 叼滚彪 皋矫瘤侩 by lovejin *///#define DEBUG0(args...)	printk(args)//#define DEBUG1(args...) printk(args) //#define DEBUG2(args...) printk(args) #define DEBUG0(args...)#define DEBUG1(args...)#define DEBUG2(args...)static int camif_dma_burst(camif_cfg_t *);static int camif_scaler(camif_cfg_t *);static const char *camif_version =        "$Id: camif.c,v 1.10 2004/06/04 04:24:14 swlee Exp $";    /* For SXGA Image */#define RESERVE_MEM  4*1024*1024#define YUV_MEM      2*1024*1024#define RGB_MEM      (RESERVE_MEM - YUV_MEM)#define MEM_SIZE     128*1024*1024static int camif_malloc(camif_cfg_t *cfg){    unsigned int t_size;    unsigned int daon = cfg->target_x *cfg->target_y;		DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin    if(cfg->dma_type & CAMIF_CODEC) {        if (cfg->fmt & CAMIF_OUT_YCBCR420) {            t_size = daon * 3 / 2 ;        }        else  { t_size = daon * 2; /* CAMIF_OUT_YCBCR422 */ }        t_size = t_size *cfg->pp_num;#ifndef SAMSUNG_SXGA_CAM//      cfg->pp_virt_buf = consistent_alloc(GFP_KERNEL, t_size, &cfg->pp_phys_buf); /* Helios 2.4 侩 *///      cfg->pp_virt_buf = dma_alloc_coherent(NULL, t_size, &cfg->pp_phys_buf, GFP_KERNEL); /* Helios 2.6 侩 by lovejin*/#if 1 // helios        printk(KERN_INFO "Reserving High RAM Addresses \n");        cfg->pp_phys_buf = PHYS_OFFSET + (MEM_SIZE - RESERVE_MEM);        cfg->pp_virt_buf = ioremap_nocache(cfg->pp_phys_buf,YUV_MEM);#endif#else        printk(KERN_INFO "Reserving High RAM Addresses \n");        cfg->pp_phys_buf = PHYS_OFFSET + (MEM_SIZE - RESERVE_MEM);        cfg->pp_virt_buf = ioremap_nocache(cfg->pp_phys_buf,YUV_MEM);#endif        if ( !cfg->pp_virt_buf ) {            printk(KERN_ERR"CAMERA:Failed to request YCBCR MEM\n");			DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin            return -ENOMEM;        }        memset(cfg->pp_virt_buf, 0, t_size);        cfg->pp_totalsize = t_size;		DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin        return 0;    }    if ( cfg->dma_type & CAMIF_PREVIEW ) {        if (cfg->fmt & CAMIF_RGB16)             t_size = daon * 2; /*  4byte per two pixel*/        else {            assert(cfg->fmt & CAMIF_RGB24);            t_size = daon * 4; /* 4byte per one pixel */        }        t_size = t_size * cfg->pp_num;	//printk("debug>> memory size %d(0x%08x)\n", t_size, t_size);#ifndef SAMSUNG_SXGA_CAM//		cfg->pp_virt_buf = consistent_alloc(GFP_KERNEL, t_size, &cfg->pp_phys_buf);  /* Helios 2.4 侩 *///		cfg->pp_virt_buf = dma_alloc_coherent(NULL, t_size, &cfg->pp_phys_buf, GFP_KERNEL); /* Helios 2.6 侩 by lovejin*/#if 1 // helios        printk(KERN_INFO "Reserving High RAM Addresses \n");        cfg->pp_phys_buf = PHYS_OFFSET + (MEM_SIZE - RESERVE_MEM ) + YUV_MEM;        cfg->pp_virt_buf = ioremap_nocache(cfg->pp_phys_buf,RGB_MEM);#endif#else        printk(KERN_INFO "Reserving High RAM Addresses \n");        cfg->pp_phys_buf = PHYS_OFFSET + (MEM_SIZE - RESERVE_MEM ) + YUV_MEM;        cfg->pp_virt_buf = ioremap_nocache(cfg->pp_phys_buf,RGB_MEM);#endif        if ( !cfg->pp_virt_buf ) {             printk(KERN_ERR"CAMERA:Failed to request RGB MEM\n");			DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin            return -ENOMEM;        }        memset(cfg->pp_virt_buf, 0, t_size);        cfg->pp_totalsize = t_size;		DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin        return 0;    }		DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin    return 0;       /* Never come. */}static int camif_demalloc(camif_cfg_t *cfg){		DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin#ifndef SAMSUNG_SXGA_CAM#if 0 // original by lovejin    if ( cfg->pp_virt_buf ) {//        consistent_free(cfg->pp_virt_buf,cfg->pp_totalsize,cfg->pp_phys_buf); /* Helios 2.6 侩 by lovejin */		dma_alloc_coherent(NULL, cfg->pp_totalsize, cfg->pp_virt_buf, cfg->pp_phys_buf); /* Helios 2.6 侩 by lovejin*/        cfg->pp_virt_buf = 0;    }#endif#if 1 // helios by lovejin    iounmap(cfg->pp_virt_buf);    cfg->pp_virt_buf = 0;#endif#else    iounmap(cfg->pp_virt_buf);    cfg->pp_virt_buf = 0;#endif	DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin    return 0;}/*  * advise a person to use this func in ISR  * index value indicates the next frame count to be used  */int camif_g_frame_num(camif_cfg_t *cfg){    int index = 0;		DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin    if (cfg->dma_type & CAMIF_CODEC ) {        index = FRAME_CNT(rCICOSTATUS);        DPRINTK("CAMIF_CODEC frame %d \n", index);    }    else {        assert(cfg->dma_type & CAMIF_PREVIEW );        index = FRAME_CNT(rCIPRSTATUS);        DPRINTK("CAMIF_PREVIEW frame %d  0x%08X \n", index, CIPRSTATUS);    }    cfg->now_frame_num = (index + 2) % 4; /* When 4 PingPong */	DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin    return index; /* meaningless */}static int camif_pp_codec(camif_cfg_t *cfg){    u32 i, c_size; /* Cb,Cr size */    u32 one_p_size;    u32 daon = cfg->target_x * cfg->target_y;		DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin    	if (cfg->fmt & CAMIF_OUT_YCBCR420) {        c_size = daon /4;    }    else {        assert(cfg->fmt & CAMIF_OUT_YCBCR422);        c_size = daon /2;    }    switch ( cfg->pp_num ) {        case 1 :            for ( i =0 ; i < 4; i=i+1) {                cfg->img_buf[i].virt_y = cfg->pp_virt_buf;                cfg->img_buf[i].phys_y = cfg->pp_phys_buf;                cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + daon;                 cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + daon;                cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + daon + c_size;                cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + daon + c_size;                rCICOYSA(i)  =  cfg->img_buf[i].phys_y;                rCICOCBSA(i) =  cfg->img_buf[i].phys_cb;                rCICOCRSA(i) =  cfg->img_buf[i].phys_cr;            }            break;        case 2:#define  TRY   (( i%2 ) ? 1 :0)            one_p_size = daon + 2*c_size;            for (i = 0; i < 4  ; i++) {                cfg->img_buf[i].virt_y = cfg->pp_virt_buf + TRY * one_p_size;                cfg->img_buf[i].phys_y = cfg->pp_phys_buf + TRY * one_p_size;                cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + daon + TRY * one_p_size;                cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + daon + TRY * one_p_size;                cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + daon + c_size + TRY * one_p_size;                cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + daon + c_size + TRY * one_p_size;                rCICOYSA(i)  = cfg->img_buf[i].phys_y;                rCICOCBSA(i) = cfg->img_buf[i].phys_cb;                rCICOCRSA(i) = cfg->img_buf[i].phys_cr;            }            break;        case 4:             one_p_size = daon + 2*c_size;            for (i = 0; i < 4 ; i++) {                cfg->img_buf[i].virt_y = cfg->pp_virt_buf + i * one_p_size;                cfg->img_buf[i].phys_y = cfg->pp_phys_buf + i * one_p_size;                cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + daon + i * one_p_size;                cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + daon + i * one_p_size;                cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + daon + c_size + i * one_p_size;                cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + daon + c_size + i * one_p_size;                rCICOYSA(i)  =  cfg->img_buf[i].phys_y;                rCICOCBSA(i) =  cfg->img_buf[i].phys_cb;                rCICOCRSA(i) =  cfg->img_buf[i].phys_cr;            }            break;        default:            printk("Invalid PingPong Number %d \n",cfg->pp_num);            panic("halt\n");    }		DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin    return 0;}/* RGB Buffer Allocation */static int camif_pp_preview(camif_cfg_t *cfg){    int i;    u32 daon = cfg->target_x * cfg->target_y;		DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin    if(cfg->fmt & CAMIF_RGB24)          daon = daon * 4 ;    else {        assert (cfg->fmt & CAMIF_RGB16);        daon = daon *2;    }      switch ( cfg->pp_num ) {        case 1:            for ( i = 0; i < 4 ; i++ ) {                cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf ;                cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf ;                rCIPRCLRSA(i) = cfg->img_buf[i].phys_rgb;            }            break;        case 2:            for ( i = 0; i < 4 ; i++) {                cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf + TRY * daon;                cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf + TRY * daon;                rCIPRCLRSA(i) = cfg->img_buf[i].phys_rgb;            }            break;        case 4:            for ( i = 0; i < 4 ; i++) {                cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf + i * daon;                cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf + i * daon;                rCIPRCLRSA(i) = cfg->img_buf[i].phys_rgb;            }            break;        default:            printk("Invalid PingPong Number %d \n",cfg->pp_num);            panic("halt\n");    }		DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin    return 0;}static int camif_pingpong(camif_cfg_t *cfg){	DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin    	if (cfg->dma_type & CAMIF_CODEC ) {        camif_pp_codec(cfg);    }    if ( cfg->dma_type & CAMIF_PREVIEW) {        camif_pp_preview(cfg);    }	DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin	    return 0;}/***********       Image Convert *******************************//*  Return Format  *  Supported by Hardware *  V4L2_PIX_FMT_YUV420, *  V4L2_PIX_FMT_YUV422P, *  V4L2_PIX_FMT_BGR32 (BGR4) * ----------------------------------- *  V4L2_PIX_FMT_RGB565(X)  *  Currenly 2byte --> BGR656 Format *  S3C2440A,S3C24A0 supports vairants with reversed FMT_RGB565     i.e  blue toward the least, red towards the most significant bit     --  by SW.LEE *//*  * After calling camif_g_frame_num, * this func must be called  */u8 * camif_g_frame(camif_cfg_t *cfg){    u8 * ret = NULL;    int cnt = cfg->now_frame_num;    if(cfg->dma_type & CAMIF_PREVIEW) {        ret = cfg->img_buf[cnt].virt_rgb;    }    if (cfg->dma_type & CAMIF_CODEC) {        ret = cfg->img_buf[cnt].virt_y;    }    return ret;}/* This function must be called in module initial time */static int camif_source_fmt(camif_gc_t *gc) {    u32 cmd = 0;		DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin#if 1    printk("camif_source_fmt: start\n");    /* Configure CISRCFMT --Source Format */    if (gc->itu_fmt & CAMIF_ITU601) {        cmd = CAMIF_ITU601;    }    else {        assert ( gc->itu_fmt & CAMIF_ITU656);

⌨️ 快捷键说明

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