亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? csi.c

?? 基于Arm9的嵌入式linux攝像頭接口驅動。
?? C
?? 第 1 頁 / 共 2 頁
字號:
/*
 * MX21 CSI driver
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Copyright (C) 2004 Motorola Semiconductors Hong Kong.
 *
 */

/**
*@defgroup CSI CSI driver
*/
/**@{*/

/**
 *@file csi.c
 *@brief CSI driver source file
 *
 *  linux/drivers/csi/csi.c
 */
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/hfs_sysdep.h>
#include <linux/compatmac.h>
#include <linux/hdreg.h>
#include <linux/vmalloc.h>
#include <linux/malloc.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/blkpg.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/i2c-id.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/mm.h>
#include <linux/wrapper.h>
#include <asm/dma.h>
#include <linux/miscdevice.h>
#include <linux/proc_fs.h>

#include <asm/arch/mx2.h>
#include <asm/arch/platform.h>

#include <linux/pm.h>
#include <asm/arch/apmc.h>

#include "csi.h"


/*******************************************************************************
*---------------------------- HARDWARE SPECIFIC -------------------------------
*/

//tapeout 2 specific
#ifndef _reg_CSI_CSICR3
#define _reg_CSI_CSICR3	(*((volatile unsigned long *)(CSI_IO_ADDRESS(CSI_BASE_ADDR+0x1C))))
#endif

//global
static int g_csi_ver = 2;
	//version check
	//-- should be done by s/w, however in current csi design, there is no way to distinguish
	//   TO1 & 2 by software
static int g_csi_busy = 0;
static CSI_CFG g_csi_cfg;
static CSI_STATUS g_csi_status;
	//cache copy of csi status register

//local
static void csihw_read_config(CSI_CFG * _cfg);
static void csihw_config(CSI_CFG * _cfg);
static int csihw_poll(unsigned int * _buf, int byte_size);
static void csihw_reset_frame_count(void);
static int csihw_get_frame_count(void);
static int csihw_pol_eof(int rxcnt);	//block
static int csihw_pol_sof(void);		//block
static void csihw_clock_enable(void);
static void csihw_clock_disable(void);
static void csihw_reset(void);

//reset values
#define CSICR1_RESET_VAL	0x40000800
#define CSICR2_RESET_VAL	0x0
#define CSICR3_RESET_VAL	0x0

//csi control reg 1
#define BIT_SWAP16_EN		(0x1 << 31)
#define BIT_EXT_VSYNC		(0x1 << 30)
#define BIT_EOF_INT_EN		(0x1 << 29)
#define BIT_PRP_IF_EN		(0x1 << 28)
#define BIT_CCIR_MODE		(0x1 << 27)
#define BIT_COF_INT_EN		(0x1 << 26)
#define BIT_SF_OR_INTEN		(0x1 << 25)
#define BIT_RF_OR_INTEN		(0x1 << 24)
#define BIT_STATFF_LEVEL	(0x3 << 22)
#define BIT_STATFF_INTEN	(0x1 << 21)
#define BIT_RXFF_LEVEL		(0x3 << 19)
#define BIT_RXFF_INTEN		(0x1 << 18)
#define BIT_SOF_POL		(0x1 << 17)
#define BIT_SOF_INTEN		(0x1 << 16)
#define BIT_MCLKDIV		(0xF << 12)
#define BIT_HSYNC_POL		(0x1 << 11)
#define BIT_CCIR_EN		(0x1 << 10)
#define BIT_MCLKEN		(0x1 << 9)
#define BIT_FCC			(0x1 << 8)
#define BIT_PACK_DIR		(0x1 << 7)
#define BIT_CLR_STATFIFO	(0x1 << 6)
#define BIT_CLR_RXFIFO		(0x1 << 5)
#define BIT_GCLK_MODE		(0x1 << 4)
#define BIT_INV_DATA		(0x1 << 3)
#define BIT_INV_PCLK		(0x1 << 2)
#define BIT_REDGE		(0x1 << 1)

#define SHIFT_STATFF_LEVEL	22
#define SHIFT_RXFF_LEVEL	19
#define SHIFT_MCLKDIV		12

//control reg 3
#define BIT_FRMCNT		(0xFFFF << 16)
#define BIT_FRMCNT_RST		(0x1 << 15)
#define BIT_CSI_SUP		(0x1 << 3)
#define BIT_ZERO_PACK_EN	(0x1 << 2)
#define BIT_ECC_INT_EN		(0x1 << 1)
#define BIT_ECC_AUTO_EN		(0x1)

#define SHIFT_FRMCNT		16

//csi status reg
#define BIT_SFF_OR_INT	(0x1 << 25)
#define BIT_RFF_OR_INT	(0x1 << 24)
#define BIT_STATFF_INT	(0x1 << 21)
#define BIT_RXFF_INT	(0x1 << 18)
#define BIT_EOF_INT	(0x1 << 17)
#define BIT_SOF_INT	(0x1 << 16)
#define BIT_F2_INT	(0x1 << 15)
#define BIT_F1_INT	(0x1 << 14)
#define BIT_COF_INT	(0x1 << 13)
#define BIT_ECC_INT	(0x1 << 1)
#define BIT_DRDY	(0x1 << 0)


static void csihw_read_status(CSI_STATUS * _status)
{
	_status->sff_or_int = (_reg_CSI_CSISR & BIT_SFF_OR_INT) ? 1 : 0;
	_status->rff_or_int = (_reg_CSI_CSISR & BIT_RFF_OR_INT) ? 1 : 0;
	_status->statff_int = (_reg_CSI_CSISR & BIT_STATFF_INT) ? 1 : 0;
	_status->rxff_int = (_reg_CSI_CSISR & BIT_RXFF_INT) ? 1 : 0;
	_status->eof_int = (_reg_CSI_CSISR & BIT_EOF_INT) ? 1 : 0;
	_status->sof_int = (_reg_CSI_CSISR & BIT_SOF_INT) ? 1 : 0;
	_status->f2_int = (_reg_CSI_CSISR & BIT_F2_INT) ? 1 : 0;
	_status->f1_int = (_reg_CSI_CSISR & BIT_F1_INT) ? 1 : 0;
	_status->cof_int = (_reg_CSI_CSISR & BIT_COF_INT) ? 1 : 0;
	_status->ecc_int = (_reg_CSI_CSISR & BIT_ECC_INT) ? 1 : 0;
	_status->drdy = (_reg_CSI_CSISR & BIT_DRDY) ? 1 : 0;
	
	return;
}


static void csi_irq_handler(int irq, void * data, struct pt_regs * pt)
{
	csihw_read_status(&g_csi_status);

//go to individual handlers
//leave it untouched if user has not enabled the interrupt
	if(g_csi_cfg.rf_or_inten)
	{
		if(g_csi_status.rff_or_int)
		{
			g_csi_status.rff_or_int = 0;
			
			printk("csi error: rxff overflow\n");
			
		//flush fifo
			_reg_CSI_CSICR1 &= ~BIT_FCC;
			_reg_CSI_CSICR1 |= BIT_CLR_RXFIFO;
			if(g_csi_cfg.fcc)
				_reg_CSI_CSICR1 |= BIT_FCC;
			
			_reg_CSI_CSISR = BIT_RFF_OR_INT;
		}
	}
	if(g_csi_cfg.sof_inten)
	{
		if(g_csi_status.sof_int)
		{
			_reg_CSI_CSISR = BIT_SOF_INT;
			g_csi_status.sof_int = 0;
		}
	}
	
	return;
}


