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

📄 iic.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	return; }void ci_set_fifo(unsigned int timeout, CI_FIFO_THRESHOLD threshold, int fifo1_enable,               int fifo2_enable){	unsigned int value;	// write citor	CITOR = timeout; 		// write cifr: always enable fifo 0! also reset input fifo 	value = CIFR;	value &= ~(CI_CIFR_FEN0 | CI_CIFR_FEN1 | CI_CIFR_FEN2 | CI_CIFR_RESETF | 	CI_CIFR_THL_0_SMASK<<CI_CIFR_THL_0_SHIFT);	value |= (unsigned int)threshold << CI_CIFR_THL_0_SHIFT;	value |= (fifo1_enable) ? CI_CIFR_FEN1 : 0;	value |= (fifo2_enable) ? CI_CIFR_FEN2 : 0;	value |= CI_CIFR_RESETF | CI_CIFR_FEN0;	CIFR = value;	return; }void ci_reset_fifo(){	unsigned int value;	value = CIFR;	value |= CI_CIFR_RESETF;	CIFR = value;}void ci_set_int_mask(unsigned int mask){	unsigned int value;	// write mask in cicr0  	value = CICR0;	value &= ~CI_CICR0_INTERRUPT_MASK;	value |= (mask & CI_CICR0_INTERRUPT_MASK);	CICR0 = value;   	return; }unsigned int ci_get_int_mask(){	unsigned int value;	// write mask in cicr0  	value = CICR0;	return (value & CI_CICR0_INTERRUPT_MASK);}void ci_clear_int_status(unsigned int status){	// write 1 to clear	CISR = status;}unsigned int ci_get_int_status(){	int value;	value = CISR;	return  value;}void ci_set_reg_value(unsigned int reg_offset, unsigned int value){	CI_REG((u32)(ci_regs_base) + reg_offset) = value;}int ci_get_reg_value(unsigned int reg_offset){	int value;	value = CI_REG((u32)(ci_regs_base) + reg_offset);	return value;}//-------------------------------------------------------------------------------------------------------//  Control APIs//-------------------------------------------------------------------------------------------------------int ci_init(){	// clear all CI registers	CICR0 = 0x3FF;   // disable all interrupts	CICR1 = 0;	CICR2 = 0;	CICR3 = 0;	CICR4 = 0;	CISR = ~0;	CIFR = 0;	CITOR = 0;		// enable CI clock	CKEN |= CKEN24_CAMERA;	return 0;}void ci_deinit(){	// disable CI clock	CKEN &= ~CKEN24_CAMERA;}void ci_enable(int dma_en){	unsigned int value;	// write mask in cicr0  	value = CICR0;	value |= CI_CICR0_ENB;	if (dma_en) {		value |= CI_CICR0_DMA_EN;	}	CICR0 = value;	udelay(100);	GPSR0 |= 0x00000800;	udelay(100);  	return; }int ci_disable(int quick){	volatile unsigned int value, mask;	int retry;	// write control bit in cicr0   	value = CICR0;	if (quick) {		value &= ~CI_CICR0_ENB;		mask = CI_CISR_CQD;	}	else {		value |= CI_CICR0_DIS;		mask = CI_CISR_CDD;	}	CICR0 = value;   		// wait shutdown complete	retry = 50;	while ( retry-- > 0 ) {		value = CISR;		if ( value & mask ) {			CISR = mask;			return 0;		}		mdelay(10);	}	return -1; }void ci_slave_capture_enable(){	unsigned int value;	// write mask in cicr0  	value = CICR0;	value |= CI_CICR0_SL_CAP_EN;	CICR0 = value;   	return; }void ci_slave_capture_disable(){	unsigned int value;		// write mask in cicr0  	value = CICR0;	value &= ~CI_CICR0_SL_CAP_EN;	CICR0 = value;   	return; }void pxa_ci_dma_irq_y(int channel, void *data, struct pt_regs *regs){	int dcsr;	static int dma_repeated = 0;	camera_context_t  *cam_ctx = g_camera_context;	dcsr = DCSR(channel);	DCSR(channel) = dcsr & ~DCSR_STOPIRQEN;	if (still_image_mode == 1) {		if (task_waiting == 1) {			wake_up_interruptible (&camera_wait_q);			task_waiting = 0;		}		else {			still_image_rdy = 1;		}	} 	else 	if (dma_repeated == 0 		&& (cam_ctx->block_tail == ((cam_ctx->block_header + 2) % cam_ctx->block_number)))  {		dma_repeated = 1;		pxa_dma_repeat(cam_ctx);		cam_ctx->block_header = (cam_ctx->block_header + 1) % cam_ctx->block_number;	}	else if (dma_repeated == 1 && 			(cam_ctx->block_tail != ((cam_ctx->block_header + 1) % cam_ctx->block_number))			&& (cam_ctx->block_tail != ((cam_ctx->block_header + 2) % cam_ctx->block_number)))  {			pxa_dma_continue(cam_ctx);			dma_repeated = 0;	}	else if (dma_repeated == 0) {		cam_ctx->block_header = (cam_ctx->block_header + 1) % cam_ctx->block_number;	}	if (task_waiting == 1 && !(cam_ctx->block_header == cam_ctx->block_tail)) {		wake_up_interruptible (&camera_wait_q);		task_waiting = 0;	}}void pxa_ci_dma_irq_cb(int channel, void *data, struct pt_regs *regs){	return;}void pxa_ci_dma_irq_cr(int channel, void *data, struct pt_regs *regs){	return;}                                                                                                                     inline static void pxa_ci_dma_stop(camera_context_t  *cam_ctx){        int ch0, ch1, ch2;                ch0 = cam_ctx->dma_channels[0];        ch1 = cam_ctx->dma_channels[1];        ch2 = cam_ctx->dma_channels[2];        DCSR(ch0) &= ~DCSR_RUN;        DCSR(ch1) &= ~DCSR_RUN;        DCSR(ch2) &= ~DCSR_RUN;}                                                                                                                             void pxa_dma_start(camera_context_t  *cam_ctx){        unsigned char cnt_blk;        pxa_dma_desc   *cnt_desc;	cam_ctx->block_header = (cam_ctx->block_header + 1) % cam_ctx->block_number;        cnt_blk = (unsigned char)cam_ctx->block_header;	        cnt_desc = (pxa_dma_desc *)cam_ctx->fifo0_descriptors_physical + cnt_blk * cam_ctx->fifo0_num_descriptors;        DDADR(cam_ctx->dma_channels[0]) = cnt_desc;        DCSR(cam_ctx->dma_channels[0]) |= DCSR_RUN;        if (cam_ctx->fifo1_num_descriptors) {                cnt_desc = (pxa_dma_desc *)cam_ctx->fifo1_descriptors_physical + cnt_blk * cam_ctx->fifo1_num_descriptors;                 DDADR(cam_ctx->dma_channels[1]) = cnt_desc;                DCSR(cam_ctx->dma_channels[1]) |= DCSR_RUN;        }                                                                                                                                     if (cam_ctx->fifo2_num_descriptors) {                cnt_desc = (pxa_dma_desc *)cam_ctx->fifo2_descriptors_physical + cnt_blk * cam_ctx->fifo2_num_descriptors;                 DDADR(cam_ctx->dma_channels[2]) = cnt_desc;                DCSR(cam_ctx->dma_channels[2]) |= DCSR_RUN;        }		return;}void pxa_camera_irq(int irq, void *dev_id, struct pt_regs *regs){        int cisr;        static int dma_started=0;	disable_irq(IRQ_CAMERA);        cisr = CISR;        if (cisr & CI_CISR_SOF) {		if (dma_started == 0) {			dma_started = 1;		}                CISR |= CI_CISR_SOF;        }        if (cisr & CI_CISR_EOF) {                CISR |= CI_CISR_EOF;        }	enable_irq(IRQ_CAMERA);}void pxa_dma_repeat(camera_context_t  *cam_ctx){	pxa_dma_desc *cnt_head, *cnt_tail; 	int cnt_block;	cnt_block = (cam_ctx->block_header + 1) % cam_ctx->block_number;// FIFO0	(pxa_dma_desc *)cnt_head = (pxa_dma_desc *)cam_ctx->fifo0_descriptors_virtual + cnt_block * cam_ctx->fifo0_num_descriptors;	cnt_tail = cnt_head + cam_ctx->fifo0_num_descriptors - 1;	cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc);// FIFO1	if (cam_ctx->fifo1_transfer_size) {		cnt_head = (pxa_dma_desc *)cam_ctx->fifo1_descriptors_virtual + cnt_block * cam_ctx->fifo1_num_descriptors;		cnt_tail = cnt_head + cam_ctx->fifo1_num_descriptors - 1;		cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc);	}// FIFO2	if (cam_ctx->fifo2_transfer_size) {		cnt_head = (pxa_dma_desc *)cam_ctx->fifo2_descriptors_virtual + cnt_block * cam_ctx->fifo2_num_descriptors;		cnt_tail = cnt_head + cam_ctx->fifo2_num_descriptors - 1;		cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc);	}	return;}void pxa_dma_continue(camera_context_t *cam_ctx){	pxa_dma_desc *cnt_head, *cnt_tail; 	pxa_dma_desc *next_head;	int cnt_block, next_block;		cnt_block = cam_ctx->block_header;	next_block = (cnt_block + 1) % cam_ctx->block_number;// FIFO0		cnt_head = (pxa_dma_desc *)cam_ctx->fifo0_descriptors_virtual + cnt_block * cam_ctx->fifo0_num_descriptors;	cnt_tail = cnt_head + cam_ctx->fifo0_num_descriptors - 1;	next_head = (pxa_dma_desc *)cam_ctx->fifo0_descriptors_virtual + next_block * cam_ctx->fifo0_num_descriptors;	cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc);// FIFO1	if (cam_ctx->fifo1_transfer_size) {		cnt_head = (pxa_dma_desc *)cam_ctx->fifo1_descriptors_virtual + cnt_block * cam_ctx->fifo1_num_descriptors;		cnt_tail = cnt_head + cam_ctx->fifo1_num_descriptors - 1;		next_head = (pxa_dma_desc *)cam_ctx->fifo1_descriptors_virtual + next_block * cam_ctx->fifo1_num_descriptors;		cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc);	}// FIFO2	if (cam_ctx->fifo2_transfer_size) {		cnt_head = (pxa_dma_desc *)cam_ctx->fifo2_descriptors_virtual + cnt_block * cam_ctx->fifo2_num_descriptors;		cnt_tail = cnt_head + cam_ctx->fifo2_num_descriptors - 1;		next_head = (pxa_dma_desc *)cam_ctx->fifo2_descriptors_virtual + next_block * cam_ctx->fifo2_num_descriptors;		cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc);	}	return;	}static int iic_init(){	printk("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;        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");		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 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");		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);        //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");	

⌨️ 快捷键说明

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