[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>
This commit is contained in:
parent
04ef052419
commit
6c493f8b28
@ -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);
|
||||
|
||||
|
@ -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 ||
|
||||
|
@ -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);
|
||||
|
||||
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
Load Diff
@ -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
|
Loading…
x
Reference in New Issue
Block a user