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

📄 camif_mx2ads.c

📁 pxa270下的摄像头mtd91111的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
        minmod = mod = (*mclk) * (*hclk);        /* This is very rough estimation , but it should works */        for (div2 = 1; div2 <= 64; div2++ ) {            for (div1 = 2; div1 <= 32; div1 +=2) {                 mod = MOD(div1 * div2, sysclk/cam_clock);                 if (mod < minmod) {                     minmod = mod;                     *mclk = div1;                     *hclk = div2;                     if (!mod)                         break;                 }             }        }        ret_freq = CLK_MPLL / (*hclk) / (*mclk);        *hclk = *hclk - 1;        *mclk = (*mclk - 1) >> 1;        return ret_freq;}static intcamif_open(int channel){        int ret;        unsigned int hclk, mclk;        unsigned int reg_val;        int i, initilized = 0;        if (channel >= CAMIF_CHANNELS_NUM)                return -EINVAL;                if (!this->camera)                return 0;        for (i = 0; i < CAMIF_CHANNELS_NUM; i++) {                if (chan_stat[i].opened)                        initilized = 1;        }                chan_stat[channel].opened = 1;        init_waitqueue_head(&chan_stat[channel].abortqueue);        if (initilized)                return 0;#ifdef CONFIG_MX2TO1	mx_module_clk_open(HCLK_MODULE_CSI);#else        camera_clk = camera_set_csi_clock(camera_clk, &hclk, &mclk);        dbg("Set camera Master clock to %ld Hz\n", camera_clk);	CRM_PCDR1 = (CRM_PCDR1 & ~PCDR1_PERDIV4) |             ((hclk << PCDR1_PERDIV4_SHIFT) & PCDR1_PERDIV4);        	mx_module_clk_open(HCLK_MODULE_CSI);	mx_module_clk_open(IPG_MODULE_PERCLK4);        mx_module_clk_open(HCLK_MODULE_EMMA);        mx_module_clk_open(IPG_MODULE_EMMA);        	CSI_REG_READ(CSICR1, reg_val); /* Clear register */        reg_val &= ~(CSICR1_MCLKDIV);        reg_val |= (mclk << CSICR1_MCLKDIV_SHIFT) & CSICR1_MCLKDIV;	CSI_REG_WRITE(CSICR1, reg_val); /* Clear register */#endif        /* Reset eMMa */        PRP_CNTL = PRP2_CNTL_RST;        mdelay(5);                if (PRP_CNTL & PRP2_CNTL_RST)        {                err("prp: reset timeout\n");                return  -EIO;        }                PRP_CNTL        = PRP2_CNTL_IN_RGB16 | PRP2_CNTL_CSI | PRP2_CNTL_UNCHAIN;        PRP_INTRSTATUS  = 0x0;               /* change irq to named constatnt*/        if (request_irq(INT_EMMAPRP, emma_prp_isr, SA_INTERRUPT,                                 "eMMA prp", NULL)) {                 err("eMMa interrupt requesting error\n");                camif_close(channel);		return -1;	}        if ((ret = this->camera->open())) {                err("Camera open error\n");                camif_close(channel);                return ret;        }        camif_start();	return 0;}/* * Deallocate CSI-related resources */static intcamif_close(int channel){        int i;        if (channel >= CAMIF_CHANNELS_NUM)                return -EINVAL;                camif_abort(channel);        chan_stat[channel].opened = 0;        for (i = 0; i < CAMIF_CHANNELS_NUM; i++) {                if (chan_stat[i].opened) {                        /* Other channel opened  we can't stop now */                        return 0;                }        }	free_irq(INT_EMMAPRP, NULL);                camif_stop();	this->camera->close();#ifdef CONFIG_MX2TO1	mx_module_clk_close(HCLK_MODULE_CSI);#else	/* disable CSI PerClock 4 and HCLK */	mx_module_clk_close(HCLK_MODULE_CSI);	mx_module_clk_close(IPG_MODULE_PERCLK4);        mx_module_clk_close(HCLK_MODULE_EMMA);        mx_module_clk_close(IPG_MODULE_EMMA);#endif	return 0;}static intcamif_inithw(void){	uint32_t reg_val = 0;        unsigned int hclk = 0, mclk = 0;        	/*         * Before access to CSI registers, CSI clock control should be         * configured	 */#ifdef CONFIG_MX2TO1	mx_module_clk_open(HCLK_MODULE_CSI);        mclk = CSICR1_MCLKDIV_4 >> CSICR1_MCLKDIV_SHIFT;#else	/* adjust CSI PerClock 4 */	/* enable CSI PerClock 4 and HCLK */        camera_set_csi_clock(camera_clk, &hclk, &mclk);	CRM_PCDR1 = (CRM_PCDR1 & ~PCDR1_PERDIV4) |             ((hclk << PCDR1_PERDIV4_SHIFT) & PCDR1_PERDIV4);        mx_module_clk_open(HCLK_MODULE_CSI);	mx_module_clk_open(IPG_MODULE_PERCLK4);        mx_module_clk_open(HCLK_MODULE_EMMA);        mx_module_clk_open(IPG_MODULE_EMMA);#endif        reg_val = 0;        reg_val |= (mclk << CSICR1_MCLKDIV_SHIFT) & CSICR1_MCLKDIV;        reg_val |= CSICR1_SOF_POL_RISE;        reg_val |= CSICR1_SOF_INTEN;        reg_val |= CSICR1_REDGE;        reg_val |= CSICR1_GCLK_MODE;        reg_val |= CSICR1_HSYNC_POL_HIGH;        reg_val |= CSICR1_FCC_SCLR ;        reg_val |= CSICR1_RXFF_LEVEL_16;        reg_val |= CSICR1_SWAP16_EN;        reg_val |= CSICR1_PRP_IFEN;	CSI_REG_WRITE(CSICR1, reg_val);        return 0;}static intcamif_ioctl(unsigned int cmd, void *arg){        return -ENOIOCTLCMD;}/* * Cannel specific initialization */static intcamif_chan_init(unsigned int chan, void (*callback)(void *), void* data){        if (chan >= CAMIF_CHANNELS_NUM)                 return -EINVAL;        chan_stat[chan].capture_callback = callback;        chan_stat[chan].callback_data = data;        return 0;}#define CSI_REG_REQUESTED       (1)#define PRP_REG_REQUESTED       (2)/* * Initialise CSI for first use (set gpios, reserve memory) */static intcamif_init(void){        this = &camif_mx2ads;        memset(&chan_stat, 0, sizeof(chan_stat));	/*	 * reserve virtual addresses for CSI registers physical address	 */	if (!request_mem_region(CSI_BASE, CSI_IO_SIZE, "MX21.CSI registers")) {		err("MX2 Camera: CSI memory region is already in use\n");		dbg("Address=0x%08x, size=0x%x\n", CSI_BASE, CSI_IO_SIZE);		return -1;	}	mem_region_reserved |= CSI_REG_REQUESTED;                if (!request_mem_region(EMMA_PRP_BASE, EMMA_PRP_IO_SIZE,                                 "MX21.EMMA PRP registers")) {                err("MX2 Camera: MX21.EMMA PRP memory region is already in "                                "use\n");                dbg("Address=0x%08x, size=0x%x\n", EMMA_PRP_BASE,                                EMMA_PRP_IO_SIZE);		return -1;	}	mem_region_reserved |= PRP_REG_REQUESTED;	/*	 * Enable CSI GPIOs	 */	if (mx2_register_gpios(PORT_B, CSI_GPIO_MASK, PRIMARY)) {		    err("MX2 Camera: CSI GPIO pins are already in use\n");		return -1;	}        if (camif_inithw()) {            return -1;        }	camera_module_present = 1;        	return 0;}static voidcamif_cleanup(void) {	info("Unloading camera interface \n");	if (this->camera)		this->camera->cleanup();                if (mem_region_reserved & CSI_REG_REQUESTED) {		release_mem_region(CSI_BASE, CSI_IO_SIZE);        }        if (mem_region_reserved & PRP_REG_REQUESTED) {		release_mem_region(EMMA_PRP_BASE, EMMA_PRP_IO_SIZE);        }	mx2_unregister_gpios(PORT_B, CSI_GPIO_MASK);#ifdef CONFIG_MX2TO1	mx_module_clk_close(HCLK_MODULE_CSI);#else	/* disable CSI PerClock 4 and HCLK */	mx_module_clk_close(HCLK_MODULE_CSI);	mx_module_clk_close(IPG_MODULE_PERCLK4);#endif}typedef struct cam_dev_tag {        char *cam_name;        struct camera* camera_if;        struct camera_serial_bus * sbus;        unsigned long camera_clk;} cam_dev_t;cam_dev_t camera_devs[] = {#ifdef CONFIG_VIDEO_MX2ADS_OV9640        {                .cam_name =     "OV9640",                .camera_if =    &camera_ov9640,                .sbus =         &camera_mx2ads_omnivision_i2c,                .camera_clk =   CAMERA_OV9640_WORK_FREQ,        },#endif /* CONFIG_VIDEO_MX2ADS_OV9640 */#ifdef CONFIG_VIDEO_MX2ADS_MISOC0343        {                .cam_name =     "MI-SOC-0343",                .camera_if =    &camera_misoc0343,                .sbus =         &camera_mx2ads_generic_i2c,                .camera_clk =   CAMERA_MISOC0343_WORK_FREQ,        },#endif /* CONFIG_VIDEO_MX2ADS_MISOC0343 */#ifdef CONFIG_VIDEO_MX2ADS_MT9V111        {                .cam_name =     "MT9V111",                .camera_if =    &camera_mt9v111,                .sbus =         &camera_mx2ads_generic_i2c,                .camera_clk =   CAMERA_MT9V111_WORK_FREQ,        },#endif /* CONFIG_VIDEO_MX2ADS_MT9V111 */        {                .cam_name =     NULL,                .camera_if =    NULL,                .sbus =         NULL,                .camera_clk =   0,        }};/**************************** * Routine:  Description: ***************************/static struct camera * camif_camera_detect(void){        cam_dev_t *devices = camera_devs;		ENTRY();	this->camera = NULL;	if (!camera_module_present)		return NULL;		camif_start();        while (devices->camera_if) {                int ret;                char *name = devices->cam_name;	        struct camera * cam = devices->camera_if;                                cam->camif = this;                                camera_clk = devices->camera_clk;	        this->sbus = devices->sbus;                devices++;                info("Trying to detect %s camera\n", name);                                if ((ret = cam->detect())) {                        info("%s camera not detected\n", name);                        if (ret == -ENODEV)                                continue;                        else                                break;                } else {                        info("%s camera detected\n", name);                        this->camera = cam;                        this->camera->init();                        break;                }                                info("%s camera not detected\n", name);        }        if (!this->camera) {                info("No camera devices detected\n");                /*TODO: the camif has ability ro read stream indirect from                 * memeoty, So we can use this V4l2 module even if no camera                 * modules present. In this cae the write primitive should be                 * defined.                  */        }                	camif_stop();	return this->camera;}struct camera_interface camif_mx2ads = {	.camera_detect          = camif_camera_detect,	.init                   = camif_init,        .init_chan              = camif_chan_init,	.cleanup                = camif_cleanup,	.open                   = camif_open,	.close                  = camif_close,	.snapshot               = camif_snapshot,	.start_streaming        = camif_start_streaming,	.abort                  = camif_abort,	.set_frame_period       = camif_set_fp,        .ioctl                  = camif_ioctl,        .set_format             = camif_set_format,        .convert_image          = camif_convert_image,};

⌨️ 快捷键说明

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