static void csihw_read_config(CSI_CFG * _cfg)
{
	unsigned int tmp;
	unsigned val;

//1. read from register
	//control reg 1
	val = _reg_CSI_CSICR1;
	_cfg->swap16_en = (val & BIT_SWAP16_EN)? 1 : 0;
	_cfg->ext_vsync = (val & BIT_EXT_VSYNC)? 1 : 0;
	_cfg->eof_int_en = (val & BIT_EOF_INT_EN)? 1 : 0;
	_cfg->prp_if_en = (val & BIT_PRP_IF_EN)? 1 : 0;
	_cfg->ccir_mode = (val & BIT_CCIR_MODE)? 1 : 0;
	_cfg->cof_int_en = (val & BIT_COF_INT_EN)? 1 : 0;
	_cfg->sf_or_inten = (val & BIT_SF_OR_INTEN)? 1 : 0;
	_cfg->rf_or_inten = (val & BIT_RF_OR_INTEN)? 1 : 0;
	
	tmp = (val & BIT_STATFF_LEVEL) >> SHIFT_STATFF_LEVEL;
	if(tmp == 0x3)
		_cfg->statff_level = 16;
	else if(tmp == 0x2)
		_cfg->statff_level = 12;
	else if(tmp == 0x1)
		_cfg->statff_level = 8;
	else
		_cfg->statff_level = 4;
		
	_cfg->staff_inten = (val & BIT_STATFF_INTEN)? 1 : 0;
	
	tmp = (val & BIT_RXFF_LEVEL) >> SHIFT_RXFF_LEVEL;
	if(tmp == 0x3)
		_cfg->rxff_level = 24;
	else if(tmp == 0x2)
		_cfg->rxff_level = 16;
	else if(tmp == 0x1)
		_cfg->rxff_level = 8;
	else
		_cfg->rxff_level = 4;
		
	_cfg->rxff_inten = (val & BIT_RXFF_INTEN)? 1 : 0;
	_cfg->sof_pol = (val & BIT_SOF_POL)? 1 : 0;
	_cfg->sof_inten = (val & BIT_SOF_INTEN)? 1 : 0;

	tmp = (val & BIT_MCLKDIV) >> SHIFT_MCLKDIV;
	_cfg->mclkdiv = (tmp + 1) * 2;
	
	_cfg->hsync_pol = (val & BIT_HSYNC_POL)? 1 : 0;
	_cfg->ccir_en = (val & BIT_CCIR_EN)? 1 : 0;
	_cfg->mclken = (val & BIT_MCLKEN)? 1 : 0;
	_cfg->fcc = (val & BIT_FCC)? 1 : 0;
	_cfg->pack_dir = (val & BIT_PACK_DIR)? 1 : 0;
	
	_cfg->gclk_mode = (val & BIT_GCLK_MODE)? 1 : 0;
	_cfg->inv_data = (val & BIT_INV_DATA)? 1 : 0;
	_cfg->inv_pclk = (val & BIT_INV_PCLK)? 1 : 0;
	_cfg->redge = (val & BIT_REDGE)? 1 : 0;

	//control reg 3
	val = _reg_CSI_CSICR3;
	_cfg->csi_sup = (val & BIT_CSI_SUP)? 1 : 0;
	_cfg->zero_pack_en = (val & BIT_ZERO_PACK_EN)? 1 : 0;
	_cfg->ecc_int_en = (val & BIT_ECC_INT_EN)? 1 : 0;
	_cfg->ecc_auto_en = (val & BIT_ECC_AUTO_EN)? 1 : 0;
	
	//rxfifo reg
	val = _reg_CSI_CSIRXCNT;

	//keep system settings
	_cfg->module_irq_enable = g_csi_cfg.module_irq_enable;

//2. update global config
	memcpy(&g_csi_cfg, _cfg, sizeof(CSI_CFG));

	return;
}


static void csihw_config(CSI_CFG * _cfg)
{
	unsigned int tmp;
	unsigned val = 0x0;
	int rt;

//1. write to registers
	//control reg 1
	if(_cfg->swap16_en)
		val |= BIT_SWAP16_EN;
	if(_cfg->ext_vsync)
		val |= BIT_EXT_VSYNC;
	if(_cfg->eof_int_en)
		val |= BIT_EOF_INT_EN;
	if(_cfg->prp_if_en)
		val |= BIT_PRP_IF_EN;
	if(_cfg->ccir_mode)
		val |= BIT_CCIR_MODE;
	if(_cfg->cof_int_en)
		val |= BIT_COF_INT_EN;
	if(_cfg->sf_or_inten)
		val |= BIT_SF_OR_INTEN;
	if(_cfg->rf_or_inten)
		val |= BIT_RF_OR_INTEN;

	if(_cfg->statff_level == 16)
		tmp = 0x3;
	else if(_cfg->statff_level == 12)
		tmp = 0x2;
	else if(_cfg->statff_level == 8)
		tmp = 0x1;
	else
		tmp = 0x0;
	val |= (tmp << SHIFT_STATFF_LEVEL);

	if(_cfg->staff_inten)
		val|= BIT_STATFF_INTEN;
	
	if(_cfg->rxff_level == 24)
		tmp = 0x3;
	else if(_cfg->rxff_level == 16)
		tmp = 0x2;
	else if(_cfg->rxff_level == 8)
		tmp = 0x1;
	else
		tmp = 0x0;
	val |= (tmp << SHIFT_RXFF_LEVEL);
		
	if(_cfg->rxff_inten)
		val |= BIT_RXFF_INTEN;
	if(_cfg->sof_pol)
		val |= BIT_SOF_POL;
	if(_cfg->sof_inten)
		val |= BIT_SOF_INTEN;

	tmp = (_cfg->mclkdiv / 2) - 1;
	val |= (tmp << SHIFT_MCLKDIV);
	
	if(_cfg->hsync_pol)
		val |= BIT_HSYNC_POL;
	if(_cfg->ccir_en)
		val |= BIT_CCIR_EN;
	if(_cfg->mclken)
		val |= BIT_MCLKEN;
	if(_cfg->fcc)
		val |= BIT_FCC;
	if(_cfg->pack_dir)
		val |= BIT_PACK_DIR;
	
	if(_cfg->gclk_mode)
		val |= BIT_GCLK_MODE;
	if(_cfg->inv_data)
		val |= BIT_INV_DATA;
	if(_cfg->inv_pclk)
		val |= BIT_INV_PCLK;
	if(_cfg->redge)
		val |= BIT_REDGE;
	
	_reg_CSI_CSICR1 = val;

	//control reg 3
	val = 0x0;
	if(_cfg->csi_sup)
		val |= BIT_CSI_SUP;
	if(_cfg->zero_pack_en)
		val |= BIT_ZERO_PACK_EN;
	if(_cfg->ecc_int_en)
		val |= BIT_ECC_INT_EN;
	if(_cfg->ecc_auto_en)
		val |= BIT_ECC_AUTO_EN;
		
	_reg_CSI_CSICR3 = val;

	//rxfifo counter
	_reg_CSI_CSIRXCNT = _cfg->rxcnt;

//2. update global config
	memcpy(&g_csi_cfg, _cfg, sizeof(CSI_CFG));

//3. interrupt enable
	if(_cfg->module_irq_enable)
	{
		rt = request_irq(INT_CSI, 
			  	 csi_irq_handler,
			  	 SA_INTERRUPT,
				 "csi",
				 "csi");

		if(rt)
			printk("csi error: irq request fail\n");
	}
	
//4. init status flags
	memset(&g_csi_status, 0, sizeof(CSI_CFG));

	return;
}


//nothing special, simply set gpio
static void csihw_init(void)
{
//disable GPIO PB[21..10]
	_reg_GPIO_GIUS(GPIOB) &= ~0x3FFC00;

//note -- csi version check should be here...

	return;
}


static void csihw_cleanup(void)
{
//resume GPIO PB[21..10]
	_reg_GPIO_GIUS(GPIOB) |= 0x3FFC00;
	csihw_clock_disable();
	csihw_reset();

	return;
}


