📄 h3600_backpaq_core.c
字号:
/****************************************************************************** * * Power management interface - shut down capture if we get reset * ******************************************************************************/#ifdef CONFIG_PMstatic struct h3600_backpaq_device *h3600_backpaq_camera_dev;static int h3600_backpaq_camera_callback(struct h3600_backpaq_device *device, h3600_backpaq_request_t req ){ struct h3600_camera_struct *cam = &hc_camera;// printk(__FUNCTION__ ": camera backpaq callback %d\n", req); switch (req) { case H3600_BACKPAQ_EJECT: case H3600_BACKPAQ_SUSPEND: stop_capture(cam); cam->state = HC_V4L_IDLE; wake_up_interruptible(&cam->capq); break; case H3600_BACKPAQ_INSERT: case H3600_BACKPAQ_RESUME: cam->param_mask = 0xffff; /* Ask for everything to be reprogrammed */ break; } return 0;}#endif /* CONFIG_PM *//****************************************************************************** * * Video 4 Linux interface * ******************************************************************************/static long h3600_camera_read( struct video_device *dev, char *buf, unsigned long count, int noblock ){ struct h3600_camera_struct *cam = (struct h3600_camera_struct *) dev; long retval; int status; /* We're ignoring "noblock" */ if ( count < required_buf_size(cam)) /* Check for adequate buffer size */ return -EIO; if ( verify_area(VERIFY_WRITE, buf, count)) return -EFAULT; if ( (status = h3600_backpaq_fpga_status()) != 0) return status; down(&cam->lock); /* Prevent others from using the camera during the read */ if ( cam->read_polling_mode ) retval = grab_frame_polling(cam); else retval = grab_frame(cam); if ( retval > 0 ) retval = process_frame( cam, buf, 0 ); up(&cam->lock); return retval;}#define FIX_PARAM(x,m) \ do {if (cam->x != params.x ) { cam->x = params.x; cam->param_mask |= m; }} while(0)static int h3600_camera_ioctl( struct video_device *dev, unsigned int cmd, void *arg ){ struct h3600_camera_struct *cam = (struct h3600_camera_struct *) dev; int retval = 0; switch(cmd) { case VIDIOCGCAP: /* Get core camera capabilities */ { struct video_capability b; strcpy(b.name, "iPAQ H3600 Mercury BackPAQ"); b.type = VID_TYPE_CAPTURE; b.channels = 1; b.audios = 0; b.maxwidth = HC_TRUE_WIDTH; b.maxheight = HC_TRUE_HEIGHT; b.minwidth = HC_MIN_ALLOWED_WIDTH; b.minheight = HC_MIN_ALLOWED_HEIGHT; if (copy_to_user(arg, &b,sizeof(b))) retval = -EFAULT; break; } case VIDIOCGCHAN: /* Get channel info (sources) - We have just one channel */ { struct video_channel v; if (copy_from_user(&v, arg, sizeof(v))) return -EFAULT; if (v.channel !=0) /* We only have a single channel */ return -EINVAL; v.tuners = 0; v.flags = 0; v.type = VIDEO_TYPE_CAMERA; v.norm = 0; /* What is this? */ strcpy(v.name, "Camera"); /* Generic camera */ if (copy_to_user(arg, &v, sizeof(v))) retval = -EFAULT; break; } case VIDIOCSCHAN: /* Set channel - must be 0 */ { int v; if (copy_from_user(&v, arg,sizeof(v))) retval = -EFAULT; else if (v!=0) retval = -EINVAL; break; } case VIDIOCGPICT: /* Get picture properties */ { if (copy_to_user(arg, &cam->vpic, sizeof(struct video_picture))) retval = -EFAULT; break; } case VIDIOCSPICT: /* Set picture properties */ { struct video_picture p; int status; if (copy_from_user(&p, arg, sizeof(p))) { retval = -EFAULT; break; } /* For the moment, we force the following defaults */ if ( (p.palette != VIDEO_PALETTE_RGB24 && p.palette != VIDEO_PALETTE_GREY && p.palette != VIDEO_PALETTE_RAW && p.palette != VIDEO_PALETTE_YUV422)) { retval = -EINVAL; break; } if ( (status = h3600_backpaq_fpga_status()) != 0) return status; /* Load the camera */ down(&cam->lock); if ( cam->vpic.brightness != p.brightness ) { cam->vpic.brightness = p.brightness; cam->electronic_shutter = (cam->vpic.brightness >> 8); // For philips cam cam->param_mask |= PARAM_FPGA_INTEGRATION_TIME | PARAM_IMAGER_PH_ESHUTTER; } if ( cam->vpic.contrast != p.contrast ) { cam->vpic.contrast = p.contrast >> 8; cam->param_mask |= PARAM_IMAGER_PH_PGA; } /* Fix camera resolution */ set_camera_resolution( cam, p.palette, cam->vwin.width, cam->vwin.height ); update_camera_params(cam); up(&cam->lock); break; } case VIDIOCGWIN: /* Get the video capture window */ { if (copy_to_user(arg, &cam->vwin, sizeof(struct video_window))) retval = -EFAULT; break; } case VIDIOCSWIN: /* Set the capture area */ { struct video_window vw; int status; if (copy_from_user(&vw, arg,sizeof(vw))) { retval = -EFAULT; break; } if (vw.clipcount != 0) { /* clipping not supported */ retval = -EINVAL; break; } if (vw.clips != NULL) { /* clipping not supported */ retval = -EINVAL; break; } if (vw.height < HC_MIN_ALLOWED_HEIGHT || vw.height > HC_TRUE_HEIGHT || vw.width < HC_MIN_ALLOWED_WIDTH || vw.width > HC_TRUE_WIDTH) { retval = -EINVAL; break; } if ( (status = h3600_backpaq_fpga_status()) != 0) return status; /* Fix the camera resolution */ down(&cam->lock); set_camera_resolution( cam, cam->vpic.palette, vw.width, vw.height ); update_camera_params(cam); up(&cam->lock); break; } case H3600CAM_G_TYPE: { struct h3600_backpaq_camera_type v; v.model = h3600_backpaq_eeprom_shadow.camera & BACKPAQ_EEPROM_CAMERA_TYPE_MASK; v.orientation = ( h3600_backpaq_eeprom_shadow.camera & BACKPAQ_EEPROM_CAMERA_ORIENTATION ? 1 : 0 ); v.type = cam->ctype; if (copy_to_user(arg, &v, sizeof(struct h3600_backpaq_camera_type))) retval = -EFAULT; break; } /* Private interface for SMaL camera */ case H3600CAM_G_PARAMS: { struct h3600_backpaq_camera_params params; params.clock_divisor = cam->clock_divisor; params.interrupt_fifo = cam->interrupt_fifo; params.power_setting = cam->power_setting; params.gain_format = cam->gain_format; params.power_mgmt = cam->power_mgmt; params.special_modes = cam->special_modes; params.autobright = cam->autobright; params.read_polling_mode = cam->read_polling_mode; params.flip = cam->flip; if (copy_to_user(arg, ¶ms, sizeof(struct h3600_backpaq_camera_params))) retval = -EFAULT; break; } case H3600CAM_S_PARAMS: { struct h3600_backpaq_camera_params params; int status; if (copy_from_user(¶ms, arg, sizeof(params))) { retval = -EFAULT; break; } /* Some sanity checking */ if (params.clock_divisor < 16 /* About 160 Hz */ || params.interrupt_fifo > 255 || params.power_setting > 15 || params.power_mgmt > 15 || params.special_modes > 15 || params.gain_format > 5 ) { retval = -EINVAL; break; } if ( (status = h3600_backpaq_fpga_status()) != 0) return status; down(&cam->lock); params.clock_divisor &= 0xfffe; /* Make it even */ FIX_PARAM(clock_divisor,PARAM_FPGA_CLOCK_DIVISOR); FIX_PARAM(interrupt_fifo,PARAM_FPGA_INTERRUPT_FIFO); FIX_PARAM(special_modes,PARAM_IMAGER_SPECIAL_MODES); FIX_PARAM(autobright,PARAM_IMAGER_AUTOBRIGHT); FIX_PARAM(gain_format,PARAM_IMAGER_GAIN_FORMAT); FIX_PARAM(power_setting,PARAM_IMAGER_POWER_SETTING); FIX_PARAM(power_mgmt,PARAM_IMAGER_POWER_MGMT); cam->read_polling_mode = params.read_polling_mode; cam->flip = params.flip; update_camera_params(cam); up(&cam->lock); break; } /* Private interface for Philips camera */ case H3600CAM_PH_G_PARAMS: { struct h3600_backpaq_camera_philips params; params.clock_divisor = cam->clock_divisor; params.interrupt_fifo = cam->interrupt_fifo; params.read_polling_mode = cam->read_polling_mode; params.flip = cam->flip; params.electronic_shutter = cam->electronic_shutter; params.subrow = cam->subrow; if (copy_to_user(arg, ¶ms, sizeof(struct h3600_backpaq_camera_philips))) retval = -EFAULT; break; } case H3600CAM_PH_S_PARAMS: { struct h3600_backpaq_camera_philips params; int status; if (copy_from_user(¶ms, arg, sizeof(params))) { retval = -EFAULT; break; } /* Some sanity checking */ if (params.clock_divisor < 2 || params.interrupt_fifo > 255 ) { retval = -EINVAL; break; } if ( (status = h3600_backpaq_fpga_status()) != 0) return status; down(&cam->lock); //params.clock_divisor &= 0xfffe; /* Make it even */ FIX_PARAM(clock_divisor,PARAM_FPGA_CLOCK_DIVISOR); FIX_PARAM(interrupt_fifo,PARAM_FPGA_INTERRUPT_FIFO); FIX_PARAM(electronic_shutter,PARAM_IMAGER_PH_ESHUTTER); FIX_PARAM(subrow,PARAM_IMAGER_PH_SUBROW); cam->read_polling_mode = params.read_polling_mode; cam->flip = params.flip; update_camera_params(cam); up(&cam->lock); break; } case H3600CAM_RESET: { int status; printk("RESET\n"); if ( (status = h3600_backpaq_fpga_status()) != 0) return status; down(&cam->lock); set_default_params(cam); update_camera_params(cam); up(&cam->lock); break; } case H3600CAM_PH_SET_ESHUT: // Set electronic shutter value in Philips sensor { int data; int status;// printk("PH_SET_ESHUT\n"); if ( (retval = get_user( data, (int *)arg )) != 0 ) break; if ( (status = h3600_backpaq_fpga_status()) != 0 ) return status; down(&cam->lock); cam->electronic_shutter = data; cam->param_mask |= PARAM_IMAGER_PH_ESHUTTER; update_camera_params(cam); up(&cam->lock); break; } case H3600CAM_PH_SET_SUBROW: // Set Sub row e-shutter value in Philips sensor { int data; int status; if ( (retval = get_user( data, (int *)arg )) != 0 ) break; if ( (status = h3600_backpaq_fpga_status()) != 0 ) return status; down(&cam->lock); cam->subrow = data; cam->param_mask |= PARAM_IMAGER_PH_SUBROW; update_camera_params(cam); up(&cam->lock); break; } case H3600CAM_PH_SET_PGA: // Set programmable gain amp in Philips sensor { int data; int status; if ( (retval = get_user( data, (int *)arg )) != 0 ) break; if ( (status = h3600_backpaq_fpga_status()) != 0) return status; down(&cam->lock); cam->vpic.contrast = data; cam->param_mask |= PARAM_IMAGER_PH_PGA; update_camera_params(cam); up(&cam->lock); break; } /* mmap interface */ case VIDIOCGMBUF: { struct video_mbuf vm; int i; memset(&vm, 0, sizeof(vm)); vm.size = HC_MAX_PROCESSED_FRAME_SIZE * NUMBER_OF_FRAMES; vm.frames = NUMBER_OF_FRAMES; for (i = 0; i < NUMBER_OF_FRAMES; i++) vm.offsets[i] = HC_MAX_PROCESSED_FRAME_SIZE * i; if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm))) retval = -EFAULT; break; } case VIDIOCMCAPTURE: { struct video_mmap vm; int status; if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm))) { retval = -EFAULT; break; }// CAMDEBUG(" ** Camera CAPTURE : fpga status %d\n", h3600_backpaq_fpga_status()); if ( vm.frame < 0 || vm.frame > NUMBER_OF_FRAMES ) { retval = -EINVAL; break; } /* Sanity checks on heights and widths */ if (vm.height < HC_MIN_ALLOWED_HEIGHT || vm.height > HC_TRUE_HEIGHT || vm.width < HC_MIN_ALLOWED_WIDTH || vm.width > HC_TRUE_WIDTH) { retval = -EINVAL; break; } if ( vm.format != VIDEO_PALETTE_RGB24 && vm.format != VIDEO_PALETTE_GREY && vm.format != VIDEO_PALETTE_YUV422 && vm.format != VIDEO_PALETTE_RAW ) { retval = -EINVAL; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -