📄 pxa_camera.c
字号:
if (copy_from_user(&pipe, param, sizeof(pipe))) { retval = -EFAULT; break; } adcm2650_write(PAGE_REG,pipe.page); pipe.value = adcm2650_read(pipe.reg,&ret); if (copy_to_user(param, &pipe, sizeof(pipe))) retval = -EFAULT; break; } case NW_PIPELINE_WRITE: { struct pipeline pipe; if (copy_from_user(&pipe, param, sizeof(pipe))) { retval = -EFAULT; break; } adcm2650_write(PAGE_REG,pipe.page); printk("\n yul pipe write ok\n"); adcm2650_write(pipe.reg,pipe.value); printk("\n yul pipe write ok\n"); break; } //flash added by yul@2006-1-12 10:50 case NW_FLASH_OPEN: { /*struct pipeline pipe; if (copy_from_user(&pipe, param, sizeof(pipe))) { retval = -EFAULT; break; }*/ /*yul set cif_led gpio22 output=1*/ GPDR0 |= (1<<22); GAFR0_U &= ~(0x3 <<12); GPSR0 |= (1<<22); /*yul set cif_flash gpio17 alt function2 out pwm_out<1> */ CKEN |= CKEN1_PWM1; set_GPIO_mode(GPIO17_PWM1_MD); /* PWM_OUT<1> */ //set 1khz 1/10 duty cycle PWM_CTRL1 = 0xc; PWM_PWDUTY1 = 0x64; PWM_PERVAL1 = 0x3e8; printk("\n yul flash open ok\n"); break; } case NW_FLASH_CLOSE: { /*yul set cif_led gpio22 output=0*/ GPCR0 |= (1<<22); PWM_PERVAL1 = 0xc; PWM_PWDUTY1 = 0x0; PWM_CTRL1 = 0x3e8; printk("\n yul flash close ok\n"); break; } case NW_VIDEOGET: { unsigned char frame = 0; unsigned char temp = 0; unsigned long i,j,count,sum= 0; unsigned char *pfBuffer; unsigned int value = 0; pfBuffer = param; //printk("\n!!yul NW_VIDEOGET pfBuffer = 0x%x",pfBuffer); /*value = *(volatile u32*)(0x50000000); value &= ~(1<<6); *(volatile u32*)(0x50000000) = value;*/ /*printk("\ncicr0 = 0x%x",CICR0); printk("\ncicr1 = 0x%x",CICR1); printk("\ncicr2 = 0x%x",CICR2); printk("\ncicr3 = 0x%x",CICR3); printk("\ncicr4 = 0x%x",CICR4); printk("\ncisr = 0x%x",CISR); printk("\ncifr = 0x%x",CIFR); printk("\ncitor = 0x%x",CITOR); printk("\ncibr0 = 0x%x",CIBR0); printk("\ncibr1 = 0x%x",CIBR1); printk("\ncibr2 = 0x%x",CIBR2);*/ while(1) { if(CISR & (1<<4)) { CISR |= (1<<4); break; } } //printk("\n yul CISR0 = 0x%x",CISR); while(1) { if(CISR & (1<<8)) { CISR |= (1<<8); count = (CIFR >> 8) & 0xff; while(count) { value = CIBR0; count -= 4; if(count < 0) count = 0; } j = 1; break; } } printk("\n yul CISR1 = 0x%x",CISR); while(1) { count = (CIFR >> 8) & 0xff; if(count) { //printk("\n yul count = 0x%x",count); /*if((sum + count) >= 240*2) { count = 320*240*2 - sum; }*/ for(i=0;i<count;) { value = CIBR0; pfBuffer[240*2*j + sum +i] = value & 0xff; pfBuffer[240*2*j + sum + i + 1] = (value >> 8)& 0xff; pfBuffer[240*2*j + sum + i + 2] = (value >> 16)& 0xff; pfBuffer[240*2*j + sum + i + 3] = (value >> 24)& 0xff; i =i + 4; } sum += count; //printk("\n yul count = 0x%x",count); /*for(i = 0;i<count;) { value = CIBR0; pfBuffer[sum + i] = value & 0xff; pfBuffer[sum + i + 1] = (value >> 8)& 0xff; pfBuffer[sum + i + 2] = (value >> 16)& 0xff; pfBuffer[sum + i + 3] = (value >> 24)& 0xff; i = i+4; }*/ } /*if((sum == 240*2) && (j == 319)) break; */ if(j == 319) break; if(CISR & (1<< 8)) { //printk("\yul end of line !!!"); CISR |= (1<<8); count = (CIFR >> 8) & 0xff; /*while(count--) { value = CIBR0; }*/ for(i=0;i<count;) { value = CIBR0; pfBuffer[240*2*j + sum +i] = value & 0xff; pfBuffer[240*2*j + sum + i + 1] = (value >> 8)& 0xff; pfBuffer[240*2*j + sum + i + 2] = (value >> 16)& 0xff; pfBuffer[240*2*j + sum + i + 3] = (value >> 24)& 0xff; i =i + 4; } j++; sum = 0; } /*for(i=0;i<320*240*2;) { value = CIBR0; pfBuffer[i] = value & 0xff; pfBuffer[i + 1] = (value >> 8)& 0xff; pfBuffer[i + 2] = (value >> 16)& 0xff; pfBuffer[i + 3] = (value >> 24)& 0xff; i = i+4; }*/ } /*for(j = 0; j<320;j++) { i = 0;x for(i=0;i<240*2;) { value = CIBR0; pfBuffer[240*2*j + i] = value & 0xff; pfBuffer[240*2*j + i + 1] = (value >> 8)& 0xff; pfBuffer[240*2*j + i + 2] = (value >> 16)& 0xff; pfBuffer[240*2*j + i + 3] = (value >> 24)& 0xff; i =i + 4; } }*/ printk("\n!!yul NW_VIDEOGET end"); break; } //end of added by yul default: printk(KERN_WARNING PREFIX "invalid ioctl %x\n", cmd); retval = -ENOIOCTLCMD; break; } return retval;}static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr){ unsigned long ret = 0UL; pmd_t *pmd; pte_t *ptep, pte; if (!pgd_none(*pgd)) { pmd = pmd_offset(pgd, adr); if (!pmd_none(*pmd)) { ptep = pte_offset(pmd, adr); pte = *ptep; if (pte_present(pte)) { ret = (unsigned long) page_address(pte_page(pte)); ret |= (adr & (PAGE_SIZE-1)); } } } return ret;}static inline unsigned long kvirt_to_pa(unsigned long adr){ unsigned long va, kva, ret; va = VMALLOC_VMADDR(adr); kva = uvirt_to_kva(pgd_offset_k(va), va); ret = __pa(kva); return ret;}static int pxa_camera_mmap(struct video_device *dev, const char *adr, unsigned long size){ unsigned long start = (unsigned long)adr; unsigned long page, pos; camera_context_t *cam_ctx = g_camera_context; pos = (unsigned long)(cam_ctx->buffer_virtual); page = kvirt_to_pa(pos); if (remap_page_range(start, page, size, PAGE_SHARED)) { return -EFAULT; } return 0;}unsigned int pxa_camera_poll(struct video_device *dev, 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; 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) { //printk ("enter waiting, tail = %d, header = %d \n", cam_ctx->block_tail, cam_ctx->block_header); task_waiting = 1; waited = 1; //interruptible_sleep_on (&camera_wait_q); return 0; } else waited = 0; return POLLIN | POLLRDNORM;}int pxa_camera_video_init(struct video_device *vdev){ printk(KERN_DEBUG PREFIX "camera initialized\n"); return 0;}static struct video_device vd = { owner: THIS_MODULE, name: "PXA Camera", type: VID_TYPE_CAPTURE, hardware: VID_HARDWARE_PXA_CAMERA, /* FIXME */ open: pxa_camera_open, close: pxa_camera_close, read: pxa_camera_read, poll: pxa_camera_poll, ioctl: pxa_camera_ioctl, mmap: pxa_camera_mmap, initialize: pxa_camera_video_init, minor: -1,};static int __init pxa_camera_init(void){ camera_context_t *cam_ctx = NULL; int err; /*yul set camera power gpio9,10 output=1*/ GPDR0 |= (1<<9|1<<10); GAFR0_L &= ~(0xF <<18); GPSR0 |= (1<<9|1<<10); /* 1. mapping CI registers, so that we can access the CI */ if ((err = request_irq(IRQ_CAMERA, pxa_camera_irq, 0, "PXA Camera", &vd))) { printk(KERN_WARNING PREFIX "camera interrupt register failed, error %d\n", err); return -ENXIO; } ci_dma_y = pxa_request_dma("CI_Y",DMA_PRIO_HIGH, pxa_ci_dma_irq_y, &vd); if (ci_dma_y < 0) { printk(KERN_WARNING PREFIX "can't request DMA for Y\n"); goto error; } ci_dma_cb = pxa_request_dma("CI_Cb",DMA_PRIO_HIGH, pxa_ci_dma_irq_cb, &vd); if (ci_dma_cb < 0) { printk(KERN_WARNING PREFIX "can't request DMA for Cb\n"); goto error; } ci_dma_cr = pxa_request_dma("CI_Cr",DMA_PRIO_HIGH, pxa_ci_dma_irq_cr, &vd); if (ci_dma_cr < 0) { printk(KERN_WARNING PREFIX "can't request DMA for Cr\n"); goto error; } DRCMR68 = ci_dma_y | DRCMR_MAPVLD; DRCMR69 = ci_dma_cb | DRCMR_MAPVLD; DRCMR70 = ci_dma_cr | DRCMR_MAPVLD; (unsigned long*)ci_regs_base = (unsigned long*)ioremap(CI_REGS_PHYS, CI_REG_SIZE); if(!ci_regs_base) { printk(KERN_ERR PREFIX "can't remap I/O registers at %x\n", CI_REGS_PHYS); return -1; } cam_ctx = (camera_context_t *) kmalloc(sizeof(struct camera_context_s), GFP_KERNEL); if (cam_ctx == NULL) { printk(KERN_WARNING PREFIX "can't allocate buffer for camera control structure\n"); goto error; } else { g_camera_context = cam_ctx; atomic_set(&cam_ctx->refcount, 0);#ifdef CONFIG_DPM cam_ctx->dma_started = 0;#endif } cam_ctx->dma_descriptors_virtual = consistent_alloc( GFP_KERNEL, MAX_DESC_NUM * sizeof(pxa_dma_desc), (void *)&cam_ctx->dma_descriptors_physical); if (cam_ctx->dma_descriptors_virtual == NULL) { printk(KERN_WARNING PREFIX "memory allocation for DMA descriptors (%ld bytes) failed\n", (long)(MAX_DESC_NUM * sizeof (pxa_dma_desc))); goto error; } cam_ctx->buf_size = BUF_SIZE_DEFT; cam_ctx->buffer_virtual = consistent_alloc( GFP_KERNEL, cam_ctx->buf_size, (void *)&cam_ctx->buffer_physical); if (!cam_ctx->buffer_virtual) goto error; cam_ctx->dma_descriptors_size = MAX_DESC_NUM; if (video_register_device(&vd, VFL_TYPE_GRABBER, minor) < 0) { printk(KERN_WARNING PREFIX "can't register video device\n"); goto error; }#ifdef CONFIG_DPM pxa_camera_ldm_register();#endif printk(KERN_NOTICE PREFIX "video device registered, use device /dev/video%d \n",minor); printk("\nyul pxa_camera_init:camera init ok!!!!\n"); //added by yul //camera_gpio_init(); //pxa_camera_open(&vd,0); return 0;error: 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -