diff options
Diffstat (limited to 'drivers/media/video/cpia2/cpia2_usb.c')
-rw-r--r-- | drivers/media/video/cpia2/cpia2_usb.c | 78 |
1 files changed, 59 insertions, 19 deletions
diff --git a/drivers/media/video/cpia2/cpia2_usb.c b/drivers/media/video/cpia2/cpia2_usb.c index 59c797c15277..95b5d6e7cdc4 100644 --- a/drivers/media/video/cpia2/cpia2_usb.c +++ b/drivers/media/video/cpia2/cpia2_usb.c | |||
@@ -54,6 +54,8 @@ static void cpia2_usb_complete(struct urb *urb); | |||
54 | static int cpia2_usb_probe(struct usb_interface *intf, | 54 | static int cpia2_usb_probe(struct usb_interface *intf, |
55 | const struct usb_device_id *id); | 55 | const struct usb_device_id *id); |
56 | static void cpia2_usb_disconnect(struct usb_interface *intf); | 56 | static void cpia2_usb_disconnect(struct usb_interface *intf); |
57 | static int cpia2_usb_suspend(struct usb_interface *intf, pm_message_t message); | ||
58 | static int cpia2_usb_resume(struct usb_interface *intf); | ||
57 | 59 | ||
58 | static void free_sbufs(struct camera_data *cam); | 60 | static void free_sbufs(struct camera_data *cam); |
59 | static void add_APPn(struct camera_data *cam); | 61 | static void add_APPn(struct camera_data *cam); |
@@ -74,6 +76,9 @@ static struct usb_driver cpia2_driver = { | |||
74 | .name = "cpia2", | 76 | .name = "cpia2", |
75 | .probe = cpia2_usb_probe, | 77 | .probe = cpia2_usb_probe, |
76 | .disconnect = cpia2_usb_disconnect, | 78 | .disconnect = cpia2_usb_disconnect, |
79 | .suspend = cpia2_usb_suspend, | ||
80 | .resume = cpia2_usb_resume, | ||
81 | .reset_resume = cpia2_usb_resume, | ||
77 | .id_table = cpia2_id_table | 82 | .id_table = cpia2_id_table |
78 | }; | 83 | }; |
79 | 84 | ||
@@ -218,10 +223,9 @@ static void cpia2_usb_complete(struct urb *urb) | |||
218 | return; | 223 | return; |
219 | } | 224 | } |
220 | 225 | ||
221 | if (!cam->streaming || !cam->present || cam->open_count == 0) { | 226 | if (!cam->streaming || !video_is_registered(&cam->vdev)) { |
222 | LOG("Will now stop the streaming: streaming = %d, " | 227 | LOG("Will now stop the streaming: streaming = %d, present=%d\n", |
223 | "present=%d, open_count=%d\n", | 228 | cam->streaming, video_is_registered(&cam->vdev)); |
224 | cam->streaming, cam->present, cam->open_count); | ||
225 | return; | 229 | return; |
226 | } | 230 | } |
227 | 231 | ||
@@ -392,7 +396,7 @@ static int configure_transfer_mode(struct camera_data *cam, unsigned int alt) | |||
392 | struct cpia2_command cmd; | 396 | struct cpia2_command cmd; |
393 | unsigned char reg; | 397 | unsigned char reg; |
394 | 398 | ||
395 | if(!cam->present) | 399 | if (!video_is_registered(&cam->vdev)) |
396 | return -ENODEV; | 400 | return -ENODEV; |
397 | 401 | ||
398 | /*** | 402 | /*** |
@@ -752,8 +756,8 @@ int cpia2_usb_stream_pause(struct camera_data *cam) | |||
752 | { | 756 | { |
753 | int ret = 0; | 757 | int ret = 0; |
754 | if(cam->streaming) { | 758 | if(cam->streaming) { |
755 | ret = set_alternate(cam, USBIF_CMDONLY); | ||
756 | free_sbufs(cam); | 759 | free_sbufs(cam); |
760 | ret = set_alternate(cam, USBIF_CMDONLY); | ||
757 | } | 761 | } |
758 | return ret; | 762 | return ret; |
759 | } | 763 | } |
@@ -770,6 +774,10 @@ int cpia2_usb_stream_resume(struct camera_data *cam) | |||
770 | cam->first_image_seen = 0; | 774 | cam->first_image_seen = 0; |
771 | ret = set_alternate(cam, cam->params.camera_state.stream_mode); | 775 | ret = set_alternate(cam, cam->params.camera_state.stream_mode); |
772 | if(ret == 0) { | 776 | if(ret == 0) { |
777 | /* for some reason the user effects need to be set | ||
778 | again when starting streaming. */ | ||
779 | cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE, | ||
780 | cam->params.vp_params.user_effects); | ||
773 | ret = submit_urbs(cam); | 781 | ret = submit_urbs(cam); |
774 | } | 782 | } |
775 | } | 783 | } |
@@ -784,6 +792,7 @@ int cpia2_usb_stream_resume(struct camera_data *cam) | |||
784 | int cpia2_usb_stream_stop(struct camera_data *cam) | 792 | int cpia2_usb_stream_stop(struct camera_data *cam) |
785 | { | 793 | { |
786 | int ret; | 794 | int ret; |
795 | |||
787 | ret = cpia2_usb_stream_pause(cam); | 796 | ret = cpia2_usb_stream_pause(cam); |
788 | cam->streaming = 0; | 797 | cam->streaming = 0; |
789 | configure_transfer_mode(cam, 0); | 798 | configure_transfer_mode(cam, 0); |
@@ -812,7 +821,8 @@ static int cpia2_usb_probe(struct usb_interface *intf, | |||
812 | /* If we get to this point, we found a CPiA2 camera */ | 821 | /* If we get to this point, we found a CPiA2 camera */ |
813 | LOG("CPiA2 USB camera found\n"); | 822 | LOG("CPiA2 USB camera found\n"); |
814 | 823 | ||
815 | if((cam = cpia2_init_camera_struct()) == NULL) | 824 | cam = cpia2_init_camera_struct(intf); |
825 | if (cam == NULL) | ||
816 | return -ENOMEM; | 826 | return -ENOMEM; |
817 | 827 | ||
818 | cam->dev = udev; | 828 | cam->dev = udev; |
@@ -825,16 +835,9 @@ static int cpia2_usb_probe(struct usb_interface *intf, | |||
825 | return ret; | 835 | return ret; |
826 | } | 836 | } |
827 | 837 | ||
828 | if ((ret = cpia2_register_camera(cam)) < 0) { | ||
829 | ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret); | ||
830 | kfree(cam); | ||
831 | return ret; | ||
832 | } | ||
833 | |||
834 | 838 | ||
835 | if((ret = cpia2_init_camera(cam)) < 0) { | 839 | if((ret = cpia2_init_camera(cam)) < 0) { |
836 | ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret); | 840 | ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret); |
837 | cpia2_unregister_camera(cam); | ||
838 | kfree(cam); | 841 | kfree(cam); |
839 | return ret; | 842 | return ret; |
840 | } | 843 | } |
@@ -853,6 +856,13 @@ static int cpia2_usb_probe(struct usb_interface *intf, | |||
853 | 856 | ||
854 | usb_set_intfdata(intf, cam); | 857 | usb_set_intfdata(intf, cam); |
855 | 858 | ||
859 | ret = cpia2_register_camera(cam); | ||
860 | if (ret < 0) { | ||
861 | ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret); | ||
862 | kfree(cam); | ||
863 | return ret; | ||
864 | } | ||
865 | |||
856 | return 0; | 866 | return 0; |
857 | } | 867 | } |
858 | 868 | ||
@@ -865,13 +875,16 @@ static void cpia2_usb_disconnect(struct usb_interface *intf) | |||
865 | { | 875 | { |
866 | struct camera_data *cam = usb_get_intfdata(intf); | 876 | struct camera_data *cam = usb_get_intfdata(intf); |
867 | usb_set_intfdata(intf, NULL); | 877 | usb_set_intfdata(intf, NULL); |
868 | cam->present = 0; | ||
869 | 878 | ||
870 | DBG("Stopping stream\n"); | 879 | DBG("Stopping stream\n"); |
871 | cpia2_usb_stream_stop(cam); | 880 | cpia2_usb_stream_stop(cam); |
872 | 881 | ||
882 | mutex_lock(&cam->v4l2_lock); | ||
873 | DBG("Unregistering camera\n"); | 883 | DBG("Unregistering camera\n"); |
874 | cpia2_unregister_camera(cam); | 884 | cpia2_unregister_camera(cam); |
885 | v4l2_device_disconnect(&cam->v4l2_dev); | ||
886 | mutex_unlock(&cam->v4l2_lock); | ||
887 | v4l2_device_put(&cam->v4l2_dev); | ||
875 | 888 | ||
876 | if(cam->buffers) { | 889 | if(cam->buffers) { |
877 | DBG("Wakeup waiting processes\n"); | 890 | DBG("Wakeup waiting processes\n"); |
@@ -884,14 +897,41 @@ static void cpia2_usb_disconnect(struct usb_interface *intf) | |||
884 | DBG("Releasing interface\n"); | 897 | DBG("Releasing interface\n"); |
885 | usb_driver_release_interface(&cpia2_driver, intf); | 898 | usb_driver_release_interface(&cpia2_driver, intf); |
886 | 899 | ||
887 | if (cam->open_count == 0) { | 900 | LOG("CPiA2 camera disconnected.\n"); |
888 | DBG("Freeing camera structure\n"); | 901 | } |
889 | kfree(cam); | 902 | |
903 | static int cpia2_usb_suspend(struct usb_interface *intf, pm_message_t message) | ||
904 | { | ||
905 | struct camera_data *cam = usb_get_intfdata(intf); | ||
906 | |||
907 | mutex_lock(&cam->v4l2_lock); | ||
908 | if (cam->streaming) { | ||
909 | cpia2_usb_stream_stop(cam); | ||
910 | cam->streaming = 1; | ||
890 | } | 911 | } |
912 | mutex_unlock(&cam->v4l2_lock); | ||
891 | 913 | ||
892 | LOG("CPiA2 camera disconnected.\n"); | 914 | dev_info(&intf->dev, "going into suspend..\n"); |
915 | return 0; | ||
893 | } | 916 | } |
894 | 917 | ||
918 | /* Resume device - start device. */ | ||
919 | static int cpia2_usb_resume(struct usb_interface *intf) | ||
920 | { | ||
921 | struct camera_data *cam = usb_get_intfdata(intf); | ||
922 | |||
923 | mutex_lock(&cam->v4l2_lock); | ||
924 | v4l2_ctrl_handler_setup(&cam->hdl); | ||
925 | if (cam->streaming) { | ||
926 | cam->streaming = 0; | ||
927 | cpia2_usb_stream_start(cam, | ||
928 | cam->params.camera_state.stream_mode); | ||
929 | } | ||
930 | mutex_unlock(&cam->v4l2_lock); | ||
931 | |||
932 | dev_info(&intf->dev, "coming out of suspend..\n"); | ||
933 | return 0; | ||
934 | } | ||
895 | 935 | ||
896 | /****************************************************************************** | 936 | /****************************************************************************** |
897 | * | 937 | * |