Loading drivers/media/video/zr364xx.c +51 −58 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ #include <linux/highmem.h> #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> #include <media/v4l2-device.h> #include <media/videobuf-vmalloc.h> Loading Loading @@ -173,6 +174,7 @@ static const struct zr364xx_fmt formats[] = { struct zr364xx_camera { struct usb_device *udev; /* save off the usb device pointer */ struct usb_interface *interface;/* the interface for this device */ struct v4l2_device v4l2_dev; struct video_device vdev; /* v4l video device */ int nb; struct zr364xx_bufferi buffer; Loading @@ -181,7 +183,6 @@ struct zr364xx_camera { int height; int method; struct mutex lock; struct mutex open_lock; int users; spinlock_t slock; Loading Loading @@ -230,11 +231,6 @@ static int send_control_msg(struct usb_device *udev, u8 request, u16 value, transfer_buffer, size, CTRL_TIMEOUT); kfree(transfer_buffer); if (status < 0) dev_err(&udev->dev, "Failed sending control message, error %d.\n", status); return status; } Loading Loading @@ -468,6 +464,7 @@ static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t count, loff_t * ppos) { struct zr364xx_camera *cam = video_drvdata(file); int err = 0; _DBG("%s\n", __func__); Loading @@ -477,17 +474,20 @@ static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t count, if (!count) return -EINVAL; if (mutex_lock_interruptible(&cam->lock)) return -ERESTARTSYS; if (cam->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && zr364xx_vidioc_streamon(file, cam, cam->type) == 0) { DBG("%s: reading %d bytes at pos %d.\n", __func__, (int) count, (int) *ppos); /* NoMan Sux ! */ return videobuf_read_one(&cam->vb_vidq, buf, count, ppos, err = videobuf_read_one(&cam->vb_vidq, buf, count, ppos, file->f_flags & O_NONBLOCK); } return 0; mutex_unlock(&cam->lock); return err; } /* video buffer vmalloc implementation based partly on VIVI driver which is Loading Loading @@ -705,16 +705,13 @@ static int zr364xx_read_video_callback(struct zr364xx_camera *cam, static int res_get(struct zr364xx_camera *cam) { /* is it free? */ mutex_lock(&cam->lock); if (cam->resources) { /* no, someone else uses it */ mutex_unlock(&cam->lock); return 0; } /* it's free, grab it */ cam->resources = 1; _DBG("res: get\n"); mutex_unlock(&cam->lock); return 1; } Loading @@ -725,9 +722,7 @@ static inline int res_check(struct zr364xx_camera *cam) static void res_free(struct zr364xx_camera *cam) { mutex_lock(&cam->lock); cam->resources = 0; mutex_unlock(&cam->lock); _DBG("res: put\n"); } Loading Loading @@ -811,11 +806,9 @@ static int zr364xx_vidioc_s_ctrl(struct file *file, void *priv, case V4L2_CID_BRIGHTNESS: cam->mode.brightness = c->value; /* hardware brightness */ mutex_lock(&cam->lock); send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0); temp = (0x60 << 8) + 127 - cam->mode.brightness; send_control_msg(cam->udev, 1, temp, 0, NULL, 0); mutex_unlock(&cam->lock); break; default: return -EINVAL; Loading Loading @@ -1270,7 +1263,8 @@ static int zr364xx_open(struct file *file) DBG("%s\n", __func__); mutex_lock(&cam->open_lock); if (mutex_lock_interruptible(&cam->lock)) return -ERESTARTSYS; if (cam->users) { err = -EBUSY; Loading Loading @@ -1299,7 +1293,7 @@ static int zr364xx_open(struct file *file) NULL, &cam->slock, cam->type, V4L2_FIELD_NONE, sizeof(struct zr364xx_buffer), cam, NULL); sizeof(struct zr364xx_buffer), cam, &cam->lock); /* Added some delay here, since opening/closing the camera quickly, * like Ekiga does during its startup, can crash the webcam Loading @@ -1308,27 +1302,20 @@ static int zr364xx_open(struct file *file) err = 0; out: mutex_unlock(&cam->open_lock); mutex_unlock(&cam->lock); DBG("%s: %d\n", __func__, err); return err; } static void zr364xx_destroy(struct zr364xx_camera *cam) static void zr364xx_release(struct v4l2_device *v4l2_dev) { struct zr364xx_camera *cam = container_of(v4l2_dev, struct zr364xx_camera, v4l2_dev); unsigned long i; if (!cam) { printk(KERN_ERR KBUILD_MODNAME ", %s: no device\n", __func__); return; } mutex_lock(&cam->open_lock); video_unregister_device(&cam->vdev); /* stops the read pipe if it is running */ if (cam->b_acquire) zr364xx_stop_acquire(cam); v4l2_device_unregister(&cam->v4l2_dev); zr364xx_stop_readpipe(cam); videobuf_mmap_free(&cam->vb_vidq); /* release sys buffers */ for (i = 0; i < FRAMES; i++) { Loading @@ -1341,25 +1328,20 @@ static void zr364xx_destroy(struct zr364xx_camera *cam) /* release transfer buffer */ kfree(cam->pipe->transfer_buffer); cam->pipe->transfer_buffer = NULL; mutex_unlock(&cam->open_lock); kfree(cam); } /* release the camera */ static int zr364xx_release(struct file *file) static int zr364xx_close(struct file *file) { struct zr364xx_camera *cam; struct usb_device *udev; int i, err; int i; DBG("%s\n", __func__); cam = video_drvdata(file); if (!cam) return -ENODEV; mutex_lock(&cam->open_lock); mutex_lock(&cam->lock); udev = cam->udev; /* turn off stream */ Loading @@ -1374,26 +1356,17 @@ static int zr364xx_release(struct file *file) file->private_data = NULL; for (i = 0; i < 2; i++) { err = send_control_msg(udev, 1, init[cam->method][i].value, 0, init[cam->method][i].bytes, init[cam->method][i].size); if (err < 0) { dev_err(&udev->dev, "error during release sequence\n"); goto out; } } /* Added some delay here, since opening/closing the camera quickly, * like Ekiga does during its startup, can crash the webcam */ mdelay(100); err = 0; out: mutex_unlock(&cam->open_lock); return err; mutex_unlock(&cam->lock); return 0; } Loading Loading @@ -1432,10 +1405,10 @@ static unsigned int zr364xx_poll(struct file *file, static const struct v4l2_file_operations zr364xx_fops = { .owner = THIS_MODULE, .open = zr364xx_open, .release = zr364xx_release, .release = zr364xx_close, .read = zr364xx_read, .mmap = zr364xx_mmap, .ioctl = video_ioctl2, .unlocked_ioctl = video_ioctl2, .poll = zr364xx_poll, }; Loading Loading @@ -1552,10 +1525,20 @@ static int zr364xx_probe(struct usb_interface *intf, dev_err(&udev->dev, "cam: out of memory !\n"); return -ENOMEM; } cam->v4l2_dev.release = zr364xx_release; err = v4l2_device_register(&intf->dev, &cam->v4l2_dev); if (err < 0) { dev_err(&udev->dev, "couldn't register v4l2_device\n"); kfree(cam); return err; } /* save the init method used by this camera */ cam->method = id->driver_info; mutex_init(&cam->lock); cam->vdev = zr364xx_template; cam->vdev.parent = &intf->dev; cam->vdev.lock = &cam->lock; cam->vdev.v4l2_dev = &cam->v4l2_dev; video_set_drvdata(&cam->vdev, cam); if (debug) cam->vdev.debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; Loading Loading @@ -1607,8 +1590,6 @@ static int zr364xx_probe(struct usb_interface *intf, cam->users = 0; cam->nb = 0; cam->mode.brightness = 64; mutex_init(&cam->lock); mutex_init(&cam->open_lock); DBG("dev: %p, udev %p interface %p\n", cam, cam->udev, intf); Loading @@ -1625,6 +1606,7 @@ static int zr364xx_probe(struct usb_interface *intf, if (!cam->read_endpoint) { dev_err(&intf->dev, "Could not find bulk-in endpoint\n"); v4l2_device_unregister(&cam->v4l2_dev); kfree(cam); return -ENOMEM; } Loading @@ -1647,6 +1629,7 @@ static int zr364xx_probe(struct usb_interface *intf, err = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); if (err) { dev_err(&udev->dev, "video_register_device failed\n"); v4l2_device_unregister(&cam->v4l2_dev); kfree(cam); return err; } Loading @@ -1660,10 +1643,20 @@ static int zr364xx_probe(struct usb_interface *intf, static void zr364xx_disconnect(struct usb_interface *intf) { struct zr364xx_camera *cam = usb_get_intfdata(intf); videobuf_mmap_free(&cam->vb_vidq); mutex_lock(&cam->lock); usb_set_intfdata(intf, NULL); dev_info(&intf->dev, DRIVER_DESC " webcam unplugged\n"); zr364xx_destroy(cam); video_unregister_device(&cam->vdev); v4l2_device_disconnect(&cam->v4l2_dev); /* stops the read pipe if it is running */ if (cam->b_acquire) zr364xx_stop_acquire(cam); zr364xx_stop_readpipe(cam); mutex_unlock(&cam->lock); v4l2_device_put(&cam->v4l2_dev); } Loading Loading
drivers/media/video/zr364xx.c +51 −58 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ #include <linux/highmem.h> #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> #include <media/v4l2-device.h> #include <media/videobuf-vmalloc.h> Loading Loading @@ -173,6 +174,7 @@ static const struct zr364xx_fmt formats[] = { struct zr364xx_camera { struct usb_device *udev; /* save off the usb device pointer */ struct usb_interface *interface;/* the interface for this device */ struct v4l2_device v4l2_dev; struct video_device vdev; /* v4l video device */ int nb; struct zr364xx_bufferi buffer; Loading @@ -181,7 +183,6 @@ struct zr364xx_camera { int height; int method; struct mutex lock; struct mutex open_lock; int users; spinlock_t slock; Loading Loading @@ -230,11 +231,6 @@ static int send_control_msg(struct usb_device *udev, u8 request, u16 value, transfer_buffer, size, CTRL_TIMEOUT); kfree(transfer_buffer); if (status < 0) dev_err(&udev->dev, "Failed sending control message, error %d.\n", status); return status; } Loading Loading @@ -468,6 +464,7 @@ static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t count, loff_t * ppos) { struct zr364xx_camera *cam = video_drvdata(file); int err = 0; _DBG("%s\n", __func__); Loading @@ -477,17 +474,20 @@ static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t count, if (!count) return -EINVAL; if (mutex_lock_interruptible(&cam->lock)) return -ERESTARTSYS; if (cam->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && zr364xx_vidioc_streamon(file, cam, cam->type) == 0) { DBG("%s: reading %d bytes at pos %d.\n", __func__, (int) count, (int) *ppos); /* NoMan Sux ! */ return videobuf_read_one(&cam->vb_vidq, buf, count, ppos, err = videobuf_read_one(&cam->vb_vidq, buf, count, ppos, file->f_flags & O_NONBLOCK); } return 0; mutex_unlock(&cam->lock); return err; } /* video buffer vmalloc implementation based partly on VIVI driver which is Loading Loading @@ -705,16 +705,13 @@ static int zr364xx_read_video_callback(struct zr364xx_camera *cam, static int res_get(struct zr364xx_camera *cam) { /* is it free? */ mutex_lock(&cam->lock); if (cam->resources) { /* no, someone else uses it */ mutex_unlock(&cam->lock); return 0; } /* it's free, grab it */ cam->resources = 1; _DBG("res: get\n"); mutex_unlock(&cam->lock); return 1; } Loading @@ -725,9 +722,7 @@ static inline int res_check(struct zr364xx_camera *cam) static void res_free(struct zr364xx_camera *cam) { mutex_lock(&cam->lock); cam->resources = 0; mutex_unlock(&cam->lock); _DBG("res: put\n"); } Loading Loading @@ -811,11 +806,9 @@ static int zr364xx_vidioc_s_ctrl(struct file *file, void *priv, case V4L2_CID_BRIGHTNESS: cam->mode.brightness = c->value; /* hardware brightness */ mutex_lock(&cam->lock); send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0); temp = (0x60 << 8) + 127 - cam->mode.brightness; send_control_msg(cam->udev, 1, temp, 0, NULL, 0); mutex_unlock(&cam->lock); break; default: return -EINVAL; Loading Loading @@ -1270,7 +1263,8 @@ static int zr364xx_open(struct file *file) DBG("%s\n", __func__); mutex_lock(&cam->open_lock); if (mutex_lock_interruptible(&cam->lock)) return -ERESTARTSYS; if (cam->users) { err = -EBUSY; Loading Loading @@ -1299,7 +1293,7 @@ static int zr364xx_open(struct file *file) NULL, &cam->slock, cam->type, V4L2_FIELD_NONE, sizeof(struct zr364xx_buffer), cam, NULL); sizeof(struct zr364xx_buffer), cam, &cam->lock); /* Added some delay here, since opening/closing the camera quickly, * like Ekiga does during its startup, can crash the webcam Loading @@ -1308,27 +1302,20 @@ static int zr364xx_open(struct file *file) err = 0; out: mutex_unlock(&cam->open_lock); mutex_unlock(&cam->lock); DBG("%s: %d\n", __func__, err); return err; } static void zr364xx_destroy(struct zr364xx_camera *cam) static void zr364xx_release(struct v4l2_device *v4l2_dev) { struct zr364xx_camera *cam = container_of(v4l2_dev, struct zr364xx_camera, v4l2_dev); unsigned long i; if (!cam) { printk(KERN_ERR KBUILD_MODNAME ", %s: no device\n", __func__); return; } mutex_lock(&cam->open_lock); video_unregister_device(&cam->vdev); /* stops the read pipe if it is running */ if (cam->b_acquire) zr364xx_stop_acquire(cam); v4l2_device_unregister(&cam->v4l2_dev); zr364xx_stop_readpipe(cam); videobuf_mmap_free(&cam->vb_vidq); /* release sys buffers */ for (i = 0; i < FRAMES; i++) { Loading @@ -1341,25 +1328,20 @@ static void zr364xx_destroy(struct zr364xx_camera *cam) /* release transfer buffer */ kfree(cam->pipe->transfer_buffer); cam->pipe->transfer_buffer = NULL; mutex_unlock(&cam->open_lock); kfree(cam); } /* release the camera */ static int zr364xx_release(struct file *file) static int zr364xx_close(struct file *file) { struct zr364xx_camera *cam; struct usb_device *udev; int i, err; int i; DBG("%s\n", __func__); cam = video_drvdata(file); if (!cam) return -ENODEV; mutex_lock(&cam->open_lock); mutex_lock(&cam->lock); udev = cam->udev; /* turn off stream */ Loading @@ -1374,26 +1356,17 @@ static int zr364xx_release(struct file *file) file->private_data = NULL; for (i = 0; i < 2; i++) { err = send_control_msg(udev, 1, init[cam->method][i].value, 0, init[cam->method][i].bytes, init[cam->method][i].size); if (err < 0) { dev_err(&udev->dev, "error during release sequence\n"); goto out; } } /* Added some delay here, since opening/closing the camera quickly, * like Ekiga does during its startup, can crash the webcam */ mdelay(100); err = 0; out: mutex_unlock(&cam->open_lock); return err; mutex_unlock(&cam->lock); return 0; } Loading Loading @@ -1432,10 +1405,10 @@ static unsigned int zr364xx_poll(struct file *file, static const struct v4l2_file_operations zr364xx_fops = { .owner = THIS_MODULE, .open = zr364xx_open, .release = zr364xx_release, .release = zr364xx_close, .read = zr364xx_read, .mmap = zr364xx_mmap, .ioctl = video_ioctl2, .unlocked_ioctl = video_ioctl2, .poll = zr364xx_poll, }; Loading Loading @@ -1552,10 +1525,20 @@ static int zr364xx_probe(struct usb_interface *intf, dev_err(&udev->dev, "cam: out of memory !\n"); return -ENOMEM; } cam->v4l2_dev.release = zr364xx_release; err = v4l2_device_register(&intf->dev, &cam->v4l2_dev); if (err < 0) { dev_err(&udev->dev, "couldn't register v4l2_device\n"); kfree(cam); return err; } /* save the init method used by this camera */ cam->method = id->driver_info; mutex_init(&cam->lock); cam->vdev = zr364xx_template; cam->vdev.parent = &intf->dev; cam->vdev.lock = &cam->lock; cam->vdev.v4l2_dev = &cam->v4l2_dev; video_set_drvdata(&cam->vdev, cam); if (debug) cam->vdev.debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; Loading Loading @@ -1607,8 +1590,6 @@ static int zr364xx_probe(struct usb_interface *intf, cam->users = 0; cam->nb = 0; cam->mode.brightness = 64; mutex_init(&cam->lock); mutex_init(&cam->open_lock); DBG("dev: %p, udev %p interface %p\n", cam, cam->udev, intf); Loading @@ -1625,6 +1606,7 @@ static int zr364xx_probe(struct usb_interface *intf, if (!cam->read_endpoint) { dev_err(&intf->dev, "Could not find bulk-in endpoint\n"); v4l2_device_unregister(&cam->v4l2_dev); kfree(cam); return -ENOMEM; } Loading @@ -1647,6 +1629,7 @@ static int zr364xx_probe(struct usb_interface *intf, err = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); if (err) { dev_err(&udev->dev, "video_register_device failed\n"); v4l2_device_unregister(&cam->v4l2_dev); kfree(cam); return err; } Loading @@ -1660,10 +1643,20 @@ static int zr364xx_probe(struct usb_interface *intf, static void zr364xx_disconnect(struct usb_interface *intf) { struct zr364xx_camera *cam = usb_get_intfdata(intf); videobuf_mmap_free(&cam->vb_vidq); mutex_lock(&cam->lock); usb_set_intfdata(intf, NULL); dev_info(&intf->dev, DRIVER_DESC " webcam unplugged\n"); zr364xx_destroy(cam); video_unregister_device(&cam->vdev); v4l2_device_disconnect(&cam->v4l2_dev); /* stops the read pipe if it is running */ if (cam->b_acquire) zr364xx_stop_acquire(cam); zr364xx_stop_readpipe(cam); mutex_unlock(&cam->lock); v4l2_device_put(&cam->v4l2_dev); } Loading