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

📄 pxa_camera.c

📁 基于intel xscale下的linux系统camera驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
        pos = (unsigned long)(cam_ctx->buffer_virtual);        //page = kvirt_to_pa(pos);			//commented by hzh        page = (unsigned long)cam_ctx->buffer_physical;	//modified by hzh//printk(KERN_DEBUG "start %x, end %x, size %d, page %x\n", start, end, size, page);//hzh        if (remap_page_range(vma, start, page, size, PAGE_SHARED)) {			                return -EFAULT;        }        return 0;}unsigned int pxa_camera_poll(struct file *file, poll_table *wait){	camera_context_t *cam_ctx = g_camera_context;	static int waited = 0;	poll_wait(file, &camera_wait_q, wait);	if (still_image_mode == 1 && still_image_rdy == 1) {		//still_image_rdy = 0;	//masked by hzh, don't clear rdy		return POLLIN | POLLRDNORM;	}	if (first_video_frame == 1) 		first_video_frame = 0;	else if (still_image_mode == 0 && waited != 1) 		cam_ctx->block_tail = (cam_ctx->block_tail + 1) % cam_ctx->block_number;			if (cam_ctx->block_header == cam_ctx->block_tail)  {		task_waiting = 1;		waited = 1;		return 0;	}	else waited = 0;		return POLLIN | POLLRDNORM;}/* * Suspend the Camera Module. */static int pxa_camera_suspend(struct device * dev,  u32 state, u32 level){   switch(level){   case SUSPEND_POWER_DOWN:        printk(KERN_INFO "pxa_camera: camera suspend\n");        disable_irq(IRQ_CAMERA);   }      return 0;}/* * Resume the Camera Module. */static int pxa_camera_resume(struct device * dev, u32 level){   switch(level){   case RESUME_POWER_ON:       printk(KERN_INFO "pxa_camera: camera resume\n");       enable_irq(IRQ_CAMERA);        	DRCMR68 = ci_dma_y | DRCMR_MAPVLD;	DRCMR69 = ci_dma_cb | DRCMR_MAPVLD;	DRCMR70 = ci_dma_cr | DRCMR_MAPVLD;	   }      return 0;}int pxa_camera_video_init(struct video_device *vdev){	int status = -1;		if (! (g_camera_context = kmalloc (sizeof(struct camera_context_s), GFP_KERNEL) ) ) 		printk( "PXA_CAMERA: Cann't allocate buffer for camera control structure \n");	else 		status = 0;	memset(g_camera_context, 0, sizeof(*g_camera_context));	//hzh!!!	g_camera_context->dma_channels[0] = ci_dma_y;	g_camera_context->dma_channels[1] = ci_dma_cb;	g_camera_context->dma_channels[2] = ci_dma_cr;	return status;}static void pxa_camera_release(struct video_device *dev){#if 0	/*FIXME: add specific release function here*/	printk(KERN_WARNING "videodev:  has no release callback. "		       "Please fix your driver for proper sysfs support, see "		       "http://lwn.net/Articles/36850/\n");#endif}static struct file_operations pxa_camera_fops ={        .owner   	= THIS_MODULE,        .open     	= pxa_camera_open,        .release	= pxa_camera_close,        .ioctl    	= pxa_camera_ioctl,        .read     	= pxa_camera_read,        .mmap   	= pxa_camera_mmap,        .poll     	= pxa_camera_poll,		.llseek     = no_llseek,        };static struct video_device vd ={        .name    	= "PXA Camera",        .type     	= VID_TYPE_CAPTURE,        .hardware 	= VID_HARDWARE_PXA_CAMERA,	/* FIXME */        .fops     	= &pxa_camera_fops,        .release	= pxa_camera_release,        .minor   	= -1,};static int pxa_camera_probe(struct device *dev){			/* 1. mapping CI registers, so that we can access the CI */    if (request_irq(IRQ_CAMERA, pxa_camera_irq, 0, "PXA Camera", &vd)) {		printk ("Camera interrupt register failed \n");		goto init_error_1;	} 	ci_dma_y = -1;	ci_dma_cb = -1;	ci_dma_cr = -1;		ci_dma_y = pxa_request_dma("CI_Y",DMA_PRIO_HIGH, pxa_ci_dma_irq_y, &vd);	if (ci_dma_y < 0) {		printk( "PXA_CAMERA: Cann't request DMA for Y\n");		goto init_error_2;	} 	ci_dma_cb = pxa_request_dma("CI_Cb",DMA_PRIO_HIGH, pxa_ci_dma_irq_cb, &vd);	if (ci_dma_cb < 0) {		printk( "PXA_CAMERA: Cann't request DMA for Cb\n");		goto init_error_2;	}	ci_dma_cr = pxa_request_dma("CI_Cr",DMA_PRIO_HIGH, pxa_ci_dma_irq_cr, &vd);	if (ci_dma_cr < 0) {		printk( "PXA_CAMERA: Cann't request DMA for Cr\n");		goto init_error_2;	}	DRCMR68 = ci_dma_y | DRCMR_MAPVLD;	DRCMR69 = ci_dma_cb | DRCMR_MAPVLD;	DRCMR70 = ci_dma_cr | DRCMR_MAPVLD;	 	if (video_register_device(&vd, VFL_TYPE_GRABBER, minor) < 0) {		printk("PXA_CAMERA: video_register_device failed\n");		goto init_error_2;	} else {		printk("PXA_CAMERA: PXA Camera driver loaded for: /dev/video%d \n",minor);	}		if(pxa_camera_video_init(&vd)<0){		goto init_error_2;	}	return 0;init_error_2:	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);	if (g_camera_context)		kfree(g_camera_context);	free_irq (IRQ_CAMERA, &vd);init_error_1:			return -EIO;}static int pxa_camera_remove(struct device *dev){       camera_context_t *cam_ctx = g_camera_context;       if (cam_ctx->dma_channels[0]) {                pxa_free_dma(cam_ctx->dma_channels[0]);                cam_ctx->dma_channels[0] = 0;        }        if (cam_ctx->dma_channels[1]) {                pxa_free_dma(cam_ctx->dma_channels[1]);                cam_ctx->dma_channels[1] = 0;        }        if (cam_ctx->dma_channels[2]) {                pxa_free_dma(cam_ctx->dma_channels[2]);                cam_ctx->dma_channels[2] = 0;        }        free_irq(IRQ_CAMERA,  &vd);        kfree(g_camera_context);        video_unregister_device(&vd);				printk("PXA_CAMERA: PXA Camera driver unloaded.\n");		return 0;}static struct device_driver pxa_camera_driver = {        .name           = "pxa2xx-camera",        .bus            = &platform_bus_type,		.probe          = pxa_camera_probe,        .remove         = pxa_camera_remove,        .suspend 		= pxa_camera_suspend,        .resume 		= pxa_camera_resume,};static int __devinit pxa_camera_init(void){	return driver_register(&pxa_camera_driver);}static void __exit pxa_camera_exit(void){	return driver_unregister(&pxa_camera_driver);}//-------------------------------------------------------------------------------------------------------//      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;	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;		case CI_RGB666_PACKED:			rgb_conv = 1;			rgb_f = 1;			break;		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; }void 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)

⌨️ 快捷键说明

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