Browse Source

[media] cpia2: major overhaul to get it in a working state again

This driver was severely broken. This patch makes it work again, and updates
it to the latest V4L2 frameworks (except for videobuf2). It passes the
v4l2-compliance tests and it now handles suspend/resume correctly.

Several custom controls are replaced by new standard controls, only the
USB_ALTERNATE control remains.

Tested with the Hanse HVS-CM500PC USB microscope.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Hans Verkuil 13 years ago
parent
commit
6c493f8b28

+ 16 - 18
drivers/media/video/cpia2/cpia2.h

@@ -32,11 +32,12 @@
 #define __CPIA2_H__
 
 #include <linux/videodev2.h>
-#include <media/v4l2-common.h>
 #include <linux/usb.h>
 #include <linux/poll.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
 
-#include "cpia2dev.h"
 #include "cpia2_registers.h"
 
 /* define for verbose debug output */
@@ -65,7 +66,6 @@
 
 /* Flicker Modes */
 #define NEVER_FLICKER   0
-#define ANTI_FLICKER_ON 1
 #define FLICKER_60      60
 #define FLICKER_50      50
 
@@ -148,7 +148,6 @@ enum {
 #define DEFAULT_BRIGHTNESS 0x46
 #define DEFAULT_CONTRAST 0x93
 #define DEFAULT_SATURATION 0x7f
-#define DEFAULT_TARGET_KB 0x30
 
 /* Power state */
 #define HI_POWER_MODE CPIA2_SYSTEM_CONTROL_HIGH_POWER
@@ -287,7 +286,6 @@ struct camera_params {
 	struct {
 		u8 cam_register;
 		u8 flicker_mode_req;	/* 1 if flicker on, else never flicker */
-		int mains_frequency;
 	} flicker_control;
 
 	struct {
@@ -337,7 +335,7 @@ struct camera_params {
 		u8 vc_control;
 		u8 vc_mp_direction;
 		u8 vc_mp_data;
-		u8 target_kb;
+		u8 quality;
 	} vc_params;
 
 	struct {
@@ -366,23 +364,23 @@ struct framebuf {
 	struct framebuf *next;
 };
 
-struct cpia2_fh {
-	enum v4l2_priority prio;
-	u8 mmapped;
-};
-
 struct camera_data {
 	/* locks */
+	struct v4l2_device v4l2_dev;
 	struct mutex v4l2_lock;	/* serialize file operations */
-	struct v4l2_prio_state prio;
+	struct v4l2_ctrl_handler hdl;
+	struct {
+		/* Lights control cluster */
+		struct v4l2_ctrl *top_light;
+		struct v4l2_ctrl *bottom_light;
+	};
+	struct v4l2_ctrl *usb_alt;
 
 	/* camera status */
-	volatile int present;	/* Is the camera still present? */
-	int open_count;		/* # of process that have camera open */
 	int first_image_seen;
-	u8 mains_freq;		/* for flicker control */
 	enum sensors sensor_type;
 	u8 flush;
+	struct v4l2_fh *stream_fh;
 	u8 mmapped;
 	int streaming;		/* 0 = no, 1 = yes */
 	int xfer_mode;		/* XFER_BULK or XFER_ISOC */
@@ -390,7 +388,7 @@ struct camera_data {
 
 	/* v4l */
 	int video_size;			/* VIDEO_SIZE_ */
-	struct video_device *vdev;	/* v4l videodev */
+	struct video_device vdev;	/* v4l videodev */
 	u32 width;
 	u32 height;			/* Its size */
 	__u32 pixelformat;       /* Format fourcc      */
@@ -425,6 +423,7 @@ struct camera_data {
 /* v4l */
 int cpia2_register_camera(struct camera_data *cam);
 void cpia2_unregister_camera(struct camera_data *cam);
+void cpia2_camera_release(struct v4l2_device *v4l2_dev);
 
 /* core */
 int cpia2_reset_camera(struct camera_data *cam);
@@ -443,7 +442,7 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd);
 int cpia2_do_command(struct camera_data *cam,
 		     unsigned int command,
 		     unsigned char direction, unsigned char param);
-struct camera_data *cpia2_init_camera_struct(void);
+struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf);
 int cpia2_init_camera(struct camera_data *cam);
 int cpia2_allocate_buffers(struct camera_data *cam);
 void cpia2_free_buffers(struct camera_data *cam);
@@ -454,7 +453,6 @@ unsigned int cpia2_poll(struct camera_data *cam,
 int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma);
 void cpia2_set_property_flip(struct camera_data *cam, int prop_val);
 void cpia2_set_property_mirror(struct camera_data *cam, int prop_val);
-int cpia2_set_target_kb(struct camera_data *cam, unsigned char value);
 int cpia2_set_gpio(struct camera_data *cam, unsigned char setting);
 int cpia2_set_fps(struct camera_data *cam, int framerate);
 

+ 31 - 111
drivers/media/video/cpia2/cpia2_core.c

@@ -66,7 +66,6 @@ static int config_sensor_410(struct camera_data *cam,
 static int config_sensor_500(struct camera_data *cam,
 			    int reqwidth, int reqheight);
 static int set_all_properties(struct camera_data *cam);
-static void get_color_params(struct camera_data *cam);
 static void wake_system(struct camera_data *cam);
 static void set_lowlight_boost(struct camera_data *cam);
 static void reset_camera_struct(struct camera_data *cam);
@@ -453,15 +452,6 @@ int cpia2_do_command(struct camera_data *cam,
 		cam->params.version.vp_device_hi = cmd.buffer.block_data[0];
 		cam->params.version.vp_device_lo = cmd.buffer.block_data[1];
 		break;
-	case CPIA2_CMD_GET_VP_BRIGHTNESS:
-		cam->params.color_params.brightness = cmd.buffer.block_data[0];
-		break;
-	case CPIA2_CMD_GET_CONTRAST:
-		cam->params.color_params.contrast = cmd.buffer.block_data[0];
-		break;
-	case CPIA2_CMD_GET_VP_SATURATION:
-		cam->params.color_params.saturation = cmd.buffer.block_data[0];
-		break;
 	case CPIA2_CMD_GET_VP_GPIO_DATA:
 		cam->params.vp_params.gpio_data = cmd.buffer.block_data[0];
 		break;
@@ -617,6 +607,7 @@ int cpia2_reset_camera(struct camera_data *cam)
 {
 	u8 tmp_reg;
 	int retval = 0;
+	int target_kb;
 	int i;
 	struct cpia2_command cmd;
 
@@ -800,9 +791,16 @@ int cpia2_reset_camera(struct camera_data *cam)
 	}
 	cpia2_do_command(cam, CPIA2_CMD_SET_VC_CONTROL, TRANSFER_WRITE,tmp_reg);
 
-	/* Set target size (kb) on vc */
+	/* Set target size (kb) on vc
+	   This is a heuristic based on the quality parameter and the raw
+	   framesize in kB divided by 16 (the compression factor when the
+	   quality is 100%) */
+	target_kb = (cam->width * cam->height * 2 / 16384) *
+				cam->params.vc_params.quality / 100;
+	if (target_kb < 1)
+		target_kb = 1;
 	cpia2_do_command(cam, CPIA2_CMD_SET_TARGET_KB,
-			 TRANSFER_WRITE, cam->params.vc_params.target_kb);
+			 TRANSFER_WRITE, target_kb);
 
 	/* Wiggle VC Reset */
 	/***
@@ -1538,23 +1536,17 @@ static int set_all_properties(struct camera_data *cam)
 	 * framerate and user_mode were already set (set_default_user_mode).
 	 **/
 
-	cpia2_set_color_params(cam);
-
 	cpia2_usb_change_streaming_alternate(cam,
 					  cam->params.camera_state.stream_mode);
 
-	cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
-			 cam->params.vp_params.user_effects);
-
-	cpia2_set_flicker_mode(cam,
-			       cam->params.flicker_control.flicker_mode_req);
-
 	cpia2_do_command(cam,
 			 CPIA2_CMD_SET_VC_MP_GPIO_DIRECTION,
 			 TRANSFER_WRITE, cam->params.vp_params.gpio_direction);
 	cpia2_do_command(cam, CPIA2_CMD_SET_VC_MP_GPIO_DATA, TRANSFER_WRITE,
 			 cam->params.vp_params.gpio_data);
 
+	v4l2_ctrl_handler_setup(&cam->hdl);
+
 	wake_system(cam);
 
 	set_lowlight_boost(cam);
@@ -1569,7 +1561,6 @@ static int set_all_properties(struct camera_data *cam)
  *****************************************************************************/
 void cpia2_save_camera_state(struct camera_data *cam)
 {
-	get_color_params(cam);
 	cpia2_do_command(cam, CPIA2_CMD_GET_USER_EFFECTS, TRANSFER_READ, 0);
 	cpia2_do_command(cam, CPIA2_CMD_GET_VC_MP_GPIO_DIRECTION, TRANSFER_READ,
 			 0);
@@ -1577,30 +1568,6 @@ void cpia2_save_camera_state(struct camera_data *cam)
 	/* Don't get framerate or target_kb. Trust the values we already have */
 }
 
-/******************************************************************************
- *
- *  get_color_params
- *
- *****************************************************************************/
-static void get_color_params(struct camera_data *cam)
-{
-	cpia2_do_command(cam, CPIA2_CMD_GET_VP_BRIGHTNESS, TRANSFER_READ, 0);
-	cpia2_do_command(cam, CPIA2_CMD_GET_VP_SATURATION, TRANSFER_READ, 0);
-	cpia2_do_command(cam, CPIA2_CMD_GET_CONTRAST, TRANSFER_READ, 0);
-}
-
-/******************************************************************************
- *
- *  cpia2_set_color_params
- *
- *****************************************************************************/
-void cpia2_set_color_params(struct camera_data *cam)
-{
-	DBG("Setting color params\n");
-	cpia2_set_brightness(cam, cam->params.color_params.brightness);
-	cpia2_set_contrast(cam, cam->params.color_params.contrast);
-	cpia2_set_saturation(cam, cam->params.color_params.saturation);
-}
 
 /******************************************************************************
  *
@@ -1664,15 +1631,9 @@ int cpia2_set_flicker_mode(struct camera_data *cam, int mode)
 
 	switch(mode) {
 	case NEVER_FLICKER:
-		cam->params.flicker_control.flicker_mode_req = mode;
-		break;
 	case FLICKER_60:
-		cam->params.flicker_control.flicker_mode_req = mode;
-		cam->params.flicker_control.mains_frequency = 60;
-		break;
 	case FLICKER_50:
 		cam->params.flicker_control.flicker_mode_req = mode;
-		cam->params.flicker_control.mains_frequency = 50;
 		break;
 	default:
 		err = -EINVAL;
@@ -1701,6 +1662,7 @@ void cpia2_set_property_flip(struct camera_data *cam, int prop_val)
 	{
 		cam_reg &= ~CPIA2_VP_USER_EFFECTS_FLIP;
 	}
+	cam->params.vp_params.user_effects = cam_reg;
 	cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
 			 cam_reg);
 }
@@ -1725,35 +1687,11 @@ void cpia2_set_property_mirror(struct camera_data *cam, int prop_val)
 	{
 		cam_reg &= ~CPIA2_VP_USER_EFFECTS_MIRROR;
 	}
+	cam->params.vp_params.user_effects = cam_reg;
 	cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
 			 cam_reg);
 }
 
-/******************************************************************************
- *
- *  set_target_kb
- *
- *  The new Target KB is set in cam->params.vc_params.target_kb and
- *  activates on reset.
- *****************************************************************************/
-
-int cpia2_set_target_kb(struct camera_data *cam, unsigned char value)
-{
-	DBG("Requested target_kb = %d\n", value);
-	if (value != cam->params.vc_params.target_kb) {
-
-		cpia2_usb_stream_pause(cam);
-
-		/* reset camera for new target_kb */
-		cam->params.vc_params.target_kb = value;
-		cpia2_reset_camera(cam);
-
-		cpia2_usb_stream_resume(cam);
-	}
-
-	return 0;
-}
-
 /******************************************************************************
  *
  *  cpia2_set_gpio
@@ -1843,7 +1781,7 @@ void cpia2_set_brightness(struct camera_data *cam, unsigned char value)
 	if (cam->params.pnp_id.device_type == DEVICE_STV_672 && value == 0)
 		value++;
 	DBG("Setting brightness to %d (0x%0x)\n", value, value);
-	cpia2_do_command(cam,CPIA2_CMD_SET_VP_BRIGHTNESS, TRANSFER_WRITE,value);
+	cpia2_do_command(cam, CPIA2_CMD_SET_VP_BRIGHTNESS, TRANSFER_WRITE, value);
 }
 
 /******************************************************************************
@@ -1854,7 +1792,6 @@ void cpia2_set_brightness(struct camera_data *cam, unsigned char value)
 void cpia2_set_contrast(struct camera_data *cam, unsigned char value)
 {
 	DBG("Setting contrast to %d (0x%0x)\n", value, value);
-	cam->params.color_params.contrast = value;
 	cpia2_do_command(cam, CPIA2_CMD_SET_CONTRAST, TRANSFER_WRITE, value);
 }
 
@@ -1866,7 +1803,6 @@ void cpia2_set_contrast(struct camera_data *cam, unsigned char value)
 void cpia2_set_saturation(struct camera_data *cam, unsigned char value)
 {
 	DBG("Setting saturation to %d (0x%0x)\n", value, value);
-	cam->params.color_params.saturation = value;
 	cpia2_do_command(cam,CPIA2_CMD_SET_VP_SATURATION, TRANSFER_WRITE,value);
 }
 
@@ -2168,14 +2104,10 @@ static void reset_camera_struct(struct camera_data *cam)
 	/***
 	 * The following parameter values are the defaults from the register map.
 	 ***/
-	cam->params.color_params.brightness = DEFAULT_BRIGHTNESS;
-	cam->params.color_params.contrast = DEFAULT_CONTRAST;
-	cam->params.color_params.saturation = DEFAULT_SATURATION;
 	cam->params.vp_params.lowlight_boost = 0;
 
 	/* FlickerModes */
 	cam->params.flicker_control.flicker_mode_req = NEVER_FLICKER;
-	cam->params.flicker_control.mains_frequency = 60;
 
 	/* jpeg params */
 	cam->params.compression.jpeg_options = CPIA2_VC_VC_JPEG_OPT_DEFAULT;
@@ -2188,7 +2120,7 @@ static void reset_camera_struct(struct camera_data *cam)
 	cam->params.vp_params.gpio_data = 0;
 
 	/* Target kb params */
-	cam->params.vc_params.target_kb = DEFAULT_TARGET_KB;
+	cam->params.vc_params.quality = 100;
 
 	/***
 	 * Set Sensor FPS as fast as possible.
@@ -2228,7 +2160,7 @@ static void reset_camera_struct(struct camera_data *cam)
  *
  *  Initializes camera struct, does not call reset to fill in defaults.
  *****************************************************************************/
-struct camera_data *cpia2_init_camera_struct(void)
+struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf)
 {
 	struct camera_data *cam;
 
@@ -2239,8 +2171,13 @@ struct camera_data *cpia2_init_camera_struct(void)
 		return NULL;
 	}
 
+	cam->v4l2_dev.release = cpia2_camera_release;
+	if (v4l2_device_register(&intf->dev, &cam->v4l2_dev) < 0) {
+		v4l2_err(&cam->v4l2_dev, "couldn't register v4l2_device\n");
+		kfree(cam);
+		return NULL;
+	}
 
-	cam->present = 1;
 	mutex_init(&cam->v4l2_lock);
 	init_waitqueue_head(&cam->wq_stream);
 
@@ -2373,11 +2310,6 @@ long cpia2_read(struct camera_data *cam,
 		return -EINVAL;
 	}
 
-	if (!cam->present) {
-		LOG("%s: camera removed\n",__func__);
-		return 0;	/* EOF */
-	}
-
 	if (!cam->streaming) {
 		/* Start streaming */
 		cpia2_usb_stream_start(cam,
@@ -2393,12 +2325,12 @@ long cpia2_read(struct camera_data *cam,
 	if (frame->status != FRAME_READY) {
 		mutex_unlock(&cam->v4l2_lock);
 		wait_event_interruptible(cam->wq_stream,
-			       !cam->present ||
+			       !video_is_registered(&cam->vdev) ||
 			       (frame = cam->curbuff)->status == FRAME_READY);
 		mutex_lock(&cam->v4l2_lock);
 		if (signal_pending(current))
 			return -ERESTARTSYS;
-		if (!cam->present)
+		if (!video_is_registered(&cam->vdev))
 			return 0;
 	}
 
@@ -2423,17 +2355,10 @@ long cpia2_read(struct camera_data *cam,
 unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
 			poll_table *wait)
 {
-	unsigned int status=0;
+	unsigned int status = v4l2_ctrl_poll(filp, wait);
 
-	if (!cam) {
-		ERR("%s: Internal error, camera_data not found!\n",__func__);
-		return POLLERR;
-	}
-
-	if (!cam->present)
-		return POLLHUP;
-
-	if(!cam->streaming) {
+	if ((poll_requested_events(wait) & (POLLIN | POLLRDNORM)) &&
+			!cam->streaming) {
 		/* Start streaming */
 		cpia2_usb_stream_start(cam,
 				       cam->params.camera_state.stream_mode);
@@ -2441,10 +2366,8 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
 
 	poll_wait(filp, &cam->wq_stream, wait);
 
-	if(!cam->present)
-		status = POLLHUP;
-	else if(cam->curbuff->status == FRAME_READY)
-		status = POLLIN | POLLRDNORM;
+	if (cam->curbuff->status == FRAME_READY)
+		status |= POLLIN | POLLRDNORM;
 
 	return status;
 }
@@ -2462,12 +2385,9 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
 	unsigned long start = (unsigned long) adr;
 	unsigned long page, pos;
 
-	if (!cam)
-		return -ENODEV;
-
 	DBG("mmap offset:%ld size:%ld\n", start_offset, size);
 
-	if (!cam->present)
+	if (!video_is_registered(&cam->vdev))
 		return -ENODEV;
 
 	if (size > cam->frame_size*cam->num_frames  ||

+ 59 - 19
drivers/media/video/cpia2/cpia2_usb.c

@@ -54,6 +54,8 @@ static void cpia2_usb_complete(struct urb *urb);
 static int cpia2_usb_probe(struct usb_interface *intf,
 			   const struct usb_device_id *id);
 static void cpia2_usb_disconnect(struct usb_interface *intf);
+static int cpia2_usb_suspend(struct usb_interface *intf, pm_message_t message);
+static int cpia2_usb_resume(struct usb_interface *intf);
 
 static void free_sbufs(struct camera_data *cam);
 static void add_APPn(struct camera_data *cam);
@@ -74,6 +76,9 @@ static struct usb_driver cpia2_driver = {
 	.name		= "cpia2",
 	.probe		= cpia2_usb_probe,
 	.disconnect	= cpia2_usb_disconnect,
+	.suspend	= cpia2_usb_suspend,
+	.resume		= cpia2_usb_resume,
+	.reset_resume	= cpia2_usb_resume,
 	.id_table	= cpia2_id_table
 };
 
@@ -218,10 +223,9 @@ static void cpia2_usb_complete(struct urb *urb)
 		return;
 	}
 
-	if (!cam->streaming || !cam->present || cam->open_count == 0) {
-		LOG("Will now stop the streaming: streaming = %d, "
-		    "present=%d, open_count=%d\n",
-		    cam->streaming, cam->present, cam->open_count);
+	if (!cam->streaming || !video_is_registered(&cam->vdev)) {
+		LOG("Will now stop the streaming: streaming = %d, present=%d\n",
+		    cam->streaming, video_is_registered(&cam->vdev));
 		return;
 	}
 
@@ -392,7 +396,7 @@ static int configure_transfer_mode(struct camera_data *cam, unsigned int alt)
 	struct cpia2_command cmd;
 	unsigned char reg;
 
-	if(!cam->present)
+	if (!video_is_registered(&cam->vdev))
 		return -ENODEV;
 
 	/***
@@ -752,8 +756,8 @@ int cpia2_usb_stream_pause(struct camera_data *cam)
 {
 	int ret = 0;
 	if(cam->streaming) {
-		ret = set_alternate(cam, USBIF_CMDONLY);
 		free_sbufs(cam);
+		ret = set_alternate(cam, USBIF_CMDONLY);
 	}
 	return ret;
 }
@@ -770,6 +774,10 @@ int cpia2_usb_stream_resume(struct camera_data *cam)
 		cam->first_image_seen = 0;
 		ret = set_alternate(cam, cam->params.camera_state.stream_mode);
 		if(ret == 0) {
+			/* for some reason the user effects need to be set
+			   again when starting streaming. */
+			cpia2_do_command(cam, CPIA2_CMD_SET_USER_EFFECTS, TRANSFER_WRITE,
+					cam->params.vp_params.user_effects);
 			ret = submit_urbs(cam);
 		}
 	}
@@ -784,6 +792,7 @@ int cpia2_usb_stream_resume(struct camera_data *cam)
 int cpia2_usb_stream_stop(struct camera_data *cam)
 {
 	int ret;
+
 	ret = cpia2_usb_stream_pause(cam);
 	cam->streaming = 0;
 	configure_transfer_mode(cam, 0);
@@ -812,7 +821,8 @@ static int cpia2_usb_probe(struct usb_interface *intf,
 	/* If we get to this point, we found a CPiA2 camera */
 	LOG("CPiA2 USB camera found\n");
 
-	if((cam = cpia2_init_camera_struct()) == NULL)
+	cam = cpia2_init_camera_struct(intf);
+	if (cam == NULL)
 		return -ENOMEM;
 
 	cam->dev = udev;
@@ -825,16 +835,9 @@ static int cpia2_usb_probe(struct usb_interface *intf,
 		return ret;
 	}
 
-	if ((ret = cpia2_register_camera(cam)) < 0) {
-		ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret);
-		kfree(cam);
-		return ret;
-	}
-
 
 	if((ret = cpia2_init_camera(cam)) < 0) {
 		ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret);
-		cpia2_unregister_camera(cam);
 		kfree(cam);
 		return ret;
 	}
@@ -853,6 +856,13 @@ static int cpia2_usb_probe(struct usb_interface *intf,
 
 	usb_set_intfdata(intf, cam);
 
+	ret = cpia2_register_camera(cam);
+	if (ret < 0) {
+		ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret);
+		kfree(cam);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -865,13 +875,16 @@ 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);
 
+	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");
@@ -884,14 +897,41 @@ static void cpia2_usb_disconnect(struct usb_interface *intf)
 	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");
+}
+
+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);
 
-	LOG("CPiA2 camera disconnected.\n");
+	dev_info(&intf->dev, "going into suspend..\n");
+	return 0;
 }
 
+/* Resume device - start device. */
+static int cpia2_usb_resume(struct usb_interface *intf)
+{
+	struct camera_data *cam = usb_get_intfdata(intf);
+
+	mutex_lock(&cam->v4l2_lock);
+	v4l2_ctrl_handler_setup(&cam->hdl);
+	if (cam->streaming) {
+		cam->streaming = 0;
+		cpia2_usb_stream_start(cam,
+				cam->params.camera_state.stream_mode);
+	}
+	mutex_unlock(&cam->v4l2_lock);
+
+	dev_info(&intf->dev, "coming out of suspend..\n");
+	return 0;
+}
 
 /******************************************************************************
  *

File diff suppressed because it is too large
+ 192 - 561
drivers/media/video/cpia2/cpia2_v4l.c


+ 0 - 50
drivers/media/video/cpia2/cpia2dev.h

@@ -1,50 +0,0 @@
-/****************************************************************************
- *
- *  Filename: cpia2dev.h
- *
- *  Copyright 2001, STMicrolectronics, Inc.
- *
- *  Contact:  steve.miller@st.com
- *
- *  Description:
- *     This file provides definitions for applications wanting to use the
- *     cpia2 driver beyond the generic v4l capabilities.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************************/
-
-#ifndef CPIA2_DEV_HEADER
-#define CPIA2_DEV_HEADER
-
-#include <linux/videodev2.h>
-
-/***
- * The following defines are ioctl numbers based on video4linux private ioctls,
- * which can range from 192 (BASE_VIDIOCPRIVATE) to 255. All of these take int
- * args
- */
-#define CPIA2_IOC_SET_GPIO         _IOW('v', BASE_VIDIOC_PRIVATE + 17, __u32)
-
-/* V4L2 driver specific controls */
-#define CPIA2_CID_TARGET_KB     (V4L2_CID_PRIVATE_BASE+0)
-#define CPIA2_CID_GPIO          (V4L2_CID_PRIVATE_BASE+1)
-#define CPIA2_CID_FLICKER_MODE  (V4L2_CID_PRIVATE_BASE+2)
-#define CPIA2_CID_FRAMERATE     (V4L2_CID_PRIVATE_BASE+3)
-#define CPIA2_CID_USB_ALT       (V4L2_CID_PRIVATE_BASE+4)
-#define CPIA2_CID_LIGHTS        (V4L2_CID_PRIVATE_BASE+5)
-#define CPIA2_CID_RESET_CAMERA  (V4L2_CID_PRIVATE_BASE+6)
-
-#endif

Some files were not shown because too many files changed in this diff