//generate default mclk to drive sensor
static void csihw_open(void)
{
	unsigned int val;
	unsigned int perclk4div = 3;	//default set to fclk/3 => 88MHz
	unsigned int mclkdiv = 4;	//default set to perclk4/4 => 22MHz

	csihw_clock_enable();

//set default perclk4 for mclk
	if(g_csi_ver == 2)
	{
		val = _reg_CRM_PCDR1;
		val &= ~(0x3F << 24);
		val |= (perclk4div - 1) << 24;
		_reg_CRM_PCDR1 = val;
	}

	csihw_reset();
	
//enable default mclk clock
	val = CSICR1_RESET_VAL;
	val |= ((mclkdiv / 2) - 1) << SHIFT_MCLKDIV;
	val |= BIT_MCLKEN;
	_reg_CSI_CSICR1 = val;

	return;
}


static void csihw_release(void)
{
	//nothing to do
	//as a result, the csi state will not unchange unless the module is unloaded
	
	return;
}


//Read a frame by polling
static int csihw_poll(unsigned int * _buf, int byte_size)
{
	int i, j;
	int word_size = byte_size >> 2;

	unsigned int *_kbuf = NULL;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
精品国产麻豆免费人成网站| 日韩av一二三| 亚洲成av人**亚洲成av**| 日韩精品亚洲一区| 成人av在线电影| 欧美成人乱码一区二区三区| 亚洲日穴在线视频| 国产精品一品视频| 日韩午夜电影av| 亚洲国产日韩精品| 成人激情午夜影院| 欧美成人video| 亚洲第一成年网| 一本到三区不卡视频| 精品福利二区三区| 日韩精品一级中文字幕精品视频免费观看| 成人免费视频app| 国产亚洲欧洲一区高清在线观看| 午夜电影一区二区三区| 色婷婷香蕉在线一区二区| 国产日韩精品一区| 精品一区二区综合| 91麻豆精品国产91久久久使用方法| 国产精品国产三级国产a| 国产在线国偷精品产拍免费yy| 欧美伦理电影网| 一区二区激情小说| 色先锋aa成人| 亚洲精品写真福利| 99久久精品国产麻豆演员表| 欧美激情在线看| 国产成人综合亚洲91猫咪| 欧美精品一区二区高清在线观看 | 成人av在线网站| 久久精品人人做人人爽97| 精品一区二区免费视频| 日韩一区二区三区四区| 蜜桃视频一区二区三区| 日韩一级片网站| 国内外精品视频| 久久久国产精华| 成人久久18免费网站麻豆| 国产精品久久久久久久久免费丝袜 | 最新日韩在线视频| 99久久精品国产麻豆演员表| 亚洲欧洲国产专区| 91成人国产精品| 性感美女久久精品| 欧美顶级少妇做爰| 麻豆成人在线观看| 久久日一线二线三线suv| 国产成人在线色| 中文字幕一区二区三区在线播放| 91麻豆精东视频| 天天色 色综合| 精品国产乱码久久久久久久久| 国产精品1区二区.| 国产精品成人一区二区艾草| 欧洲一区在线电影| 奇米精品一区二区三区在线观看一| 欧美变态口味重另类| 国产91清纯白嫩初高中在线观看| 国产精品美女一区二区三区 | 成人黄色电影在线| 国产日产欧美一区| 在线观看91视频| 久久99精品国产麻豆不卡| 国产欧美日韩另类一区| 色猫猫国产区一区二在线视频| 亚洲国产精品久久久久秋霞影院| 日韩视频在线观看一区二区| 丰满放荡岳乱妇91ww| 亚洲午夜在线视频| 国产欧美日韩激情| 欧美男人的天堂一二区| 国产乱一区二区| 亚洲专区一二三| 欧美激情在线看| 91精品国产aⅴ一区二区| 成人激情开心网| 免费一级片91| 亚洲欧美乱综合| 久久蜜桃香蕉精品一区二区三区| 91成人免费电影| 国产精品综合在线视频| 伊人色综合久久天天| 久久精品日韩一区二区三区| 欧美日韩午夜影院| 99精品国产一区二区三区不卡| 久久精品国产在热久久| 一区二区三区欧美视频| 久久久亚洲国产美女国产盗摄| 欧美日韩在线电影| av亚洲产国偷v产偷v自拍| 经典三级视频一区| 亚洲成人精品影院| 亚洲美女电影在线| 国产精品久久久一本精品| 精品国产乱码91久久久久久网站| 欧美日韩一区中文字幕| 欧美一级免费大片| 欧美日韩国产欧美日美国产精品| 91在线云播放| av一区二区三区| 福利一区在线观看| 精品系列免费在线观看| 美腿丝袜亚洲色图| 日韩av电影天堂| 视频精品一区二区| 亚洲一本大道在线| 亚洲蜜桃精久久久久久久| 亚洲色欲色欲www| 中文字幕亚洲综合久久菠萝蜜| 精品99999| 久久久久久久久久看片| 精品福利av导航| 国产亚洲欧美中文| 国产精品色婷婷| 国产精品国产三级国产aⅴ中文| 国产视频一区在线播放| 亚洲精品一区二区三区四区高清| 精品久久久三级丝袜| 日韩精品专区在线影院观看| 日韩欧美卡一卡二| 精品va天堂亚洲国产| 欧美精品一区二区三区高清aⅴ| 久久婷婷综合激情| 中文字幕欧美日本乱码一线二线| 欧美国产欧美亚州国产日韩mv天天看完整| 亚洲精品一区二区三区在线观看| 久久影院电视剧免费观看| 久久亚洲一级片| 亚洲欧洲国产日韩| 亚洲午夜免费电影| 久久精品久久99精品久久| 国产剧情一区二区| 成人性生交大合| 91精品福利视频| 欧美日韩高清一区| 精品免费视频一区二区| 中文字幕巨乱亚洲| 国产伦精品一区二区三区在线观看| 黄色精品一二区| 91麻豆国产香蕉久久精品| 欧美中文字幕亚洲一区二区va在线 | 欧美色精品在线视频| 欧美一级淫片007| 久久精品欧美日韩| 亚洲免费av高清| 日本在线不卡视频| 风流少妇一区二区| 欧美三级资源在线| 久久久久久综合| 亚洲小说春色综合另类电影| 精品综合久久久久久8888| 成人国产精品免费观看| 88在线观看91蜜桃国自产| 欧美极品另类videosde| 天堂久久久久va久久久久| 国产91富婆露脸刺激对白| 欧美日韩午夜在线视频| 中文字幕av一区 二区| 亚洲国产精品久久不卡毛片| 狠狠色丁香婷婷综合| 一本到不卡精品视频在线观看| 日韩一区二区三区在线视频| 中文字幕一区二区三区视频| 奇米精品一区二区三区在线观看 | 在线精品观看国产| 久久综合九色综合97_久久久| 亚洲一区精品在线| 福利91精品一区二区三区| 91 com成人网| 亚洲午夜在线电影| 国产99久久精品| 欧美videossexotv100| 亚洲综合在线电影| hitomi一区二区三区精品| 精品日韩在线观看| 亚洲成人精品在线观看| 99久久99久久精品免费观看 | 亚洲欧美色图小说| 国产九九视频一区二区三区| 欧美一区二区三区视频在线观看| 亚洲一区在线电影| aaa欧美色吧激情视频| 国产蜜臀av在线一区二区三区| 麻豆精品国产91久久久久久| 欧美日免费三级在线| 亚洲精品国产高清久久伦理二区| 国产成人精品亚洲777人妖 | 日本一区二区三区电影| 久草中文综合在线| 日韩女同互慰一区二区| 日韩avvvv在线播放| 在线不卡中文字幕播放| 亚洲一级不卡视频| 欧美日韩在线亚洲一区蜜芽| 一区二区三区蜜桃| 在线精品视频一区二区|