⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zc030x_main.c

📁 中星微301摄想头最新驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Implementation file for kernel spec *//* Zc030x     -- Driver --      Zc030x *//* This file is under GPL              *//* Copyright :         Martin     Braun         Arnaud     Patard         Andre      Freitas         Tommy         Andrew     Birkett                  Cyril      Russo---------------------------------------*//* Include the kernel headers */#include <linux/config.h>#include <linux/version.h>/* Declare module versions specific */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)#define MODVERSIONS#endif#ifdef MODVERSIONS#include <linux/modversions.h>#endif#endif/* Module insertion + scheduler + usb */#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/usb.h>#include <linux/slab.h> /* This module specific declarations */ /* Include kernel definitions */#include "zc030x_kerneldef.h"/* Jpeg decoding to RGB/YUV */#include "zc030x_jpeg.h"/* V4L specific */#include "zc030x_v4l.h"/* Proc fs specific */#include "zc030x_proc.h"/* Memory management */#include "zc030x_mm.h"/* I2C register reading */#include "zc030x_i2c.h"/* Bridge chip registers */#include "zc030x_reg.h"/* Camera specific */#include "zc030x_cameras.h"/* Isochronous transfers */#include "zc030x_isochron.h"/* Matrix stuff */#include "zc030x_matrix.h"/* Module paramaters */int debug = 5;int width = 320;int currentwidth = 0;int height = 232;int currentheight = 0;int quality = 1;int sensoraccept = 90;char * sensor = (char*)"auto";/* Debug level */MODULE_PARM (debug, "i");MODULE_PARM_DESC (debug, "Debug level 1:Release -> 5:All messages");/* Default width */MODULE_PARM (width, "i");MODULE_PARM_DESC (width, "Default width of the frame");/* Default height */MODULE_PARM (height, "i");MODULE_PARM_DESC (height, "Default height of the frame");/* Default quality */MODULE_PARM (quality, "i");MODULE_PARM_DESC (quality, "Picture quality 1:Normal 5:Very high (CPU intensive)");/* Sensor accept level */MODULE_PARM (sensoraccept, "i");MODULE_PARM_DESC (sensoraccept, "Sensor signature accept level (in percent) 0:Accept any unmatching sensors -> 100: Accept sensor only if its signature match");/* Sensor accept level */MODULE_PARM (sensor, "s");MODULE_PARM_DESC (sensor, "Sensor name (to avoid detection)");/* Needed declarations */MODULE_AUTHOR("Martin Braun <martinbraun at gmx.net>, Arnaud Patard <thertp at users.sourceforge.net>, Andre Freitas <linux at uninet.com.br>, Cyril Russo<>, Andrew Birkett <andy@nobugs.org>");MODULE_DESCRIPTION("ZC030X USB Camera Driver");MODULE_LICENSE("GPL");/* Device table */MODULE_DEVICE_TABLE (usb, zc030x_table);/* USB device functions */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) static void *zc030x_probe (struct usb_device *dev, unsigned int ifnum,	const struct usb_device_id *id);static void zc030x_disconnect (struct usb_device *dev, void *ptr);#elsestatic int zc030x_probe (struct usb_interface *interface, const struct usb_device_id *id);static void zc030x_disconnect (struct usb_interface *interface);#endif/* Exported read function */ ssize_t zc030x_read (struct file *file, char *buffer, size_t count, loff_t * ppos);/* Exported ioctl function */ int zc030x_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);/* Exported mmap function */ int zc030x_mmap(struct file *file, struct vm_area_struct *vma);/* Exported open function */ int zc030x_open (struct inode *inode, struct file *file);/* Exported release function */ int zc030x_release (struct inode *inode, struct file *file);/* File operations supported by this device */struct file_operations zc030x_fops = {    .owner      =	    THIS_MODULE,    .open       =	    zc030x_open,    .release    =	    zc030x_release,    .read       =	    zc030x_read,    .ioctl      =	    zc030x_ioctl,    .mmap       =       zc030x_mmap,     .llseek     =       no_llseek,};/* Lock to protect the minor_table structure */static DECLARE_MUTEX (disconnect_sem);/* USB specific object needed to register this driver with the USB subsystem */static struct usb_driver zc030x_driver = {    .owner =        THIS_MODULE,    .name =	        "zc030x",    .probe =	    zc030x_probe,    .disconnect =   zc030x_disconnect,    .id_table =     zc030x_table,};/* Probe for a device matching the ID given in the table */#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)static int zc030x_probe(struct usb_interface *intf, const struct usb_device_id *id)#elsestatic void *zc030x_probe (struct usb_device *udev, unsigned int ifnum,	                   const struct usb_device_id *id)#endif{    /* Zc030x device pointer */    struct usb_zc030x *dev = NULL;    /* Interface descriptor */    struct usb_interface_descriptor *iface;    /* Iterator */    int i;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)    /* Actual alternate settings */    int actalt = 0;#else    struct usb_device *udev = interface_to_usbdev(intf);#endif      /* Debug this probing */    PDEBUG(1,"probe!!\n");        /* Removed the following line */    //    probe_calls++;        /* Check for multiconfiguration devices */    if (udev->descriptor.bNumConfigurations != 1)    {        PDEBUG(1,"ERROR: Can't handle camera: multiconfiguration device");        goto nodevice;    }    #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)    if (ifnum > 0)  goto nodevice;        /* Skip probe for alternate settings (fixed)*/    actalt = udev->actconfig->interface[ifnum].act_altsetting;    if (actalt > 0) goto nodevice; #endif          /*** If we reach this point, we found our interface/altsetting */    PDEBUG(3, ">> zc030x_probe");#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)    MOD_INC_USE_COUNT;#endif         /* Allocate memory for our device object and intialize it */    dev = kmalloc (sizeof (struct usb_zc030x), GFP_KERNEL);        /* Check allocation */    if (dev == NULL)         { err ("Couldn't kalloc zc030x device struct!"); goto error; }    /* Clear it */    memset (dev, 0x00, sizeof (struct usb_zc030x));    /* Start filling it */    dev->udev = udev;    /* Detect our camera ! */    if ((zc030x_detect_camera (dev)) < 0)    {        PDEBUG(1,"ERROR: Device not supported !");        goto error;    }           /* Init mutexes */    init_MUTEX (&dev->sem);    init_MUTEX (&dev->buf_lock);        /* USB specific initialization... */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)       PDEBUG (3, "Set device configuration to %d\n", DEFAULT_CONFIGURATION);    usb_set_configuration (udev, DEFAULT_CONFIGURATION);#endif    PDEBUG (3, "Set interface to %d\n", VIDEO_INTERFACE);    PDEBUG (3, "Set alternate configuration %d\n", dev->alt);    usb_set_interface (udev, VIDEO_INTERFACE, dev->alt);    #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)    iface = &udev->actconfig->interface[ifnum].altsetting[dev->alt];#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,6)    iface = &intf->cur_altsetting->desc;#else    iface = &intf->altsetting[dev->alt].desc;#endif        dev->iface_desc = iface;        /* Endpoint scan procedure was removed, think we can stick with fixed values */    dev->isocend = 0x01;    dev->intrend = 0x02;        /* Create the Video For Linux device */    if (zc030x_v4l_initdev(&zc030x_fops, dev, CamList[dev->type_id].Name, udev) == V4L_Error)    {        PDEBUG(1, "Error while registering the camera!");        goto error;    }        /* Init device queue */    init_waitqueue_head(&dev->wq);    /* Init frame queue */    for (i = 0; i < ZC030X_NUMFRAMES; i++)    {        init_waitqueue_head(&dev->frame[i].wq);        /* Reset the frame sequence number */        dev->frame[i].SeqNumber=0;        /* And init its lock too */        init_MUTEX(&dev->frame[i].Lock);    }    /* Set the default brightness contrast and gamma */    dev->Brightness = DefaultBrightness;    dev->Contrast   = DefaultContrast;    dev->Gamma      = DefaultGamma;        /* Create a gamma array and debug it */    zc030x_gamma_init();    /* Initialize the pseudo-JPEG decoder  */     zc030x_jpeg_init();        /* Configure the zc030x camera */    if (zc030x_configure_camera(dev, width, height, quality) != 0 )     {        PDEBUG(1, "Error while configuring the camera!");        goto error;    }        /* Allow device read, ioctl, mmap */    dev->present = 1;                //PDEBUG(1,"Probe was called %d times", probe_calls);    /* Okay, return */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)    MOD_DEC_USE_COUNT;    return dev;#else    usb_set_intfdata(intf, dev);    return 0;#endif    nodevice:    /* Quit */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)    return NULL; #else    return -ENODEV;#endif     error:    /* Release video device */    zc030x_v4l_releasedev(dev->pVideoDevice);    /* Release the driver it self */    if (dev != NULL)    kfree(dev);    /* And quit */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)    MOD_DEC_USE_COUNT;    return NULL;#else    return -ENOMEM;#endif  }/* Handle disconnected device  */						 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)static void zc030x_disconnect(struct usb_interface *interface){    struct usb_zc030x *dev =  usb_get_intfdata (interface);    usb_set_intfdata (interface, NULL);#else  static void zc030x_disconnect (struct usb_device *udev, void *ptr){    struct usb_zc030x *dev = (struct usb_zc030x *) ptr;#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)    MOD_INC_USE_COUNT;#endif    PDEBUG(3,">> zc030x_disconnect()");          /* prevent races with open */    down (&disconnect_sem);        /* prevent device read, write and ioctl */    dev->present = 0;        /* We don't want people trying to open up the device */    zc030x_v4l_releasedev(dev->pVideoDevice);         /* Stop stream (if any) and unlink & free urbs */      zc030x_isoc_stop(dev);        /* Dellocate buffers */    zc030x_unallocate_buffers(dev);         /* Deregister interrupt urb */    usb_unlink_urb(dev->inturb);    usb_free_urb(dev->inturb);        /* Take up the lock */    down (&dev->sem);        /* if the device is not opened, then we clean up right now */    if (!dev->open)     {        up (&dev->sem);        kfree (dev);    }    else     {        dev->udev = NULL;        up (&dev->sem);    }        /* Release the lock */    up (&disconnect_sem);    #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)    MOD_DEC_USE_COUNT;#endif}/* Open the device from its /dev/videoX structure */int zc030x_open (struct inode *inode, struct file *file){    /* Get the video device */    struct video_device *vdev = video_devdata(file);    /* And the USB device too */    struct usb_zc030x *dev;        /* Debug this function */    PDEBUG(3,">> zc030x_open()");    /* Check argument */        if (vdev == NULL)    {        PDEBUG (2, "vdev is NULL, returning");        return 0;    }        /* Get driver data */    dev = video_get_drvdata(vdev);    if (dev == NULL)    {        PDEBUG (2, "dev is NULL, returning");        return 0;    }    #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)    MOD_INC_USE_COUNT;#endif        /* Lock this device before modifying it */    down (&dev->sem);       /* Increment our usage count for the driver */    ++dev->open;    /* Save our object in the file's private structure */    file->private_data = vdev;        /* Check the current video format */    if (!dev->VideoFormat)        dev->VideoFormat = VIDEO_PALETTE_RGB24;    /* Set the default brightness contrast and gamma */    dev->Brightness = DefaultBrightness;    dev->Contrast   = DefaultContrast;    dev->Gamma      = DefaultGamma;        /* Init the isochronous transfers */    zc030x_isoc_start(dev);        /* unlock this device */    up (&dev->sem);        /* Return */    PDEBUG(3,"<< zc030x_open()");    return 0;}/* Release the device through its /dev/videoX file */int zc030x_release (struct inode *inode, struct file *file){    /* Get the video device */    struct video_device *vdev = video_devdata(file);    /* And the USB device too */    struct usb_zc030x *dev;    /* Iterator */    int i = 0;        /* Debug this function */    PDEBUG(3,">> zc030x_release()");    /* Check parameter */    if (vdev == NULL)    {        PDEBUG (2, "vdev is NULL, returning");        return 0;    }        /* Get USB device too */    dev = video_get_drvdata(vdev);    if (dev == NULL)    {        PDEBUG (2, "dev is NULL, returning");        return 0;    }        /* Lock our device */    down (&dev->sem);        /* Check if the device is opened */    if (dev->open <= 0)    {        PDEBUG (5, "%s - device not opened", __FUNCTION__);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -