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

📄 adcm2650_hw.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
字号:
/* *  mt9d011_hw.c * *  mt9d011 Camera Module driver. * *  Copyright (C) 2005, Nanwang Corporation * *  Author: nanwang Inc. *          yulu * * */ #include <linux/types.h>#include <asm/mach-types.h>#include <asm/io.h>#include <asm/semaphore.h>#include <asm/hardware.h>#include <asm/mach-types.h>#include <asm/dma.h>#include <asm/irq.h>#include <linux/types.h>#include <linux/module.h>#include <linux/init.h>#include <linux/wrapper.h>#include <linux/delay.h>#include <linux/i2c.h>#include "adcm2650_hw.h"#include "pxa_camera.h"void adcm2650_wait( int ms ){	mdelay( ms );}/******************************************************************************									     									**        I2C Management		 					     						**									     									******************************************************************************/void i2c_init(void){		//reset = 0 ,udelay	GPCR0 |= (1<<11);	udelay(20);		nw_set_clock(1,1,7);	udelay(20);	//reset = 1	GPSR0 |= (1<<11);			//iic_test();		//configure i2c communication	nw_i2c_init();		//initialize camera sensor registers	nw_camera_init();			printk("\n yul adcm2650_hw:i2c init ok!!!");}void i2c_deinit(void){	}//初始化camera sensor 的寄存器int nw_camera_init(void){	u16 value = 0;	u16 regValue = 0;	int i;	//reset mcu	adcm2650_write(PAGE_REG, 1);	adcm2650_write(0xc3,0x0001);    mdelay(10);    adcm2650_write(0xc3,0x0000);		adcm2650_write(PAGE_REG, 0);	adcm2650_write(RESET, 0x1);    mdelay(10);	adcm2650_write(RESET, 0x0);	//	for(i=0;i<100;i++)//		udelay(1000);    mdelay(10);#if 0	/*pll registers*/	//program pll	adcm2650_write(PLL_CTRL_1, 0x1000);	//m 0x28 n 0x9	adcm2650_write(PLL_CTRL_2, 0x0002);	//p 0x2	//power up pll	adcm2650_write(CLK_CTRL, 0xa000);	//use pll	udelay(300);	adcm2650_write(CLK_CTRL, 0x2000);	//use pll     printk("\n p0 PLL_CTRL_1 = 0x%x",adcm2650_read(PLL_CTRL_1,&regValue));     printk("\n p0 PLL_CTRL_2 = 0x%x",adcm2650_read(PLL_CTRL_2,&regValue));     printk("\n p0 CLK_CTRL = 0x%x",adcm2650_read(CLK_CTRL,&regValue));#endif        	        	   	  	/*context A, PREVIEW*/	var_write8(1,0x20,0x0000);//SEQ_CAP_MODE	var_write8(1,0x03,0x0001);//SEQ_CMD #if 0              /*resize contextA 240*320*/	var_write16(7,0x27,0x0000);//MODE_CROP_X0_A	var_write16(7,0x29,0x0320);//MODE_CROP_X1_A	var_write16(7,0x2b,0x0000);//MODE_CROP_Y0_A	var_write16(7,0x2d,0x0258);//MODE_CROP_Y1_A	var_write16(7,0x03,0x00f0);//MODE_OUTPUT_WIDTH_A	var_write16(7,0x05,0x0140);//MODE_OUTPUT_HEIGHT_A 	var_write8(1,0x03,0x0005);//SEQ_CMD  	mdelay(100);#endif		/*resize*/		adcm2650_write(PAGE_REG, 1);	adcm2650_write(0xC6, 0x2727);//MODE_CROP_X0_A      	adcm2650_write(0xC8, 0x0);   //MODE_CROP_X0_A      	adcm2650_write(0xC6, 0x2729);//MODE_CROP_X1_A      	adcm2650_write(0xC8, 0x0320);//MODE_CROP_X1_A      	adcm2650_write(0xC6, 0x272B);//MODE_CROP_Y0_A      	adcm2650_write(0xC8, 0x0000);//MODE_CROP_Y0_A      	adcm2650_write(0xC6, 0x272D);//MODE_CROP_Y1_A      	adcm2650_write(0xC8, 0x0258);//MODE_CROP_Y1_A      	adcm2650_write(0xC6, 0x2703);//MODE_OUTPUT_WIDTH_A 	adcm2650_write(0xC8, 0x00f0);//MODE_OUTPUT_WIDTH_A 	adcm2650_write(0xC6, 0x2705);//MODE_OUTPUT_HEIGHT_A	adcm2650_write(0xC8, 0x0140);//MODE_OUTPUT_HEIGHT_A	adcm2650_write(0xC6, 0xA103);//SEQ_CMD             	adcm2650_write(0xC8, 0x0005);//SEQ_CMD  #if 0 //yuv420 output 	adcm2650_read(0x15,&regValue);	printk("\n yuv 420 = 0x%x",regValue);	regValue |= 1<<4;	adcm2650_write(0x15, regValue);//YUV420 ENABLE 	//printk("\n yuv 420 = 0x%x",regValue);	//printk("\n yuv 420 = 0x%x",adcm2650_read(0x15,&regValue));  #endif#if 0		/*disable cr ab */	adcm2650_read(0x98,&regValue);	regValue |= 0x05;	adcm2650_write(0x98, regValue);	    adcm2650_write(0x97,0x20);   	var_write16(7,0x7F,0x6443);//MODE_SPEC_EFFECTS_A   	var_write8(1,0x03,0x0005);//SEQ_CMD refresh	adcm2650_write(PAGE_REG,0x1);	adcm2650_write(0xA4, 0x6441);		/************print size related reg&VAR****************/	adcm2650_write(PAGE_REG,0x1);	printk("\n weight x = 0x%x",adcm2650_read(0x16,&regValue));	printk("\n weight y = 0x%x",adcm2650_read(0x17,&regValue));		adcm2650_write(PAGE_REG,0x0);	printk("\n p0 ROW_WIDTH = 0x%x",adcm2650_read(ROW_WIDTH,&regValue));	printk("\n p0 COL_WIDTH = 0x%x",adcm2650_read(COL_WIDTH,&regValue));	printk("\n p0 0x0D = 0x%x",adcm2650_read(0x0D,&regValue));		adcm2650_write(PAGE_REG,0x2);	printk("\n p2,0x16 = 0x%x",adcm2650_read(0x16,&regValue));	printk("\n p2,0x17 = 0x%x",adcm2650_read(0x17,&regValue));		printk("\n p2,0x10 = 0x%x",adcm2650_read(0x10,&regValue));	printk("\n p2,0x11 = 0x%x",adcm2650_read(0x11,&regValue));      		/************print mode related reg&VAR****************/  	adcm2650_write(PAGE_REG,0x0);	printk("\n p0 CONTEXT CONTROL = 0x%x",adcm2650_read(0xF2,&regValue));   	    	adcm2650_write(PAGE_REG,0x1);	printk("\n p1 0XC3 MCU RESET  = 0x%x",adcm2650_read(0xC3,&regValue));			/************print effect related reg&VAR****************/	adcm2650_write(PAGE_REG,0x1);	printk("\n p0 0xA4 Special Effect= 0x%x",adcm2650_read(0xA4,&regValue));		printk("\n 7,0x7F Spec_effects_A= 0x%x",var_read16(7,0x7F));		          /*************SFP REG VALUE******/	adcm2650_write(PAGE_REG,0x1);	adcm2650_write(198,0x9046);	printk("\n SFP LineCnt 0x1046 = 0x%x",adcm2650_read(200,&regValue));	adcm2650_write(198,0x9047);	printk("\n SFP LineCnt 0x1047 = 0x%x",adcm2650_read(200,&regValue));		adcm2650_write(198,0x1048);	printk("\n SFP ClockCnt 0x1048/9= 0x%x",adcm2650_read(200,&regValue));	adcm2650_write(198,0x104A);	printk("\n SFP ClockCnt 0x104A/B= 0x%x",adcm2650_read(200,&regValue)); 	adcm2650_write(PAGE_REG,0x0);	printk("\n CHIP_VER = 0x%x",adcm2650_read(CHIP_VER,&regValue));		printk("\n G1_GAIN = 0x%x",adcm2650_read(G1_GAIN,&regValue));	printk("\n B_GAIN = 0x%x",adcm2650_read(B_GAIN,&regValue));	printk("\n R_GAIN = 0x%x",adcm2650_read(R_GAIN,&regValue));	printk("\n G2_GAIN = 0x%x",adcm2650_read(G2_GAIN,&regValue));	printk("\n PLL_CTRL_1 = 0x%x",adcm2650_read(PLL_CTRL_1,&regValue));	printk("\n PLL_CTRL_2 = 0x%x",adcm2650_read(PLL_CTRL_2,&regValue));	printk("\n CLK_CTRL = 0x%x",adcm2650_read(CLK_CTRL,&regValue));	printk("\n ROW_START = 0x%x",adcm2650_read(ROW_START,&regValue));	printk("\n COL_START = 0x%x",adcm2650_read(COL_START,&regValue));	printk("\n ROW_WIDTH = 0x%x",adcm2650_read(ROW_WIDTH,&regValue));	printk("\n COL_WIDTH = 0x%x",adcm2650_read(COL_WIDTH,&regValue));	printk("\n SHUT_WIDTH = 0x%x",adcm2650_read(SHUT_WIDTH,&regValue));	printk("\n 0XF2 = 0x%x",adcm2650_read(0xF2,&regValue));	printk("\n 0X21 = 0x%x",adcm2650_read(0x21,&regValue));            adcm2650_write(PAGE_REG,0x1);    printk("\n 0XA4 = 0x%x",adcm2650_read(0xA4,&regValue));	printk("\n 7,0x03 = 0x%x",var_read16(7,0x03));	printk("\n 7,0x05 = 0x%x",var_read16(7,0x05));	printk("\n 7,0x27 = 0x%x",var_read16(7,0x27));	printk("\n 7,0x29 = 0x%x",var_read16(7,0x29));	printk("\n 7,0x2b = 0x%x",var_read16(7,0x2b));	printk("\n 7,0x2d = 0x%x",var_read16(7,0x2d));	printk("\n 7,0x79 = 0x%x",var_read16(7,0x79));	printk("\n 7,0x7b = 0x%x",var_read16(7,0x7b));	printk("\n 7,0x37 = 0x%x",var_read16(7,0x37));	printk("\n 7,0x3b = 0x%x",var_read16(7,0x3b));    printk("\n 7,0x7F = 0x%x",var_read16(7,0x7F));    	printk("\n 7,0x02 = 0x%x",var_read8(7,0x02));       	printk("\n 1,0x03 = 0x%x",var_read8(1,0x03));	printk("\n 1,0x20 = 0x%x",var_read8(1,0x20));	printk("\n 1,0x04 = 0x%x",var_read8(1,0x04));	printk("\n 1,0x07 = 0x%x",var_read8(1,0x07));	printk("\n 1,0x08 = 0x%x",var_read8(1,0x08));	printk("\n 1,0x09 = 0x%x",var_read8(1,0x09));	printk("\n p1,0x97 = 0x%x",adcm2650_read(0x97,&regValue));		adcm2650_write(PAGE_REG,0x2);	printk("\n p2,0x16 = 0x%x",adcm2650_read(0x16,&regValue));	printk("\n p2,0x17 = 0x%x",adcm2650_read(0x17,&regValue));	#endif	return 0;}int adcm2650_set_size( adcm_window_size * window ){		if((window->height > 1600) || ( window->width > 1200))	{		printk("\n adcm2650_hw: window is out of the max!!!");		return ADCM_ERR_PARAMETER;	}	adcm2650_write(PAGE_REG, 0);		//input row width	adcm2650_write(ROW_WIDTH, window->height);		//input col width	adcm2650_write(COL_WIDTH, window->width);		//row start,column start	/*adcm2650_write(ROW_START, 0x1c);	adcm2650_write(COL_START, 0x3c);*/		return ADCM_ERR_NONE;}/*i2c的读写接口*/int adcm2650_read(u16 addr, u16 *pvalue){	u16 res = 0;		res = iic_read(READ_SLAVE_ADDR,addr);	*pvalue = (u16)res;		return res;}int adcm2650_write(u16 addr, u16 value){		return iic_write(WRITE_SLAVE_ADDR,addr, value);}#if 1int var_write16(u8 id, u16 offset, u16 value){	adcm2650_write(PAGE_REG,0x1);		adcm2650_write(VAR_ADDR,((id<<8) | offset | VAR_LOGIC_ACCESS ));		adcm2650_write(VAR_DATA,value);}int var_write8(u8 id, u16 offset, u16 value){	adcm2650_write(PAGE_REG,0x1);		adcm2650_write(VAR_ADDR,((id<<8) | offset | VAR_LOGIC_ACCESS | VAR_8_ACCESS));		adcm2650_write(VAR_DATA,value);}int var_read8(u8 id, u16 offset){	u16 value;	adcm2650_write(PAGE_REG,0x1);		adcm2650_write(VAR_ADDR,((id<<8) | offset | VAR_LOGIC_ACCESS | VAR_8_ACCESS));		adcm2650_read(VAR_DATA,&value);		return value;}int var_read16(u8 id, u16 offset ){	u16 value;	adcm2650_write(PAGE_REG,0x1);		adcm2650_write(VAR_ADDR,((id<<8) | offset | VAR_LOGIC_ACCESS));		adcm2650_read(VAR_DATA,&value);		return value;}#endif/*配置i2c初始化*/static int nw_i2c_init(){	//printk("\nnanwang iic init here\n");	CKEN |= CKEN14_I2C;	set_GPIO_mode(117 | GPIO_ALT_FN_1_IN);	set_GPIO_mode(118 | GPIO_ALT_FN_1_IN);	ICR |= ICR_UR;	udelay(1000);	ICR &= ~ICR_UR;	udelay(1000);	ICR &= ~ICR_IUE;	ISAR = 0xff;	ISR = 0;	ICR = ICR_IUE | ICR_SCLE | ICR_GCD;	udelay(100);	return 0;}static int iic_read(unsigned char dev_addr,unsigned char reg_addr){	int i;	u16 value = 0;    unsigned char data1 = 0;	unsigned char data2 = 0;    //printk(" dev_addr = 0x%x, reg_addr = 0x%x\n",dev_addr,reg_addr);        //send start signal and device addr here    IDBR = (unsigned int)dev_addr;    ICR &= ~(ICR_STOP | ICR_ALDIE | ICR_TB);    ICR |= ICR_START | ICR_TB;    for(i=0;i<0x100000;i++)	{		if((ISR & ISR_ITE) == ISR_ITE)			break;	}	if(i >= 0x100000)	{		printk("time out at dev_addr\n");		printk("IDBR = 0x%x\n",IDBR);		printk("ICR = 0x%x\n",ICR);		printk("ISR = 0x%x\n",ISR);	}	//while((ISR & ISR_ITE) == 0);    ISR &= ISR_ITE;    while(ISR & ISR_ACKNAK);    udelay(2);        //send slaveaddr here    IDBR = (unsigned int)reg_addr;    ICR &= ~(ICR_TB | ICR_START | ICR_STOP | ICR_ALDIE);    ICR |= ICR_TB;    for(i=0;i<0x100000;i++)	{		if((ISR & ISR_ITE) == ISR_ITE)			break;	}	if(i >= 0x100000)	{		printk("time out at dev_addr\n");	}	//while((ISR & ISR_ITE) == 0);    ISR &= ISR_ITE;    while(ISR & ISR_ACKNAK);    udelay(2);		//send start signal and dev_addr read    IDBR = (unsigned int)dev_addr | 0x01;    ICR &= ~(ICR_TB | ICR_STOP | ICR_ALDIE);    ICR |= ICR_TB | ICR_START;    for(i=0;i<0x100000;i++)	{		if((ISR & ISR_ITE) == ISR_ITE)			break;	}	if(i >= 0x100000)	{		printk("time out at dev_addr\n");	}	//while((ISR & ISR_ITE) == 0);    ISR &= ISR_ITE;    while(ISR & ISR_ACKNAK);    udelay(2);        //init read    ICR &= ~(ICR_START | ICR_STOP | ICR_TB | ICR_ACKNAK | ICR_ALDIE);    ICR |= ICR_TB;    for(i=0;i<0x100000;i++)	{		if((ISR & ISR_IRF) == ISR_IRF)			break;	}	if(i >= 0x100000)	{		printk("time out at dev_addr\n");	}    ISR &= ISR_IRF;    //while(ISR & ISR_ACKNAK);    data1 = (unsigned char)IDBR;	ICR &= ~(ICR_STOP | ICR_ACKNAK);	udelay(2);    ICR &= ~(ICR_START | ICR_TB | ICR_ALDIE | ICR_ACKNAK);    ICR |= ICR_TB | ICR_STOP | ICR_ACKNAK;    for(i=0;i<0x100000;i++)	{		if((ISR & ISR_IRF) == ISR_IRF)			break;	}	if(i >= 0x100000)	{		printk("time out at dev_addr\n");	}    ISR &= ISR_IRF;    //while(ISR & ISR_ACKNAK);	data2 = (unsigned char)IDBR;		ICR &= ~(ICR_STOP | ICR_ACKNAK);    //data = (unsigned char)IDBR | (data << 8);    udelay(20);		value = (data1 << 8) | data2;    return (value);}static int iic_write(unsigned char dev_addr,unsigned char reg_addr,unsigned short value){	int i;	u8 data1,data2 = 0;		data1 = (value & 0xff00) >> 8;	data2 =  value & 0xff;	 	//printk("\niic write here dev_addr = 0x%x,reg_addr = 0x%x, data1 = 0x%x, data2 = 0x%x\n",dev_addr,reg_addr,data1,data2);//	mdelay(10);    for(i=0;i<100;i++)		udelay(1000);    IDBR = (unsigned int)dev_addr;    ICR &= ~(ICR_STOP | ICR_ALDIE | ICR_TB);    ICR |= ICR_START | ICR_TB;    for(i=0;i<0x100000;i++)	{		if((ISR & ISR_ITE) == ISR_ITE)			break;	}	if(i >= 0x100000)	{		printk("time out at dev_addr\n");	}	//while((ISR & ISR_ITE) == 0);    ISR &= ISR_ITE;    while(ISR & ISR_ACKNAK);    udelay(2);       //send slaveaddr here    IDBR = (unsigned int)reg_addr;    ICR &= ~(ICR_TB | ICR_START | ICR_STOP | ICR_ALDIE);    ICR |= ICR_TB;    for(i=0;i<0x100000;i++)	{		if((ISR & ISR_ITE) == ISR_ITE)			break;	}	if(i >= 0x100000)	{		printk("time out at reg_addr\n");	}	//while((ISR & ISR_ITE ) == 0);    ISR &= ISR_ITE;    while(ISR & ISR_ACKNAK);    udelay(2);        //send data here    IDBR = (unsigned int)data1;    ICR &= ~(ICR_TB | ICR_START | ICR_STOP | ICR_ALDIE);    ICR |= ICR_TB;    for(i=0;i<0x100000;i++)	{		if((ISR & ISR_ITE) == ISR_ITE)			break;	}	if(i >= 0x100000)	{		printk("time out at data1\n");	}    //while((ISR & ISR_ITE ) == 0);    ISR &= ISR_ITE;    //while(PWRISR & ISR_ACKNAK);    udelay(2);    IDBR = (unsigned int)data2;    ICR &= ~(ICR_TB | ICR_START | ICR_ALDIE);    ICR |= ICR_TB | ICR_STOP;    for(i=0;i<0x100000;i++)	{		if((ISR & ISR_ITE) == ISR_ITE)			break;	}	if(i >= 0x100000)	{		printk("time out at data2\n");	}    //while((ISR & ISR_ITE ) == 0);    ISR &= ISR_ITE;    udelay(20);	return 0;}static void nw_set_clock(int pclk_enable, int mclk_enable, unsigned int mclk_khz){	unsigned int ciclk,  value, div, cccr_l, K;	// determine the LCLK frequency programmed into the CCCR.	cccr_l = (CCCR & 0x0000001F);	if (cccr_l < 8)		K = 1;	else if (cccr_l < 17)		K = 2;	else 		K = 3;	ciclk = (13 * cccr_l) / K;		//div = ciclk / ( 2 * mclk_khz ) - 1 ;  	div = 0; //not div by yul	// 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;	//value |= 0x2;	CICR4 = value;   	return; }                                                                                               

⌨️ 快捷键说明

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