📄 usbvision.c
字号:
static int init_brightness = 128; // Initalize the brightness of the video devicestatic int init_contrast = 192; // Initalize the contrast of the video devicestatic int init_color = 128; // Initalize the color mode of the video devicestatic int init_hue = 128; // Initalize the Hue settings of the video device// Function prototypesstatic int usbvision_restart_isoc(struct usb_usbvision *usbvision);static int usbvision_begin_streaming(struct usb_usbvision *usbvision);static int usbvision_muxsel(struct usb_usbvision *usbvision, int channel, int norm);static int usbvision_i2c_write(void *data, unsigned char addr, char *buf, short len);static int usbvision_i2c_read(void *data, unsigned char addr, char *buf, short len);static int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg);static int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg, unsigned char value);static int usbvision_request_intra (struct usb_usbvision *usbvision);static int usbvision_unrequest_intra (struct usb_usbvision *usbvision);static int usbvision_adjust_compression (struct usb_usbvision *usbvision);static int usbvision_measure_bandwidth (struct usb_usbvision *usbvision);static void usbvision_release(struct usb_usbvision *usbvision);// Bit flags (options)#define FLAGS_RETRY_VIDIOCSYNC (1 << 0)#define FLAGS_MONOCHROME (1 << 1)#define FLAGS_DISPLAY_HINTS (1 << 2)#define FLAGS_OSD_STATS (1 << 3)#define FLAGS_FORCE_TESTPATTERN (1 << 4)#define FLAGS_SEPARATE_FRAMES (1 << 5)#define FLAGS_CLEAN_FRAMES (1 << 6)// Default initalization of device driver parametersstatic int flags = 0; // Set the default Overlay Display mode of the device driverstatic int debug = 0; // Set the default Debug Mode of the device driverstatic int isocMode = ISOC_MODE_COMPRESS; // Set the default format for ISOC endpointstatic int adjustCompression = 1; // Set the compression to be adaptivestatic int dga = 1; // Set the default Direct Graphic Accessstatic int PowerOnAtOpen = 1; // Set the default device to power on at startupstatic int SwitchSVideoInput = 0; // To help people with Black and White output with using s-video input. Some cables and input device are wired differently.static int video_nr = -1; // Sequential Number of Video Devicestatic int radio_nr = -1; // Sequential Number of Radio Devicestatic int vbi_nr = -1; // Sequential Number of VBI Devicestatic char *CustomDevice=NULL; // Set as nothing....// Grab parameters for the device driver#if defined(module_param) // Showing parameters under SYSFSmodule_param(flags, int, 0444);module_param(debug, int, 0444);module_param(isocMode, int, 0444);module_param(adjustCompression, int, 0444);module_param(dga, int, 0444);module_param(PowerOnAtOpen, int, 0444);module_param(SwitchSVideoInput, int, 0444);module_param(video_nr, int, 0444);module_param(radio_nr, int, 0444);module_param(vbi_nr, int, 0444);module_param(CustomDevice, charp, 0444);#else // Old StyleMODULE_PARM(flags, "i"); // Grab the Overlay Display mode of the device driverMODULE_PARM(debug, "i"); // Grab the Debug Mode of the device driverMODULE_PARM(isocMode, "i"); // Grab the video format of the video deviceMODULE_PARM(adjustCompression, "i"); // Grab the compression to be adaptiveMODULE_PARM(dga, "i"); // Grab the Direct Graphic AccessMODULE_PARM(PowerOnAtOpen, "i"); // Grab the device to power on at startupMODULE_PARM(SwitchSVideoInput, "i"); // To help people with Black and White output with using s-video input. Some cables and input device are wired differently.MODULE_PARM(video_nr, "i"); // video_nr option allows to specify a certain /dev/videoX device (like /dev/video0 or /dev/video1 ...) MODULE_PARM(radio_nr, "i"); // radio_nr option allows to specify a certain /dev/radioX device (like /dev/radio0 or /dev/radio1 ...)MODULE_PARM(vbi_nr, "i"); // vbi_nr option allows to specify a certain /dev/vbiX device (like /dev/vbi0 or /dev/vbi1 ...)MODULE_PARM(CustomDevice, "s"); // .... CustomDevice#endifMODULE_PARM_DESC(flags, " Set the default Overlay Display mode of the device driver. Default: 0 (Off)");MODULE_PARM_DESC(debug, " Set the default Debug Mode of the device driver. Default: 0 (Off)");MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)");MODULE_PARM_DESC(adjustCompression, " Set the ADPCM compression for the device. Default: 1 (On)");MODULE_PARM_DESC(dga, " Set the Direct Graphic Access for the device. Default: 1 (On)");MODULE_PARM_DESC(PowerOnAtOpen, " Set the default device to power on when device is opened. Default: 1 (On)");MODULE_PARM_DESC(SwitchSVideoInput, " Set the S-Video input. Some cables and input device are wired differently. Default: 0 (Off)");MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)");MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");MODULE_PARM_DESC(vbi_nr, "Set vbi device number (/dev/vbiX). Default: -1 (autodetect)");MODULE_PARM_DESC(CustomDevice, " Define the fine tuning parameters for the device. Default: null");// Misc stuffMODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE(DRIVER_LICENSE);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) MODULE_VERSION(DRIVER_VERSION); MODULE_ALIAS(DRIVER_ALIAS); #endif#ifdef MODULEstatic unsigned int autoload = 1;#elsestatic unsigned int autoload = 0;#endif/********************************************************************** * /proc interface * Based on the CPiA driver version 0.7.4 -claudio **********************************************************************/#if defined(CONFIG_VIDEO_PROC_FS)static struct proc_dir_entry *usbvision_proc_entry = NULL;extern struct proc_dir_entry *video_proc_entry;#define YES_NO(x) ((x) ? "Yes" : "No")/* /proc/video/usbvision/<minor#>/info */static intusbvision_read_proc_info(char *page, char **start, off_t off, int count, int *eof, void *data){ char *out = page; int idx, len; struct usb_usbvision *usbvision = data; if (!USBVISION_IS_OPERATIONAL(usbvision)) return -ENODEV; // IMPORTANT: This output MUST be kept under PAGE_SIZE // or we need to get more sophisticated. out += sprintf(out, "Driver version : %s\n", DRIVER_VERSION); out += sprintf(out, "VID:PID : %04X:%04X\n", usbvision_device_data[usbvision->DevModel].idVendor, usbvision_device_data[usbvision->DevModel].idProduct); out += sprintf(out, "Model : %s\n", usbvision_device_data[usbvision->DevModel].ModelString); out += sprintf(out, "Streaming : %s\n", YES_NO(usbvision->streaming)); out += sprintf(out, "Overlay : %s\n", YES_NO(usbvision->overlay)); out += sprintf(out, "Compression : %s\n", YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS)); out += sprintf(out, " BlockPos : %d\n", usbvision->BlockPos); out += sprintf(out, "Picture\n"); out += sprintf(out, " Brightness : %d\n", usbvision->vpic.brightness >> 8); out += sprintf(out, " Colour : %d\n", usbvision->vpic.colour >> 8); out += sprintf(out, " Contrast : %d\n", usbvision->vpic.contrast >> 8); out += sprintf(out, " Hue : %d\n", usbvision->vpic.hue >> 8); if (usbvision->isocMode==ISOC_MODE_COMPRESS) { out += sprintf(out, "IntraFrameBuf @ : 0x%p\n", usbvision->IntraFrameBuffer); for (idx = 0; idx < 4; idx++) { out += sprintf(out, "# Blocks Type %d : %d\n", idx, usbvision->ComprBlockTypes[idx]); usbvision->ComprBlockTypes[idx] = 0; } } if (usbvision->overlay) { out += sprintf(out, "Overlay\n"); out += sprintf(out, " Position : %d,%d\n", usbvision->vid_win.x, usbvision->vid_win.y); out += sprintf(out, " Expected size : %dx%d\n", usbvision->vid_win.width, usbvision->vid_win.height); out += sprintf(out, " Current size : %dx%d\n", usbvision->overlay_frame.frmwidth, usbvision->overlay_frame.frmheight); out += sprintf(out, " Depth : %d\n", usbvision_v4l_format[usbvision->overlay_frame.v4l_format].depth); out += sprintf(out, " Format : %s\n", usbvision_v4l_format[usbvision->overlay_frame.v4l_format].desc); out += sprintf(out, " # Clips : %d\n", usbvision->vid_win.clipcount); } else { out += sprintf(out, "FrameBuffer @ : 0x%p\n", usbvision->fbuf); out += sprintf(out, "# Frames : %d\n", USBVISION_NUMFRAMES); for (idx = 0; idx < USBVISION_NUMFRAMES; idx++) { out += sprintf(out, "Frame # : %d\n", idx); out += sprintf(out, " Expected size : %dx%d\n", usbvision->frame[idx].width, usbvision->frame[idx].height); out += sprintf(out, " Current size : %dx%d\n", usbvision->frame[idx].frmwidth, usbvision->frame[idx].frmheight); out += sprintf(out, " Depth : %d\n", usbvision_v4l_format[usbvision->frame[idx].v4l_format].depth); out += sprintf(out, " Format : %s\n", usbvision_v4l_format[usbvision->frame[idx].v4l_format].desc); out += sprintf(out, " Data buffer @ : 0x%p\n", usbvision->frame[idx].data); } } for (idx = 0; idx < USBVISION_I2C_CLIENTS_MAX; idx++) { if (usbvision->i2c_clients[idx] == NULL) continue; out += sprintf(out, "I2C client # : %d\n", idx); out += sprintf(out, " Name : %s\n", usbvision->i2c_clients[idx]->name); out += sprintf(out, " Address : 0x%02X\n", usbvision->i2c_clients[idx]->addr << 1); out += sprintf(out, " Flags : 0x%02X\n", usbvision->i2c_clients[idx]->flags); if (usbvision->i2c_clients[idx]->driver == NULL) continue; out += sprintf(out, " Driver : %s\n", usbvision->i2c_clients[idx]->driver->name); } out += sprintf(out, "Time in irq [ms]: %lu\n", usbvision->timeInIrq * (1000L / HZ)); usbvision->timeInIrq = 0; out += sprintf(out, "Isoc packetsize : %d\n", usbvision->isocPacketSize); out += sprintf(out, "# Packets : %lu\n", usbvision->isocPacketCount); out += sprintf(out, "Isoc URBs : %lu\n", usbvision->isocUrbCount); out += sprintf(out, "Isoc tot data : %lu\n", usbvision->isocDataCount); out += sprintf(out, "# Frames : %d\n", usbvision->frame_num); out += sprintf(out, "usedBandwidth : %d\n", usbvision->usedBandwidth); out += sprintf(out, "comprLevel : %d\n", usbvision->comprLevel); usbvision->maxStripLen = 0; usbvision->isocUrbCount = 0; usbvision->frame_num = 0; usbvision->isocDataCount = 0; usbvision->isocPacketCount = 0; out += sprintf(out, "Usb bus # : %d\n", usbvision->dev->bus->busnum); out += sprintf(out, "Usb device # : %d\n", usbvision->dev->devnum); len = out - page; len -= off; if (len < count) { *eof = 1; if (len <= 0) return 0; } else len = count; *start = page + off; return len;}/* /proc/video/usbvision/<minor#>/register */static intusbvision_read_proc_register(char *page, char **start, off_t off, int count, int *eof, void *data){ char *out = page; int idx, len; struct usb_usbvision *usbvision = data; if (!USBVISION_IS_OPERATIONAL(usbvision)) return -ENODEV; // IMPORTANT: This output MUST be kept under PAGE_SIZE // or we need to get more sophisticated. out += sprintf(out, "Addr.\tValue\n"); for (idx = 0; idx < USBVISION_MAX_DIST_H + 1; idx++) { out += sprintf(out, "0x%02X\t0x%02X\n", idx, usbvision_read_reg(usbvision, idx)); } len = out - page; len -= off; if (len < count) { *eof = 1; if (len <= 0) return 0; } else len = count; *start = page + off; return len;}static intusbvision_read_proc_frame(char *page, char **start, off_t off, int count, int *eof, void *data){ char *out = page; int len; struct usb_usbvision *usbvision = data; if (!USBVISION_IS_OPERATIONAL(usbvision)) return -ENODEV; // IMPORTANT: This output MUST be kept under PAGE_SIZE // or we need to get more sophisticated. if (usbvision->frame[0].grabstate == FrameState_Ready) memcpy(out, usbvision->frame[0].data, PAGE_SIZE-1); else if (usbvision->frame[1].grabstate == FrameState_Ready) memcpy(out, usbvision->frame[1].data, PAGE_SIZE-1); len = PAGE_SIZE-1; len -= off; if (len < count) { *eof = 1; if (len <= 0) return 0; } else len = count; *start = page + off; return len;}/* /proc/video/usbvision/<minor#>/register */static intusbvision_write_proc_register (struct file *file, const char *buffer, unsigned long count, void *data){ char *in = (char *)buffer; unsigned int reg_addr, reg_value; int ret; struct usb_usbvision *usbvision = data; in[count] = 0; rmspace(in); do { ret = sscanf(in,"0x%x",®_addr); if (ret == 0) { printk(KERN_INFO "usbvision_write_proc_register: ret=%d\n", ret); //break; } goto2next(in); ret = sscanf(in,"0x%x",®_value); if (ret == 0) { printk(KERN_INFO "usbvision_write_proc_register: ret=%d\n", ret); //break; } printk(KERN_INFO "usbvision_write_proc_register will write %d to %d\n", reg_value, reg_addr); usbvision_write_reg(usbvision, (unsigned char)reg_addr, (unsigned char)reg_value); } while(0); return (int)count;}static voidusbvision_proc_dev_create(struct usb_usbvision *usbvision){ char dirname[10]; if (!usbvision_proc_entry || !usbvision) return; // Create per-device directory#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 10) snprintf(dirname, 10, "%d", usbvision->vdev->minor);#else sprintf(dirname, "%d", usbvision->vdev->minor);#endif PDEBUG(DBG_PROCFS, "creating /proc/video/usbvision/%s/", dirname); usbvision->proc_devdir = create_proc_entry(dirname, S_IFDIR, usbvision_proc_entry); if (!usbvision->proc_devdir) return; usbvision->proc_devdir->owner = THIS_MODULE; // Create "info" entry (human readable device information) PDEBUG(DBG_PROCFS, "creating /proc/video/usbvision/%s/info", dirname); usbvision->proc_info = create_proc_read_entry("info", S_IFREG|S_IRUGO|S_IWUSR, usbvision->proc_devdir, usbvision_read_proc_info, usbvision); if (!usbvision->proc_info) return; usbvision->proc_info->owner = THIS_MODULE; // Create "register" entry (read/write interface) PDEBUG(DBG_PROCFS, "creating /proc/video/usbvision/%s/register", dirname); usbvision->proc_register = create_proc_read_entry("register", S_IFREG|S_IRUGO|S_IWUSR, usbvision->proc_devdir, usbvision_read_proc_register, usbvision); if (!usbvision->proc_register) return; usbvision->proc_register->owner = THIS_MODULE; usbvision->proc_register->write_proc = usbvision_write_proc_register; // Create "frame" entry PDEBUG(DBG_PROCFS, "creating /proc/video/usbvision/%s/frame", dirname); usbvision->proc_frame = create_proc_read_entry("frame", S_IFREG|S_IRUGO|S_IWUSR, usbvision->proc_devdir, usbvision_read_proc_frame, usbvision); if (!usbvision->proc_frame) return; usbvision->proc_frame->owner = THIS_MODULE;}static voidusbvision_proc_dev_destroy(struct usb_usbvision *usbvision){ char dirname[10]; if (!usbvision || !usbvision->proc_devdir) return;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 10) snprintf(dirname, 10, "%d", usbvision->vdev->minor);#else sprintf(dirname, "%d", usbvision->vdev->minor);#endif /* Destroy "control" entry */ if (usbvision->proc_control) { PDEBUG(DBG_PROCFS, "destroying /proc/video/usbvision/%s/control", dirname);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -