/****************************************************************************** * * cpia2_disconnect * *****************************************************************************/ static void cpia2_usb_disconnect(struct usb_interface *intf) { struct camera_data *cam = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); cam->present = 0; DBG("Stopping stream\n"); cpia2_usb_stream_stop(cam); DBG("Unregistering camera\n"); cpia2_unregister_camera(cam); if(cam->buffers) { DBG("Wakeup waiting processes\n"); cam->curbuff->status = FRAME_READY; cam->curbuff->length = 0; if (waitqueue_active(&cam->wq_stream)) wake_up_interruptible(&cam->wq_stream); } DBG("Releasing interface\n"); usb_driver_release_interface(&cpia2_driver, intf); if (cam->open_count == 0) { DBG("Freeing camera structure\n"); kfree(cam); } LOG("CPiA2 camera disconnected.\n"); }
/****************************************************************************** * * cpia2_disconnect * *****************************************************************************/ static void cpia2_usb_disconnect(struct usb_interface *intf) { struct camera_data *cam = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); DBG("Stopping stream\n"); cpia2_usb_stream_stop(cam); mutex_lock(&cam->v4l2_lock); DBG("Unregistering camera\n"); cpia2_unregister_camera(cam); v4l2_device_disconnect(&cam->v4l2_dev); mutex_unlock(&cam->v4l2_lock); v4l2_device_put(&cam->v4l2_dev); if(cam->buffers) { DBG("Wakeup waiting processes\n"); cam->curbuff->status = FRAME_READY; cam->curbuff->length = 0; wake_up_interruptible(&cam->wq_stream); } DBG("Releasing interface\n"); usb_driver_release_interface(&cpia2_driver, intf); LOG("CPiA2 camera disconnected.\n"); }
static int cpia2_usb_suspend(struct usb_interface *intf, pm_message_t message) { struct camera_data *cam = usb_get_intfdata(intf); mutex_lock(&cam->v4l2_lock); if (cam->streaming) { cpia2_usb_stream_stop(cam); cam->streaming = 1; } mutex_unlock(&cam->v4l2_lock); dev_info(&intf->dev, "going into suspend..\n"); return 0; }
static int cpia2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) { struct camera_data *cam = video_drvdata(file); int ret = -EINVAL; DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming); if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; if (cam->streaming) { ret = cpia2_usb_stream_stop(cam); if (!ret) v4l2_ctrl_grab(cam->usb_alt, false); } return ret; }
/****************************************************************************** * * cpia2_close * *****************************************************************************/ static int cpia2_close(struct file *file) { struct video_device *dev = video_devdata(file); struct camera_data *cam = video_get_drvdata(dev); if (video_is_registered(&cam->vdev) && v4l2_fh_is_singular_file(file)) { cpia2_usb_stream_stop(cam); /* save camera state for later open */ cpia2_save_camera_state(cam); cpia2_set_low_power(cam); cpia2_free_buffers(cam); } if (cam->stream_fh == file->private_data) { cam->stream_fh = NULL; cam->mmapped = 0; } return v4l2_fh_release(file); }