linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / usb / media / w9968cf.c
index 36fbe80..9937fc6 100644 (file)
@@ -25,7 +25,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               *
  ***************************************************************************/
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/kmod.h>
@@ -63,7 +62,6 @@ MODULE_LICENSE(W9968CF_MODULE_LICENSE);
 MODULE_SUPPORTED_DEVICE("Video");
 
 static int ovmod_load = W9968CF_OVMOD_LOAD;
-static int vppmod_load = W9968CF_VPPMOD_LOAD;
 static unsigned short simcams = W9968CF_SIMCAMS;
 static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/
 static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] = 
@@ -108,33 +106,32 @@ static unsigned int param_nv[24]; /* number of values per parameter */
 
 #ifdef CONFIG_KMOD
 module_param(ovmod_load, bool, 0644);
-module_param(vppmod_load, bool, 0444);
 #endif
 module_param(simcams, ushort, 0644);
-module_param_array(video_nr, short, param_nv[0], 0444);
-module_param_array(packet_size, uint, param_nv[1], 0444);
-module_param_array(max_buffers, ushort, param_nv[2], 0444);
-module_param_array(double_buffer, bool, param_nv[3], 0444);
-module_param_array(clamping, bool, param_nv[4], 0444);
-module_param_array(filter_type, ushort, param_nv[5], 0444);
-module_param_array(largeview, bool, param_nv[6], 0444);
-module_param_array(decompression, ushort, param_nv[7], 0444);
-module_param_array(upscaling, bool, param_nv[8], 0444);
-module_param_array(force_palette, ushort, param_nv[9], 0444);
-module_param_array(force_rgb, ushort, param_nv[10], 0444);
-module_param_array(autobright, bool, param_nv[11], 0444);
-module_param_array(autoexp, bool, param_nv[12], 0444);
-module_param_array(lightfreq, ushort, param_nv[13], 0444);
-module_param_array(bandingfilter, bool, param_nv[14], 0444);
-module_param_array(clockdiv, short, param_nv[15], 0444);
-module_param_array(backlight, bool, param_nv[16], 0444);
-module_param_array(mirror, bool, param_nv[17], 0444);
-module_param_array(monochrome, bool, param_nv[18], 0444);
-module_param_array(brightness, uint, param_nv[19], 0444);
-module_param_array(hue, uint, param_nv[20], 0444);
-module_param_array(colour, uint, param_nv[21], 0444);
-module_param_array(contrast, uint, param_nv[22], 0444);
-module_param_array(whiteness, uint, param_nv[23], 0444);
+module_param_array(video_nr, short, &param_nv[0], 0444);
+module_param_array(packet_size, uint, &param_nv[1], 0444);
+module_param_array(max_buffers, ushort, &param_nv[2], 0444);
+module_param_array(double_buffer, bool, &param_nv[3], 0444);
+module_param_array(clamping, bool, &param_nv[4], 0444);
+module_param_array(filter_type, ushort, &param_nv[5], 0444);
+module_param_array(largeview, bool, &param_nv[6], 0444);
+module_param_array(decompression, ushort, &param_nv[7], 0444);
+module_param_array(upscaling, bool, &param_nv[8], 0444);
+module_param_array(force_palette, ushort, &param_nv[9], 0444);
+module_param_array(force_rgb, ushort, &param_nv[10], 0444);
+module_param_array(autobright, bool, &param_nv[11], 0444);
+module_param_array(autoexp, bool, &param_nv[12], 0444);
+module_param_array(lightfreq, ushort, &param_nv[13], 0444);
+module_param_array(bandingfilter, bool, &param_nv[14], 0444);
+module_param_array(clockdiv, short, &param_nv[15], 0444);
+module_param_array(backlight, bool, &param_nv[16], 0444);
+module_param_array(mirror, bool, &param_nv[17], 0444);
+module_param_array(monochrome, bool, &param_nv[18], 0444);
+module_param_array(brightness, uint, &param_nv[19], 0444);
+module_param_array(hue, uint, &param_nv[20], 0444);
+module_param_array(colour, uint, &param_nv[21], 0444);
+module_param_array(contrast, uint, &param_nv[22], 0444);
+module_param_array(whiteness, uint, &param_nv[23], 0444);
 #ifdef W9968CF_DEBUG
 module_param(debug, ushort, 0644);
 module_param(specific_debug, bool, 0644);
@@ -151,18 +148,6 @@ MODULE_PARM_DESC(ovmod_load,
                  "\ninto memory."
                  "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"."
                  "\n");
-MODULE_PARM_DESC(vppmod_load, 
-                 "\n<0|1> Automatic 'w9968cf-vpp' module loading."
-                 "\n0 disabled, 1 enabled."
-                 "\nIf enabled, every time an application attempts to open a"
-                 "\ncamera, 'insmod' searches for the video post-processing"
-                 "\nmodule in the system and loads it automatically (if"
-                 "\npresent). The optional 'w9968cf-vpp' module adds extra"
-                 "\n image manipulation functions to the 'w9968cf' module,like"
-                 "\nsoftware up-scaling,colour conversions and video decoding"
-                 "\nfor very high frame rates."
-                 "\nDefault value is "__MODULE_STRING(W9968CF_VPPMOD_LOAD)"."
-                 "\n");
 #endif
 MODULE_PARM_DESC(simcams, 
                  "\n<n> Number of cameras allowed to stream simultaneously."
@@ -457,7 +442,6 @@ static int w9968cf_i2c_control(struct i2c_adapter*, unsigned int cmd,
                                unsigned long arg);
 
 /* Memory management */
-static inline unsigned long kvirt_to_pa(unsigned long adr);
 static void* rvmalloc(unsigned long size);
 static void rvfree(void *mem, unsigned long size);
 static void w9968cf_deallocate_memory(struct w9968cf_device*);
@@ -494,10 +478,6 @@ static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num);
 static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**);
 static void w9968cf_release_resources(struct w9968cf_device*);
 
-/* Intermodule communication */
-static int w9968cf_vppmod_detect(struct w9968cf_device*);
-static void w9968cf_vppmod_release(struct w9968cf_device*);
-
 
 
 /****************************************************************************
@@ -611,20 +591,6 @@ static struct w9968cf_symbolic_list urb_errlist[] = {
 /****************************************************************************
  * Memory management functions                                              *
  ****************************************************************************/
-
-/* Here we want the physical address of the memory.
-   This is used when initializing the contents of the area. */
-static inline unsigned long 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;
-}
-
-
 static void* rvmalloc(unsigned long size)
 {
        void* mem;
@@ -1538,7 +1504,6 @@ static u32 w9968cf_i2c_func(struct i2c_adapter* adap)
 static int w9968cf_i2c_attach_inform(struct i2c_client* client)
 {
        struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
-       const char* clientname = i2c_clientname(client);
        int id = client->driver->id, err = 0;
 
        if (id == I2C_DRIVERID_OVCAMCHIP) {
@@ -1550,12 +1515,12 @@ static int w9968cf_i2c_attach_inform(struct i2c_client* client)
                }
        } else {
                DBG(4, "Rejected client [%s] with driver [%s]", 
-                   clientname, client->driver->name)
+                   client->name, client->driver->driver.name)
                return -EINVAL;
        }
 
        DBG(5, "I2C attach client [%s] with driver [%s]",
-           clientname, client->driver->name)
+           client->name, client->driver->driver.name)
 
        return 0;
 }
@@ -1564,12 +1529,11 @@ static int w9968cf_i2c_attach_inform(struct i2c_client* client)
 static int w9968cf_i2c_detach_inform(struct i2c_client* client)
 {
        struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
-       const char* clientname = i2c_clientname(client);
 
        if (cam->sensor_client == client)
                cam->sensor_client = NULL;
 
-       DBG(5, "I2C detach client [%s]", clientname)
+       DBG(5, "I2C detach client [%s]", client->name)
 
        return 0;
 }
@@ -1588,15 +1552,13 @@ static int w9968cf_i2c_init(struct w9968cf_device* cam)
        int err = 0;
 
        static struct i2c_algorithm algo = {
-               .name =          "W996[87]CF algorithm",
-               .id =            I2C_ALGO_SMBUS,
                .smbus_xfer =    w9968cf_i2c_smbus_xfer,
                .algo_control =  w9968cf_i2c_control,
                .functionality = w9968cf_i2c_func,
        };
 
        static struct i2c_adapter adap = {
-               .id =                I2C_ALGO_SMBUS | I2C_HW_SMBUS_W9968CF,
+               .id =                I2C_HW_SMBUS_W9968CF,
                .class =             I2C_CLASS_CAM_DIGITAL,
                .owner =             THIS_MODULE,
                .client_register =   w9968cf_i2c_attach_inform,
@@ -2757,9 +2719,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
        cam->streaming = 0;
        cam->misconfigured = 0;
 
-       if (!w9968cf_vpp)
-               if ((err = w9968cf_vppmod_detect(cam)))
-                       goto out;
+       w9968cf_adjust_configuration(cam);
 
        if ((err = w9968cf_allocate_memory(cam)))
                goto deallocate_memory;
@@ -2786,7 +2746,6 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
 
 deallocate_memory:
        w9968cf_deallocate_memory(cam);
-out:
        DBG(2, "Failed to open the video device")
        up(&cam->dev_sem);
        up_read(&w9968cf_disconnect);
@@ -2804,8 +2763,6 @@ static int w9968cf_release(struct inode* inode, struct file* filp)
 
        w9968cf_stop_transfer(cam);
 
-       w9968cf_vppmod_release(cam);
-
        if (cam->disconnected) {
                w9968cf_release_resources(cam);
                up(&cam->dev_sem);
@@ -2919,9 +2876,9 @@ static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma)
                return -EINVAL;
 
        while (vsize > 0) {
-               page = kvirt_to_pa(pos) + vma->vm_pgoff;
-               if (remap_page_range(vma, start, page, PAGE_SIZE, 
-                                    vma->vm_page_prot))
+               page = vmalloc_to_pfn((void *)pos);
+               if (remap_pfn_range(vma, start, page + vma->vm_pgoff,
+                                               PAGE_SIZE, vma->vm_page_prot))
                        return -EAGAIN;
                start += PAGE_SIZE;
                pos += PAGE_SIZE;
@@ -2978,7 +2935,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
        };
 
        #define V4L1_IOCTL(cmd) \
-               ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \
+               ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \
                v4l1_ioctls[_IOC_NR((cmd))] : "?")
 
        cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
@@ -3510,6 +3467,7 @@ static struct file_operations w9968cf_fops = {
        .release = w9968cf_release,
        .read =    w9968cf_read,
        .ioctl =   w9968cf_ioctl,
+       .compat_ioctl = v4l_compat_ioctl32,
        .mmap =    w9968cf_mmap,
        .llseek =  no_llseek,
 };
@@ -3531,11 +3489,11 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
        u8 sc = 0; /* number of simultaneous cameras */
        static unsigned short dev_nr = 0; /* we are handling device number n */
 
-       if (udev->descriptor.idVendor  == winbond_id_table[0].idVendor &&
-           udev->descriptor.idProduct == winbond_id_table[0].idProduct)
+       if (le16_to_cpu(udev->descriptor.idVendor)  == winbond_id_table[0].idVendor &&
+           le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
                mod_id = W9968CF_MOD_CLVBWGP; /* see camlist[] table */
-       else if (udev->descriptor.idVendor  == winbond_id_table[1].idVendor &&
-                udev->descriptor.idProduct == winbond_id_table[1].idProduct)
+       else if (le16_to_cpu(udev->descriptor.idVendor)  == winbond_id_table[1].idVendor &&
+                le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[1].idProduct)
                mod_id = W9968CF_MOD_GENERIC; /* see camlist[] table */
        else
                return -ENODEV;
@@ -3574,7 +3532,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
 
 
        /* Allocate 2 bytes of memory for camera control USB transfers */
-       if (!(cam->control_buffer = (u16*)kmalloc(2, GFP_KERNEL))) {
+       if (!(cam->control_buffer = kmalloc(2, GFP_KERNEL))) {
                DBG(1,"Couldn't allocate memory for camera control transfers")
                err = -ENOMEM;
                goto fail;
@@ -3582,7 +3540,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
        memset(cam->control_buffer, 0, 2);
 
        /* Allocate 8 bytes of memory for USB data transfers to the FSB */
-       if (!(cam->data_buffer = (u16*)kmalloc(8, GFP_KERNEL))) {
+       if (!(cam->data_buffer = kmalloc(8, GFP_KERNEL))) {
                DBG(1, "Couldn't allocate memory for data "
                       "transfers to the FSB")
                err = -ENOMEM;
@@ -3639,10 +3597,8 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
        return 0;
 
 fail: /* Free unused memory */
-       if (cam->control_buffer)
-               kfree(cam->control_buffer);
-       if (cam->data_buffer)
-               kfree(cam->data_buffer);
+       kfree(cam->control_buffer);
+       kfree(cam->data_buffer);
        if (cam->v4ldev)
                video_device_release(cam->v4ldev);
        up(&cam->dev_sem);
@@ -3690,7 +3646,6 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf)
 
 
 static struct usb_driver w9968cf_usb_driver = {
-       .owner =      THIS_MODULE,
        .name =       "w9968cf",
        .id_table =   winbond_id_table,
        .probe =      w9968cf_usb_probe,
@@ -3703,106 +3658,6 @@ static struct usb_driver w9968cf_usb_driver = {
  * Module init, exit and intermodule communication                          *
  ****************************************************************************/
 
-static int w9968cf_vppmod_detect(struct w9968cf_device* cam)
-{
-       if (!w9968cf_vpp)
-               if (vppmod_load)
-                       request_module("w9968cf-vpp");
-
-       down(&w9968cf_vppmod_lock);
-
-       if (!w9968cf_vpp) {
-               DBG(4, "Video post-processing module not detected")
-               w9968cf_adjust_configuration(cam);
-               goto out;
-       }
-
-       if (!try_module_get(w9968cf_vpp->owner)) {
-               DBG(1, "Couldn't increment the reference count of "
-                      "the video post-processing module")
-               up(&w9968cf_vppmod_lock);
-               return -ENOSYS;
-       }
-
-       w9968cf_vpp->busy++;
-
-       DBG(5, "Video post-processing module detected")
-
-out:
-       up(&w9968cf_vppmod_lock);
-       return 0;
-}
-
-
-static void w9968cf_vppmod_release(struct w9968cf_device* cam)
-{
-       down(&w9968cf_vppmod_lock);
-
-       if (w9968cf_vpp && w9968cf_vpp->busy) {
-               module_put(w9968cf_vpp->owner);
-               w9968cf_vpp->busy--;
-               wake_up(&w9968cf_vppmod_wait);
-               DBG(5, "Video post-processing module released")
-       }
-
-       up(&w9968cf_vppmod_lock);
-}
-
-
-int w9968cf_vppmod_register(struct w9968cf_vpp_t* vpp)
-{
-       down(&w9968cf_vppmod_lock);
-
-       if (w9968cf_vpp) {
-               KDBG(1, "Video post-processing module already registered")
-               up(&w9968cf_vppmod_lock);
-               return -EINVAL;
-       }
-
-       w9968cf_vpp = vpp;
-       w9968cf_vpp->busy = 0;
-
-       KDBG(2, "Video post-processing module registered")
-       up(&w9968cf_vppmod_lock);
-       return 0;
-}
-
-
-int w9968cf_vppmod_deregister(struct w9968cf_vpp_t* vpp)
-{
-       down(&w9968cf_vppmod_lock);
-
-       if (!w9968cf_vpp) {
-               up(&w9968cf_vppmod_lock);
-               return -EINVAL;
-       }
-
-       if (w9968cf_vpp != vpp) {
-               KDBG(1, "Only the owner can unregister the video "
-                       "post-processing module")
-               up(&w9968cf_vppmod_lock);
-               return -EINVAL;
-       }
-
-       if (w9968cf_vpp->busy) {
-               KDBG(2, "Video post-processing module busy. Wait for it to be "
-                       "released...")
-               up(&w9968cf_vppmod_lock);
-               wait_event(w9968cf_vppmod_wait, !w9968cf_vpp->busy);
-               w9968cf_vpp = NULL;
-               goto out;
-       }
-
-       w9968cf_vpp = NULL;
-
-       up(&w9968cf_vppmod_lock);
-
-out:
-       KDBG(2, "Video post-processing module unregistered")
-       return 0;
-}
-
-
 static int __init w9968cf_module_init(void)
 {
        int err;
@@ -3832,6 +3687,3 @@ static void __exit w9968cf_module_exit(void)
 module_init(w9968cf_module_init);
 module_exit(w9968cf_module_exit);
 
-
-EXPORT_SYMBOL(w9968cf_vppmod_register);
-EXPORT_SYMBOL(w9968cf_vppmod_deregister);