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

📄 pxa_camera.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	if(ci_regs_base)		iounmap((unsigned long*)ci_regs_base);	if (g_camera_context)	{		if (cam_ctx->dma_descriptors_virtual)		{	                consistent_free (cam_ctx->dma_descriptors_virtual,				MAX_DESC_NUM * sizeof (pxa_dma_desc),				(int)cam_ctx->dma_descriptors_physical);		}	        if (cam_ctx->buffer_virtual)		{			consistent_free (cam_ctx->buffer_virtual,				cam_ctx->buf_size,				(int)cam_ctx->dma_descriptors_physical);		}		kfree(g_camera_context);	}	return -ENXIO;}static void __exit pxa_camera_exit(void){	camera_context_t *cam_ctx = g_camera_context;#ifdef CONFIG_DPM	pxa_camera_ldm_unregister();#endif        video_unregister_device(&vd);        free_irq(IRQ_CAMERA,  &vd);	if (ci_dma_y >= 0)		pxa_free_dma(ci_dma_y);	if (ci_dma_cb >= 0)		pxa_free_dma(ci_dma_cb);	if (ci_dma_cr >= 0)		pxa_free_dma(ci_dma_cr);	DRCMR68 = 0;	DRCMR69 = 0;	DRCMR70 = 0;	if(ci_regs_base)		iounmap((unsigned long*)ci_regs_base);		if (cam_ctx->dma_descriptors_virtual)	{                consistent_free (cam_ctx->dma_descriptors_virtual,				 MAX_DESC_NUM * sizeof (pxa_dma_desc),				 (int)cam_ctx->dma_descriptors_physical);	}		if (cam_ctx->buffer_virtual)                consistent_free (cam_ctx->buffer_virtual,                        cam_ctx->buf_size,                        (int)cam_ctx->buffer_physical);        kfree(g_camera_context);}//-------------------------------------------------------------------------------------------------------//      Configuration APIs//-------------------------------------------------------------------------------------------------------void ci_set_frame_rate(CI_FRAME_CAPTURE_RATE frate){	unsigned int value;	// write cicr4	value = CICR4;	value &= ~(CI_CICR4_FR_RATE_SMASK << CI_CICR4_FR_RATE_SHIFT);	value |= (unsigned)frate << CI_CICR4_FR_RATE_SHIFT;	CICR4 = value;}CI_FRAME_CAPTURE_RATE ci_get_frame_rate(void){	unsigned int value;	value = CICR4;	return (CI_FRAME_CAPTURE_RATE)((value >> CI_CICR4_FR_RATE_SHIFT) & CI_CICR4_FR_RATE_SMASK);}void ci_set_image_format(CI_IMAGE_FORMAT input_format, CI_IMAGE_FORMAT output_format){	unsigned int value, tbit, rgbt_conv, rgb_conv, rgb_f, ycbcr_f, rgb_bpp, raw_bpp, cspace;	// write cicr1: preserve ppl value and data width value	value = CICR1;	value &= ( (CI_CICR1_PPL_SMASK << CI_CICR1_PPL_SHIFT) | ((CI_CICR1_DW_SMASK) << CI_CICR1_DW_SHIFT));	tbit = rgbt_conv = rgb_conv = rgb_f = ycbcr_f = rgb_bpp = raw_bpp = cspace = 0;	switch(input_format) {	case CI_RAW8:		cspace = 0;		raw_bpp = 0;		break;	case CI_RAW9:		cspace = 0;		raw_bpp = 1;		break;	case CI_RAW10:		cspace = 0;		raw_bpp = 2;		break;	case CI_YCBCR422:	case CI_YCBCR422_PLANAR:		cspace = 2;		if (output_format == CI_YCBCR422_PLANAR) {			ycbcr_f = 1;		}		break;	/*added by yul@2006-1-12 10:08	case CI_YCBCR420:	case CI_YCBCR420_PLANAR:		cspace = 2;		if (output_format == CI_YCBCR420_PLANAR) {			ycbcr_f = 1;		}		break;*/	case CI_RGB444:		cspace = 1;		rgb_bpp = 0;		break;  	case CI_RGB555:		cspace = 1;		rgb_bpp = 1;		if (output_format == CI_RGBT555_0) {			rgbt_conv = 2;			tbit = 0;		} 		else if (output_format == CI_RGBT555_1) {			rgbt_conv = 2;			tbit = 1;		}		break;  	case CI_RGB565:		cspace = 1;		rgb_bpp = 2;		rgb_f = 1;		break;  	case CI_RGB666:		cspace = 1;		rgb_bpp = 3;		if (output_format == CI_RGB666_PACKED) {			rgb_f = 1;		}		break;  	case CI_RGB888:	case CI_RGB888_PACKED:		cspace = 1;		rgb_bpp = 4;		switch(output_format) {		case CI_RGB888_PACKED:			rgb_f = 1;			break;		case CI_RGBT888_0:			rgbt_conv = 1;			tbit = 0;			break;		case CI_RGBT888_1:			rgbt_conv = 1;			tbit = 1;			break;		case CI_RGB666:			rgb_conv = 1;			break;// RGB666 PACKED - JamesL		case CI_RGB666_PACKED:			rgb_conv = 1;			rgb_f = 1;			break;// end		case CI_RGB565:			rgb_conv = 2;			break;		case CI_RGB555:			rgb_conv = 3;			break;		case CI_RGB444:			rgb_conv = 4;			break;		default:			break;		}		break;  	default:		break;	}	value |= (tbit==1) ? CI_CICR1_TBIT : 0;	value |= rgbt_conv << CI_CICR1_RGBT_CONV_SHIFT;	value |= rgb_conv << CI_CICR1_RGB_CONV_SHIFT;	value |= (rgb_f==1) ? CI_CICR1_RBG_F : 0;	value |= (ycbcr_f==1) ? CI_CICR1_YCBCR_F : 0;	value |= rgb_bpp << CI_CICR1_RGB_BPP_SHIFT;	value |= raw_bpp << CI_CICR1_RAW_BPP_SHIFT;	value |= cspace << CI_CICR1_COLOR_SP_SHIFT;	CICR1 = value;   		return; }void ci_set_mode(CI_MODE mode, CI_DATA_WIDTH data_width){	unsigned int value;		// write mode field in cicr0	value = CICR0;	value &= ~(CI_CICR0_SIM_SMASK << CI_CICR0_SIM_SHIFT);	value |= (unsigned int)mode << CI_CICR0_SIM_SHIFT;	CICR0 = value;   		// write data width cicr1	value = CICR1;	value &= ~(CI_CICR1_DW_SMASK << CI_CICR1_DW_SHIFT);	value |= ((unsigned)data_width) << CI_CICR1_DW_SHIFT;	CICR1 = value;   	return; }//yul set ppl lpfvoid ci_configure_mp(unsigned int ppl, unsigned int lpf, CI_MP_TIMING* timing){	unsigned int value;	// write ppl field in cicr1	value = CICR1;	value &= ~(CI_CICR1_PPL_SMASK << CI_CICR1_PPL_SHIFT);	value |= (ppl & CI_CICR1_PPL_SMASK) << CI_CICR1_PPL_SHIFT;	CICR1 = value;   		// write BLW, ELW in cicr2  	value = CICR2;	value &= ~(CI_CICR2_BLW_SMASK << CI_CICR2_BLW_SHIFT | CI_CICR2_ELW_SMASK << CI_CICR2_ELW_SHIFT );	value |= (timing->BLW & CI_CICR2_BLW_SMASK) << CI_CICR2_BLW_SHIFT;	CICR2 = value;   		// write BFW, LPF in cicr3	value = CICR3;	value &= ~(CI_CICR3_BFW_SMASK << CI_CICR3_BFW_SHIFT | CI_CICR3_LPF_SMASK << CI_CICR3_LPF_SHIFT );	value |= (timing->BFW & CI_CICR3_BFW_SMASK) << CI_CICR3_BFW_SHIFT;	value |= (lpf & CI_CICR3_LPF_SMASK) << CI_CICR3_LPF_SHIFT;	CICR3 = value;  		return;}void ci_configure_sp(unsigned int ppl, unsigned int lpf, CI_SP_TIMING* timing){	unsigned int value;	// write ppl field in cicr1	value = CICR1;	value &= ~(CI_CICR1_PPL_SMASK << CI_CICR1_PPL_SHIFT);	value |= (ppl & CI_CICR1_PPL_SMASK) << CI_CICR1_PPL_SHIFT;	CICR1 = value;   		// write cicr2	value = CICR2;	value |= (timing->BLW & CI_CICR2_BLW_SMASK) << CI_CICR2_BLW_SHIFT;	value |= (timing->ELW & CI_CICR2_ELW_SMASK) << CI_CICR2_ELW_SHIFT;	value |= (timing->HSW & CI_CICR2_HSW_SMASK) << CI_CICR2_HSW_SHIFT;	value |= (timing->BFPW & CI_CICR2_BFPW_SMASK) << CI_CICR2_BFPW_SHIFT;	value |= (timing->FSW & CI_CICR2_FSW_SMASK) << CI_CICR2_FSW_SHIFT;	CICR2 = value;   	// write cicr3	value = CICR3;	value |= (timing->BFW & CI_CICR3_BFW_SMASK) << CI_CICR3_BFW_SHIFT;	value |= (timing->EFW & CI_CICR3_EFW_SMASK) << CI_CICR3_EFW_SHIFT;	value |= (timing->VSW & CI_CICR3_VSW_SMASK) << CI_CICR3_VSW_SHIFT;	value |= (lpf & CI_CICR3_LPF_SMASK) << CI_CICR3_LPF_SHIFT;	CICR3 = value;   	return;}void ci_configure_ms(unsigned int ppl, unsigned int lpf, CI_MS_TIMING* timing){	// the operation is same as Master-Parallel	ci_configure_mp(ppl, lpf, (CI_MP_TIMING*)timing);}void ci_configure_ep(int parity_check){	unsigned int value;		// write parity_enable field in cicr0   	value = CICR0;	//added by yul	value &= ~(CI_CICR0_SIM_SMASK << CI_CICR0_SIM_SHIFT );	value |= (0x3 & CI_CICR0_SIM_SMASK ) << CI_CICR0_SIM_SHIFT;	//end of added by yul		if (parity_check) {		value |= CI_CICR0_PAR_EN;	}	else {		value &= ~CI_CICR0_PAR_EN;	}	CICR0 = value;   	return; }void ci_configure_es(int parity_check){	// the operationi is same as Embedded-Parallel	ci_configure_ep(parity_check);}void ci_set_clock(unsigned int clk_regs_base, 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 ;  	// 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;	CICR4 = value;   	return; }void ci_set_polarity(int pclk_sample_falling, int hsync_active_low, int vsync_active_low){	unsigned int value;		// write cicr4	value = CICR4;	value &= ~(CI_CICR4_PCP | CI_CICR4_HSP | CI_CICR4_VSP);	value |= (pclk_sample_falling)? CI_CICR4_PCP : 0;	value |= (hsync_active_low) ? CI_CICR4_HSP : 0;	value |= (vsync_active_low) ? CI_CICR4_VSP : 0;	CICR4 = value;   	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;

⌨️ 快捷键说明

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