From 6c493f8b28c6744995e92801a20dca192635dd22 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 29 Apr 2012 08:44:44 -0300 Subject: [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 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cpia2/cpia2_core.c | 142 +++++++-------------------------- 1 file changed, 31 insertions(+), 111 deletions(-) (limited to 'drivers/media/video/cpia2/cpia2_core.c') diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c index ee91e295c90a..17188e234770 100644 --- a/drivers/media/video/cpia2/cpia2_core.c +++ b/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 || -- cgit