📄 usbvision.c
字号:
remove_proc_entry("control", usbvision->proc_devdir); usbvision->proc_control = NULL; } /* Destroy "button" entry */ if (usbvision->proc_button) { PDEBUG(DBG_PROCFS, "destroying /proc/video/usbvision/%s/button", dirname); remove_proc_entry("button", usbvision->proc_devdir); usbvision->proc_button = NULL; } /* Destroy "frame" entry */ if (usbvision->proc_frame) { PDEBUG(DBG_PROCFS, "destroying /proc/video/usbvision/%s/frame", dirname); remove_proc_entry("frame", usbvision->proc_devdir); usbvision->proc_frame = NULL; } /* Destroy "register" entry */ if (usbvision->proc_register) { PDEBUG(DBG_PROCFS, "destroying /proc/video/usbvision/%s/register", dirname); remove_proc_entry("register", usbvision->proc_devdir); usbvision->proc_register = NULL; } /* Destroy "info" entry */ if (usbvision->proc_info) { PDEBUG(DBG_PROCFS, "destroying /proc/video/usbvision/%s/info", dirname); remove_proc_entry("info", usbvision->proc_devdir); usbvision->proc_info = NULL; } /* Destroy per-device directory */ PDEBUG(DBG_PROCFS, "destroying /proc/video/usbvision/%s/", dirname); remove_proc_entry(dirname, usbvision_proc_entry); usbvision->proc_devdir = NULL;}static voidusbvision_proc_create(void){ /* No current standard here. Alan prefers /proc/video/ as it keeps * /proc "less cluttered than /proc/randomcardifoundintheshed/" * -claudio */ if (video_proc_entry == NULL) { err("Error: /proc/video/ does not exist"); return; } usbvision_proc_entry = create_proc_entry("usbvision", S_IFDIR, video_proc_entry); if (usbvision_proc_entry) usbvision_proc_entry->owner = THIS_MODULE; else err("Unable to create /proc/video/usbvision");}static voidusbvision_proc_destroy(void){ PDEBUG(3, "removing /proc/video/usbvision"); if (usbvision_proc_entry == NULL) return; remove_proc_entry("usbvision", video_proc_entry);}#elsestatic inline void usbvision_proc_dev_create(struct usb_usbvision *usbvision) { }static inline void usbvision_proc_dev_destroy(struct usb_usbvision *usbvision) { }static inline void usbvision_proc_create(void) { }static inline void usbvision_proc_destroy(void) { }#endif /* #ifdef CONFIG_VIDEO_PROC_FS *//****************************************************************************************//* SYSFS Code - Copied from the stv680.c usb module. *//* Device information is located at /sys/class/video4linux/video0 *//* Device parameters information is located at /sys/module/usbvision *//* Device USB Information is located at /sys/bus/usb/drivers/USBVision Video Grabber *//****************************************************************************************/#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)#define YES_NO(x) ((x) ? "Yes" : "No")static inline struct usb_usbvision *cd_to_usbvision(struct class_device *cd){ struct video_device *vdev = to_video_device(cd); return video_get_drvdata(vdev);}static ssize_t show_version(struct class_device *cd, char *buf){ return sprintf(buf, "%s\n", DRIVER_VERSION);} static CLASS_DEVICE_ATTR(version, S_IRUGO, show_version, NULL);static ssize_t show_model(struct class_device *class_dev, char *buf){ struct video_device *vdev = to_video_device(class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%s\n", usbvision_device_data[usbvision->DevModel].ModelString);} static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL);static ssize_t show_hue(struct class_device *class_dev, char *buf){ struct video_device *vdev = to_video_device(class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%d\n", usbvision->vpic.hue >> 8);} static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);static ssize_t show_contrast(struct class_device *class_dev, char *buf){ struct video_device *vdev = to_video_device(class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%d\n", usbvision->vpic.contrast >> 8);} static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);static ssize_t show_brightness(struct class_device *class_dev, char *buf){ struct video_device *vdev = to_video_device(class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%d\n", usbvision->vpic.brightness >> 8);} static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);static ssize_t show_colour(struct class_device *class_dev, char *buf){ struct video_device *vdev = to_video_device(class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%d\n", usbvision->vpic.colour >> 8);} static CLASS_DEVICE_ATTR(colour, S_IRUGO, show_colour, NULL);static ssize_t show_streaming(struct class_device *class_dev, char *buf){ struct video_device *vdev = to_video_device(class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%s\n", YES_NO(usbvision->streaming));} static CLASS_DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL);static ssize_t show_overlay(struct class_device *class_dev, char *buf){ struct video_device *vdev = to_video_device(class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%s\n", YES_NO(usbvision->overlay));} static CLASS_DEVICE_ATTR(overlay, S_IRUGO, show_overlay, NULL);static ssize_t show_compression(struct class_device *class_dev, char *buf){ struct video_device *vdev = to_video_device(class_dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%s\n", YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS));} static CLASS_DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL);static void usbvision_create_sysfs(struct video_device *vdev){ if (vdev) { video_device_create_file(vdev, &class_device_attr_version); video_device_create_file(vdev, &class_device_attr_model); video_device_create_file(vdev, &class_device_attr_hue); video_device_create_file(vdev, &class_device_attr_contrast); video_device_create_file(vdev, &class_device_attr_brightness); video_device_create_file(vdev, &class_device_attr_colour); video_device_create_file(vdev, &class_device_attr_streaming); video_device_create_file(vdev, &class_device_attr_overlay); video_device_create_file(vdev, &class_device_attr_compression); }}static void usbvision_remove_sysfs(struct video_device *vdev){ if (vdev) { video_device_remove_file(vdev, &class_device_attr_version); video_device_remove_file(vdev, &class_device_attr_model); video_device_remove_file(vdev, &class_device_attr_hue); video_device_remove_file(vdev, &class_device_attr_contrast); video_device_remove_file(vdev, &class_device_attr_brightness); video_device_remove_file(vdev, &class_device_attr_colour); video_device_remove_file(vdev, &class_device_attr_streaming); video_device_remove_file(vdev, &class_device_attr_overlay); video_device_remove_file(vdev, &class_device_attr_compression); }}#endif/*******************************//* Memory management functions *//*******************************//* * Here we want the physical address of the memory. * This is used when initializing the contents of the area. */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)unsigned long usbvision_kvirt_to_pa(unsigned long adr){ unsigned long kva, ret; kva = (unsigned long) page_address(vmalloc_to_page((void *)adr)); kva |= adr & (PAGE_SIZE-1); /* restore the offset */ ret = __pa(kva); return ret;}#endifvoid *usbvision_rvmalloc(unsigned long size){ void *mem; unsigned long adr; size = PAGE_ALIGN(size); mem = vmalloc_32(size); if (!mem) return NULL; memset(mem, 0, size); /* Clear the ram out, no junk to the user */ adr = (unsigned long) mem; while (size > 0) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) mem_map_reserve(vmalloc_to_page((void *)adr)); #else SetPageReserved(vmalloc_to_page((void *)adr)); #endif adr += PAGE_SIZE; size -= PAGE_SIZE; } return mem;}void usbvision_rvfree(void *mem, unsigned long size){ unsigned long adr; if (!mem) return; adr = (unsigned long) mem; while ((long) size > 0) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) mem_map_unreserve(vmalloc_to_page((void *)adr)); #else ClearPageReserved(vmalloc_to_page((void *)adr)); #endif adr += PAGE_SIZE; size -= PAGE_SIZE; } vfree(mem);}#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,25)/* helper functions to access driver private data. */static inline void *video_get_drvdata(struct video_device *dev){ return dev->priv;}static inline void video_set_drvdata(struct video_device *dev, void *data){ dev->priv = data;}struct video_device *video_device_alloc(void){ struct video_device *vfd; vfd = kmalloc(sizeof(*vfd),GFP_KERNEL); if (NULL == vfd) return NULL; memset(vfd,0,sizeof(*vfd)); return vfd;}void video_device_release(struct video_device *vfd){ kfree(vfd);}#endif#if ENABLE_HEXDUMPstatic void usbvision_hexdump(const unsigned char *data, int len){ char tmp[80]; int i, k; for (i = k = 0; len > 0; i++, len--) { if (i > 0 && (i % 16 == 0)) { printk("%s\n", tmp); k = 0; } k += sprintf(&tmp[k], "%02x ", data[i]); } if (k > 0) printk("%s\n", tmp);}#endif/* These procedures handle the scratch ring buffer */int scratch_len(struct usb_usbvision *usbvision) /*This returns the amount of data actually in the buffer */{ int len = usbvision->scratch_write_ptr - usbvision->scratch_read_ptr; if (len < 0) { len += scratch_buf_size; } PDEBUG(DBG_SCRATCH, "scratch_len() = %d\n", len); return len;}/* This returns the free space left in the buffer */int scratch_free(struct usb_usbvision *usbvision){ int free = usbvision->scratch_read_ptr - usbvision->scratch_write_ptr; if (free <= 0) { free += scratch_buf_size; } if (free) { free -= 1; /* at least one byte in the buffer must */ /* left blank, otherwise there is no chance to differ between full and empty */ } PDEBUG(DBG_SCRATCH, "return %d\n", free); return free;}void *debug_memcpy(void *dest, void *src, size_t len){ printk(KERN_DEBUG "memcpy(%p, %p, %d);\n", dest, src, len); return memcpy(dest, src, len);}/* This puts data into the buffer */int scratch_put(struct usb_usbvision *usbvision, unsigned char *data, int len){ int len_part; if (usbvision->scratch_write_ptr + len < scratch_buf_size) { memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len); usbvision->scratch_write_ptr += len; } else { len_part = scratch_buf_size - usbvision->scratch_write_ptr; memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len_part); if (len == len_part) { usbvision->scratch_write_ptr = 0; /* just set write_ptr to zero */ } else { memcpy(usbvision->scratch, data + len_part, len - len_part); usbvision->scratch_write_ptr = len - len_part; } } PDEBUG(DBG_SCRATCH, "len=%d, new write_ptr=%d\n", len, usbvision->scratch_write_ptr); return len;}/* This marks the write_ptr as position of new frame header */void scratch_mark_header(struct usb_usbvision *usbvision){ PDEBUG(DBG_SCRATCH, "header at write_ptr=%d\n", usbvision->scratch_headermarker_write_ptr); usbvision->scratch_headermarker[usbvision->scratch_headermarker_write_ptr] = usbvision->scratch_write_ptr; usbvision->scratch_headermarker_write_ptr += 1; usbvision->scratch_headermarker_write_ptr %= USBVISION_NUM_HEADERMARKER;}/* This gets data from the buffer at the given "ptr" position */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -