📄 pxa_camera.c
字号:
/*********************************************************************** * * Frame rate APIs * ***********************************************************************/// Set desired frame ratevoid camera_set_capture_frame_rate( p_camera_context_t camera_context ){ ci_set_frame_rate(camera_context->frame_rate); return;} // return current settingvoid camera_get_capture_frame_rate( p_camera_context_t camera_context ){ camera_context->frame_rate = ci_get_frame_rate(); return;} /*********************************************************************** * * Interrupt APIs * ***********************************************************************/// set interrupt mask void camera_set_int_mask( p_camera_context_t camera_context, unsigned int mask ){ pxa_dma_desc *end_des_virtual; int dma_interrupt_on; unsigned int i; // set CI interrupt ci_set_int_mask( mask & CI_CICR0_INTERRUPT_MASK ); // set dma end interrupt if ( mask & CAMERA_INTMASK_END_OF_DMA ) dma_interrupt_on = 1; else dma_interrupt_on = 0; // set fifo0 dma chains' flag end_des_virtual = (pxa_dma_desc*)camera_context->fifo0_descriptors_virtual + camera_context->fifo0_num_descriptors - 1; for(i=0; i<camera_context->block_number; i++) { if (dma_interrupt_on) end_des_virtual->dcmd |= DCMD_ENDIRQEN; else end_des_virtual->dcmd &= ~DCMD_ENDIRQEN; end_des_virtual += camera_context->fifo0_num_descriptors; }} // get interrupt mask unsigned int camera_get_int_mask( p_camera_context_t camera_context ){ pxa_dma_desc *end_des_virtual; unsigned int ret; // get CI mask ret = ci_get_int_mask(); // get dma end mask end_des_virtual = (pxa_dma_desc *)camera_context->fifo0_descriptors_virtual + camera_context->fifo0_num_descriptors - 1; if (end_des_virtual->dcmd & DCMD_ENDIRQEN) ret |= CAMERA_INTMASK_END_OF_DMA; return ret; } // clear interrupt statusvoid camera_clear_int_status( p_camera_context_t camera_context, unsigned int status ){ ci_clear_int_status( (status & 0xFFFF) ); }/************************************************************************************ Application interface ************************************************************************************/static int pxa_camera_open(struct video_device *dev, int flags){ int status = -1; camera_context_t *cam_ctx; cam_ctx = g_camera_context; if (atomic_read(&cam_ctx->refcount)) return -EBUSY; atomic_inc(&cam_ctx->refcount); init_waitqueue_head(&camera_wait_q); //yul cam_ctx 参数修改 cam_ctx->sensor_type = CAMERA_TYPE_ADCM_2650; cam_ctx->capture_width = WIDTH_DEFT; cam_ctx->capture_height = HEIGHT_DEFT; cam_ctx->capture_input_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR/*CAMERA_IMAGE_FORMAT_RAW10*/; cam_ctx->capture_output_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR/*CAMERA_IMAGE_FORMAT_RAW10*/; cam_ctx->frame_rate = FRAMERATE_DEFT; // init function dispatch table adcm2650_func.init = camera_func_adcm2650_init; adcm2650_func.deinit = camera_func_adcm2650_deinit; adcm2650_func.set_capture_format = camera_func_adcm2650_set_capture_format; adcm2650_func.start_capture = camera_func_adcm2650_start_capture; adcm2650_func.stop_capture = camera_func_adcm2650_stop_capture; cam_ctx->camera_functions = &adcm2650_func; cam_ctx->ost_reg_base = 0; cam_ctx->gpio_reg_base = 0; cam_ctx->ci_reg_base = 0; cam_ctx->board_reg_base = 0; /* FIXME: handle camera_init() errors ? */ status = camera_init(cam_ctx); printk(KERN_DEBUG PREFIX "camera opened\n"); status = 0; return status;}static void pxa_camera_close(struct video_device *dev){ camera_context_t *cam_ctx = g_camera_context; printk(KERN_DEBUG PREFIX "camera closed\n"); atomic_dec(&cam_ctx->refcount); camera_deinit(cam_ctx);}static long pxa_camera_read(struct video_device *dev, char *buf, unsigned long count, int noblock){ camera_context_t *cam_ctx = g_camera_context; int offset = 0; if (still_image_mode == 1 && still_image_rdy == 1) { if (copy_to_user(buf, cam_ctx->buffer_virtual + offset, cam_ctx->block_size)) return -EFAULT; still_image_rdy = 0; return cam_ctx->block_size; } if (first_video_frame == 1) first_video_frame = 0; else if (still_image_mode == 0) cam_ctx->block_tail = (cam_ctx->block_tail + 1) % cam_ctx->block_number; offset = cam_ctx->block_tail * cam_ctx->block_size; if (cam_ctx->block_header == cam_ctx->block_tail) { task_waiting = 1; interruptible_sleep_on (&camera_wait_q); } if (copy_to_user(buf, cam_ctx->buffer_virtual + offset, cam_ctx->block_size)) return -EFAULT; return cam_ctx->block_size;}struct reg_set_s { int val1; int val2;};static int pxa_camera_ioctl(struct video_device *dev, unsigned int cmd, void *param){ int retval = 0; camera_context_t *cam_ctx = g_camera_context; switch (cmd) {/* V4L Standard IOCTL. */ case VIDIOCGCAP: { struct video_capability vc; strcpy (vc.name, "Bulverde Camera"); vc.maxwidth = MAX_WIDTH; vc.maxheight = MAX_HEIGHT; vc.minwidth = MIN_WIDTH; vc.minheight = MIN_HEIGHT; if (copy_to_user(param, &vc, sizeof(struct video_capability))) return -EFAULT; break; } /* get capture size */ case VIDIOCGWIN: { struct video_window vw; vw.width = cam_ctx->capture_width; vw.height = cam_ctx->capture_height; 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); if (copy_to_user(param, &vw, sizeof(struct video_window))) retval = -EFAULT; break; } /* set capture size. */ case VIDIOCSWIN: { struct video_window vw; if (copy_from_user(&vw, param, sizeof(vw))) { retval = -EFAULT; break; } //printk("\nyul case VIDIOCSWIN2:vw.width=0x%x, vw.height=0x%x",vw.width,vw.height); if (vw.width > MAX_WIDTH || vw.height > MAX_HEIGHT || vw.width < MIN_WIDTH || vw.height < MIN_HEIGHT) { retval = -EFAULT; break; } cam_ctx->capture_width = vw.width; cam_ctx->capture_height = vw.height; //printk("\nyul case VIDIOCSWIN:vw.width=0x%x, vw.height=0x%x",vw.width,vw.height); camera_set_capture_format(cam_ctx); break; } case VIDIOCSPICT: { struct video_picture vp; if (copy_from_user(&vp, param, sizeof(vp))) { retval = -EFAULT; break; } cam_ctx->capture_output_format = vp.palette; retval = camera_set_capture_format(cam_ctx); break; } case VIDIOCGPICT: { struct video_picture vp; vp.palette = cam_ctx->capture_output_format; if (copy_to_user(param, &vp, sizeof(struct video_picture))) retval = -EFAULT; break; } case VIDIOCCAPTURE: { int capture_flag; capture_flag = (int)param;/* Still Image Capture */ if (capture_flag == STILL_IMAGE) { camera_set_int_mask(cam_ctx, 0x3f9 | 0x0400); cam_ctx->block_header = 0; cam_ctx->block_tail = 0; still_image_mode = 1; camera_capture_still_image(cam_ctx, 0); break; }/* Video Capture Start */ else if (capture_flag == VIDEO_START) { camera_set_int_mask(cam_ctx, 0x3f9 | 0x0400); cam_ctx->block_header = 0; cam_ctx->block_tail = 0; still_image_mode = 0; first_video_frame = 1; camera_start_video_capture (cam_ctx, 0); break; }/* Video Capture Stop */ else if (capture_flag == VIDEO_STOP) { camera_set_int_mask(cam_ctx, 0x3ff); camera_stop_video_capture(cam_ctx); break; } else { retval = -EFAULT; break; } } /* mmap interface */ case VIDIOCGMBUF: { struct video_mbuf vm; int i; memset(&vm, 0, sizeof(vm)); vm.size = cam_ctx->buf_size; vm.frames = cam_ctx->block_number; for (i = 0; i < vm.frames; i++) vm.offsets[i] = cam_ctx->block_size * i; if (copy_to_user((void *)param, (void *)&vm, sizeof(vm))) retval = -EFAULT; break; }/* Application extended IOCTL. *//* Register access interface */ case WCAM_VIDIOCSINFOR: { struct reg_set_s reg_s; if (copy_from_user(®_s, param, sizeof(int) * 2)) { retval = -EFAULT; break; } cam_ctx->capture_input_format = reg_s.val1; cam_ctx->capture_output_format = reg_s.val2; retval = camera_set_capture_format(cam_ctx); break; } case WCAM_VIDIOCGINFOR: { struct reg_set_s reg_s; reg_s.val1 = cam_ctx->capture_input_format; reg_s.val2 = cam_ctx->capture_output_format; if (copy_to_user(param, ®_s, sizeof(int) * 2)) retval = -EFAULT; break; } case WCAM_VIDIOCGCIREG: { struct reg_set_s reg_s; if (copy_from_user(®_s, param, sizeof(int) * 2)) { retval = -EFAULT; break; } reg_s.val2 = ci_get_reg_value (reg_s.val1); if (copy_to_user(param, ®_s, sizeof(int) * 2)) retval = -EFAULT; break; } case WCAM_VIDIOCSCIREG: { struct reg_set_s reg_s; if (copy_from_user(®_s, param, sizeof(int) * 2)) { retval = -EFAULT; break; } ci_set_reg_value (reg_s.val1, reg_s.val2); break; } case WCAM_VIDIOCGCAMREG: { struct reg_set_s reg_s; if (copy_from_user(®_s, param, sizeof(int) * 2)) { retval = -EFAULT; break; } adcm2650_read((u16)reg_s.val1, (u16 *)®_s.val2); if (copy_to_user(param, ®_s, sizeof(int) * 2)) retval = -EFAULT; break; } case WCAM_VIDIOCSCAMREG: { struct reg_set_s reg_s; if (copy_from_user(®_s, param, sizeof(int) * 2)) { retval = -EFAULT; break; } adcm2650_write ((u16)reg_s.val1, (u16)reg_s.val2); break; } case WCAM_VIDIOCGCAPINFO: { struct camera_capture_info_s cap_info; cap_info.first_frame_id = camera_get_first_frame_buffer_id(cam_ctx); cap_info.last_frame_id = camera_get_last_frame_buffer_id(cam_ctx); cap_info.frames = camera_get_num_frame_buffers(cam_ctx); if (copy_to_user((void *)param, (void *)&cap_info, sizeof(struct camera_capture_info_s))) retval = -EFAULT; break; } //start of added by yul case NW_VAR_READ: { struct variable var; if (copy_from_user(&var, param, sizeof(var))) { retval = -EFAULT; break; } if(var.flag) var.value = var_read16(var.id,var.offset); else var.value = var_read8(var.id,var.offset); if (copy_to_user(param, &var, sizeof(var))) retval = -EFAULT; break; } case NW_VAR_WRITE: { struct variable var; if (copy_from_user(&var, param, sizeof(var))) { retval = -EFAULT; break; } printk("\n yul var write !!!\n"); printk("\n yul var write var.flag = 0x%x",var.flag); printk("\n yul var write var.id = 0x%x",var.id); printk("\n yul var write var.offset = 0x%x",var.offset); printk("\n yul var write var.value = 0x%x",var.value); if(var.flag) var_write16(var.id,var.offset,var.value); else var_write8(var.id,var.offset,var.value); printk("\n yul var write ok\n"); break; } case NW_PIPELINE_READ: { struct pipeline pipe; __u16 ret;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -